image de mise en avant pour l'article les bases de Kubernetes

Les bases de Kubernetes

Temps de lecture estimé: 15 minutes

toujours dans la continuité de la migration de mon infra d’un simple serveur virtualisé, je continue à me former sur Kubernetes. après avoir installé un cluster sur 2 machines virtuelles Ubuntu 22.04, fait quelques opérations simples et installé Kubernetes Dashboard, je suis finalement revenu sur les bases avec un cours FreecodeCamp de 3h que j’avais mis de côté sur YouTube.

le cours vidéo en anglais est ci dessous ou ici

Je vais reprendre ici les grandes étapes et faire une sorte de mémo pour moi ou toute autre personne à qui ça pourrait servir. Ça me conforte dans l’idée que j’ai de Kubernetes : c’est complet, mais complexe. il y a plein de notions à connaitre pour réussir à l’utiliser convenablement dans un environnement production. Pour information, il y a aussi une Cheatsheet disponible sur la documentation Kubernetes.

Dans ce cours, c’est Minikube qui est utilisé. Donc si c’est pour des raisons de test en local, tu peux installer une instance simplifiée comme Minikube. Comme moi j’avance sur mon infra serveur, j’ai déjà un cluster Kubernetes avec un nœud Master et un nœud worker.

  1. Info sur le cluster
  2. API Kubernetes
  3. Lancer un pod unique
  4. Afficher les détails d’un pod
  5. Exécuter une commande sur un pod
  6. Supprimer une ressource
  7. Créer un déploiement Kubernetes
  8. Mettre à l’échelle un déploiement
  9. Afficher les détails d’un déploiement
  10. Redémarrer les pods d’un déploiement
  11. Suivre le déroulement d’un rollout
  12. Créer un service ClusterIp
  13. Afficher les détails d’un service
  14. Gérer les accès depuis l’extérieur avec des services NodePort
    1. Application Node
    2. Image Docker
    3. Déployer l’application sur le cluster Kubernetes
    4. Accès au service Kubernetes depuis l’extérieur
    5. Mettre à jour une image et un déploiement
    6. Créer des spécifications de déploiement avec des fichier Yaml
    7. Faire communiquer 2 pods ou 2 services

Info sur le cluster

pour savoir si dans les grandes lignes le cluster est fonctionnel

kubectl cluster-info
Kubernetes control plane is running at https://IP_MASTER:6443
CoreDNS is running at https://IP_MASTER:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

pour lister les nœuds

kubectl get nodes 

globalement pour la plupart des commandes de listing on peut définir le format de sortie avec l’option output

pour avoir un affichage plus complet, j’utilise souvent –output=wide ou -o=wide ou simplement -o wide

kubectl get nodes -o=wide

API Kubernetes

kubectl utilise finalement qu’une API donc à chaque fois ça va se décomposer avec

kubectl action ressource

kubectl get pods
kubectl get namespaces
kubectl delete pods mon_pod
kubectl describe service mon_service

Si tu ne spécifies rien sur les commandes, le namespace utilisé va être celui par défaut, default.

du coup si tu crées tes éléments dans un autre namespace il faudra le spécifier ensuite avec l’option –namespace=mon_namespace ou -n=mon_namespace ou -n mon_namespace

kubectl get pods -n kube-system -o wide

Lancer un pod unique

pour lancer un pod à partir d’une image docker

kubectl run nom_de_mon_pod --image=image_docker

donc par exemple pour un pod Nginx de base

kubectl run nginx-single-pod --image=nginx

Afficher les détails d’un pod

pour avoir des détails sur un pod, celui créer juste au-dessus par exemple, on va demander à le décrire

kubectl describe pod nginx-single-pod

ça permet d’avoir accès à des infos détaillées sur le pod, comme l’image Docker utilisée ou l’Id du conteneur Docker

Container ID:   docker://477223dc4216144046145a382bb515adeb6479b50ab4f98ba695aed6b66f07ce

Exécuter une commande sur un pod

ce qui permet ensuite d’utiliser Docker pour d’autres actions isolées si tu le souhaite, comme lancer une console bash dans ce conteneur

