Toute l'actualité devOps
Sécurité - Trivy scanne désormais les clusters Kubernetes
Table des matières Introduction Installation de Trivy Audit d’un cluster Audit par défaut Audit CIS Conclusion Introduction Trivy fait partie de ma liste d’outils que j’utilise couramment sur poste de développement. Pour ceux qui ne connaissent pas Trivy, il s’agit d’un outil d’audit de sécurité tout-en-un pour les conteneurs. La dernière version apporte l’audit CIS des clusters kubernetes. Rappel : CIS est une organisation sans but lucratif qui fournit des recommandations sur les meilleures pratiques en matière de sécurité.

Sécurité - Trivy scanne désormais les clusters...
Table des matières Introduction Installation de Trivy Audit d’un cluster...
Source: Stéphane ROBERT
Kubernetes multi cluster et multi région en GitOps avec ArgoCD
Je présenterai dans cet article comment gérer les applications et ressources déployées sur plusieurs clusters Kubernetes, déployés dans plusieurs datacenters, avec ArgoCD. ArgoCD ArgoCD est un outil de déploiement continu pour Kubernetes, permettant de configurer en GitOps vos clusters. Cet outil est capable de gérer tout type de ressources Kubernetes (sans aucune limitations, CRD incluses). Il supporte également très bien l’écosystème Kubernetes standard pour gérer les manifests de déploiements (Helm, Kustomize… mais étendre l’outil avec ses propres outils est également possible), et dispose égalemement d’une très bonne interface utilisateur. ArgoCD est l’outil que je recommande le plus aujourd’hui pour les utilisateurs de Kubernetes. Nous commencerons dans cet article par expliquer rapidement le fonctionnement d’ArgoCD, puis nous déploierons 3 clusters Kubernetes sur Exoscale. SKS, l’offre Kubernetes as a service d’Exoscale, est actuellement la meilleure offre "managed Kubernetes" européenne, meilleure en tout point de vue par rapport à celles de Scaleway et OVH. C’est aussi celle la plus facile et rapide à déployer et à administrer. Mais il serait tout à fait possible de réaliser l’architecture de ce tutoriel sur un autre cloud provider, on premise, ou même en mode "multi cloud" pour une meilleure tolérance aux pannes ! C’est une des forces de Kubernetes: c’est disponible partout. Un cluster sera utilisé pour déployer ArgoCD. Les deux autres seront eux gérés par l’instance ArgoCD installée sur le premier cluster. Chaque cluster sera déployé dans un datacenter séparé, dans des pays différents. Je trouve cette approche intéressante pour plusieurs raisons: ArgoCD pilote l’ensemble des clusters et permet donc d’avoir une gestion de configuration de ces clusters centralisée, notamment grâce aux ApplicationSet que je présenterai plus loin. Toutes les ressources déployées dans tous les clusters seront par exemple visibles dans l’interface d’ArgoCD. Le cluster où ArgoCD tourne peut être très simple (avec seulement ArgoCD et pour un cas réel de production quelques outils de monitoring). Cela donne un cluster facile à administrer, facile à reconstruire, et peu coûteux. Cela peut avoir l’air d’un Single Point of Failure mais perdre ArgoCD n’est pas très grave: toutes les applications continuent de tourner, seulement les mises à jour seront impossibles. Si le cluster est complètement reconstructible en quelques minutes (ce qui est largement faisable sur le cloud), ArgoCD n’est plus vraiment un SPOF. Vous pouvez même si vous le souhaitez avoir un cluster Kubernetes passif avec ArgoCD préinstallé mais désactivé (0 replica), pour pouvoir à tout moment le redémarrer en cas de perte du cluster principal. Votre source de vérité sera de toute façon Git, le cluster ArgoCD sera complètement stateless. On voit sur cette image que seul le cluster Kubernetes à Genève aura ArgoCD d’installé. Il pilotera les deux autres clusters installés dans deux autres datacenters (Zurich et Vienne), et pourra également être utilisé pour se configure soit même. Avec cette architecture, des load balancers devant vos clusters Kubernetes et du DNS, vous pouvez facilement avoir des applications fortement tolérantes aux pannes, en actif/passif entre régions et clouds ou même en actif/actif si votre architecture le permet. Je vais maintenant présenter très brièvement les différentes CRD d’ArgoCD. Pour plus d’informations, lisez la documentation de l’outil. Project La première ressource importante d’ArgoCD est AppProject. Un AppProject est une abstraction permettant de regrouper des Applications (présentées juste après) ensemble. Les AppProject permettent d’exprimer des choses comme "dans le namespace monitoring de Kubernetes, je n’ai le droit que de déployer que les applications venant du dépot gît dont l’URL est github.com/mon-org/monitoring.git, et j’autorise seulement ces types de ressources Kubernetes (deployment, service, ingress…) à être déployés". Un exemple: apiVersion: argoproj.io/v1alpha1 kind: AppProject metadata: name: example-project namespace: argocd spec: sourceRepos: - '*' destinations: - namespace: '*' server: '*' clusterResourceWhitelist: - group: '*' kind: '*' Ce projet appelé example-project autorise tout. SourceRepos, la liste des dépôts Git autorisés à être déployés pour ce projet, contient *. On pourrait la remplacer comme dit précédemment par les addresses des dépôts autorisés à être déployés. destinations permet de configurer dans quelles namespaces et servers (clusters kubernetes) les applications peuvent être déployées. Enfin, clusterResourceWhitelist permet de spécifier quelles types de ressources Kubernetes sont autorisées. Application Une Application représente un groupe de ressources Kubernetes gérées par ArgoCD: apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: guestbook namespace: argocd spec: project: default source: repoURL: https://github.com/argoproj/argocd-example-apps.git targetRevision: HEAD path: guestbook destination: server: https://kubernetes.default.svc namespace: guestbook Cette application s’appelle guestbook. Le paramètre source dans la spec permet de référencer un dépôt Git contenant les fichiers Kubernetes à déployer. Le paramètre destination indique sur quel cluster les déployer, et dans quel namespace. Ici c’est le cluster où ArgoCD est déployé qui est ciblé. Ici, ArgoCD récupérera les fichiers présents dans https://github.com/argoproj/argocd-example-apps, dans le dossier guestbook (le paramètre path de la source), et les déploiera sur le cluster Kubernetes local (où ArgoCD tourne, accessible sur https://kubernetes.default.svc) et dans le namespace guestbook Dans cet exemples de simples fichiers sont déployés. La ressource Application supporte aussi des outils comme Helm, ou Kustomize. ApplicationSet On voit que la partie destination permet déjà de déployer sur plusieurs clusters Kubernetes depuis une même instance d’ArgoCD. Cela est pratique mais a un désavantage: si vous souhaitez déployer la même ressource sur 3 clusters, vous allez devoir définir 3 applications, chacunes avec une destination différente. C’est là que les ApplicationSet interviennent. Voici un exemple d’ApplicationSet: apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: guestbook namespace: argocd spec: generators: - clusters: {} template: metadata: name: '{{name}}-guestbook' spec: project: "default" source: repoURL: https://github.com/argoproj/argocd-example-apps/ targetRevision: HEAD path: guestbook destination: server: '{{server}}' namespace: guestbook On voit qu’une ApplicationSet est assez similaire à une Application: la partie template contient d’ailleurs la définition d’une Application. L’ApplicationSet va en fait être utilisée pour générer des ressources de type Application en fonction de générateurs (generators dans la configuration). Dans cet exemple, on utilise le generateur clusters qui génère par défaut une Application ArgoCD pour chaque cluster configuré dans ArgoCD (la partie suivante montrera comment configurer des clusters). La ressource ApplicationSet permet également de templatiser en fonction du générateur utilisé la configuration des Applications générées. Par exemple ici: La variable {{name}} contiendra le nom du cluster cible de l’application générée. La variable {{server}} contiendra l’URL du cluster cible. Si j’ai par exemple deux clusters configurés dans ArgoCD, l’un appelé cluster1 ayant pour URL cluster1.com, et l’autre appelé cluster2 ayant pour URL cluster2.com, cette ApplicationSet me génèrera 2 applications dont les noms seront cluster1-guestbook et cluster2-guestbook et dont les destinations seront les URL correspondantes. Il existe de très nombreux générateurs, permettant d’automatiser la génération d’applications ArgoCD en se basant sur de nombreux critères (clusters, Pull Requests ouvertes sur un projet Git, en fonction de fichiers, en fonction d’une simple liste de variables…). Les ApplicationSet sont un très bon outil pour éviter de passer son temps à réécrire plusieurs fois des Applications quasiment identiques. Les ApplicationSet autorisent aussi depuis peu des rollout progressifs, pour mettre à jour des clusters un par un dans un ordre pré-déterminé. Cas pratique Création des clusters Comme dit précédemment je vais utiliser Exoscale pour ce tutoriel. Vous pouvez reproduire l’exercice sur un autre cloud également avec quelques variations mais je vous recommande vraiment d’essayer l’offre d’Exoscale qui est de bonne qualité, et qui permet d’avoir dans son mode starter un contrôle plane Kubernetes gratuit. La documentation d’Exoscale vous explique comment créer un cluster grâce à sa CLI. Vous aurez besoin aussi de kubectl pour interagir avec Kubernetes. Le script suivant vous permettra de créer les 3 clusters comme montré dans la première image (dans 3 régions différentes). A noter qu’en production il vaudrait mieux créer un security group par cluster pour plus de sécurité, mais dans ce contexte de POC ce n’est pas trop grave de partager le même: #!/bin/bash set -e ## Création des règles réseaux exo compute security-group create sks-argo-tuto exo compute security-group rule add sks-argo-tuto --description "NodePort services" --protocol tcp --network 0.0.0.0/0 --port 30000-32767 exo compute security-group rule add sks-argo-tuto --description "SKS kubelet" --protocol tcp --port 10250 --security-group sks-argo-tuto exo compute security-group rule add sks-argo-tuto --description "Calico traffic" --protocol udp --port 4789 --security-group sks-argo-tuto ## Création des 3 clusters ### Premier cluster dans la région ch-gva-2 qui hébergera ArgoCD exo compute sks create argocd --zone ch-gva-2 --service-level starter --nodepool-name argocd --nodepool-instance-prefix argocd --nodepool-size 3 --nodepool-security-group sks-argo-tuto ### Second cluster dans la région ch-zrh-1 (anciennement appelée ch-dk-2) exo compute sks create zrh1 --zone ch-dk-2 --service-level starter --nodepool-name zrh1 --nodepool-instance-prefix zrh1 --nodepool-size 3 --nodepool-security-group sks-argo-tuto ### Troisième cluster dans la région at-vie-1 exo compute sks create vie1 --zone at-vie-1 --service-level starter --nodepool-name vie1 --nodepool-instance-prefix vie1 --nodepool-size 3 --nodepool-security-group sks-argo-tuto Récupération des kubeconfig Nous allons maintenant récupérer des fichiers Kubeconfig root pour chaque cluster dans le but de pouvoir intéragir avec eux via kubectl: exo compute sks kubeconfig argocd kube-admin --zone ch-gva-2 --group system:masters > argocd.kubeconfig exo compute sks kubeconfig zrh1 kube-admin --zone ch-dk-2 --group system:masters > zrh1.kubeconfig exo compute sks kubeconfig vie1 kube-admin --zone at-vie-1 --group system:masters > vie1.kubeconfig Vous devriez maintenant pouvoir par exemple lister les noeuds de vos clusters, avec kubectl --kubeconfig <kubeconfig-file> get nodes, par exemple kubectl --kubeconfig argocd.kubeconfig get nodes. Installation d’ArgoCD Nous allons maintenant installer ArgoCD sur le cluster Kubernetes de la zone ch-gva-2: kubectl --kubeconfig argocd.kubeconfig create namespace argocd kubectl --kubeconfig argocd.kubeconfig apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml Pour ce tutoriel nous désactivons pour plus de facilité l’authentification d’ArgoCD. ArgoCD supporte une gestion fine des utilisateurs et permissions (et supporte également des protocoles comme OIDC), donc n’hésitez pas à jeter un oeil à la documentation officielle. Exécutez tout d’abord kubectl --kubeconfig argocd.kubeconfig -n argocd edit configmap argocd-cm pour désactiver l’authentification. Rajoutez le block suivant dans le YAML affiché, sauvegardez et fermez votre éditeur: data: users.anonymous.enabled: "true" Faisons la même chose pour une seconde configmap via kubectl --kubeconfig argocd.kubeconfig -n argocd edit configmap argocd-rbac-cm, pour rendre admin l’utilisateur par défaut. data: policy.default: role:admin Rappel: ne faites pas ça sur un "vrai" cluster, ou même un cluster de test où ArgoCD est exposé sur internet ! Je ne vais pas configurer d’ingress controller dans ce tutoriel l’accès à ArgoCD se fera via kubectl port-forward. Lancez kubectl --kubeconfig argocd.kubeconfig port-forward svc/argocd-server -n argocd 8080:443 et ouvrez votre navigateur sur localhost:8080: une fois le certificat auto signé accepté vous devriez pouvoir accéder à l’interface d’ArgoCD. Configuration des clusters ArgoCD permet par défaut de déployer des applications sur le cluster où il est installé mais pas ailleurs. Nous allons donc reconfigurer les clusters dans ArgoCD. Cela se fait en créant un secret Kubernetes par cluster. Nous utiliserons ici directement les certificats contenus dans les kubeconfig générés précédemment pour s’authentifier aux clusters distants (pour le cluster local, l’authentification se fera par défaut via le service account d’ArgoCD). Voici la configuration à appliquer, en remplaçant les valeurs server et les certificats attendus par chaque cluster par ce que vous avez dans vos kubeconfig: --- apiVersion: v1 kind: Secret metadata: name: cluster-gva2 namespace: argocd labels: argocd.argoproj.io/secret-type: cluster type: Opaque stringData: name: gva2 server: https://kubernetes.default.svc --- apiVersion: v1 kind: Secret metadata: name: cluster-zrh1 namespace: argocd labels: argocd.argoproj.io/secret-type: cluster type: Opaque stringData: name: zrh1 server: "<contenu de server dans zrh1.kubeconfig>" config: | { "tlsClientConfig": { "caData": "<contenu de certificate-authority-data dans dans zrh1.kubeconfig>", "certData": "<contenu de client-certificate-data dans dans zrh1.kubeconfig>", "keyData": "<contenu de client-key-data dans dans zrh1.kubeconfig>" } } --- apiVersion: v1 kind: Secret metadata: name: cluster-vie1 namespace: argocd labels: argocd.argoproj.io/secret-type: cluster type: Opaque stringData: name: vie1 server: "<contenu de server dans vie1.kubeconfig>" config: | { "tlsClientConfig": { "caData": "<contenu de certificate-authority-data dans dans vie1.kubeconfig>", "certData": "<contenu de client-certificate-data dans dans vie1.kubeconfig>", "keyData": "<contenu de client-key-data dans dans vie1.kubeconfig>" } } Note Dans le cas d’Exoscale, la bonne pratique serait de créer un ClusterRole dédié pour ArgoCD pour éviter l’utilisations de system:masters pour l’authentification, et d’utiliser par exemple des certificats avec un TTL maîtrisé. La commande exo compute sks kubeconfig permet en effet de spécifier un TTL. Voir mon article sur le TLS et l’authentification dans Kubernetes pour plus de détails. Une fois les valeurs remplacées, et le fichier appliqué via kubectl --kubeconfig argocd.kubeconfig apply -f <fichier>, les clusters devraient être visibles dans l’interface d’ArgoCD à l’adresse https://localhost:8080/settings/clusters: Déploiement d’un ApplicationSet Déployez maintenant l’ApplicationSet suivant pour tester le setup, toujours via kubectl --kubeconfig argocd.kubeconfig apply -f <fichier>: --- apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: guestbook namespace: argocd spec: generators: - clusters: {} template: metadata: name: '{{name}}-guestbook' spec: project: "default" source: repoURL: https://github.com/argoproj/argocd-example-apps/ targetRevision: HEAD path: guestbook destination: server: '{{server}}' namespace: guestbook syncPolicy: syncOptions: - CreateNamespace=true automated: prune: true selfHeal: true ArgoCD devrait vous générer automatiquement 3 applications, chacunes sur un cluster différent, le tout en fonction de ce qui est stocké dans le dossier guestbook sur le répertoire github https://github.com/argoproj/argocd-example-apps/. Elles seront également visibles dans l’interface. On remarque que le nom de chaque application est bien <cluster>-guestbook, par exemple vie1-guestbook. Rappelez vous que les générateurs des ApplicationSet vous permettent de filtrer si besoin sur quelles clusters les applications doivent être déployées, via des labels par exemple. Dans le setup actuel, ArgoCD créera automatiquement l’application pour chaque nouveau cluster ajouté, ou la supprimera si un cluster est supprimé. Chaque changement dans Git sera répercuté sur l’ensemble des clusters automatiquement également (grâce à l’option syncPolicy.automated, vous pouvez également choisir de "sync" manuellement les applications). Vous pouvez également vérifier sur vos clusters avec kubectl que l’application a bien été déployée, par exemple avec kubectl --kubeconfig vie1.kubeconfig get po -n guestbook. Un dernier point avant la conclusion: rien ne vous empêche d’utiliser les Application ET les ApplicationSet ArgoCD en parallèle selon les besoins. Conclusion ArgoCD est un outil puissant, qui peut grandement simplifier le multi region ou le multi cloud Kubernetes. On voit encore une fois ici l’avantage de Kubernetes: l’outillage est là pour répondre à des problématiques assez complexes, et ça fonctionne très bien.

