Chargement en cours

K8S #01 : Flannel, MetalLB, Nginx

K8S #01 : Flannel, MetalLB, Nginx

Cet article a déjà 1 an ! Merci d'en tenir compte... Images manquantes, liens et informations pas forcément mis à jour... !

A voir si j’en fais une sĂ©rie
 đŸ€”

Chose promise, chose due ! Mon cluster Kubernetes installĂ© via Kubeadm commence lentement mais sĂ»rement Ă  prendre forme ! 😁

I) Découverte de K8S, et de la partie Networking

Alors pour un peu de contexte, je ne suis clairement pas un expert en K8S… je suis familier avec les notions de base (pods, nodes, namespaces, services, deployment…) et la CLI, mais j’ai encore clairement Ă©normĂ©ment de choses Ă  apprendre.

En gĂ©nĂ©ral, quand je veux me former Ă  une techno j’aime bien avoir un objectif, un projet. Bref, avoir un lab. C’est donc comme ça que je me suis mis Ă  installer un p’tit cluster via Kubeadm composĂ© de 3 nƓuds sous UbuntuServer. J’avais fait deux prĂ©cĂ©dents articles oĂč via Packer/Terraform je crĂ©ais le template, puis je le clonais et prĂ©parer les hĂŽtes.

Une fois le tout setupĂ©, mon premier rĂ©flexe a Ă©tĂ© de mettre en place le rĂ©seau. Et dĂ©jĂ  lĂ  faut apprendre deux trois bricoles d’entrĂ©e de jeu !

J’utilise kubeadm pour setuper mon cluster, et j’ai choisi Flannel comme CNI par dĂ©faut. La commande utilisĂ©e pour crĂ©er le tout a donc ressemblĂ© Ă  ceci :

# On initialise notre cluster, en renseignant le subnet utilisé par les pods. Par défaut, Flannel utilise 10.244.0.0/16

sudo kubeadm init --pod-network-cidr=10.244.0.0/16

Mais ensuite il faut l’installer, ce fameux CNI qu’est donc Flannel ! Et lĂ , avant d’aller plus loin, expliquons ce que c’est et Ă  quoi ça sert


II) Les CNIs, Container Network Interface

Un CNI est donc un plugin pour K8S responsable de la gestion du réseau pour les pods dans un cluster. Il va permettre de gérer la connexion entre les pods grosso modo.

Il existe forcĂ©ment une looooongue liste de CNIs… parmi lesquels :

  • Flannel, trĂšs simple et trĂšs lĂ©ger Ă  utiliser. En gĂ©nĂ©ral c’est celui que beaucoup de personnes choisissent ;
  • Calico, un chouilla plus complexe et plus avancĂ©. Comme dit plus haut, je ne suis pas expert donc je ne saurai vous dire les vraies options supplĂ©mentaires comparĂ© Ă  Flannel ;
  • WeaveNet, … ;
  • Cilium, … ;
  • … ;

Bref, vous l’aurez compris, ici je vais me concentrer sur mon premier choix. Voyons maintenant comment installer tout ça !

III) Installation de Flannel

Pour ce faire rien de plus simple, il suffit de tĂ©lĂ©charger et appliquer le manifeste. Un manifeste n’est ni plus ni moins qu’un fichier permettant de dĂ©crire l’Ă©tat d’une ressource, comme un Deployment, un Service, un ConfigMap… avec ses caractĂ©ristiques, comme le nombre de rĂ©plicas, le nom de l’image, ses labels… :

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

Et c’est bon ! On peut vĂ©rifier que nos pods sont bien en running, en vĂ©rifiant ceux tournant dans le namespace kube-flannel :

kubectl get pods -n kube-flannel

Comme quoi, pas si compliquĂ© que ça
 maintenant passons Ă  l’installation de MetalLB, et voyons en mĂȘme temps pourquoi nous en avons besoin.

IV) MetalLB, le « DHCP » pour LoadBalancers bare-metal

Comme dit en dĂ©but d’article, mon cluster est donc On-Premise, comprenez par lĂ  qu’il n’est pas installĂ© sur un Cloud.

J’utilise aussi kubeadm pour setuper le tout, mais sachez qu’il existe plĂ©thore d’autres outils
 alors ce n’est pas le sujet ici, mais par exemple il existe minikube, j’avais justement fait un article dessus il y a un sacrĂ© bout de temps. Bref, je digresse.

Tout ça pour dire qu’en gĂ©nĂ©ral, dans 90% du temps, on a son petit cluster K8S sur Azure/AWS/GCP, et nos services LoadBalancer rĂ©cupĂšrent une IP publique automatiquement. On a rien Ă  configurer en CLI ou autre. Le bĂ©mol, c’est qu’ici, et beh c’est pas le cas.