docker exec -it 477223dc4216144046145a382bb515adeb6479b50ab4f98ba695aed6b66f07ce bash

cet exemple me permet aussi d’introduire le fait que l’équivalent est possible directement avec kubectl

kubectl exec -it -n default nginx-single-pod -- bash

Supprimer une ressource

pour supprimer une ressource Kubernetes, il suffit d’utiliser l’action delete

kubectl delete pod nginx-single-pod

Créer un déploiement Kubernetes

maintenant que l’image nginx est supprimée, on va plutôt créer un « déploiement ». c’est ce déploiement qui va s’occuper, suivant les paramètres fournis, de lancer les différents pods.

Pour créer un déploiement qui va se charger de déployer un seul pod 

kubectl create deployment nginx-deployment –image=nginx

si par contre tu souhaites déployer directement 5 pods tu peux aussi spécifier

kubectl create deployment nginx-deployment --image=nginx --replicas=5

Mettre à l’échelle un déploiement

C’est quelque chose qui peut ensuite être modifié si jamais tu veux mettre à l’échelle tes déploiements. la mise à l’échelle se fait avec scale

kubectl scale deployment nginx-deployment --replicas=10

Afficher les détails d’un déploiement

de la même manière que pour avoir des détails pour un pod, on peut avoir des détails du déploiement avec

kubectl describe deployment nginx-deployment

Redémarrer les pods d’un déploiement

pour redémarrer les pods d’un déploiement, il faut faire un rollout

kubectl rollout restart deployment nginx-deployment

Suivre le déroulement d’un rollout

pour suivre le déroulement d’un rollout (ou d’une mise à l’échelle), il faut consulter le statut du rollout

kubectl rollout status deployment nginx-deployment

Créer un service ClusterIp

pour l’instant, si je fais

kubectl get pods -o wide
NAMESPACE              NAME                                                       READY   STATUS    RESTARTS         AGE   IP              NODE                               NOMINATED NODE   READINESS GATES
default                nginx-deployment-85c6d5f6dd-f58sv                          1/1     Running   0                12m   172.17.0.10     k8s-workernode.anthony-jacob.com   <none>           <none>
default                nginx-deployment-85c6d5f6dd-gjt9w                          1/1     Running   0                12m   172.17.0.6      k8s-workernode.anthony-jacob.com   <none>           <none>
default                nginx-deployment-85c6d5f6dd-mxsss                          1/1     Running   0                12m   172.17.0.9      k8s-workernode.anthony-jacob.com   <none>           <none>
default                nginx-deployment-85c6d5f6dd-q8xlt                          1/1     Running   0                12m   172.17.0.5      k8s-workernode.anthony-jacob.com   <none>           <none>
default                nginx-deployment-85c6d5f6dd-wjglf                          1/1     Running   0                12m   172.17.0.4      k8s-workernode.anthony-jacob.com   <none>           <none>

on peut voir l’adresse IP des pods Nginx. depuis le nœud, dans mon cas le workernode, je peux tester Nginx sur chacun des pods avec curl

curl 172.17.0.10

ou

curl 172.17.0.6

ou ou les autres adresses IP de mes pods Nginx, ça me renvoie bien la page HTML d’accueil du serveur Nginx Welcome to nginx!

Si maintenant on veut non plus accéder à chaque pod individuellement, mais qu’on souhaite laisser le déploiement faire ça sauce, on peut exposer un port et créer un service Kubernetes.
Si par exemple on souhaite exposer le port 8080 et le rediriger sur le port 80

kubectl expose deployment nginx-deployment --port 8080 --target-port=80

ce qui a pour effet de créer un service

kubectl get services
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP    35d
nginx-deployment   ClusterIP   10.100.178.93   <none>        8080/TCP   2s

J’ai bien mon service nginx-deployment accessible depuis le port 8080 avec l’adresse IP 10.100.178.93
Si maintenant je teste depuis mon nœud workernode avec un curl, j’ai toujours bien la réponse de nginx avec la page HTML Welcome to nginx!

curl 10.100.178.93:8080

par contre, cette adresse IP n’est toujours pas accessible depuis l’extérieur

Afficher les détails d’un service

la logique commence à rentrer, pour avoir une vue plus détaillée du service