Kubernetes multi cluster et multi région en GitOps...
Je présenterai dans cet article comment gérer les applications et ressources...
Source: mcorbin
Retour sur la KubeCon 2023 à Amsterdam
Trois jours à la KubeCon J'ai eu l'occasion d'assister pour la deuxième fois à ce grand événement qu'est la KubeCon grâce à mon entreprise SFEIR, qui se déroulait cette fois-ci à Amsterdam pour

Retour sur la KubeCon 2023 à Amsterdam
Trois jours à la KubeCon
J'ai eu l'occasion d'assister pour...
Source: Filador
Kubernetes - Premiers pas avec l'operateur Ansible
Table des matières Introduction Les opérateurs Kubernetes Qu’est-ce qu’un opérateur Kubernetes Comment écrire un opérateur Kubernetes ? Qu’est l’Operator Framework Pourquoi utiliser Ansible pour écrire un opérateur Kubernetes ? Création de notre premier Operateur Ansible Installation des prérequis Installation d’un cluster Kubernetes Installation de l’Operator Framework Installation d’une registry Docker Installation des librairies python pour molecule Installation des outils Création de l’opérateur Ajout des ressources pilotées par l’opérateur Création de l’image docker Déploiement de l’opérateur Ansible Création de notre première ressource Tout décommissionner Plus loin Introduction Pour déployer une application au sein d’un cluster Kubernetes, on peut le faire de manière classique avec des fichiers de configuration YAML ou un gestionnaire de packages comme Helm.

