Blog de dada

DevOps, bidouilleur et routard plein de logiciels libres

virtualbox

Le dashboard de Kubernetes

Rédigé par dada / 04 novembre 2018 / 2 commentaires


Perdu ? Retrouvez les épisodes précédents :

À la fin de la deuxième partie de ce tuto, je dis que les couleurs, c'est quand même mieux. Enfin, c'est surtout assez fatiguant de lutter avec un grand nombre de terminaux pour vérifier le bon comportement du cluster. Pour nous sauver, il y a un Dashboard.

Installer le Dashboard

Pour installer le Dashboard, placez-vous sur votre master et tapez la commande suivante :
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
Kubernetes va aller chercher la configuration nécessaire la mise à en place du Dashboard directement depuis son dépôt Github et le faire apparaître dans la liste des pods de votre cluster.
dada@k8smaster:~$  kubectl get pods --all-namespaces -o wide | grep dashb
kube-system   kubernetes-dashboard-77fd78f978-f8p9l   1/1     Running   0          60s     10.244.1.230   k8snode1    <none>
Il est  "Running", ça veut dire qu'il est disponible, mais pas encore accessible.

Créez un compte utilisateur

Créez un fichier admin-user.yaml avec ce qui suit dedans :
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
Puis créez le rôle qui lui sera attaché : admin-role.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system
Chargez ces configurations dans le cluster :
kubectl apply -f admin-user.yaml
kubectl apply -f admin-role.yaml

Récupérer le token de connexion

Pour vous connecter au Dashboard, en plus d'avoir le pod et un utilisateur, il vous faut le token qui va bien. Pour le récupérer :
dada@k8smaster:~$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
Name:         admin-user-token-b8qmq
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: admin-user
              kubernetes.io/service-account.uid: a8a600b1-e010-11e8-96ec-0800273c4560

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1025 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJl.........
J'ai tronqué l'affichage du token. Il est d'une longueur dingue. Copiez-le dans un coin maintenant que vous l'avez.

Accéder au Dashboard

Le Dashboard n'est par défaut pas accessible en dehors du cluster. On peut cependant tricher en passant par un proxy et un tunnel SSH.

Le proxy

Ouvrez un nouveau terminal branché sur votre master et tapez la commande suivante :
dada@k8smaster:~$ kubectl proxy
Starting to serve on 127.0.0.1:8001

Le tunnel SSH

Depuis votre PC hôte, lancez le tunnel :
dada@dada-laptop:~$ ssh -L 8001:127.0.0.1:8001 dada@IP_DU_MASTER

Affichez le fameux tant attendu

Si tout s'est bien passé jusqu'ici, vous deviez pouvoir accéder au Dashboard via cette url :


Et voir ceci : 


Vous voici avec une belle interface pour admirer le comportement de votre cluster k8s. Foncez cliquer absolument partout et chercher le pourquoi du comment de telles options à tel endroit !

La suite ?

Démarrer notre cluster kubernetes

Rédigé par dada / 01 novembre 2018 / 4 commentaires



Vous ne comprenez pas d'où vient ce billet ? Retrouvez sa première partie !

Configurez le master

Le master, c'est la machine qui va gérer le cluster. Pour ce tutoriel, nous n'allons utiliser qu'un seul master. Pas la peine de s'ennuyer à aller plus loin pour le moment. Sachez tout de même que c'est une mauvaise pratique : s'il se casse la figure, vous êtes dans la mouise.

Initialisation

Pour initialiser le master (k8smaster), pour faire comprendre à la VM que c'est elle la cheffe, tapez la commande suivante :
kubeadm init --pod-network-cidr=10.244.0.0/16
Elle va initialiser le cluster et lui assigner une plage d'IP privée.

Si vous avez bien suivi la première partie de ce tuto, vous devriez voir afficher les choses (tronquées) suivantes :
root@k8smaster:/home/dada# kubeadm init --pod-network-cidr=10.244.0.0/16
[init] using Kubernetes version: v1.12.2
[preflight] running pre-flight checks
[preflight/images] Pulling images required for setting up a Kubernetes cluster
[preflight/images] This might take a minute or two, depending on the speed of your internet connection
[preflight/images] You can also perform this action in beforehand using 'kubeadm config images pull'
[..]
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes master has initialized successfully!
Le message affirmant que le master est bien initialisé parle de lui-même : on est bon ! Ou presque. Il faut faire ce que la suite du message vous demande.

Configurez l'utilisateur qui aura le droit de jouer avec k8s

Notez que jongler entre k8s et docker peut-être épuisant : certaines commandes se jouent en root et d'autres en simple utilisateur. Pensez à changer d'utilisateur si rien ne se passe ou si le terminal vous insulte.