kubectl describe service nginx-deployment

Gérer les accès depuis l’extérieur avec des services NodePort

Application Node

Maintenant pour gérer les accès depuis l’extérieur avec des services NodePort, on va passer au déploiement d’une petite application Node. Tous les fichiers nécessaires sont disponible sur mon dépôt git (un fork du dépôt original de l’auteur de ce cours avec quelques petites différences)

Dans mon environnement de développement sous Windows, j’ai tous les outils déjà installés et accessibles dans mon PATH (npm, docker, vscode etc etc), il faut aussi dans le cadre de ce cours un compte sur Docker Hub pour pousser des images Docker donc je te laisse voir ce qu’il te manque pour aller plus loin

Je créer le dossier k8s-freecodecamp qui me servira de répertoire pour tout ce training. je créer aussi le sous répertoire k8s-web-hello dans lequel il y aura l’application Node de ce tuto. C’est un serveur Express qui aura pour but de renvoyer le hostname à chaque requête.

Dans ce répertoire en ligne de commande, j’initialise un projet Node avec npm

npm init -y

ce qui crée le fichier package.json, et ensuite on installe Express

npm install express

je créer le fichier index.mjs dans lequel je copie le contenu du fichier sur mon dépôt git

import express from 'express'
import os from 'os'

const app = express()
const PORT = 3000

app.get("/", (req, res) => {
  const helloMessage = `Hello from the ${os.hostname()} \n`
  console.log(helloMessage)
  res.send(helloMessage)
})

app.listen(PORT, () => {
  console.log(`Web server is listening at port ${PORT}`)
})

dans le fichier package.json, je rajoute une instruction start

"start": "node index.mjs"

Image Docker

l’application Node est prête, passons maintenant a la construction de l’image Docker qui servira au déploiement. Donc dans le dossier de l’application Node, k8s-web-hello, je crée le fichier Dockerfile dans lequel je mets le contenu du fichier présent sur mon dépôt git

#depuis l'image Node:alpine
FROM node:alpine

#on defini le repertoire de travail /app
WORKDIR /app

#on expose le port 3000, 
EXPOSE 3000

#on copie les 2 fichiers package.json package-lock.json dans ce workdir /app
COPY package.json package-lock.json ./

#ce qui permet de passer ensuite à l'etape d'installation de tos les package node necessaire
RUN npm install

#on copie le reste du dossier (index.mjs) 
COPY . ./

#et on fini par lancer l'application avec la commande npm et la directive start qu'on a creé un peu plus tot dans le fichier package.json
CMD ["npm", "start"]

maintenant que le Dockerfile est prêt, on peut construire l’image Docker avec

docker build . -t anthonygj/k8s-web-hello

(anthonygj est mon espace sur le hub Docker)

Je vais maintenant pousser l’image sur le hub docker pour pouvoir l’utiliser en déploiement avec Kubernetes. D’abord, je me log sur le hub Docker avec

docker login

et ensuite pour pousser l’image

docker push anthonygj/k8s-web-hello

elle est bien poussée et présente sur https://hub.docker.com/repositories

Déployer l’application sur le cluster Kubernetes

l’image est maintenant disponible, on peut maintenant la déployer sur Kubernetes avec la commande utilisée dans la première partie sur les basiques de Kubernetes

kubectl create deployment k8s-web-hello --image=anthonygj/k8s-web-hello --replicas=3

encore une fois, de la même manière que dans la première partie, on peut créer un service pour ce déploiement et exposé le port 80 pour le redirigé sur le port 3000 interne des pods

kubectl expose deployment k8s-web-hello --port 80 --target-port=3000

mon service est bien créé

kubectl get services
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
k8s-web-hello   ClusterIP   10.108.73.221   <none>        80/TCP    8s

et cette fois si, je peux voir qu’avec un curl sur l’ip du cluster, j’ai une réponse de mon application depuis plusieurs pods suivant le load balancing

curl 10.108.73.221
VERSION 2: Hello from the k8s-web-hello-5fb9f678bf-qkpfk

curl 10.108.73.221
VERSION 2: Hello from the k8s-web-hello-5fb9f678bf-6j6j7

