Installation d’un cluster Kubernetes sur Rocky Linux 8
Dans cet article, nous allons présenter l’installation d’un cluster Kubernetes (que nous abrégerons K8s par la suite) sur Rocky Linux 8.5. Pour rappel, Kubernetes est un orchestrateur de conteneurs. Ce cluster sera composé de 3 noeuds Master qui exposerons l’api K8s sur une adresse IP virtuelle assurant la haute disponibilité via l’utilisation de HAProxy et Keepalived. Il sera également composé de deux noeuds Worker sur lesquels se déploieront les conteneurs. Par défaut, les conteneurs ne seront pas déployés sur les noeuds masters (taint) mais il sera tout à fait possible d’outrepasser cette fonctionnalité à l’aide d’une simple commande. L’installation se fera avec la version 1.24 de Kubernetes et donc n’utilisera pas docker-shim.
Prérequis
Nous supposons que toutes les machines sont installées avec une Rocky Linux 8.5 minimale, SELinux étant désactivé. Les noms des machines sont correctement configurés et les adresses IP correctement positionnées.Le swap est désactivé et les horloges sont synchronisées.Les manipulations suivantes sont à faire sur l’ensemble des machines.
Nous allons créer le fichier /etc/sysctl.d/98-k8s.conf :
net.ipv4.ip_forward=1 net.ipv4.ip_nonlocal_bind=1 net.bridge.bride-nf-call-iptables=1 net.netfilter.nf_conntrack_max=1000000
Puis appliquer les modifications grace à :
/sbin/sysctl --system
Nous allons ensuite créer le fichier /etc/modules-load.d/containerd.conf :
overlay br_netfilter
Et charger directement ces modules :
modprobe overlay modprobe br_netfilter
Puis nous allons ajouter au fichier /etc/hosts les lignes suivantes :
192.168.11.101 master-1 192.168.11.102 master-2 192.168.11.103 master-3 192.168.11.121 worker-1 192.168.11.122 worker-2 192.168.11.110 api.be-root.com api
Installation KeepAlived + HAProxy
Installation
Ces manipulations seront à faire sur les noeuds master uniquement.
Nous installons les paquets nécessaires :
dnf install -y haproxy keepalived psmisc
Nous allons ensuite créer le fichier /etc/keepalived/keepalived.conf :
global_defs { router_id LVS_DEVEL } vrrp_script check_haproxy { script "killall -0 haproxy" interval 2 weight 2 } vrrp_instance haproxy-vip { state master # mettre backup sur master-2 et master-3 priority 250 # 249 sur master-2 et sur master-3 interface ens160 # a adapter en fonction du nom de l'interface reseau advert_int 1 virtual_router_id 160 unicast_src_ip 192.168.11.101 # Mettre l'ip de la machine actuelle unicast_peer { 192.168.11.102 # Mettre les IP des deux autres master 192.168.11.103 } authentication { auth_type PASS auth_pass 123456 # Mettre une passphrase identique sur les 3 masters } virtual_ipaddress { 192.168.11.110 } track_script { check_haproxy } }
Il nous reste ensuite à modifier firewalld et lancer keepalived :
firewall-cmd --add-rich-rule='rule protocol value="vrrp" accept' --permanent firewall-cmd --reload systemctl enable --now keepalived
Sur le master-1, il est possible de vérifier que l’ip virtuelle est bien en fonctionnement :
Nous allons ensuite créer le fichier /etc/haproxy/haproxy.cfg :
global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon stats socket /var/lib/haproxy/stats stats timeout 30s ssl-default-bind-ciphers PROFILE=SYSTEM ssl-default-server-ciphers PROFILE=SYSTEM defaults mode http log global option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.0/8 option redispatch retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen hafrontend bind *:16443 mode tcp option tcplog default_backend kube-apiserver backend kube-apiserver mode tcp option tcplog option ssl-hello-chk balance roundrobin server master-1 192.168.11.101:6443 cookie master-1 check server master-2 192.168.11.102:6443 cookie master-2 check server master-3 192.168.11.103:6443 cookie master-3 check
Puis il nous suffit de configurer firewalld (supprimer la ligne firewall-cmd qui correspond au noeud master courant) et lancer HAProxy :
firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101/32" port protocol="tcp" port="16443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102/32" port protocol="tcp" port="16443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103/32" port protocol="tcp" port="16443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121/32" port protocol="tcp" port="16443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122/32" port protocol="tcp" port="16443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.110/32" port protocol="tcp" port="6443" accept" firewall-cmd --reload systemctl enable --now haproxy
Vérification du fonctionnement
sur Master-1 :
L’adresse IP virtuelle est présente sur master-1. L’arrêt de haproxy provoque le transfert de l’adresse ip virtuelle vers un autre noeud master :
Le redémarrage de HAProxy sur master-1 provoque le transfert de l’adresse ip virtuelle à nouveau sur ce dernier :
Installation de containerd
L’installation est à faire sur l’ensemble des noeuds master et worker.
dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo dnf -y update dnf install -y containerd.io
Nous allons ensuite générer le fichier de configuration :
containerd config default | tee /etc/containerd/config.toml
Puis nous allons ensuite éditer le fichier /etc/containerd/config.toml pour y positionner l’option SystemdCgroup à true :
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] .... [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] SystemdCgroup=true
Nous démarrons ensuite containerd :
systemctl enable --now containerd
Installation de Kubernetes
Prérequis
Nous allons créer le fichier /etc/yum.repos.d/k8s.repo sur l’ensemble des noeuds masters et workers:
[k8s] name=k8s baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg exclude=kubelet kubeadm kubectl
Les paquets kubelet kubeadm et kubectl sont exclus afin d’éviter tout update ultérieure non intentionnelle.
Installation de Master-1 :
Nous installons K8s :
dnf install -y iproute-tc dnf install -y kubelet kubeadm kubectl --disableexcludes=k8s systemctl enable kubelet.service
Puis nous allons configurer firewalld (supprimez les lignes dont l’adresse source correspond au noeud master courant). Le réseau 10.0.0.0/23 sera réservé pour les pods. Il faut faire attention à ce qu’il n’interfère pas avec un réseau local existant :
firewall-cmd --add-rich-rule='rule protocol value=4 accept' --permanent firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="tcp" port="179" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="tcp" port="2379-2380" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="udp" port="4789" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="tcp" port="5473" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="tcp" port="6443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="tcp" port="10250" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="tcp" port="10251" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="tcp" port="10255" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="tcp" port="179" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="tcp" port="2379-2380" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="udp" port="4789" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="tcp" port="5473" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="tcp" port="6443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="tcp" port="10250" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="tcp" port="10251" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="tcp" port="10255" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="tcp" port="179" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="tcp" port="2379-2380" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="udp" port="4789" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="tcp" port="5473" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="tcp" port="6443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="tcp" port="10250" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="tcp" port="10251" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="tcp" port="10255" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="tcp" port="179" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="tcp" port="2379-2380" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="udp" port="4789" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="tcp" port="5473" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="tcp" port="6443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="tcp" port="10250" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="tcp" port="10251" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="tcp" port="10255" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="tcp" port="179" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="tcp" port="2379-2380" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="udp" port="4789" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="tcp" port="5473" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="tcp" port="6443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="tcp" port="10250" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="tcp" port="10251" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="tcp" port="10255" accept" firewall-cmd --zone=public --add-port=30000-32767/tcp --permanent firewall-cmd --permanent --new-zone=kubernetes_pods firewall-cmd --permanent --zone=kubernetes_pods --set-target=ACCEPT firewall-cmd --permanent --zone=kubernetes_pods --add-source=10.0.0.0/23 # Adapter en fonction du pod-network-cidr défini dans la commande kubeadm init sur le 1er master firewall-cmd --reload
Nous allons ensuite initialiser le noeud avec :
kubeadm init --control-plane-endpoint "api.be-root.com:16443" --upload-certs --pod-network-cidr=10.0.0.0/23
La commande nous fourni les lignes de commande kubeadm à utiliser pour l’installation des autres masters et workers. Comme nous les utiliserons plus tard, pensez à les noter :
Configurons notre environnement de travail :
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
Dans le fichier /var/lib/kubelet/kubeadm-flags.env, ajoutons une ligne :
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
et redémarrons kubelet :
systemctl restart kubelet
Nous allons ensuite installer le CNI Calico qui se chargera de la partie networking :
curl -L https://docs.projectcalico.org/manifests/tigera-operator.yaml -o tigera-operator.yaml curl -L https://docs.projectcalico.org/manifests/custom-resources.yaml -o custom-resources.yaml curl -L https://github.com/projectcalico/calico/releases/download/v3.23.0/calicoctl-linux-amd64 -o /usr/bin/calicoctl chmod +x /usr/bin/calicoctl
Dans le fichier custom-resources.yaml, nous modifions la ligne cidr: 192.168.0.0/16 en :
cidr: 10.0.0.0/23
Puis nous lançons les deux commandes :
kubectl create -f tigera-operator.yaml kubectl create -f custom-resources.yaml
Nous pouvons vérifier que tout s’est correctement déroulé et que le node master-1 est en état « Ready » :
Installation de Master-2 et Master-3 :
La procédure au départ est la même que pour Master-1 : ajout du dépôt K8s, installation de k8s et paramétrage de firewalld.
En revanche, au lieu de lancer la commande kubeadm init, nous allons utiliser la commande kubeadm join qui a été affichée sur master-1 lors de la phase d’initialisation :
kubeadm join api.be-root.com:16443 --token bvvtg2.azhconkj5vbss727 \ --discovery-token-ca-cert-hash sha256:8c1b0aa71b8a7b36c2fa7636092bb72b8fa64a6ac33fa2bab23740c54e1301d4 \ --control-plane --certificate-key 9e023d8cf480c6e9671ce2b1c5f97a0fa2aa1c3c1ef1fbb58ef7b7029857314d
Nous configurons ensuite l’environnement de travail avec :
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
Puis, dans le fichier /var/lib/kubelet/kubeadm-flags.env, ajoutons une ligne :
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
et redémarrons kubelet :
systemctl restart kubelet
Il est inutile d’installer à nouveau le CNI.
Une fois l’installation de master-2 et master-3 achevée, nous pouvons vérifier que les 3 noeuds sont en état « Ready » :
Installation de Worker-1 et Worker-2 :
Nous commençons par configurer firewalld (supprimez le bloc correspondant au node courant) :
firewall-cmd --add-rich-rule='rule protocol value=4 accept' --permanent firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="tcp" port="179" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="udp" port="4789" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="tcp" port="5473" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="tcp" port="6443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="tcp" port="10250" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="tcp" port="10251" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.101" port protocol="tcp" port="10255" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="tcp" port="179" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="udp" port="4789" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="tcp" port="5473" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="tcp" port="6443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="tcp" port="10250" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="tcp" port="10251" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.102" port protocol="tcp" port="10255" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="tcp" port="179" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="udp" port="4789" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="tcp" port="5473" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="tcp" port="6443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="tcp" port="10250" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="tcp" port="10251" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.103" port protocol="tcp" port="10255" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="tcp" port="179" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="udp" port="4789" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="tcp" port="5473" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="tcp" port="6443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="tcp" port="10250" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="tcp" port="10251" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.121" port protocol="tcp" port="10255" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="tcp" port="179" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="udp" port="4789" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="tcp" port="5473" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="tcp" port="6443" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="tcp" port="10250" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="tcp" port="10251" accept" firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.11.122" port protocol="tcp" port="10255" accept" firewall-cmd --add-port=30000-32767/tcp --permanent --zone=public firewall-cmd --permanent --new-zone=kubernetes_pods firewall-cmd --permanent --zone=kubernetes_pods --set-target=ACCEPT firewall-cmd --permanent --zone=kubernetes_pods --add-source=10.0.0.0/23 # Adapter en fonction du pod-network-cidr défini dans la commande kubeadm init sur le 1er master firewall-cmd --reload
Puis nous installons K8s :
dnf install -y iproute-tc dnf install -y kubelet kubeadm kubectl --disableexcludes=k8s systemctl enable kubelet.service
Nous utilisons ensuite la seconde ligne kubeadm join indiquée lors de l’installation du master-1 pour joindre le noeud au cluster :
kubeadm join api.be-root.com:16443 --token bvvtg2.azhconkj5vbss727 \ --discovery-token-ca-cert-hash sha256:8c1b0aa71b8a7b36c2fa7636092bb72b8fa64a6ac33fa2bab23740c54e1301d4
Puis, dans le fichier /var/lib/kubelet/kubeadm-flags.env, ajoutons une ligne :
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
et redémarrons kubelet :
systemctl restart kubelet
Nous pouvons ensuite, depuis un nœud master, vérifier que l’ensemble fonctionne correctement :
Test d’un déploiement
Déploiement de nginx
Sur un nœud master, créons le fichier test.yaml :
apiVersion: v1 kind: Service metadata: name: test-nginx labels: run: test-nginx spec: type: NodePort ports: - port: 8080 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: 1 template: metadata: labels: run: test-nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80
Puis lançons la commande :
kubectl create -f test.yaml
Nous pouvons vérifier le bon déploiement à l’aide de la commande kubectl get pod,svc -o wide :
Ici, nous pouvons voir que le pod nginx est lancé sur le worker-2. De même, une commande curl sur le port alloué au nodeport permet d’obtenir la page par défaut de nginx.
Déploiement d’un pod centos
Créons le fichier centos.yaml. Comme le pod nginx tourne sur worker-2, nous allons forcer la création du pod centos sur worker-1 :
apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: centos name: centos spec: nodeName: worker-1 containers: - image: centos:8 name: centos command: ["/bin/sleep", "3650d"] resources: {} dnsPolicy: ClusterFirst restartPolicy: Never status: {}
Nous créons ensuite le pod à l’aide de :
kubectl create -f centos.yaml
Nous pouvons ensuite voir que le pod est bien déployé sur worker-1 et que le pod centos peut communiquer avec le pod nginx grace au nom du service :
Nettoyage
Nous pouvons supprimer ce que nous avons crée précédemment grâce à :
kubectl delete -f centos.yaml kubectl delete -f test.yaml
Nous voilà donc arrivé à la fin de ce (long!) article concernant la mise en place d’un cluster kubernetes. Dans les prochains articles, nous partirons de ce cluster de base pour l’enrichir de quelques fonctionnalités.
Installer un serveur Subversion sur Synology DSM 7
Avec la sortie de DSM en version 7, le paquet SVN Server permettant d’installer un serveur subversion sur un NAS Synology n’est plus supporté.
Pour ceux utilisant ce paquet sous DSM en version 6, il existe plusieurs solutions permettant d’outrepasser ce problème (passage à git, utiliser un serveur subversion externe, etc …) et donc d’envisager la mise à jour de DSMv6 vers DSMv7.
Dans cet article nous allons étudier une solution consistant à installer un conteneur docker pour faire tourner un serveur subversion sur le NAS Synology (à condition bien sûr, que votre NAS supporte l’installation du paquet Docker).
Nous verrons ensuite comment transférer les repositories subversion gérés via le paquet officiel SVN Server vers notre serveur nouvellement installé.
Installation d’un serveur SVN via Docker sur Synology DSM
Tout d’abord, si cela n’est pas encore fait, nous allons installer le paquet Docker depuis le Centre des Paquets de DSM.
Nous allons ensuite créer un répertoire svn sous le répertoire docker. Puis nous ferons trois répertoires qui nous servirons à rendre persistant les données du conteneur.
Nous allons ensuite lancer l’application Docker et y télécharger l’image clamy54/svn-svnadmin:latest.
Il s’agit d’une image basée sur ubuntu 20.04 LTS comportant les outils subversions ainsi qu’une interface web permettant d’administrer l’organisation de nos repositories subversion.
Nous allons ensuite créer le conteneur associé :
Puis, dans les paramètres avancés, nous allons configurer le redémarrage automatique du conteneur :
Nous allons ensuite associer les répertoires crées précédemment aux volumes exportés par le conteneur :
Puis rediriger des ports tcp du synology vers les ports 80/tcp et 443/tcp du conteneur :
Nous pouvons alors valider la création du conteneur et le démarrer.
Transfert des repositories svn
Le transfert des repositories est plutôt simple puisqu’il suffit d’arrêter le conteneur, puis de copier le contenu du répertoire /docker vers le répertoire /docker/svn/svn/ et de redémarrer le conteneur.
Il suffira ensuite de gérer les utilisateurs et droits d’accès directement depuis l’interface web iF-SVNAdmin fournie par le conteneur.
Accès au serveur Subversion et à l’interface iF.SVNAdmin
L’interface web est disponible en http ou https via les ports assignés précédemment.
Le login par défaut est admin et le mot de passe admin. Il est évident qu’il faut changer ce mot de passe par défaut au plus tôt.
Depuis cet interface, il nous est possible de créer des utilisateurs, des repositories et d’assigner des autorisations sur ces repositories.
L’accès depuis un client svn se fera alors, par exemple, de la manière suivante :
svn checkout --username myuser https://synology_ip:8443/svn/myrepository ./localfolder
Pour plus d’informations sur les personnalisations possibles, rendez-vous sur la page officielle du conteneur.
VMWare ESXi : Créer manuellement une partition de coredump
Dans cet article, nous allons voir comment créer manuellement une partition de coredump, utilisée notamment pour récupérer les informations de débuggage lors d’un plantage d’un ESXi.
Pré-requis : Il faut avoir accès à la ligne de commande via ssh à l’hyperviseur ESXi. Le datastore vmfs local doit également être vide car il sera supprimé lors de la manipulation.
Tout d’abord, nous allons utiliser la commande esxcfg-mpath -b afin de déterminer le nom de device associé au disque dur local :
[root@esxi:~] esxcfg-mpath -b naa.61866da0b8241a0020ee3286154ea8af : Local DELL Disk (naa.61866da0b8241a0020ee3286154ea8af) vmhba0:C2:T0:L0 LUN:0 state:active sas Adapter: 51866da0b8241a00 Target: 60ee3286154ea8af
Dans notre cas, le device se nomme naa.61866da0b8241a0020ee3286154ea8af
Nous allons ensuite utiliser la commande partedUtil getptbl « /vmfs/devices/disks/naa.61866da0b8241a0020ee3286154ea8af » pour visualiser le partitionnement actuel du disque :
[root@esxi:~] partedUtil getptbl "/vmfs/devices/disks/naa.61866da0b8241a0020ee3286154ea8af" gpt 36404 255 63 584843264 1 64 204863 C12A7328F81F11D2BA4B00A0C93EC93B systemPartition 128 5 208896 1232895 EBD0A0A2B9E5443387C068B6B72699C7 linuxNative 0 6 1234944 2258943 EBD0A0A2B9E5443387C068B6B72699C7 linuxNative 0 7 2260992 15470591 4EB2EA3978554790A79EFAE495E21F8D vmfsl 0 8 15472640 584843230 AA31E02A400F11DB9590000C2911D1B8 vmfs 0
Nous remarquons que le datastore vmfs est la partition 8, qu’il commence au secteur 15472640, se termine au secteur 584843230 et qu’il possède le GUID AA31E02A400F11DB9590000C2911D1B8 (correspondant à un datastore vmfs).
Ces GUID sont fixés par vmware. La liste des GUID peut être obtenue par la commande partedUtil showGuids :
[root@esxi:~] partedUtil showGuids Partition Type GUID vmfs AA31E02A400F11DB9590000C2911D1B8 vmkDiagnostic 9D27538040AD11DBBF97000C2911D1B8 vsan 381CFCCC728811E092EE000C2911D0B2 virsto 77719A0CA4A011E3A47E000C29745A24 VMware Reserved 9198EFFC31C011DB8F78000C2911D1B8 Basic Data EBD0A0A2B9E5443387C068B6B72699C7 Linux Swap 0657FD6DA4AB43C484E50933C84B4F4F Linux Lvm E6D6D379F50744C2A23C238F2A3DF928 Linux Raid A19D880F05FC4D3BA006743F0F84911E Efi System C12A7328F81F11D2BA4B00A0C93EC93B Microsoft Reserved E3C9E3160B5C4DB8817DF92DF00215AE Unused Entry 00000000000000000000000000000000
Il nous faut donc supprimer cette partition 8 afin d’y récupérer de l’espace pour pouvoir y recréer 2 partitions : une partition de type vmkDiagnostic et un nouveau datastore vmfs.
Pour supprimer la partition, la méthode la plus simple est de supprimer le datastore local depuis l’interface d’administration de l’ESXi. Il est également de le faire à l’aidre de la commande partedUtil.
Une fois la partition supprimée, la commande partedUtil getptbl « /vmfs/devices/disks/naa.61866da0b8241a0020ee3286154ea8af » affiche alors :
[root@esxi:~] partedUtil getptbl "/vmfs/devices/disks/naa.61866da0b8241a0020ee3286154ea8af" gpt 36404 255 63 584843264 1 64 204863 C12A7328F81F11D2BA4B00A0C93EC93B systemPartition 128 5 208896 1232895 EBD0A0A2B9E5443387C068B6B72699C7 linuxNative 0 6 1234944 2258943 EBD0A0A2B9E5443387C068B6B72699C7 linuxNative 0 7 2260992 15470591 4EB2EA3978554790A79EFAE495E21F8D vmfsl 0
Le chiffre 36404 correspond au nombre de cylindres adressable (0-36404), 255 au nombre de têtes (0-255) et 63 au nombre de secteurs par piste (0-63).
La commande esxcli storage core device capacity list permet de connaitre les caractéristiques du disque :
[root@esxi:~] esxcli storage core device capacity list Device Physical Blocksize Logical Blocksize Logical Block Count Size Format Type ------------------------------------ ------------------ ----------------- ------------------- ----------- ----------- mpx.vmhba2:C0:T5:L0 512 512 0 0 MiB 512n naa.61866da0b8241a0020ee3286154ea8af 512 512 584843264 285568 MiB 512n
Nous voyons donc que la taille d’un bloc est de 512 octets.
Une partition de coredump doit faire au moins 100Mo. Pour l’exemple, nous allons faire une partition de 200Mo.
Il faudra 200000000/512 = 390625 secteurs pour y loger cette partition. L’ancienne partition 8 commençait au secteur 15472640. Nous allons faire commencer cette nouvelle partition sur ce secteur
et nous allons la faire terminer sur le secteur 15472640+390625=15863265.
Nous allons donc créer cette nouvelle partition 8 avec un GUID de type vmkDiagnostic :
partedUtil add "/vmfs/devices/disks/naa.61866da0b8241a0020ee3286154ea8af" "gpt" "8 15472640 15863265 9D27538040AD11DBBF97000C2911D1B8 0"
Nous allons ensuite recréer un datastore vmfs dont le premier secteur sera le multiple de 64 directement supérieur à 15863265 (afin d’aligner la partition sur le
premier secteur du cylindre suivant). En l’occurrence, ici, la partition commencera donc au secteur 15863296. Pour le dernier secteur, nous utiliserons la valeur correspondante de l’ancienne partition 8.
Cette nouvelle partition portera le numéro 9 et utilisera un GUID de type vmfs.
partedUtil add "/vmfs/devices/disks/naa.61866da0b8241a0020ee3286154ea8af" "gpt" "9 15863296 584843230 AA31E02A400F11DB9590000C2911D1B8 0"
Nous allons afficher maintenant les partitions de type coredump reconnues par le systeme :
[root@esxi:~] esxcli system coredump partition list Name Path Active Configured -------------------------------------- ---------------------------------------------------------- ------ ---------- naa.61866da0b8241a0020ee3286154ea8af:8 /vmfs/devices/disks/naa.61866da0b8241a0020ee3286154ea8af:8 false false
La partition 8 est donc bien détectée mais elle n’est ni configurée ni active. Nous allons donc le faire :
esxcli system coredump partition set --partition="naa.61866da0b8241a0020ee3286154ea8af::8" esxcli system coredump partition set --enable true
La commande affiche alors :
[root@esxi:~] esxcli system coredump partition list Name Path Active Configured -------------------------------------- ---------------------------------------------------------- ------ ---------- naa.61866da0b8241a0020ee3286154ea8af:8 /vmfs/devices/disks/naa.61866da0b8241a0020ee3286154ea8af:8 true true
La partition coredump est donc maintenant configurée et active.
Il ne nous reste plus qu’à formater la partition 9 en vmfs :
vmkfstools -C vmfs6 -S esxi-local /vmfs/devices/disks/naa.61866da0b8241a0020ee3286154ea8af:9