On enchaîne donc avec :
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

Je vous laisse placer le fichier de configuration du cluster dans la home de votre utilisateur classique.

Configurer le réseau du cluster

La suite du message d'initialisation :
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/
k8s se sert d'un pod pour gérer son réseau. Il en existe plusieurs et celui que j'ai réussi à faire marcher du premier coup s'appelle Flannel.

Pour l'installer :
dada@k8smaster:~$ kubectl apply -f https://github.com/coreos/flannel/raw/master/Documentation/kube-flannel.yml
Et le retour qui confirme que tout va bien :
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.extensions/kube-flannel-ds-amd64 created
daemonset.extensions/kube-flannel-ds-arm64 created
daemonset.extensions/kube-flannel-ds-arm created
daemonset.extensions/kube-flannel-ds-ppc64le created
daemonset.extensions/kube-flannel-ds-s390x created
Il est temps de vous montrer une première commande k8s que vous allez passer votre vie à utiliser :
kubectl get pods --all-namespaces -o wide
Elle vous afficher le namespace, le nom, la quantité, le statut, l'âge, le node hôte, etc, des pods de votre cluster. Exemple :
dada@k8smaster:~$ kubectl get pods --all-namespaces -o wide
NAMESPACE     NAME                                READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE
kube-system   coredns-576cbf47c7-84x8w            1/1     Running   0          11m   10.244.0.8     k8smaster   <none>
kube-system   coredns-576cbf47c7-v88p4            1/1     Running   0          11m   10.244.0.9     k8smaster   <none>
kube-system   etcd-k8smaster                      1/1     Running   0          79s   192.168.0.19   k8smaster   <none>
kube-system   kube-apiserver-k8smaster            1/1     Running   0          79s   192.168.0.19   k8smaster   <none>
kube-system   kube-controller-manager-k8smaster   1/1     Running   0          79s   192.168.0.19   k8smaster   <none>
kube-system   kube-flannel-ds-amd64-vzrx8         1/1     Running   0          90s   192.168.0.19   k8smaster   <none>
kube-system   kube-proxy-nn7p2                    1/1     Running   0          11m   192.168.0.19   k8smaster   <none>
kube-system   kube-scheduler-k8smaster            1/1     Running   0          78s   192.168.0.19   k8smaster   <none>
Comme seul le master est actif, vous ne voyez pour le moment que les pods system (les trucs de base) de votre cluster sur le node master. Normal.

Ajouter un node dans le cluster

Votre cluster n'a qu'un master. Chiant. Est-on certain de n'avoir qu'un seul node dans ce cluster ?
dada@k8smaster:~$ kubectl get nodes
NAME        STATUS   ROLES    AGE   VERSION
k8smaster   Ready    master   23m   v1.12.2
Oui, la commande get nodes le confirme. Ajoutons un peu d'action dans tout ça en lisant la fin du message d'initialisation :
You can now join any number of machines by running the following on each node
as root:

  kubeadm join 192.168.0.19:6443 --token wdjnql.rm60fa90l0o9qv49 --discovery-token-ca-cert-hash sha256:ede807fb6f732c00acb8d40a891c436aedd3ed88f915135df252c033d55b2e10
Note : ne perdez pas la dernière ligne ! Il faudra reset votre cluster et ainsi tout perdre si vous ne la sauvegardez pas !