curl 10.108.73.221
VERSION 2: Hello from the k8s-web-hello-5fb9f678bf-cfrkl

curl 10.108.73.221
VERSION 2: Hello from the k8s-web-hello-5fb9f678bf-6j6j7

Accès au service Kubernetes depuis l’extérieur

la problématique ici étant que cette adresse IP est accessible uniquement depuis le cluster Kubernetes. Si je souhaite accéder depuis l’extérieur ou depuis mon réseau local à ce service, je ne peux pas.

Jusqu’à présent, nous avons créé les services avec le type ClusterIP. nous allons maintenant créer un service avec le type NodePort, ce qui va permettre d’accéder au service depuis l’IP et un port du nœud qui eux (sauf règle firewall contraire) sont accessible depuis mon réseaux local.

donc on supprime le service qu’on vient juste de créer

kubectl delete service k8s-web-hello

pour en recréer un de type NodePort

kubectl expose deployment k8s-web-hello --type=NodePort --port=3000

le service est maintenant créé

kubectl get service
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
k8s-web-hello   NodePort    10.98.63.173   <none>        3000:30297/TCP   15s

et on peut voir qu’un port aléatoire 30297 a été attribué pour faire la redirection en externe du nœud vers le cluster de déploiement. si maintenant j’essaie d’accéder depuis mon navigateur à http://IP_DU_NOEUD:30297/ , j’ai bien une réponse

VERSION 2: Hello from the k8s-web-hello-5fb9f678bf-6j6j7

Avec des fournisseurs de service de Cloud comme AWS, google Cloud, Azure etc qui proposent directement un load balancer intégré, on aurait aussi pu utiliser un service de type LoadBalancer.    

kubectl expose deployment k8s-web-hello --type=LoadBalancer --port=3000

sur mon instance qui n’est pas préparée pour ça, ça revient dans les grandes lignes à faire un service NodePort

Mettre à jour une image et un déploiement

Pour commencer, on va mettre à jour le projet en changeant quelque chose comme le message de réponse. dans mon cas, je le remplace par

const helloMessage = `Hello from the ${os.hostname()} pods \n`

j’enregistre et je reconstruis l’image docker avec un tag v2

docker build . -t anthonygj/k8s-web-hello:2.0

et je la pousse sur Docker Hub

docker push anthonygj/k8s-web-hello:2.0

Maintenant qu’elle est bien présente sur le repo Docker Hub, je peux spécifier aux pods de mon déploiement d’utiliser cette nouvelle image

kubectl set image deployment k8s-web-hello k8s-web-hello=anthonygj/k8s-web-hello:2.0

pour suivre le déploiement et le rollout des pods

kubectl rollout status deployment k8s-web-hello

Créer des spécifications de déploiement avec des fichier Yaml

maintenant qu’on a vu comment déployer une application en utilisant la ligne de commande pour le déploiement et les services, nous allons voir comment le faire à travers des fichiers YAML de spécification des déploiements. Pour ça, on va une nouvelle fois revenir à zéro sur les déploiements et services avec lesquels on s’amusait ici.

soit on supprime les déploiements et les services un à un

kubectl delete service nom_service -n namespace
kubectl delete deployment nom_deploiement  -n namespace

Soit un raccourci pour supprimer les objets d’un namespace

kubectl delete all --all -n namespace

dans mon cas, vu que j’utilisais le namespace par défaut, je n’ai pas besoins de le spécifier

kubectl delete all --all

on va pouvoir créer plusieurs fichiers pour définir le déploiement de l’application et le service. Ces fichiers sont un peu pompeux, c’est là que Visual Studio Code et ses extensions Kubernetes vont bien aider avec l’autocomplétion

ce qui peut être pratique aussi quand on connait l’équivalent en ligne de commande, c’est de lancer la commande en spécifiant que c’est un essai –dry-run=client et en spécifiant le format de sortie yaml -o=yaml

kubectl create deployment k8s-web-hello --image=anthonygj/k8s-web-hello --replicas=3 --dry-run=client -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: k8s-web-hello
  name: k8s-web-hello