Kubernetes - Premiers pas avec l'operateur Ansible
Table des matières Introduction Les opérateurs Kubernetes Qu’est-ce qu’un...
Source: Stéphane ROBERT
A la découverte de R2Devops
Il y a quelques mois, j'ai regardé le live Youtube Les Compagnons du DevOps, traitant de la standardisation CI/CD. J'ai…

A la découverte de R2Devops
Il y a quelques mois, j'ai regardé le live Youtube Les Compagnons du DevOps,...
Source: Antoine Mayer
Ansible - Mon générateur de taches assisté de ChatGPT
Table des matières Introduction Installation d’ansible-aisnippet Utilisation d’ansible-aisnippet Generation d’une tache Générer plusieurs taches Fonctionnement Plus loin Introduction Et voilà après deux semaines de tests, j’ai fini par livrer mon package python permettant de générer des taches ansible assisté par ChatGPT. Je l’ai appelé ansible-aisnippet. Installation d’ansible-aisnippet Il s’agit d’un package python. Vous avez donc le choix de l’installer dans votre environnement virtuel, au niveau de votre utilisateur ou encore avec pipx.

Ansible - Mon générateur de taches assisté de ChatGPT...
Table des matières Introduction Installation d’ansible-aisnippet Utilisation...
Source: Stéphane ROBERT
Kubernetes et manifests YAML: trop bas niveau pour les dev ?
Un débat fait rage depuis longtemps dans la communauté Kubernetes: devons-nous construire des abstractions au dessus des primitives de Kubernetes, notamment pour générer les manifests ? Je pense que oui et j’expliquerai dans cet article pourquoi. La boîte à outil Kubernetes Kubernetes est une formidable boîte à outil pouvant s’adapter à n’importe quelle application à déployer. C’est ce qui fait sa force: contrairement à de nombreuses autres plateformes, toutes les options imaginables sont présentes pour définir comment votre application doit se comporter: ressources (cpu et mémoires), probes et cycle de vie, gestion des rolling upgrades, autoscaling, gestion du réseau, du load balancing et du stockage… Tout est possible grâce à l’API de Kubernetes. Cette puissante flexibilité est une des raisons du succès de Kubernetes: ça tourne partout, pour tout. Une question se pose pourtant immédiatement en entreprise lorsque Kubernetes commence à être utilisé: qui doit écrire les manifests Kubernetes (ces fameux fichiers YAML servant à décrire les ressources à déployer), et sous quel format ? Pour la première question, je pense que les utilisateurs (donc les développeurs) doivent pouvoir déployer de nouvelles applications sur un cluster Kubernetes en totale autonomie. Répondons maintenant à la seconde question. Le bon niveau d’abstraction Prenons le manifest potentiel d’une application fictive: --- kind: ConfigMap apiVersion: v1 metadata: name: cabourotte data: cabourotte.yaml: | http: host: "0.0.0.0" port: 7000 dns-checks: - name: "dns-check" description: "example" domain: "appclacks.com" timeout: 5s interval: 20s --- apiVersion: apps/v1 kind: Deployment metadata: name: cabourotte namespace: default labels: app.kubernetes.io/name: cabourotte spec: replicas: 3 selector: matchLabels: app.kubernetes.io/name: cabourotte template: metadata: labels: app.kubernetes.io/name: cabourotte spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app.kubernetes.io/name operator: In values: - cabourotte topologyKey: kubernetes.io/hostname containers: - name: cabourotte image: appclacks/cabourotte:v1.13.0 imagePullPolicy: IfNotPresent args: - daemon - --config - /config/cabourotte.yaml resources: limits: memory: 150Mi requests: cpu: 100m memory: 50Mi ports: - containerPort: 7000 name: http securityContext: readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 1664 livenessProbe: httpGet: path: /healthz port: http timeoutSeconds: 5 successThreshold: 1 failureThreshold: 3 periodSeconds: 10 startupProbe: httpGet: path: /healthz port: http timeoutSeconds: 5 successThreshold: 1 failureThreshold: 30 periodSeconds: 10 volumeMounts: - name: cabourotte mountPath: /config readOnly: true volumes: - name: cabourotte configMap: name: cabourotte --- apiVersion: v1 kind: Service metadata: namespace: default name: cabourotte spec: selector: app.kubernetes.io/name: cabourotte ports: - protocol: TCP name: content targetPort: 7000 port: 7000 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: "nginx" namespace: default name: cabourotte spec: rules: - host: www.cabourotte.test-domain.com http: paths: - path: / pathType: "Prefix" backend: service: name: cabourotte port: number: 7000 Il y a beaucoup de choses dans ce manifest: on crée une configmap, un deployment avec 3 replicas, un service, un ingress. Le but de cet article n’est pas de présenter toutes les options utilisées dans ce manifest (on aurait pu en ajouter d’autres, comme par exemple la configuration des capabilities ou du rolling update), mais on voit avec cet exemple simple que la configuration de Kubernetes est verbeuse. Pourtant, les besoins sont 99 % du temps les mêmes: déployer une application, l’exposer sur un port, créer un service puis éventuellement un ingress pour l’exposer sur un domaine spécifique. Il est donc intéressant de se demander quelle est la part d’informations "utiles" dans l’exemple présenté précédemment. Personnellement, ce que j’aimerai pouvoir définir dans ces situations classiques serait quelque chose comme ça: name: cabourotte replicas: 3 image: appclacks/cabourotte:v1.13.0 args: - daemon - --config - /config/cabourotte.yaml resources: limits: memory: 150Mi requests: cpu: 100m memory: 50Mi port: 7000 host: www.cabourotte.test-domain.com config: - path: /config/cabourotte.yaml content: | http: host: "0.0.0.0" port: 7000 dns-checks: - name: "dns-check" description: "example" domain: "appclacks.com" timeout: 5s interval: 20s C’est tout de suite beaucoup plus lisible. les différentes ressources n’apparaissent plus ici, l’application apparaissant comme un tout unifié. Pourquoi devrais-je avoir à définir explicitement une configmap, puis utiliser volumeMounts et volumes alors que je souhaite juste pouvoir exprimer le besoin "je veux ce contenu dans le fichier à cet emplacement" ? Pourquoi avoir plusieurs ressources à lier ensemble pour l’ingress alors que j’ai une relation directe entre mon application et le domaine sur laquelle je veux l’exposer ? Comme vous pouvez le deviner, je suis dans le camp de ceux pensant que l’abstraction de Kubernetes est trop bas niveau pour les développeurs. Je travaille avec Kubernetes depuis 2017 et ait eu l’occasion de travailler de très nombreux développeurs sur ce sujet au cours de ces années. Je n’ai jamais (vraiment !) rencontré un développeur content de devoir écrire des centaines de lignes de YAML, c’est même complètement l’opposé: Les gens (cela inclut les meilleurs développeurs avec qui j’ai travaillé) demandent une abstraction permettant d’aller à l’essentiel. Je suis sûr que c’est comme ça aussi chez vous. Pourquoi ? Réduire la charge cognitive Personne n’aime écrire et maintenir des centaines, voir milliers de lignes de YAML, alors que l’information vraiment utile peut être exprimée beaucoup plus simplement. C’est comme en programmation, où il existe parfois un facteur 10 en nombre de ligne de code entre deux langages plus ou moins expressifs (Clojure et Java par exemple): un programme court est très souvent plus maintenable car il "tient dans la ram" de votre cerveau. Réduire la définition d’une application Kubernetes à seulement ses parties essentielles nous fait gagner du temps de cerveau que l’on peut consacrer à autre chose. Prenons d’autres exemples. Il est courant dans Kubernetes d’ajouter des comportements à des ressources via des annotations: configuration des ingress (tls, entrypoint…), du monitoring (blackbox exporter), ou autre choses de ce type. Est ce que les développeurs ont besoin de savoir que pour exposer son application via un ingress sur un entrypoint Traefik public, il faut rajouter l’annotation spécifique traefik.ingress.kubernetes.io/router.entrypoints: "public" ? Ou bien, pour activer le TLS, traefik.ingress.kubernetes.io/router.tls: "true" ? Je veux permettre d’exprimer cela simplement, sans que l’infrastructure interne "leak" côté dev. Je ne veux pas qu’ils aient à connaitre des dizaines d’annotations à rallonge pour exprimer des besoins simples, je préfère des public: true, tls: true, monitoring: enabled… Je dois l’avouer: je n’arrive jamais à définir des Network Policies qui fonctionnent du premier coup. Pourtant, la majorité des besoins sont identiques: autoriser du traffic entre pods. Je n’ai pas envie que les gens aient à écrire des fichiers YAML complexes, se trompant 9 fois sur 10, en mode "trial and error", pour exprimer un besoin qui se résume en une ligne: "je veux que mon pod A puisse communiquer avec mon pod B sur le port 9876". La gestion des secrets, se résumant souvent (si vous utilisez par exemple external secrets) à "j’ai cette valeur dans le parameter store AWS et je souhaite la retrouver dans cette variable d’environnement ou dans ce fichier". Pourquoi devoir créer ou modifier de multiples ressources alors que le besoin s’exprime en une ligne ? Je pourrai continuer comme ça encore longtemps. On se rend compte rapidement qu’une application "prod ready" sur Kubernetes nécessite énormément de configuration, beaucoup plus que mon exemple précédent. Je le répète, c’est ce qui fait la force de Kubernetes. Mais les utilisateurs finaux ne sont pas intéressés par le "bruit", seulement par l’information utile à leurs niveaux. Fournir de bons défaults securityContext, anti affinity, imagePullPolicy… de nombreuses options dans Kubernetes sont souvent identiques dans la majorité des applications. Pourquoi les répéter ad nauseam alors qu’on peut les ajouter par défaut une bonne fois pour toute ? On peut même imaginer des valeurs par défaut dans les ingress pour les domaines (<app>.<main_company_domain>) par exemple. Il est certe possible (et très fortement conseillé) de faire de l’audit avec des outils comme Kyverno sur les configurations des manifests. Mais pourquoi s’embêter à définir ces options manuellement si elles sont de toute façon obligatoires ? Eviter les erreurs et gagner en vélocité Ce point est un peu similaire à celui de la charge cognitive. Pouvoir définir une application classique prête à être déployée sur Kubernetes ne devrait pas prendre plus que quelques minutes pour n’importe qui. Utiliser une abstraction permet cela, tout en évitant les heures de debugging à chaque nouveau microservice à base de "je me suis trompé dans mon volume", "j’ai une erreur dans mon label selector mon service marche pas", "je comprends pas mon secret n’est pas injecté"… Et c’est ce qui arrivera si les développeurs (et pas que, la même chez les SRE) doivent écrire des manifests complets, 100 % garantie. Pire, ça les saoulera (à raison) et les gens commenceront à copier/coller des manifests d’autres projets (bugs inclus) jusqu’à ce que ça "marche" (à première vue). Les critiques de cette approche Commençons par sûrement la plus évidente, que je partage également en partie: comment doit être définie l’abstraction ? J’ai dans mon exemple précédent volontairement omis de définir les probes dans mon manifest "simplifié". Que doit faire l’abstraction: définir des probes par défaut au risque à ce qu’elles ne soient pas adaptées à l’application (par exemple, pas de configuration d’une startup probe, ou mauvais type de probe) ? L’abstraction doit-elle également définir par défaut de l’anti-affinity au niveau des pods ? On voit qu’une connaissance des mécanismes de Kubernetes est quand même nécessaire, même avec une abstraction, comme par exemple sur le fonctionnement du cycle de vie des pods. Est ce qu’il n’est pas risqué de ne pas exposer cela ? Si l’option est essentielle (comme par exemple le nombre de réplicas ou la définition des ressources), il faut la rendre obligatoire. Cela doit sûrement être également le cas pour les probes, même si il peut quand même être intéressant d’avoir des probes "prédéfinies" en fonction du type de service. Egalement, rien de plus frustrant que de ne pas pouvoir utiliser une option spécifique de Kubernetes car l’abstraction ne l’expose pas. Comme dit en début d’article, la force de Kubernetes est de s’adapter à tout, et chaque option a son utilité, même si elle n’est utilisée que sur une application sur 100. Si les gens commencent à lutter contre l’abstraction, c’est perdu. Au pire, rien n’empêche de rebasculer sur du pure YAML pour des cas très spécifiques. Mais mon expérience me montre qu’il sont rares. Ouin Ouin c’est pas DevOps on cache Kubernetes aux dev Ici, Kubernetes est en partie masqué aux équipes de développement. Ce n’est pas un problème. Comme dit précédemment, il faut quand même comprendre les concepts de Kubernetes même dans ce cas. De plus, le YAML final est toujours récupérable, donc rien n’est caché: on simplifie juste sa génération. Fournir une abstraction ET former les gens à Kubernetes est possible (et souhaitable), mais il ne sert à rien de perdre en productivité pour aucune raison valable autre que "j’aime bien écrire 1500 lignes de YAML et 10 ressources quand je bootstrap une application". Je me considère pas trop mauvais avec Kubernetes et je suis le premier heureux lorsque j’utilise ce type d’abstractions. Est ce que j’ai l’impression de perdre en compétence ? Non. Par contre, je pourrai définir mes manifests beaucoup plus rapidement et avec plus de confiance. Et c’est aussi grâce à ça que l’on arrive à démocratiser Kubernetes au sein d’une entreprise: en fournissant l’outillage permettant d’exprimer clairement, simplement et précisément son besoin. A vous de choisir ou concevoir les bons outils (Helm ? Kustomize ? Typescript ? Une CRD ?) pour construire votre abstraction.