Allez lancer une autre VM, disons le k8snode1, et exécutez la commande de join. Si tout va bien, vous devriez avoir le message suivant :
root@k8snode1:/home/dada#   kubeadm join 192.168.0.19:6443 --token wdjnql.rm60fa90l0o9qv49 --discovery-token-ca-cert-hash sha256:ede807fb6f732c00acb8d40a891c436aedd3ed88f915135df252c033d55b2e10
[preflight] running pre-flight checks
[discovery] Trying to connect to API Server "192.168.0.19:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://192.168.0.19:6443"
[discovery] Requesting info from "https://192.168.0.19:6443" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "192.168.0.19:6443"
[discovery] Successfully established connection with API Server "192.168.0.19:6443"
[kubelet] Downloading configuration for the kubelet from the "kubelet-config-1.12" ConfigMap in the kube-system namespace
[kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[preflight] Activating the kubelet service
[tlsbootstrap] Waiting for the kubelet to perform the TLS Bootstrap...
[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "k8snode1" as an annotation

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the master to see this node join the cluster.
Retournez taper la commande get nodes sur le master :
dada@k8smaster:~$ kubectl get nodes
NAME        STATUS   ROLES    AGE     VERSION
k8smaster   Ready    master   26m     v1.12.2
k8snode1    Ready    <none>   3m20s   v1.12.2
Vous êtes deux !

Amusons-nous à voir ce qu'il vient de se passer au niveau des pods :
dada@k8smaster:~$ kubectl get pods --all-namespaces -o wide
NAMESPACE     NAME                                READY   STATUS    RESTARTS   AGE     IP             NODE        NOMINATED NODE
kube-system   coredns-576cbf47c7-84x8w            1/1     Running   0          29m     10.244.0.8     k8smaster   <none>
kube-system   coredns-576cbf47c7-v88p4            1/1     Running   0          29m     10.244.0.9     k8smaster   <none>
kube-system   etcd-k8smaster                      1/1     Running   0          19m     192.168.0.19   k8smaster   <none>
kube-system   kube-apiserver-k8smaster            1/1     Running   0          19m     192.168.0.19   k8smaster   <none>
kube-system   kube-controller-manager-k8smaster   1/1     Running   0          19m     192.168.0.19   k8smaster   <none>
kube-system   kube-flannel-ds-amd64-6qm8n         1/1     Running   0          6m57s   192.168.0.30   k8snode1    <none>
kube-system   kube-flannel-ds-amd64-vzrx8         1/1     Running   0          19m     192.168.0.19   k8smaster   <none>
kube-system   kube-proxy-nn7p2                    1/1     Running   0          29m     192.168.0.19   k8smaster   <none>
kube-system   kube-proxy-phfww                    1/1     Running   0          6m57s   192.168.0.30   k8snode1    <none>
kube-system   kube-scheduler-k8smaster            1/1     Running   0          19m     192.168.0.19   k8smaster   <none>
Des pods se sont installés sur le k8snode1 ! Vous n'êtes plus seul avec votre master. Vous avez un copain !

Motivé ? Vous pouvez ajouter le node k8snode2 précédemment préparé dans le cluster, histoire de ne pas l'avoir fait chauffer pour rien. Si vous avez bien réussi votre coup, get nodes devrait vous répondre ceci :
dada@k8smaster:~$ kubectl get nodes
NAME        STATUS     ROLES    AGE   VERSION
k8smaster   Ready      master   41m   v1.12.2
k8snode1    Ready      <none>   18m   v1.12.2
k8snode2    Ready   <none>   6s    v1.12.

Bien joué !

Ça ne marche pas comme prévu ?

Très rapide abécédaire des commandes que vous pouvez utiliser si ça coince :

- kubeadm reset -f : elle supprime toute la configuration du cluster du node sur laquelle elle est exécutée. Ça permet de repartir de zéro.

- kubectl delete node <nomdunode> : supprime le node passé en paramètre du cluster, en gardant sa configuration.

La suite ?

Affichez le dashboard de k8s, parce que de la couleur et une interface, c'est mieux.

Préparer Virtualbox pour Kubernetes

Rédigé par dada / 01 novembre 2018 / 2 commentaires

J'ai un peu l'impression d'arriver après la bataille, mais soit. Mieux vaut tard que jamais, comme disent les gens. Je me lance dans une série de billets autour de Kubernetes, l'orchestrateur qui fait parler de lui depuis bien longtemps.
Pour mettre les mains dedans, j'ai choisi de m'amuser avec Virtualbox. Je sais qu'il existe d'autres outils et que certains préféreront se servir de service cloud pour leurs pérégrinations. Perso, j'ai pas spécialement envie d'alourdir ma facture chez Hetzner, même s'ils le méritent. Et Virtualbox marche très bien.

Équipement de départ

  • Debian Testing sur mon ThinkPad x280
  • Virtualbox 5.2.20
  • Debian 9 pour les nodes
  • Docker CE 17.03.3
  • Une Freebox Révolution
Vocabulaire : un node, c'est une VM sur laquelle vous allez faire tourner des pods. Les pods sont des conteneurs Docker, qui tournent donc sur des nodes. Ok ?

Préparer Virtualbox

La première VM

Je vous laisse installer une première machine sous Debian 9. Sans fioritures. Une Debian stable avec SSH fait parfaitement l'affaire.
Au niveau des spécifications techniques, pas la peine d'aller trop loin : 1 core / 2GB de ram et 8 Go d'espace disque suffiront.

Configurer son réseau

Votre machine sous Virtualbox va avoir besoin de 2 choses :
- Un accès internet
- Une IP permettant d'être accessible en SSH par la machine hôte et par les autres nodes.

Un accès internet

Simple, la première carte réseau mise en place par VB est configurée en NAT. Vous n'aviez rien à faire.

Une IP SSH/Nodes

Le DHCP de la Freebox fourni des IP en 192.168.0.XX. Pour choper une de ces IP, il faut aller dans la configuration réseau de la VM et ajouter une deuxième carte réseau :


Il faut la configurer en accès par pont et lui passer en paramètre le nom du réseau de votre PC. Pour moi, c'est celui de la carte Wifi wlp59s0. Si vous avez une carte Ethernet, vous devriez pouvoir choisir eth0.

Installer les bases pour Kubernetes

Ici, on va installer une version de k8s non configurée. C'est important de l'installer nue puisque cette VM servira de base aux autres.

Installer Docker

# apt-get install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common
# curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | apt-key add -
# add-apt-repository "deb https://download.docker.com/linux/debian stretch stable"
# apt-get update
# apt-get install -y docker-ce

Activez docker au démarrage :

systemctl enable docker
Configurez docker pour qu'il ne s'amuse qu'avec Systemd en créant le fichier /etc/docker/daemon.json :
root@k8snode1:/home/dada# cat /etc/docker/daemon.json
{
    "exec-opts": ["native.cgroupdriver=systemd"]
}

Et enfin, désactivez le swap avec la commande :

swapoff -a

Et commentez la ligne du fstab réactivant ce truc à chaque reboot :

# swap was on /dev/sda5 during installation
#UUID=5d159270-eaee-41ed-864c-711f242e044d none            swap    sw              0       0

Installer Kubernetes

# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
# add-apt-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
# apt-get update
# apt-get install -y kubelet kubeadm kubectl

Préparer le cluster

Kubernetes, c'est un cluster. Pour fonctionner correctement et pour vraiment s'amuser, il nous faut :
  • Un master
  • Deux nodes ou plus

Les nodes

Les nodes vont être créés à partir de la première machine de ce tuto. Pour les ajouter à Virtualbox, je vais vous demander de la cloner 2 fois. Virtualbox fait ça très bien : clique droit / cloner. Allez-y, c'est tout simple. Réaliser l'opération 2 fois.

Voici ce que vous devriez avoir maintenant :


Bon, les miennes sont "en fonction" puisqu'elles tournent à l'heure où je rédige ce billet, mais les vôtres devraient être arrêtées.

Connectez-vous en SSH aux machines

Au démarrage, votre machine n'aura peut-être pas activée son réseau. Du moins, par forcément. Si la commande ip a vous retourne quelque chose comme ça :
3: enp0s9: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 08:00:27:e4:f7:f0 brd ff:ff:ff:ff:ff:ff
C'est que l'interface n'est pas activée. Pour l'activer :
dhclient enp0s9
Et vous devriez avoir ça maintenant :
3: enp0s9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:e4:f7:f0 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.31/24 brd 192.168.0.255 scope global enp0s9
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fee4:f7f0/64 scope link
       valid_lft forever preferred_lft forever
Remarquez la présence de la tant désirée IP : 192.168.0.31. Vous pouvez maintenant vous connecter à la machine avec un bon vieux :
ssh votreuser@192.168.0.31

Configurer les nodes

Rappel : étant des clones de la première machine virtuelle créée, ces nouvelles VM ont déjà docker et k8s d'installé.

Le hostname

Allez éditer le fichier /etc/hostname pour nommer vos machines. Exemple : k8snode1 et k8snode2. Vous allez éviter des warnings et des prises de tête en faisant ça.
dada@k8snode1:~$ cat /etc/hostname
k8snode1

Le hosts

Idem pour le fichier /etc/hosts : allez y ajouter, au bout de la ligne 127.0.0.1, le hostname de la machine.
dada@k8snode1:~$ cat /etc/hosts
127.0.0.1    localhost k8snode1
127.0.1.1    debian

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Le master

Pour le master, nous allons prendre la toute première machine que vous avez laissé nue. Si vous avez bien suivi et que je suis compréhensible : le node1 est le premier clone, le node2 est le second. Nous n'avons normalement pas encore touché à la machine d'origine. C'est ce que vous allez faire maintenant.

Configurez le hosts et le hostname de la même façon que pour les nodes, en prenant bien le temps de l'appeler k8smaster. Histoire de le différencier.

Tester tout ça

Maintenant que nous avons mis en place les machines, il va falloir vérifier qu'elles se comportent bien avant d'y lancer k8s.
  • Validez que vous pouvez bien vous connecter en SSH
  • Remplacez les IP qui traînent dans les exemples par les vôtres !
  • Pinguez les machines entre elles pour être bien certain d'éviter d'insulter k8s alors que le réseau est foireux
  • Rebootez les machines au moins une fois histoire de valider le réseau, le swap, le démarrage de docker et de kubernetes
Et c'est à partir de là qu'on va commencer à jouer !

La suite ?