spec:
  replicas: 3
  selector:
    matchLabels:
      app: k8s-web-hello
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: k8s-web-hello
    spec:
      containers:
      - image: anthonygj/k8s-web-hello
        name: k8s-web-hello
        resources: {}
status: {}

ça permet d’avoir une bonne base de départ.

Les fichiers sont disponibles sur le dépôt git. Moi j’ai également créé un namespace supplémentaire.

kind: Namespace
apiVersion: v1
metadata:
  name: k8s-web-hello
  labels:
    name: k8s-web-hello
apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8s-web-hello
  namespace: k8s-web-hello 
spec:
  replicas: 3
  selector:
    matchLabels:
      app: k8s-web-hello
  template:
    metadata:
      labels:
        app: k8s-web-hello
    spec:
      containers:
      - name: k8s-web-hello
        image: anthonygj/k8s-web-hello
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 3000
apiVersion: v1
kind: Service
metadata:
  name: k8s-web-hello-svc
  namespace: k8s-web-hello
spec:
  type: NodePort
  selector:
    app: k8s-web-hello
  ports:
  - port: 80
    targetPort: 3000

pour en savoir plus sur les options disponibles dans les fichiers de définitions yaml de Kubernetes, ça se trouve sur les méandres de la documentation

une fois les fichiers créés avec les options voulues, on passe toujours par la commande kubectl et cette fois on va appliquer les fichiers

kubectl apply -f namespace.yaml -f deployment.yaml -f service.yaml

si tout va bien, le nouveau namespace, le nouveau déploiement et le nouveau service sont créés. on peut vérifier le port du service avec

kubectl get service -A

et retester avec le nouveau port, http://IP_DU_NOEUD:30562/

Maintenant que tout fonctionne… on peut tout supprimer pour passer à la suite. Pour ça, on peut juste donner les fichiers de config à manger à Kubernetes pour supprimer les objets correspondants

kubectl delete -f service.yaml -f deployment.yaml -f namespace.yaml

Faire communiquer 2 pods ou 2 services

On peut passer à la  dernière partie de ce cours, à savoir le déploiement d’une application Node qui communique avec Nginx. On va réutiliser ce qu’on a déjà fait avec l’application Node et la modifier un peu, donc on peut faire un copier coller du répertoire k8s-web-hello vers k8s-web-to-nginx

l’index.mjs est un peu plus complet, le contenu est disponible sur le dépôt git

import express from 'express'
import fetch from 'node-fetch'
import os from 'os'

const app = express()
const PORT = 3000

app.get("/", (req, res) => {
  const helloMessage = `Hello from the ${os.hostname()}`
  console.log(helloMessage)
  res.send(helloMessage)
})

app.get("/nginx", async (req, res) => {
  const url = 'http://nginx.k8s-web-to-nginx.svc.cluster.local'
  const response = await fetch(url);
  const body = await response.text();
  res.send(body)
})

app.listen(PORT, () => {
  console.log(`Web server is listening at port ${PORT}`)
})

vu qu’on utilise un paquet en plus, node-fetch, il ne faut pas oublier de l’inclure dans le package.json

npm install node-fetch

on peut maintenant build une nouvelle image Docker et la pousser sur notre repo Docker hub

docker build . -t anthonygj/k8s-web-to-nginx

et

docker push anthonygj/k8s-web-to-nginx

passons maintenant à la spécification yaml du déploiement et du service. Le fichier est disponible sur le dépôt git.

kind: Namespace
apiVersion: v1
metadata:
  name: k8s-web-to-nginx
  labels:
    name: k8s-web-to-nginx
---
apiVersion: v1
kind: Service
metadata:
  name: k8s-web-to-nginx-svc
  namespace: k8s-web-to-nginx
spec:
  type: LoadBalancer 
  selector:
    app: k8s-web-to-nginx
  ports:
  - port: 3333
    targetPort: 3000

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8s-web-to-nginx
  namespace: k8s-web-to-nginx 
spec:
  replicas: 3
  selector:
    matchLabels:
      app: k8s-web-to-nginx
  template:
    metadata:
      labels:
        app: k8s-web-to-nginx
    spec:
      containers:
      - name: k8s-web-to-nginx
        image: anthonygj/k8s-web-to-nginx:2.0
        resources:
          limits:
            memory: "128Mi"
            cpu: "1"
          requests:
            memory: "10Mi"
            cpu: "50m"
        ports:
        - containerPort: 3000