Arrive alors MetalLB. Dans le titre je parle de « DHCP » mais c’est plus pour l’image ; en rĂ©alitĂ© c’est un contrĂŽleur de LoadBalancers pour Kubernetes, en tout cas c’est une des dĂ©finitions les plus probantes que j’ai pu trouvĂ©e.

En gros, on va l’installer sur notre cluster, lui renseigner une (ou plusieurs) plages d’adresses IPv4 (ou v6 !), et il va se charger de distribuer ces adresses Ă  nos services LoadBalancer sur notre instance dĂšs que ceux-ci en auront besoin.

Bien, assez de blabla ! Pour l’installer, on a plusieurs choix (comme souvent avec K8S…) :

# Via un fichier manifeste, comme pour Flannel

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.9/config/manifests/metallb-native.yaml

Soit via Helm, le « package manager » made in K8S :

helm repo add metallb https://metallb.github.io/metallb
helm install metallb metallb/metallb

Alors cet article commence dĂ©jĂ  Ă  devenir un peu long pour juste expliquer l’install’ de Flannel/MetalLB/Nginx Ingress Controller, donc je ne vais pas dĂ©crire prĂ©cisĂ©ment ce qu’est Helm, j’en ferai peut ĂȘtre un article dĂ©diĂ©. Sachez simplement qu’il permet d’installer/gĂ©rer des charts, des sortes d’applications K8S « prĂ©-packagĂ©s » dirons-nous.

Bref, qu’importe la façon que vous allez choisir, l’important est que ça tourne !

Une fois fait, il ne nous reste plus qu’Ă  crĂ©er un petit fichier manifeste en Yaml qui va nous permettre de dĂ©finir notre fameuse plage d’IPs pour MetalLB :

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: example
  namespace: metallb-system
spec:
  addresses:
  - 192.168.0.70-192.168.0.75
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: empty
  namespace: metallb-system

Alors ici j’ai volontairement mis une petite plage, mais libre Ă  vous d’adapter, en mettant par exemple :

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: example
  namespace: metallb-system
spec:
  addresses:
  - 192.168.0.70-192.168.0.75    # Plage IPv4
  - 2001:db8::10-2001:db8::15    # Plage IPv6
  - 10.0.0.0/24                  # Subnet IPv4 en notation CIDR
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: empty
  namespace: metallb-system

Et il n’y a plus qu’Ă  appliquer le tout !

# Ici mon fichier de config s'appelle donc metallb-config.yaml, et je l'ai créé dans un folder nommé metallb, histoire d'avoir un peu de clarté

kubectl apply -f metallb/metallb-config.yaml

Et pour tester la chose… si l’on appliquer ce fichier manifeste via un classique kubectl apply -f , et qui est un simple service web Apache avec un service de type LoadBalancer :

# Création du Namespace 'web'
apiVersion: v1
kind: Namespace
metadata:
  name: web

---
# Déploiement d'un serveur web HTTP (Apache) dans le namespace 'web'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
  namespace: web
spec:
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: httpd
        image: httpd:2.4.48-alpine3.14  # Image du serveur web Apache
        ports:
        - containerPort: 80  # Le serveur web écoute sur le port 80

---
# Création d'un Service LoadBalancer pour exposer le serveur web à l'extérieur du cluster, et obtenir une IP de MetalLB justement
apiVersion: v1
kind: Service
metadata:
  name: web-server-service
  namespace: web
spec:
  selector:
    app: web  # Sélectionne le Deployment avec l'étiquette 'app: web'
  ports:
    - protocol: TCP
      port: 80           # Port du service exposé
      targetPort: 80      # Port dans le conteneur
  type: LoadBalancer      # Type de service pour exposer à l'extérieur du cluster

Tadaaaaaa~ !

On voit bien ici que notre service dans le namespace web a bien reçu une external-ip ! Si c’est pas beau ça… đŸ„č

Maintenant qu’on a donc notre cluster avec Flannel d’installĂ©, MetalLB prĂȘt Ă  distribuer des IPs pour nos services LoadBalancer… il ne reste qu’Ă  installer notre cher Nginx Ingress Controller et on aura dĂ©jĂ  une solide base pour faire mumuse !

*Nous n’aurons plus besoin de ce serveur web de test, donc autant supprimer le namespace entier. Comme ça, pas besoin de supprimer le Deployment et le Service manuellement.

kubectl delete namespace web

V) Nginx Ingress Controller

Alors initialement je comptais partir sur Traefik… j’avais fait quelques tests, et j’avais rĂ©ussi Ă  setup l’accĂšs Ă  l’interface web etc, mais pour une raison que j’ignore, impossible de faire du simple routage basĂ© sur un nom d’hĂŽte… ‘marche juste pĂŽ. J’ai cherchĂ© un peu mais plutĂŽt que de laisser le temps filer, je me suis dit qu’on pourrait trĂšs bien partir sur Nginx, qui est l’Ingress Controller de rĂ©fĂ©rence sur K8S đŸ’đŸ»â€â™‚ïž