Kubernetes et manifests YAML: trop bas niveau pour...
Un débat fait rage depuis longtemps dans la communauté Kubernetes: devons-nous...
Source: mcorbin
Me soutenir
Vous l’avez peut-être remarqué ce blog ne diffuse aucune publicité et accueille très peu de contenu sponsorisé. Pour le financer, je compte essentiellement sur le soutien de mes lecteurs. Pour rappel, mon objectif est d'aider les non-anglophones à trouver de la matière sur les technologies et les principaux outils devops que j’utilise et maîtrise : Ansible Docker Vagrant Terraform Kubernetes Gitlab Vous allez me dire, mais pourquoi te soutenir ?

Me soutenir
Vous l’avez peut-être remarqué ce blog ne diffuse aucune publicité et accueille...
Source: Stéphane ROBERT
Ansible - ChatGPT peut il m'assister partie 2 ?
Table des matières Introduction Comment stocker les templates ? Comment identifier le bon template ? On enrichit notre demande à ChatGPT La suite Introduction Dans le précédent billet, nous avons pu voir que chatGPT n’est pas si magique que cela. En effet, il ne suit pas forcément les bonnes pratiques et surtout ne propose pas toujours les solutions adaptées. La plus grosse difficulté est de trouver quelles informations lui fournir pour qu’il produise du contenu proche d’une solution acceptable.

