CérénIT - load-balancerLe blog tech de Nicolas Steinmetz (Time Series, IoT, Web, Ops, Data)Zola2019-01-23T21:15:00+01:00https://cerenit.fr/tags/load-balancer/atom.xmlKubernetes @ OVH - Traefik en Deployment et intégration des Load Balancers2019-01-23T21:15:00+01:002019-01-23T21:15:00+01:00
Unknown
https://cerenit.fr/blog/kubernetes-traefik-deployment-load-balancer-ovh/<p>Pour faire suite au billet sur le <a href="/blog/kubernetes-traefik-daemonset-ovh/">déploiement de Traefik sous la forme d'un DaemonSet chez OVH</a>, j'ai profité de la sortie en mode beta des Load Balancers pour revoir ma copie :</p>
<ul>
<li>Déploiement de Traefik sous la forme d'un Deployment plutôt qu'un DaemonSet,</li>
<li>Intégration des Load Balancers,</li>
<li>Utilisation d'un namespace "traefik" plutôt que de tout mettre dans kube-system.</li>
</ul>
<p>Par simplicité, je n'ai toujours qu'une node en plus du master fourni par OVH. Cela m'évite la problématique du stockage distribué des certificats. Cela fera l'objet d'un autre billet.</p>
<p>Créons le namespace traefik :</p>
<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#65737e;"># Create namespace
</span><span style="color:#bf616a;">kubectl</span><span> create ns traefik
</span><span style="color:#65737e;"># Change context to this namespace so that all commands are by default run for this namespace
</span><span style="color:#65737e;"># see https://github.com/ahmetb/kubectx
</span><span style="color:#bf616a;">kubens</span><span> traefik
</span></code></pre>
<p>Commençons par <code>traefik/rbac.yml</code> - le fichier défini le compte de service (<code>Service Account</code>), le rôle au niveau du cluster (<code>Cluster Role</code>) et la liaison entre le rôle et le compte de service (<code>Cluster Role Binding</code>)</p>
<pre data-lang="yaml" style="background-color:#2b303b;color:#c0c5ce;" class="language-yaml "><code class="language-yaml" data-lang="yaml"><span>---
</span><span style="color:#bf616a;">apiVersion</span><span>: </span><span style="color:#a3be8c;">v1
</span><span style="color:#bf616a;">kind</span><span>: </span><span style="color:#a3be8c;">ServiceAccount
</span><span style="color:#bf616a;">metadata</span><span>:
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-controller
</span><span> </span><span style="color:#bf616a;">namespace</span><span>: </span><span style="color:#a3be8c;">traefik
</span><span>---
</span><span style="color:#bf616a;">kind</span><span>: </span><span style="color:#a3be8c;">ClusterRole
</span><span style="color:#bf616a;">apiVersion</span><span>: </span><span style="color:#a3be8c;">rbac.authorization.k8s.io/v1beta1
</span><span style="color:#bf616a;">metadata</span><span>:
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-controller
</span><span style="color:#bf616a;">rules</span><span>:
</span><span> - </span><span style="color:#bf616a;">apiGroups</span><span>:
</span><span> - ""
</span><span> </span><span style="color:#bf616a;">resources</span><span>:
</span><span> - </span><span style="color:#a3be8c;">services
</span><span> - </span><span style="color:#a3be8c;">endpoints
</span><span> - </span><span style="color:#a3be8c;">secrets
</span><span> </span><span style="color:#bf616a;">verbs</span><span>:
</span><span> - </span><span style="color:#a3be8c;">get
</span><span> - </span><span style="color:#a3be8c;">list
</span><span> - </span><span style="color:#a3be8c;">watch
</span><span> - </span><span style="color:#bf616a;">apiGroups</span><span>:
</span><span> - </span><span style="color:#a3be8c;">extensions
</span><span> </span><span style="color:#bf616a;">resources</span><span>:
</span><span> - </span><span style="color:#a3be8c;">ingresses
</span><span> </span><span style="color:#bf616a;">verbs</span><span>:
</span><span> - </span><span style="color:#a3be8c;">get
</span><span> - </span><span style="color:#a3be8c;">list
</span><span> - </span><span style="color:#a3be8c;">watch
</span><span>---
</span><span style="color:#bf616a;">kind</span><span>: </span><span style="color:#a3be8c;">ClusterRoleBinding
</span><span style="color:#bf616a;">apiVersion</span><span>: </span><span style="color:#a3be8c;">rbac.authorization.k8s.io/v1beta1
</span><span style="color:#bf616a;">metadata</span><span>:
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-controller
</span><span style="color:#bf616a;">roleRef</span><span>:
</span><span> </span><span style="color:#bf616a;">apiGroup</span><span>: </span><span style="color:#a3be8c;">rbac.authorization.k8s.io
</span><span> </span><span style="color:#bf616a;">kind</span><span>: </span><span style="color:#a3be8c;">ClusterRole
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-controller
</span><span style="color:#bf616a;">subjects</span><span>:
</span><span>- </span><span style="color:#bf616a;">kind</span><span>: </span><span style="color:#a3be8c;">ServiceAccount
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-controller
</span><span> </span><span style="color:#bf616a;">namespace</span><span>: </span><span style="color:#a3be8c;">traefik
</span></code></pre>
<p>Ensuite, pour Traefik, j'ai besoin d'un fichier <code>traefik.toml</code> avec la configuration que je mets à disposition sous la forme d'une <code>ConfigMap</code> dans un fichier <code>traefik/traefik-toml-configmap.yml</code> :</p>
<pre data-lang="yaml" style="background-color:#2b303b;color:#c0c5ce;" class="language-yaml "><code class="language-yaml" data-lang="yaml"><span style="color:#bf616a;">apiVersion</span><span>: </span><span style="color:#a3be8c;">v1
</span><span style="color:#bf616a;">kind</span><span>: </span><span style="color:#a3be8c;">ConfigMap
</span><span style="color:#bf616a;">metadata</span><span>:
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-conf
</span><span style="color:#bf616a;">data</span><span>:
</span><span> </span><span style="color:#bf616a;">traefik.toml</span><span>: </span><span style="color:#b48ead;">|
</span><span style="color:#a3be8c;"> defaultEntryPoints = ["http", "https"]
</span><span style="color:#a3be8c;">
</span><span style="color:#a3be8c;"> logLevel = "INFO"
</span><span style="color:#a3be8c;">
</span><span style="color:#a3be8c;"> insecureSkipVerify = true
</span><span style="color:#a3be8c;">
</span><span style="color:#a3be8c;"> [entryPoints]
</span><span style="color:#a3be8c;"> [entryPoints.http]
</span><span style="color:#a3be8c;"> address = ":80"
</span><span style="color:#a3be8c;"> [entryPoints.http.redirect]
</span><span style="color:#a3be8c;"> entryPoint = "https"
</span><span style="color:#a3be8c;"> [entryPoints.https]
</span><span style="color:#a3be8c;"> address = ":443"
</span><span style="color:#a3be8c;"> [entryPoints.https.tls]
</span><span style="color:#a3be8c;"> [entryPoints.api]
</span><span style="color:#a3be8c;"> address = ":8080"
</span><span style="color:#a3be8c;">
</span><span style="color:#a3be8c;"> [acme]
</span><span style="color:#a3be8c;"> email = "contact@cerenit.fr"
</span><span style="color:#a3be8c;"> storage = "/acme/acme.json"
</span><span style="color:#a3be8c;"> entryPoint = "https"
</span><span style="color:#a3be8c;"> onHostRule = true
</span><span style="color:#a3be8c;"> [acme.httpChallenge]
</span><span style="color:#a3be8c;"> entryPoint = "http"
</span><span style="color:#a3be8c;">
</span><span style="color:#a3be8c;"> [api]
</span><span style="color:#a3be8c;"> entryPoint = "api"
</span><span style="color:#a3be8c;"> dashboard = true
</span><span style="color:#a3be8c;"> debug = false
</span><span style="color:#a3be8c;">
</span><span style="color:#a3be8c;"> [kubernetes]
</span></code></pre>
<p>Le dashboard est à protéger par une authentification pour éviter tout accès non souhaité. Je l'ai supprimé de la configuration par simplicité.</p>
<p>Ensuite, pour stocker mes certificats, il me faut un volume que je défini via le fichier <code>traefik/traefik-certificates-pvc.yml</code> :</p>
<pre data-lang="yaml" style="background-color:#2b303b;color:#c0c5ce;" class="language-yaml "><code class="language-yaml" data-lang="yaml"><span style="color:#bf616a;">kind</span><span>: </span><span style="color:#a3be8c;">PersistentVolumeClaim
</span><span style="color:#bf616a;">apiVersion</span><span>: </span><span style="color:#a3be8c;">v1
</span><span style="color:#bf616a;">metadata</span><span>:
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-certificates
</span><span style="color:#bf616a;">spec</span><span>:
</span><span> </span><span style="color:#bf616a;">accessModes</span><span>:
</span><span> - </span><span style="color:#a3be8c;">ReadWriteOnce
</span><span> </span><span style="color:#bf616a;">volumeMode</span><span>: </span><span style="color:#a3be8c;">Filesystem
</span><span> </span><span style="color:#bf616a;">resources</span><span>:
</span><span> </span><span style="color:#bf616a;">requests</span><span>:
</span><span> </span><span style="color:#bf616a;">storage</span><span>: </span><span style="color:#a3be8c;">1Gi
</span><span> </span><span style="color:#bf616a;">storageClassName</span><span>: </span><span style="color:#a3be8c;">cinder-classic
</span></code></pre>
<p>1 Go pour des certificats, c'est clairement trop mais il n'est pas possible pour le moment d'avoir un stockage plus réduit.</p>
<p>Je peux donc enfin déployer Traefik via le fichier <code>traefik/traefik-deployment.yml</code> :</p>
<pre data-lang="yaml" style="background-color:#2b303b;color:#c0c5ce;" class="language-yaml "><code class="language-yaml" data-lang="yaml"><span>---
</span><span style="color:#bf616a;">kind</span><span>: </span><span style="color:#a3be8c;">Deployment
</span><span style="color:#bf616a;">apiVersion</span><span>: </span><span style="color:#a3be8c;">extensions/v1beta1
</span><span style="color:#bf616a;">metadata</span><span>:
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-controller
</span><span> </span><span style="color:#bf616a;">labels</span><span>:
</span><span> </span><span style="color:#bf616a;">k8s-app</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-lb
</span><span style="color:#bf616a;">spec</span><span>:
</span><span> </span><span style="color:#bf616a;">replicas</span><span>: </span><span style="color:#d08770;">1
</span><span> </span><span style="color:#bf616a;">selector</span><span>:
</span><span> </span><span style="color:#bf616a;">matchLabels</span><span>:
</span><span> </span><span style="color:#bf616a;">k8s-app</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-lb
</span><span> </span><span style="color:#bf616a;">template</span><span>:
</span><span> </span><span style="color:#bf616a;">metadata</span><span>:
</span><span> </span><span style="color:#bf616a;">labels</span><span>:
</span><span> </span><span style="color:#bf616a;">k8s-app</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-lb
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-lb
</span><span> </span><span style="color:#bf616a;">spec</span><span>:
</span><span> </span><span style="color:#bf616a;">serviceAccountName</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-controller
</span><span> </span><span style="color:#bf616a;">terminationGracePeriodSeconds</span><span>: </span><span style="color:#d08770;">60
</span><span> </span><span style="color:#bf616a;">containers</span><span>:
</span><span> - </span><span style="color:#bf616a;">image</span><span>: </span><span style="color:#a3be8c;">traefik:1.7.7
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-lb
</span><span> </span><span style="color:#bf616a;">volumeMounts</span><span>:
</span><span> - </span><span style="color:#bf616a;">mountPath</span><span>: </span><span style="color:#a3be8c;">/config
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-config
</span><span> - </span><span style="color:#bf616a;">mountPath</span><span>: </span><span style="color:#a3be8c;">/acme
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">certificates
</span><span> </span><span style="color:#bf616a;">ports</span><span>:
</span><span> - </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">http
</span><span> </span><span style="color:#bf616a;">containerPort</span><span>: </span><span style="color:#d08770;">80
</span><span> - </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">admin
</span><span> </span><span style="color:#bf616a;">containerPort</span><span>: </span><span style="color:#d08770;">8080
</span><span> - </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">secure
</span><span> </span><span style="color:#bf616a;">containerPort</span><span>: </span><span style="color:#d08770;">443
</span><span> </span><span style="color:#bf616a;">args</span><span>:
</span><span> - </span><span style="color:#a3be8c;">--configfile=/config/traefik.toml
</span><span> </span><span style="color:#bf616a;">volumes</span><span>:
</span><span> - </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-config
</span><span> </span><span style="color:#bf616a;">configMap</span><span>:
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-conf
</span><span> - </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">certificates
</span><span> </span><span style="color:#bf616a;">persistentVolumeClaim</span><span>:
</span><span> </span><span style="color:#bf616a;">claimName</span><span>: </span><span style="color:#a3be8c;">traefik-certificates
</span></code></pre>
<p>Nous déployons donc :</p>
<ul>
<li>Traefik en Deployment</li>
<li>Les ports 80, 443 et 8080 sont définis</li>
<li>La configuration est une ConfigMap</li>
<li>Les certificats sont à déployer dans un volume</li>
</ul>
<p>Pour permettre au cluster d'accéder aux différents ports, il faut définir un service via le fichier <code>traefik-service-clusterip.yml</code> :</p>
<pre data-lang="yaml" style="background-color:#2b303b;color:#c0c5ce;" class="language-yaml "><code class="language-yaml" data-lang="yaml"><span>---
</span><span style="color:#bf616a;">kind</span><span>: </span><span style="color:#a3be8c;">Service
</span><span style="color:#bf616a;">apiVersion</span><span>: </span><span style="color:#a3be8c;">v1
</span><span style="color:#bf616a;">metadata</span><span>:
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-service-clusterip
</span><span style="color:#bf616a;">spec</span><span>:
</span><span> </span><span style="color:#bf616a;">selector</span><span>:
</span><span> </span><span style="color:#bf616a;">k8s-app</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-lb
</span><span> </span><span style="color:#bf616a;">ports</span><span>:
</span><span> - </span><span style="color:#bf616a;">protocol</span><span>: </span><span style="color:#a3be8c;">TCP
</span><span> </span><span style="color:#bf616a;">port</span><span>: </span><span style="color:#d08770;">80
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">web
</span><span> - </span><span style="color:#bf616a;">protocol</span><span>: </span><span style="color:#a3be8c;">TCP
</span><span> </span><span style="color:#bf616a;">port</span><span>: </span><span style="color:#d08770;">8080
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">admin
</span><span> - </span><span style="color:#bf616a;">protocol</span><span>: </span><span style="color:#a3be8c;">TCP
</span><span> </span><span style="color:#bf616a;">port</span><span>: </span><span style="color:#d08770;">443
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">secure
</span><span> </span><span style="color:#bf616a;">type</span><span>: </span><span style="color:#a3be8c;">ClusterIP
</span></code></pre>
<p>Et pour avoir un accès de l'extérieur, il faut instancier un load-balancer via le fichier <code>traefik/traefik-service-loadbalancer.yml</code></p>
<pre data-lang="yaml" style="background-color:#2b303b;color:#c0c5ce;" class="language-yaml "><code class="language-yaml" data-lang="yaml"><span style="color:#bf616a;">kind</span><span>: </span><span style="color:#a3be8c;">Service
</span><span style="color:#bf616a;">apiVersion</span><span>: </span><span style="color:#a3be8c;">v1
</span><span style="color:#bf616a;">metadata</span><span>:
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-service-lb
</span><span style="color:#bf616a;">spec</span><span>:
</span><span> </span><span style="color:#bf616a;">selector</span><span>:
</span><span> </span><span style="color:#bf616a;">k8s-app</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-lb
</span><span> </span><span style="color:#bf616a;">ports</span><span>:
</span><span> - </span><span style="color:#bf616a;">protocol</span><span>: </span><span style="color:#a3be8c;">TCP
</span><span> </span><span style="color:#bf616a;">port</span><span>: </span><span style="color:#d08770;">80
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">web
</span><span> - </span><span style="color:#bf616a;">protocol</span><span>: </span><span style="color:#a3be8c;">TCP
</span><span> </span><span style="color:#bf616a;">port</span><span>: </span><span style="color:#d08770;">443
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">secure
</span><span> </span><span style="color:#bf616a;">type</span><span>: </span><span style="color:#a3be8c;">LoadBalancer
</span></code></pre>
<p>Pour donner l'accès au dashboard via une url sécurisée par un certificat Let's Encrypt, il faut déclarer un Ingress, dans le fichier <code>traefik/traefik-api-ingress.yml</code> :</p>
<pre data-lang="yaml" style="background-color:#2b303b;color:#c0c5ce;" class="language-yaml "><code class="language-yaml" data-lang="yaml"><span>---
</span><span style="color:#bf616a;">apiVersion</span><span>: </span><span style="color:#a3be8c;">extensions/v1beta1
</span><span style="color:#bf616a;">kind</span><span>: </span><span style="color:#a3be8c;">Ingress
</span><span style="color:#bf616a;">metadata</span><span>:
</span><span> </span><span style="color:#bf616a;">name</span><span>: </span><span style="color:#a3be8c;">traefik-web-ui
</span><span style="color:#bf616a;">spec</span><span>:
</span><span> </span><span style="color:#bf616a;">rules</span><span>:
</span><span> - </span><span style="color:#bf616a;">host</span><span>: </span><span style="color:#a3be8c;">traefik.k8s.cerenit.fr
</span><span> </span><span style="color:#bf616a;">http</span><span>:
</span><span> </span><span style="color:#bf616a;">paths</span><span>:
</span><span> - </span><span style="color:#bf616a;">path</span><span>: </span><span style="color:#a3be8c;">/
</span><span> </span><span style="color:#bf616a;">backend</span><span>:
</span><span> </span><span style="color:#bf616a;">serviceName</span><span>: </span><span style="color:#a3be8c;">traefik-ingress-service
</span><span> </span><span style="color:#bf616a;">servicePort</span><span>: </span><span style="color:#a3be8c;">admin
</span></code></pre>
<p>Il ne nous reste plus qu'à faire :</p>
<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#65737e;"># Create k8s ressources for traefik
</span><span style="color:#bf616a;">kubectl</span><span> create</span><span style="color:#bf616a;"> -f</span><span> traefik/
</span><span style="color:#65737e;"># Watch service to get IPs
</span><span style="color:#bf616a;">kubectl</span><span> get svc</span><span style="color:#bf616a;"> -w
</span></code></pre>
<p>Une fois votre IP obtenue, il suffit de faire pointer votre entrée DNS vers cette IP ou de tester via :</p>
<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">curl -H </span><span>"</span><span style="color:#a3be8c;">Host: traefik.k8s.cerenit.fr</span><span>" https://xxx.xxx.xxx.xxx/
</span></code></pre>
<p>Pour l'obtention du certificat Let's Encrypt, il faut que votre enregistrement DNS soit à jour préalablement. Sinon vous aurez un certificat autosigné par Traefik en attendant.</p>
<p>Dès lors, vous pouvez accéder au dashboard de Traefik via l'url définie. Pour donner accès à d'autres sites, il faut déclarer d'autres ingress sur le même modèle et le tour est joué.</p>
<p>Comparativement au dernier tutoriel :</p>
<ul>
<li>Nous n'exposons plus le port 8080 au niveau de l'hôte,</li>
<li>Nous respectons plus les guidelines kubernetes à savoir de donner accès à une ressource via un service de type Load-Balancer ou NodePort</li>
<li>Nous utilisons une seule IP externe et nous appuyons sur les ingress pour mutualiser le load balancer et éviter d'avoir une IP publique par service à exposer</li>
<li>Nous ne sommes pas sur d'avoir un pod traefik par noeud mais nous gagnons en flexibilité - il faudra jouer avec les replicas dès qu'on ajoutera des nodes dans le cluster.</li>
</ul>
<p>Il reste encore le problème des stockage des certificats à résoudre pour passer à un contexte multi-nodes. Ce sera l'objet d'un prochain billet avec idéalement l'intégration de Traefik avec <a rel="noopener" target="_blank" href="http://docs.cert-manager.io/">cert-manager</a> (plutôt que de devoir déployer une base clé/valeur comme etcd ou consul pour y stocker les infos de traefik).</p>
<p>N'hésitez pas à me faire part de vos retours.</p>
Web, Ops & Data - Décembre 20182018-12-26T09:30:00+02:002018-12-26T09:30:00+02:00
Unknown
https://cerenit.fr/blog/web-ops-and-data-decembre-2018/<h3 id="cloud">Cloud</h3>
<ul>
<li>AWS Re:Invent 2018 : Difficle de passer à coté des annonces d'AWS - <a rel="noopener" target="_blank" href="https://blog.ippon.fr/2018/11/27/re-invent-2018-jour-1/">AWS re:Invent 2018 - Jour 1</a>, <a rel="noopener" target="_blank" href="https://blog.ippon.fr/2018/11/28/aws-re-invent-2018-jour-2/">AWS re:Invent 2018 - Jour 2</a>, <a rel="noopener" target="_blank" href="https://blog.ippon.fr/2018/11/29/aws-re-invent-jour-3/">AWS re:Invent - Jour 3</a>, <a rel="noopener" target="_blank" href="https://blog.ippon.fr/2018/11/29/aws-re-invent-jour-4/">AWS re:Invent - Jour 4</a> : le résumé des sorties de la conférence AWS re:Invent 2018 par le cabinet Ippon.</li>
<li><a rel="noopener" target="_blank" href="https://www.spreaker.com/user/guignol/ep-9-quentin-adam-horacio-gonzales-steve">#9 - Quentin Adam - Horacio Gonzales - Steven Le-Roux - La guerre du cloud</a> : dans cet épisoide du podcast databuzzword, il est question de guerre du cloud, du multi-cloud, d'AWS et de ses "partenariats" et du cloud chinois et russe.</li>
<li><a rel="noopener" target="_blank" href="https://www.spreaker.com/user/vhe74/episode-63-re-invent-le-cloud">Episode 63 : “Re-Invent le Cloud”</a> : L'épisode 63 de BigDataHebdo s'intéresse aussi aux annonces de la conférence d'AWS et discute aussi d'AWS et du monde de l'opensource.</li>
<li><a rel="noopener" target="_blank" href="https://www.confluent.io/blog/license-changes-confluent-platform">License Changes for Confluent Platform</a> : la sortie de l'offre Kafka managé n'a pas plus à Confluent. A l'instar de Redis et MongoDB, c'est au tour de Confluent d'adopter une licence plus restrictive pour les fournisseurs de cloud dans le cadre de la distribution de sa platforme Confluent. La licence de Kafka est inchangé, cela concerne l'API Rest, la Schema REgistry, KSQL et des connecteurs confluent.</li>
<li><a rel="noopener" target="_blank" href="https://www.influxdata.com/blog/copyleft-and-community-licenses-are-not-without-merit-but-they-are-a-dead-end/">Copyleft and community licenses are not without merit, but they are a dead end</a> : Paul Dix, le CTO D'InfluxData donne son avis sur les changements de licences en cours. Un point intéressant est que ce changement de license vers des licences de type "Community" va surtout pénaliser les développeurs en créant une incertitude autour du mode de collaboration/contribution et peuvent aussi chercher à créer un monopole pour les services SasS créés par l'éditeur du produit. Oui il est dommage qu'AWS par ex ne contribue pas à Kafka/Confluent dans le cadre de son offre managée, mais par la même occasion Confluent se crée un monopole de fait sur l'offre SaaS autour de KSQL. Est-ce vraiment mieux ? En ce sens, Paul préfère alors soit du tout open ou tout fermé - mais que la solution du milieu n'est pas si idéale que ça (surtout pour des couches basses des produits sur lequel nous sommes censés bâtir quelque chose).</li>
<li><a rel="noopener" target="_blank" href="https://medium.com/sustainable-free-and-open-source-communities/we-need-sustainable-free-and-open-source-communities-edf92723d619">We need Sustainable Free and Open Source Communities</a> : Pour finir sur une note plus optimiste, l'auteur cherche à renverser la conversation en regardant comment créer des communautés soutenables et faire en sorte que la licence permette de soutenir la communauté. Pas sur que les libristes les plus convaincus n'y voient pas une atteinte aux libertés du logiciel justement : <em>"Any commercial activity around the software must further the sustainability of the community, and the potential for commercial benefit must be available to all. The incentives in any commercial model must bend away from the creation of proprietary downstream software"</em></li>
</ul>
<h3 id="container-et-orchestration">Container et orchestration</h3>
<ul>
<li><a rel="noopener" target="_blank" href="https://blog.containo.us/introducing-traefik-enterprise-edition-83b78d09efeb">Introducing Traefik Enterprise Edition</a> : le reverse proxy Traefik voit apparaitre une version Entreprise qui se veut plus distribuée avec l'apparition d'un "data plane" qui gère les connexions et joue le rôle de reverse proxy et un "control plane" qui coordonne le bon fonctionnement des noeuds.</li>
<li><a rel="noopener" target="_blank" href="https://www.cncf.io/blog/2018/12/11/cncf-to-host-etcd/">CNCF to Host etcd</a> : la base clé/valeur distribuée etcd et qui sert notamment de datastore pour kubernetes va être hébergé par la CNCF. Elle fut développée initiallement par CoreOS, désormais propriété de Red Hat (et donc IBM).</li>
<li><a rel="noopener" target="_blank" href="https://blog.openshift.com/podcast-podctl-kube-security-kube-1-13-and-kubecon/">[Podcast] PodCTL – Kube Security, Kube 1.13 and KubeCon</a> : </li>
<li><a rel="noopener" target="_blank" href="https://metallb.universe.tf/">MetalLB</a> : MetalLB propose de fournir un service de type load balancer prévu pour cluster Kubernetes dans un contexte bare metal (ie non cloud).</li>
<li><a rel="noopener" target="_blank" href="https://kubernetespodcast.com/episode/032-metal-lb/">MetalLB, with David Anderson</a> : Episode du <a rel="noopener" target="_blank" href="https://kubernetespodcast.com">Kubernetes Podcast</a> sur MetalLB avec son auteur pour une présentation de la solution.</li>
</ul>
<h3 id="dataviz">Dataviz</h3>
<ul>
<li><a rel="noopener" target="_blank" href="https://grafana.com/blog/2018/12/03/grafana-v5.4-released/">Grafana v5.4 Released</a> : une version de consolidation avec des améliorations sur la temporisation des alertes avant de l'émettre. D'autres améliorations sur l'intégration Google Stackdriver, l'éditeur de requêtes MySQL et des améliorations sur les panels et des préférences d'équipes.</li>
</ul>
<h3 id="langages">Langages</h3>
<ul>
<li><a rel="noopener" target="_blank" href="https://makina-corpus.com/blog/metier/2018/pourquoi-mettre-a-jour-son-python-regulierement">Pourquoi mettre à jour son Python (régulièrement)</a> : après un petit point sur les versions disponibles et par défaut dans vos distributions préférées, une piste liste des modules sympathiques est donnée avec des exemples pour apprécier la chose.</li>
</ul>
<p>Il ne me reste plus qu'à vous souhaiter de bonnes fêtes de fin d'année et à vous retrouver l'année prochaine pour de nouvelles aventures.</p>
<h3 id="methodologie">Méthodologie</h3>
<ul>
<li><a rel="noopener" target="_blank" href="http://archiloque.net/blog/infliger-de-l-aide/">Infliger de l’aide</a> : Quand une personne demande de l'aide et qu'on n'y met pas d'empathie, on peut alors lui infliger de l'aide - Je pense que je vais reprendre ce concept et l'appliquer.</li>
</ul>
<h3 id="securite">Sécurité</h3>
<ul>
<li><a rel="noopener" target="_blank" href="https://www.hashicorp.com/blog/vault-1-0">HashiCorp Vault 1.0</a> : la solution de gestion de secrets atteind la version 1.0.</li>
</ul>
<h3 id="tests">Tests</h3>
<ul>
<li>En écoutant l'épisode <a rel="noopener" target="_blank" href="http://artisandeveloppeur.fr/objectif-100-de-couverture-avec-michael-azerhad/">Objectif 100% de couverture !</a>, j’ai découvert le <a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/Mutation_testing">Mutuation Testing</a>. Ce n’est pas récent, Octo en parlait en 2011 : <a rel="noopener" target="_blank" href="https://blog.octo.com/mutation-testing-un-pas-de-plus-vers-la-perfection/">Mutation Testing, un pas de plus vers la perfection</a>. Quelques ressources complémentaires : <a rel="noopener" target="_blank" href="https://blog.eleven-labs.com/fr/mutation-testing-verifiez-la-qualite-de-vos-tests-unitaires/">Mutation Testing – Vérifiez la qualité de vos tests unitaires</a> ou <a rel="noopener" target="_blank" href="https://fr.slideshare.net/loicknuchel/mutation-testing-enfin-une-bonne-mesure-de-la-qualit-des-tests-rivieradev-le-18052018">Mutation testing, enfin une bonne mesure de la qualité des tests ?</a> qui expliquent le concept et donne des libs sont conseillés dans différents langages. En Java, il s'agirait de <a rel="noopener" target="_blank" href="http://pitest.org/">PIT</a>.</li>
</ul>
<h3 id="web">Web</h3>
<ul>
<li><a rel="noopener" target="_blank" href="https://blogs.windows.com/windowsexperience/2018/12/06/microsoft-edge-making-the-web-better-through-more-open-source-collaboration/#GmSJg4uFjBM5y8Hz.97">Microsoft Edge: Making the web better through more open source collaboration</a> : Microsoft va reconstruire son navigateur Edge sur la base de Chromium au lieu de son propre moteur (EdgeHTML). Mozilla déplore cette décision dans un billet <a rel="noopener" target="_blank" href="https://blog.mozilla.org/blog/2018/12/06/goodbye-edge/">"Goodbye EdgeHTML"</a> et rappelle de la nécessité d'une saine compétition pour ne pas tomber dans un "Chrome is the new IE6". Commitstrip dit la même chose en soulignant le paradoxe des développeurs dans <a rel="noopener" target="_blank" href="http://www.commitstrip.com/fr/2018/12/12/chromedge/">ChromEdge</a>.</li>
</ul>
<h3 id="windows">Windows</h3>
<ul>
<li><a rel="noopener" target="_blank" href="https://blogs.windows.com/buildingapps/2018/12/11/windows-server-2019-includes-openssh/">Windows Server 2019 Includes OpenSSH</a> : Après le <a rel="noopener" target="_blank" href="https://docs.microsoft.com/en-us/windows/wsl/install-win10">Windows Subsystem for Linux</a>, c'est au tour de Windows Server 2019 d'accueillir un autre composant phare, à savoir un serveur OpenSSH.</li>
</ul>