Bref ! On va donc utiliser Helm pour l’installer, en rajoutant en premier lieu le dĂ©pĂŽt :

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

Avant de procĂ©der Ă  l’installation dans son namespace correspondant, on va rapidement rĂ©cupĂ©rer un fichier values.yaml et l’Ă©diter :

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/refs/heads/main/charts/ingress-nginx/values.yaml

Et on s’assure que le paramĂštre hostNetwork soit bien Ă  true :

Et enfin on peut crĂ©er notre namespace puis l’installer dans ce dernier !

kubectl create namespace nginx-controller
helm install ingress-nginx ingress-nginx/ingress-nginx -f values.yaml -n nginx-controller

Il rĂ©cupĂšre bien son IP ! Maintenant crĂ©ons rapidement un fichier manifeste pour un serveur web Apache, avec une IngressRoute nous permettant d’y accĂ©der via son FQDN, Ă  savoir apache.tips4tech.local.

Bien-entendu, il vous faudra crĂ©er une entrĂ©e dans votre DNS. Ici, je fais donc pointer mon FQDN vers l’IP rĂ©cupĂ©rĂ©e par mon contrĂŽleur Nginx :

apache.tips4tech.local => 192.168.0.70

VoilĂ  le manifeste pour Apache :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: apache-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: apache
  template:
    metadata:
      labels:
        app: apache
    spec:
      containers:
      - name: apache
        image: apache:latest
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

---
apiVersion: v1
kind: Service
metadata:
  name: apache-service
spec:
  selector:
    app: apache
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: apache
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: apache.tips4tech.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: apache-service
                port:
                  number: 80

On le démarre via un simple kubectl apply -f deploy-apache.yaml et on vérifie ça !

Parfait ! 😎

On a dĂ©sormais rĂ©ussi Ă  mettre en place Flannel, MetalLB, et notre Ingress Controller Nginx avec en prime le test d’un p’tit serveur web ! Pas mal comme dĂ©but !

VI) Conclusion

Comme dit en dĂ©but d’article, je ne suis (pas encore ?) un expert en K8S ! C’est pourquoi si certains abus de langage/petites coquilles se sont glissĂ©s dans cet article, n’hĂ©sitez clairement pas en commentaires đŸ«Ą.

J’ai dĂ©cidĂ© de partir pour le moment sur Nginx comme dĂ©jĂ  dit aussi, car visiblement j’ai quelques p’tits soucis avec Traefik… rien d’insurmontable, un truc qui m’Ă©chappe et ça viendra vite. Mais voilĂ , je prĂ©fĂ©rai tout de mĂȘme avancer et ne pas rester bloquĂ© trop longtemps dessus.

Je ne sais pas non plus si je ferai une « SĂ©rie Kubernetes« , on verra. LĂ  l’objectif, aprĂšs avoir setupĂ© toute la partie Network, ce serait de :

  • Checker pour la partie Storage avec un grand S, c’est-Ă -dire montages NFS, voir du GlusterFS si j’me sens motivĂ©… j’ai justement retrouvĂ© dans mes brouillons un article traitant de cette techno… ‘article datant d’il y a 4 ans 😅
  • Checker pour installer Harbor, histoire d’avoir mon propre petit registre d’images Docker ;
  • Revenir sur la partie Networking pour setup du HTTPs… en gĂ©nĂ©ral on peut utiliser Let’s Encrypt qui est super simple Ă  setuper sur Traefik/Nginx, mais ici j’aimerai pousser le vice et utiliser ma propre PKI interne… et puis vu que c’est du On-Prem isolĂ©, pas possible d’utiliser Let’s Encrypt ici ;
  • … ;

Bref, ce n’est que le dĂ©but, mais ça peut s’annoncer bien sympatoche ! Je vous tiens au courant de tout ça.

Sur ce, j’espĂšre encore et toujours vous avoir appris quelques bricoles, et vous souhaite une bonne journĂ©e/soirĂ©e ! Ciao !

Cet article a déjà 1 an ! Merci d'en tenir compte... Images manquantes, liens et informations pas forcément mis à jour... !

2 comments

comments user
Seboss666

Tu pourras tout à fait utiliser Cert-Manager avec ta propre PKI (je te laisse chercher « SelfSigned » dans la doc).

Concernant Flannel, c’est une des CNIs les plus simples qui soient, il lui manque une fonction en particulier qui m’a fait choisir autre chose : les NetworkPolicy, pour amĂ©liorer l’isolation rĂ©seau au sein d’un cluster. Un autre sujet que tu auras certainement l’occasion d’aborder 🙂

    comments user
    Anthony

    Hey salut Seboss ! Toujours sympa d’avoir un retour de quelqu’un de bien plus expĂ©rimentĂ© ! 😁

    Je vais tĂącher de continuer un peu mes labos, lĂ  ces derniers temps je suis fort pris par mon nouveau boulot mais je vais finir par trouver le temps… 🙂

Laisser un commentaire