Ansible - ChatGPT peut il m'assister partie 2 ?
Table des matières Introduction Comment stocker les templates ? Comment identifier...
Source: Stéphane ROBERT
[Comprendre Docker en 2 minutes 🇫🇷] Understanding Docker in a visual way - 16 - Stats
Suite à la série de vidéos "Understanding Kubernetes in a visual way", j'ai décidé de faire une nouvelle série de vidéos basée sur Docker. Cela peut être difficile de débuter avec Docker, de comprendre la technologie. Dans cette série de vidéos, j'essaie d'expliquer les concepts abstraits de Docker avec des illustrations et à chaque épisode des commandes concrètes d'exemples. Dans cet épisode, découvrons la commande "docker stats". Au menu : 0:00 | Introduction 0:13 | Stats 0:27 | Lignes de commandes Retrouvez toutes les commandes vues dans cette vidéo : https://github.com/scraly/understanding-docker-in-a-visual-way ----- Understanding Docker can be difficult or time-consuming. In this serie of video I try to explain Docker abstract concepts with illustrations and concrete commands. In this first episode, let's discover images. #docker #comprendre #tutoriel This serie of video is a perfect introduction for beginners and advanced users. I hope this kind of video with technical sketchnote will help you in your Docker/containers learning journey. If it could be interested you, I've sketched a lot of Kubernetes concepts in an "Understanding Docker in a visual way" book, available on GumRoad. Links: - "Understanding Docker in a visual way" book: https://gumroad.com/aurelievache - Blog: https://dev.to/aurelievache Contact me 👋 - Twitter: https://twitter.com/aurelievache - LinkedIn: https://www.linkedin.com/in/aurelievache/ - YouTube: https://www.youtube.com/c/AurelieVache

