Kubernetes

Installation d’un cluster Kubernetes

Aujourd’hui un petit tutoriel sur l’installation d’un Cluster Kubernetes. La procédure ci-dessous vous indiquera en partie la méthode que nous utilisons pour installer le cluster Kubernetes du From Zero

Pour ce tutoriel, nous n’allons utiliser un master et un worker. Pas la peine de s’ennuyer à aller plus loin pour le moment.

Qu’est-ce que Kubernetes

Créé par Google, basé sur Borg et Omega, les systèmes qui fonctionnent aujourd’hui chez Google et dont la robustesse est éprouvée depuis plus de 10 ans. Google exécute 2 milliards de conteneurs par semaine.

Créé par trois employés de Google initialement pendant l’été 2014. Il a grandi de façon exponentielle et est devenu le premier projet à être donné à la CNCF (Cloud Native Computing Foundation) .

Pour comprendre ce qu’est Kubernetes, il faut d’abord savoir ce qu’est un conteneur :

En gros, la virtualisation par conteneur est une méthode de cloisonnement au niveau de l’OS basé sur la technologie de virtualisation Linux LXC. Le principe est de faire tourner des environnements isolés les uns des autres dans des conteneurs tout en se partageant le même noyau Linux, le Kernel donc.

Le conteneur virtualise seulement l’environnement d’exécution (comme le processeur, la mémoire vive ou le système de fichier…) et ne virtualise donc pas la machine entière comme pour une machine virtuel.

Le conteneur est donc plus léger que la machine virtuel, ce qui permet de créer beaucoup plus de conteneurs que de machine virtuel sur un même serveur.

Préparation de vos serveurs

Avant de commencer le déploiement de Kubernetes, assurez-vous d’effectuer les actions suivantes en tant que root (ou avec les droits sudo nécessaires).

Les serveurs que j’utilise dans ce tutoriel sont fraîchement installer avec la version 7.6 de Centos, je recommande cette distribution car en entreprise vous retrouvez souvent la distribution Red Hat.

Mise à jour du système

Les commandes suivante vous permettrons de mettra à jour votre système :

$ yum clean all
$ yum makecache
$ yum update -y

Configuration du serveur de temps

Un des prérequis fondamentaux d’un serveur c’est qu’il soit à l’heure. Malheureusement, l’horloge intégrée de nos serveurs n’est pas suffisamment exacte. Afin remettre les pendules à l’heure de nos serveurs, les commandes suivantes vous permettrons de régler cette problématique rapidement.

$ yum install -y ntp ntpdate
$ systemctl enable ntpd
$ timedatectl set-timezone Europe/Paris

Configuration du Pare-feu

Afin de bien faire les choses, nous ne désactiverons pas le firewall (Comme beaucoup le propose malheureusement), donc pour bien faire les choses je vous propose deux configurations en fonction du type d’instance :

Sur le Kubernetes Master :

Port(s)Description
6443API Kubernetes
2379-2380API Serveur etcd
10250API Kubelet
10251Kube-Scheduler
10252Kube-Controller Manager
10255Read-Only Kubelet API
$ firewall-cmd --permanent --add-port={6443,2379-2380,10250,10251,10252,10255}/tcp
$ firewall-cmd --add-masquerade --permanent
$ systemctl restart firewalld

Sur les minions (workers) :

Port(s)Description
10250API Kubelet
10255Read-Only Kubelet API
30000-32767Ports Services NodePorts
$ firewall-cmd --permanent --add-port={10250,10255,30000-32767}/tcp
$ firewall-cmd --add-masquerade --permanent
$ systemctl restart firewalld

Activer le module noyau « br_netfilter » sur tous les hôtes du cluster, ce qui est requis par Kubernetes

$ modprobe br_netfilter

La commande modprobe permet le chargement d’un module noyau durant l’exécution, mais cela n’est pas persistant après un redémarrage des serveurs. Créer le fichier /etc/sysctl.d/k8s.conf et ajouter les lignes suivantes :

$ cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

Appliquer les règles sysctl directement :

$ sysctl -p /etc/sysctl.d/k8s.conf

Modifier le contexte SELinux