kind: Namespace
apiVersion: v1
metadata:
  name: k8s-web-to-nginx
  labels:
    name: k8s-web-to-nginx
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: k8s-web-to-nginx
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    name: http

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: k8s-web-to-nginx 
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          limits:
            memory: "128Mi"
            cpu: "1"
          requests:
            memory: "10Mi"
            cpu: "50m"
        ports:
        - containerPort: 3000

j’ai un peu tweaké les ressources, premièrement parce qu’au premier test je me suis retrouvé bloqué. Apparemment, en ne spécifiant que les limites en ressources, celles-ci sont aussi utilisées en request. ce qui fait que mon nœud Kubernetes atteignait la limite de request et refusais de lancé les pods nginx

Ces limites et ces requêtes sont définies pour chaque pods et non pour le déploiement. un article intéressant qui parle des ressources est disponible ici

J’ai voulu aller un peu plus loin en créant et en spécifiant un namespace pour tout ce petit monde. De ce fait, j’ai découvert la gestion DNS de kubernetes.

dans l’exemple de base, il y a

const url = 'http://nginx'

c’est valable parce que dans l’exemple, les pods et le service sont créés dans le même namespace, celui par defaut, default . dans mon cas, j’ai choisi de créer un namespace k8s-web-to-nginx et de changer mon url avec

const url = 'http://nginx.k8s-web-to-nginx.svc.cluster.local'

à noter que dans mon cas, les 2 déploiements (et donc les pods qui seront créés) sont dans le même namespace, donc ça fonctionnerait aussi avec juste http://nginx

Je me suis aussi rendu compte que mon cluster Kubernetes n’était pas complètement fonctionnel. Les pod ne pouvaient ni résoudre les domaines internes comme nginx.k8s-web-to-nginx.svc.cluster.local , ni ceux externes comme google.com ou debian.org, quelque chose ne tournait pas rond au niveau du pod réseau ou du service Kube-dns/coredns j’en parle plus en détail dans l’article Kubernetes problèmes DNS CoreDns et problèmes d’accès aux IP ClusterIP.

je déploie mes nouveaux pods et mes nouveaux services avec les fichiers de spécifications que je viens de créer

kubectl apply -f k8s-web-to-nginx.yaml -f nginx.yaml

je vérifie une nouvelle fois le port du service

kubectl get service -A

cette fois ci, j’ai 2 services

k8s-web-to-nginx       k8s-web-to-nginx-svc        LoadBalancer   10.105.227.24    <pending>     3333:32261/TCP                   48s
k8s-web-to-nginx       nginx                       ClusterIP      10.101.213.147   <none>        80/TCP                           48s

k8s-web-to-nginx-svc qui est le service de mon appli Node qui va nous servir ici de front (service de type LoadBalancer sur le port 32261) et le service nginx qui va être appelé par l’application Node grâce à son IP de cluster et son enregistrement DNS nginx.k8s-web-to-nginx.svc.cluster.local

donc si j’accède à http://IP_DU_NOEUD:32261/ , j’ai toujours la réponse de mon application Node

Hello from the k8s-web-to-nginx-65ff6545dc-5skxk

et la nouveauté maintenant c’est que si j’accède à http://IP_DU_NOEUD:32261/nginx, j’ai maintenant la page par défaut de nginx Welcome to nginx!

et voilà, finito pour cette introduction à Kubernetes. moi ça m’a permis d’avoir un peu plus de compréhension au fonctionnement de ce mastodonte. Dis-moi ce que tu en penses et si toi aussi ça a pu te servir !

Je ne sais pas encore dans quel ordre, mais dans les prochaines étapes, j’ai toujours dans les cartons de tester portainer.io, j’ai aussi prévu de mettre en place un reverse proxy Ingress nginx et la mise en place de la gestion de mes certificats ssl Letsencrypt au sein de Kubernetes…

Voilà, en attendant, je te dis à bientôt pour de nouvelles aventures!!

Partagez l'article:
FacebookTwitterEmailLinkedIn

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.