[Comprendre Docker en 2 minutes 🇫🇷] Understanding...
Suite à la série de vidéos "Understanding Kubernetes in a visual way", j'ai décidé...
Source: Aurelie Vache
Ansible - ChatGPT peut il m'assister partie 1 ?
Table des matières Introduction Utilisation du SDK OpenAI Installation du SDK Python OpenAI Notre première demande à l’API de ChatGPT Le code de test de ma demande à ChatGPT On lui pose notre première question Rendre moins bavard Lui demander de répondre en JSON Demander à ChatGPT de respecter les bonnes pratiques Demander à chatGPT de produire un ensemble de taches Ajustement de la température Conclusion Introduction Par nature le DSL Ansible n’est pas un langage de programmation, mais permet plutôt de décrire le résultat souhaité.

Ansible - ChatGPT peut il m'assister partie 1 ?
Table des matières Introduction Utilisation du SDK OpenAI Installation du SDK Python...
Source: Stéphane ROBERT
Ansible - Utiliser correctement les modules shell et command
Table des matières Introduction Quand utilisez les modules shell et command ? Différences entre les modules shell et command Utilisation des options creates et removes Utilisation des instructions failed_when et changed_when changed_when failed_when Introduction Même si les modules command et shell sont fortement déconseillés, il est des cas où il est impossible de s’en passer, Voyons donc comment les utiliser correctement. Quand utilisez les modules shell et command ?

Ansible - Utiliser correctement les modules shell...
Table des matières Introduction Quand utilisez les modules shell et command ? Différences...
Source: Stéphane ROBERT