Je recommande l’utilisation de SELinux généralement, mais ce dernier demande trop de configurations spécifiques et ajoute une couche de complexité que nous n’avons pas besoin dans le cadre de ce tutoriel. Je vous recommande donc d’activer uniquement ce dernier dans un environnement de production, ceci afin d’avoir une meilleure isolation entre les processus.

Petit rappelle concernant les trois modes que propose SELinux :

  • Dans le mode strict (Enforcing), les accès sont restreints en fonction des règles SELinux en vigueur sur la machine.
  • Le mode permissif (Permissive) peut être considéré comme un mode de débogage. Les règles SELinux sont interrogées, les erreurs d’accès sont enregistrées dans les logs, mais l’accès ne sera pas bloqué.
  • Lorsque SELinux est désactivé (Disabled), l’accès n’est pas restreint, et rien n’est enregistré dans les logs.

Passons donc maintenant SELinux en mode permissif de façon immédiate et permanente:

$ setenforce 0
$ sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

On vérifie l’état le status de SELinux avec la commande getenforce. Si tout va bien, cette commande vous renverra « permissive » :

$ getenforce
Permissive

Désactivation du Swap

Vous devez impérativement désactiver le swap pour que Kubernetes fonctionne correctement, les commandes suivantes vous permettrons de le désactiver complètement :

$ swapoff -a
$ sed -i '/ swap / s/^/#/' /etc/fstab

Pour rappelle, le swap est une zone d’un disque dur faisant partie de la mémoire virtuelle de votre ordinateur. Il est utilisé pour décharger la mémoire vive physique (RAM) de votre serveur lorsque celle-ci arrive à saturation.

Installation de Docker

Installer tout d’abord les dépendances pour Docker-CE :

$ yum install -y yum-utils device-mapper-persistent-data lvm2

Ajouter le repository YUM :

$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

Installer Docker-CE :

$ yum install -y docker-ce containerd.io

Démarrer le service Docker et activer le démarrage du service au boot

$ systemctl enable --now docker

Kubernetes nécessite une configuration particulière de Docker au niveau de cgroups. Cette configuration n’est pas impérative mais est fortement conseillée. Elle consiste à switcher le driver cgroup cgroupfs, par défaut utilisé par Docker, par le driver cgroup systemd.

Explications : https://kubernetes.io/docs/setup/production-environment/container-runtimes/#cgroup-drivers

Créer un fichier /etc/docker/daemon.json et ajouter le contenu suivant :

$ cat <<EOF > /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
EOF

Il convient finalement de redémarrer le daemon Docker pour prendre en compte les changements :

$ systemctl restart docker

Vérifier que le driver cgroup systemd est bien chargé

$ docker info | grep Cgroup
Cgroup Driver: systemd

Installation de Kubernetes

L’installation des dépendances d’un noeud kubernetes (master ou worker) devra s’effectuer comme suit :

$ cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
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
EOF
$ yum makecache fast
$ yum install -y kubelet kubeadm kubectl

Mis en place du cluster Kubernetes

Lancez l’initialisation de votre cluster Kubernetes (uniquement sur votre master) via la commande ci-dessous en :

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

Note : Veuillez ne pas modifier l’ip du réseau « 10.244.0.0/16 » indiquée dans le paramètre « –pod-network-cidr= » car celui-ci permet d’indiquer que nous allons utiliser le plugin Flannel pour gérer la partie réseau de nos pods.

Voici à quoi doit ressembler le retour de la précédente commande, quand le cluster s’initialise avec succès :

[init] Using Kubernetes version: v1.14.3
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Activating the kubelet service
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [srv-k8s-master01.netboot.lan localhost] and IPs [172.16.5.211 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [srv-k8s-master01.netboot.lan localhost] and IPs [172.16.5.211 127.0.0.1 ::1]
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [srv-k8s-master01.netboot.lan kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 172.16.5.211]
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 15.502251 seconds
[upload-config] storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.14" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --experimental-upload-certs
[mark-control-plane] Marking the node srv-k8s-master01.netboot.lan as control-plane by adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node srv-k8s-master01.netboot.lan as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: dx42vx.5u8emct7bvz6l2kv
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] creating the "cluster-info" ConfigMap in the "kube-public" namespace
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 172.16.5.211:6443 --token dx42vx.5u8emct7bvz6l2kv --discovery-token-ca-cert-hash sha256:de880889c87fcc683be095bac569bafaaeb80bbdff89307f0afb9398d5199983

Nous allons maintenant effectuer les opérations demandées afin de finaliser l’initialisation de notre cluster :

$ mkdir -p $HOME/.kube
$ cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

L’ajout d’un Network Overlay est tout aussi simple, chaque composant étant un add-on, une simple commande permet de l’installer et le système de Kubernetes effectuera un scalling automatique en fonction du nombre de node qui est enregistré.

Dans notre cas, pour installer Flannel, il faut juste exécuter la commande suivante :

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

Avant d’aller plus loin, il est nécessaire de vérifier que chaque composant est bien déployé, a l’aide de la commande suivante : kubectl get po -n kube-system vous allez pouvoir obtenir les informations nécessaire.

$ kubectl get po -n kube-system                                                                                                                 root@SRV-K8S-MASTER01
NAME                                                          READY   STATUS    RESTARTS   AGE
coredns-5c98db65d4-9dlnc                                      1/1     Running   1          35m
coredns-5c98db65d4-c4wnj                                      1/1     Running   1          35m
etcd-srv-k8s-master01.server.netboot.lan                      1/1     Running   3          35m
kube-apiserver-srv-k8s-master01.server.netboot.lan            1/1     Running   3          35m
kube-controller-manager-srv-k8s-master01.server.netboot.lan   1/1     Running   3          35m
kube-flannel-ds-amd64-9kjmv                                   1/1     Running   1          35m
kube-flannel-ds-amd64-pw4n8                                   1/1     Running   1          35m
kube-proxy-sqwp9                                              1/1     Running   1          35m
kube-proxy-tw8g4                                              1/1     Running   3          35m
kube-scheduler-srv-k8s-master01.server.netboot.lan            1/1     Running   3          35m

Dans la documentation officiel de Kubernetes vous trouvez l’ensemble des Network Overlay compatible : https://kubernetes.io/docs/concepts/cluster-administration/networking/

Worker nodes

Pour ajouter d’autres nœuds à notre cluster c’est très simple, la commande kubeadm init exécutée précédemment à du vous afficher une commande kubeadm join suivit d’un token qui devrait ressembler à ça :

$ kubeadm join --token <TOKEN> <IP>

Une fois cette commande exécutée sur on vérifie que le(s) nœud(s) sont correctement ajouté(s) avec kubectl get nodes.

$ kubectl get nodes
NAME               STATUS   ROLES    AGE    VERSION
srv-k8s-master01   Ready    master   13m    v1.14.3
srv-k8s-worker01   Ready    <none>   107s   v1.14.3
srv-k8s-worker02   Ready    <none>   91s    v1.14.3

Utiliser seulement un nœud

Si vous ne voulez pas utiliser d’autre nœud que le master pour ne pas vous embêter avec plusieurs machine virtuel par exemple c’est possible, sachez tout de même que c’est une mauvaise pratique : si votre cluster se casse la figure, vous êtes dans la mouise !

La commande suivante permet de ne plus restreindre votre nœud a son rôle de master, ce qui aura pour effet de pouvoir lancer des containers sur votre master :

$ kubectl taint nodes --all node-role.kubernetes.io/master-

PS: Si jamais vous avez tout cassé et que votre cluster ne fonctionne plus vous pouvez remettre à zéro votre installation avec un kubeadm reset.

Conclusion

Kubernetes facilite l’utilisation des containers sur des grosses infrastructures et propose une manière simple de faire de l’auto-scaling. Ça permet de se concentrer sur le développement et l’amélioration de son application et moins sur la gestion de ses serveurs.

Je n’ai pas abordé les détails de l’utilisation de Kubernetes, il s’agit simplement d’un mini guide d’installation pour découvrir l’outil.

Autres ressources

Tags

Thomas ILLIET

Si le développement PowerShell était un art, vous pourriez certainement me considérer comme un artisan au sens noble du terme. Apportant un savoir-faire unique, un amour du travail bien fait et une personnalisation rendant chaque pièce produite parfaitement ciselée au besoin de son commanditaire.
Bouton retour en haut de la page
Fermer
Fermer