Installation du LoadBalancer MetalLB pour Kubernetes
Présentation
Dans cet article nous allons installer MetalLB qui est un loadbalancer pour Kubernetes. Il permet ainsi d’utiliser des services de type LoadBalancer (traditionnellement utilisés par les clusters hebergés chez des cloud providers) tout en faisant tourner son propre cluster Kubernetes baremetal.
Ainsi, contrairement à un service de type ExternalIP, l’adresse IP attribuée au service LoadBalancer ne dépend pas d’un nœud en particulier.
MetalLB fonctionne soit en mode BGP soit en mode Layer 2. Dans cet article, nous allons le configurer pour le faire fonctionner dans le mode Layer 2. Nous partirons du cluster installé dans cet article.
Le fonctionnement dans ce mode à quelques ressemblances avec celui de keepalived. Une adresse IP sera fournie au service et tout le traffic à destination de ce service sera redirigé vers un noeud worker. Kube-proxy redirigera ensuite les requêtes vers les pods du service.
En cas de dysfonctionnement du nœud, un nouveau nœud fonctionnel répondra alors aux requêtes à destination de l’adresse IP attribuée. A la différence keepalived, les noeuds ne communiquent pas entre eux. En effet, MetalLB utilise memberlist pour connaître la disponibilité des nœuds du cluster k8s. Il ne s’agira donc pas d’un vrai équilibrage de charge mais plutôt d’une mise en place de haute disponibilité.
Installation
Tout d’abord, nous allons configurer firewalld sur l’ensemble des noeuds (supprimer la ligne correspondant au noeud courant) :
firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101/32" port protocol="tcp" port="7946" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102/32" port protocol="tcp" port="7946" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103/32" port protocol="tcp" port="7946" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121/32" port protocol="tcp" port="7946" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122/32" port protocol="tcp" port="7946" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101/32" port protocol="udp" port="7946" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102/32" port protocol="udp" port="7946" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103/32" port protocol="udp" port="7946" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121/32" port protocol="udp" port="7946" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122/32" port protocol="udp" port="7946" accept" firewall-cmd --reload
Ensuite nous allons positionner le paramètre StrictARP à True de la section ipvs grace à la commande :
kubectl edit configmap -n kube-system kube-proxy
L’installation se fait ensuite en lançant ces deux commandes :
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml
Configuration
La configuration de MetalLB se fait à l’aide d’un fichier au format yaml.
Nous allons définir le pool d’adresse 192.168.11.170 à 192.168.11.199 que MetalLB va pouvoir assigner aux services.
Editons un fichier nommé config.yaml :
apiVersion: v1 kind: ConfigMap metadata: namespace: metallb-system name: config data: config: | address-pools: - name: default protocol: layer2 addresses: - 192.168.11.170-192.168.11.199
Nous pouvons ensuite appliquer ce fichier :
kubectl apply -f config.yaml
Fonctionnement
Pour tester le fonctionnement, nous allons créer le fichier nginx-lb.yaml suivant :
apiVersion: v1 kind: Service metadata: name: test-nginx labels: run: test-nginx annotations: metallb.universe.tf/address-pool: default spec: type: LoadBalancer ports: - port: 80 targetPort: 80 protocol: TCP name: http - port: 443 protocol: TCP name: https selector: run: test-nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: test-nginx spec: selector: matchLabels: run: test-nginx replicas: 3 template: metadata: labels: run: test-nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80
Puis nous l’intégrons grâce à la commande :
kubectl create -f nginx-lb.yaml
La commande kubectl describe svc/test-nginx permet de connaitre l’adresse IP attribué (ici 192.168.11.170) ainsi que le noeud répondant aux requêtes (ici worker-1) :
En faisant pointer un navigateur web à cette adresse, nous avons donc bien la page d’accueil de nginx :
Si nous arrêtons le worker-1, nous pouvons voir que c’est le worker-2 qui prend le relais :
Installer Kubernetes Dashboard
Introduction
Kubernetes Dashboard est une interface web permettant d’interagir avec Kubernetes. Elle permet à la fois de gérer les ressources du cluster mais aussi de déployer des applications conteneurisées.
Dans cet article, nous allons l’installer sur le cluster configuré dans cet article.
Installation
L’installation se fait tout simplement avec la commande :
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended.yaml
Le déploiement par défaut du dashboard créer un service de type ClusterIP :
Afin de pouvoir y accéder de manière simple depuis une machine extérieur au cluster, nous allons modifier le service en NodePort :
kubectl patch svc kubernetes-dashboard -p '{"spec": {"type": "NodePort"}}' -n kubernetes-dashboard
La commande kubectl get svc kubernetes-dashboard -n kubernetes-dashboard nous permet alors de connaitre le port tcp attribué au service :
Dans notre cas, il s’agit du port 32217/TCP.
Nous pouvons donc accéder au dashboard depuis une machine extérieure au cluster à l’adresse https://une_des_adresse_IP_des_noeuds:32217/ :
Accès à l’interface
Pour accéder à l’interface, nous allons créer un token d’authentification associé à un ServiceAccount auquel nous donnerons les droits d’administration. Une des nouveautés de Kubernetes 1.24 est qu’il ne crée plus automatiquement de token
lors de la création du ServiceAccount.
Créons le fichier k8s-admin.yaml :
apiVersion: v1 kind: ServiceAccount metadata: name: k8s-admin namespace: kube-system --- apiVersion: v1 kind: Secret type: kubernetes.io/service-account-token metadata: name: k8s-admin annotations: kubernetes.io/service-account.name: "k8s-admin" namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: k8s-admin roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: k8s-admin namespace: kube-system
Puis lançons la commande :
kubectl create -f k8s-admin.yaml
La commande suivante permet d’afficher le token :
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep k8s-admin | awk '{print $1}')
Un copié-collé de ce token sur la page d’authentification du dashboard nous permet ensuite de nous connecter à ce dernier :
Installer Metrics Server sur un cluster Kubernetes
Introduction
Metrics Server pemet de collecter des données de consommations de ressources depuis les noeuds du cluster et les pods fonctionnant dessus.
Dans cet article nous nous baserons sur le cluster Kubernetes configuré dans le précédent article.
Prérequis
Sur tous les nodes (masters et workers), nous allons executer la commande suivante :
echo "serverTLSBootstrap: true" >> /var/lib/kubelet/config.yaml && systemctl restart kubelet
La commande kubectl get csr nous permet ensuite de visualiser les demandes de signature de certificats :
Nous allons ensuite les signer grace à la commande kubectl certificate approve :
Ensuite, sur les noeuds master-1, master-2 et master-3, nous allons éditer le fichier /etc/kubernetes/manifests/kube-apiserver.yaml pour y ajouter une ligne
--enable-aggregator-routing=true
Nous pouvons à présent redémarrer le service kubelet.
Installation de Metrics Server
L’installation se fait très facilement grâce à la commande :
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
Au bout de quelques instants, nous pouvons voir que le pod metrics-server est démarré :
Nous pouvons également vérifier que les données sont correctement collectées grace à la commande kubectl top nodes :
Exemple d’utilisation
Grâce au Metrics Server, nous pouvons par exemple utiliser une ressource de type HorizontalPodAutoscaler afin d’adapter le nombre de pods en fonction de l’utilisation du CPU.
Par exemple nous pouvons créer le fichier hpa.yaml :
apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: selector: matchLabels: run: nginx replicas: 1 template: metadata: labels: run: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 resources: limits: cpu: 500m requests: cpu: 250m --- apiVersion: v1 kind: Service metadata: name: nginx labels: run: nginx spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: run: nginx --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: nginx spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nginx minReplicas: 1 maxReplicas: 3 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 30
Et ensuite executer la commande :
kubectl create -f hpa.yaml
Au bout de quelques instants, nous pouvons avoir une visualisation de l’état de l’HorizontalPodAutoscaler grâce à la commande kubectl get hpa: