Blog de dada

DevOps, bidouilleur et routard plein de logiciels libres

Archives novembre 2018

Welcome to Nginx, puis Wordpress

Rédigé par dada / 09 novembre 2018 / Aucun commentaire

Perdu ?

On y arrive. Après des heures d'attente, de commandes bizarres, de pods dans tous les sens, je vais enfin vous montrer comment mettre en place un Wordpress, sa base de données et y accéder depuis le navigateur !

Wordpress

Il existe une configuration simple pour avoir un Wordpress fonctionnel : ne nous privons pas !

La partie MySQL

Son fichier de configuration :
apiVersion: v1
kind: Service
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  ports:
    - port: 3306
  selector:
    app: wordpress
    tier: mysql
  clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim2
  labels:
    app: wordpress
spec:
  storageClassName: rook-ceph-block
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 500Mi
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: mysql
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: changeme
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pv-claim2
Vous y trouverez les volumes persistant pour Rook, le point de montage, la configuration du port MySQL, le mot de passe, etc. Vous avez le temps de lire tout ça.

On lance la création du conteneur :
dada@k8smaster:~$ kubectl create -f mysql.yaml
Et le résultat :
default            wordpress-mysql-75477bf794-89mzw                          1/1     Running     1          5h38m   10.244.2.50    k8snode2    <none>

On peut enchaîner avec la suite. C'est vrai qu'une BDD de Wordpress sans le CMS pour l'utiliser, c'est moyen.

La partie PHP

Notez que je parle de la partie "PHP", mais il n'y a pas que PHP. Il me fallait un titre, alors voilà.

Cette partie, je l'ai modifié par rapport à ce que vous trouverez dans les documentations officielles.
apiVersion: v1
kind: Service
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  ports:
  - port: 80
  selector:
    app: wordpress
    tier: frontend
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-pv-claim
  labels:
    app: wordpress
spec:
  storageClassName: rook-ceph-block
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 500Mi
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
      - image: wordpress:4.6.1-apache
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: wordpress-mysql
        - name: WORDPRESS_DB_PASSWORD
          value: changeme
        ports:
        - containerPort: 80
          name: wordpress
        volumeMounts:
        - name: wordpress-persistent-storage
          mountPath: /var/www/html
      volumes:
      - name: wordpress-persistent-storage
        persistentVolumeClaim:
          claimName: wp-pv-claim
Vous pouvez lancer tout ça :
 kubectl create -f wordpress.yaml
Le pod wordpress devrait apparaître:
default            wordpress-796698694f-sxbhb                                1/1     Running     1          3h35m   10.244.2.51    k8snode2    <none>

Ce qu'il faut saisir

La présence des services de Wordpress :
dada@k8smaster:~/$ kubectl get services 
NAME                                     TYPE           CLUSTER-IP       EXTERNAL-IP    PORT(S)                      AGE
kubernetes                               ClusterIP      10.96.0.1        <none>         443/TCP                      4d8h
my-nginx-nginx-ingress-controller        LoadBalancer   10.100.45.147    192.168.0.50   80:32462/TCP,443:30337/TCP   3d5h
my-nginx-nginx-ingress-default-backend   ClusterIP      10.109.228.138   <none>         80/TCP                       3d5h
wordpress                                ClusterIP      10.102.55.203    <none>         80/TCP                       6m3s
wordpress-mysql                          ClusterIP      None             <none>         3306/TCP                     6h33m
La configuration du service wordpress-mysql, on ne va pas s'y attarder. Ça marche tout seul.
Le truc chouette, c'est la configuration du service wordpress.
dada@k8smaster:~/$ kubectl describe service wordpress
Name:              wordpress
Namespace:         default
Labels:            app=wordpress
Annotations:       <none>
Selector:          app=wordpress,tier=frontend
Type:              ClusterIP
IP:                10.102.55.203
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.2.61:80
Session Affinity:  None
Events:            <none>
On y retrouve les informations qu'il nous faut et surtout, surtout, le Endpoint ! C'est là qu'on peut savoir où vont se retrouver les requêtes ! Ici, on lit 10.244.2.61:80 : il s'agit de l'IP du pod qui fait tourner Wordpress et le port sur lequel l'attaquer.

On va pouvoir s'attaquer à la dernière configuration : le service Ingress

Le service Ingress

Ici, on va expliquer au videur du cluster qu'il peut laisser passer les requêtes vers Wordpress.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
  name: nginx-ingress
spec:
 backend:
   serviceName: wordpress
   servicePort: 80
Créez tout ça :
kubectl create -f ingress.yaml
Une fois créé, vérifiez qu'il est bien là :
dada@k8smaster:~/$ kubectl get ingresses
NAME            HOSTS   ADDRESS   PORTS   AGE
nginx-ingress   *                 80      6s
Et vérifiez sa configuration :
dada@k8smaster:~/$ kubectl describe ingress nginx-ingress
Name:             nginx-ingress
Namespace:        default
Address:         
Default backend:  wordpress:80 (10.244.2.61:80)
Rules:
  Host  Path  Backends
  ----  ----  --------
  *     *     wordpress:80 (10.244.2.61:80)
Annotations:
  kubernetes.io/ingress.class:  nginx
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  65s   nginx-ingress-controller  Ingress default/nginx-ingress
Normal  UPDATE  30s   nginx-ingress-controller  Ingress default/nginx-ingress

Dans les Rules, remarquez que le backend est bien présent. Ici, le backend est le service wordpress que nous avons mis en place un peu plus tôt. Tout va bien !

Maintenant ? Souvenez-vous de l'IP externe que vous avez réussi à récupérer dans mon précédent billet et allez voir !



Il existe des moyens bien plus simples pour arriver à ce résultat. Passer par un Ingress Controller n'est pas la plus rapide mais elle permet de mettre le nez dans cet outil qui, plus tard, vous permettra de rediriger le flux en fonction du host. Bref. C'est un choix qui invite à aller plus loin !

La suite ?

À voir...

Accéder au cluster k8s depuis l'extérieur

Rédigé par dada / 09 novembre 2018 / Aucun commentaire



Perdu ?

On vient de se battre pour mettre en place un cluster Ceph opérationnel, histoire de stocker ses données dans le cluster k8s et de les répliquer un peu. Maintenant que c'est bon, si on s'attaquait à des choses un peu plus visible, hors dashboard ?
Au programme de ce billet : Ingress, Service, Wordpress, des nouveaux pods.

Ingress Nginx

Cette chose-là va être le point d'entrée de notre cluster. Il va permettre à l'extérieur d'aller regarder à l'intérieur. Son rôle va être de comprendre la requête d'entrée et de l'orienter vers le pod qui y répondra. Dans le cas qui va suivre, aller sur l'IP du cluster pour y retrouver un Wordpress.

Installation via Helm

Comme on s'en sert déjà, on va continuer :
helm install stable/nginx-ingress --name my-nginx
Cette installation va faire apparaître les pods suivants :
dada@k8smaster:~$ kubectget pods -n default
NAME                                                      READY   STATUS    RESTARTS   AGE
my-nginx-nginx-ingress-controller-565bc9555b-pcqjz        1/1     Running   2          8h
my-nginx-nginx-ingress-default-backend-5bcb65f5f4-728tx   1/1     Running   2          8h
Et un service. On n'a pas encore parlé de services : je vous redirige vers la documentation officielle si vous voulez en savoir bien plus.
dada@k8smaster:~$ kubectl --namespace default get services -o wide -w my-nginx-nginx-ingress-controller
NAME                                TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE   SELECTOR
my-nginx-nginx-ingress-controller   LoadBalancer   10.100.45.147   <pending>     80:32462/TCP,443:30337/TCP   8s    app=nginx-ingress,component=controller,release=my-nginx
Ça veut dire que l'Ingress Controller est bien installé. Notez le <pending> : ça veut dire que notre controller n'a pas d'IP externe. En gros : il ne sert à rien. Il lui faut une IP pour que nous puissions l'attaquer.
Dans une installation chez des gros fournisseurs d'informatique dans les nuages, nous aurions une sorte de plugin nous fournissant déjà l'IP tant désirée. Avec notre infrastructure sous Virtualbox, il va falloir faire autrement. Et autrement, ça veut dire avec MetalLB.

MetalLB

MetalLB, ce sont des pods que nous allons installer dans notre cluster et qui nous serviront à palier le problème cité juste au dessus. Il ira interroger notre DHCP, la Freebox dans mon cas, pour récupérer une IP publique.

Installer MetalLB

Toujours avec Helm :
helm install --name metallb stable/metallb
Un peu d'attente et vous devriez voir de nouveaux pods :
dada@k8smaster:~$ kubectl get pods -n metallb-system
NAME                         READY   STATUS    RESTARTS   AGE
controller-765899887-ck6bv   1/1     Running   2          8h
speaker-jdqg9                1/1     Running   2          8h
speaker-t4vtk                1/1     Running   2          8h
Il lui manque un fichier de configuration pour nous offrir une adresse IP externe :
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: default
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.0.50-192.168.0.60
Les adresses IP en bas de ce fichier de conf vont permettre à MetalLB d'aller titiller notre DHCP (Freebox pour moi) pour obtenir une adresse. Quelque chose entre 192.168.0.50 et 192.168.0.60 dans mon cas. Vérifiez bien la configuration de votre Freebox avant de choisir une plage d'IP.

On l'applique :
kubectl create -f config.yaml 

Retour à l'Ingress Nginx

Une fois après avoir configuré MetalLB, vous allez vérifier l'état du service :
dada@k8smaster:~/$ kubectl --namespace default get services -o wide -w my-nginx-nginx-ingress-controller
NAME                                TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)                      AGE    SELECTOR
my-nginx-nginx-ingress-controller   LoadBalancer   10.100.45.147   192.168.0.50   80:32462/TCP,443:30337/TCP   3d3h   app=nginx-ingress,component=controller,release=my-nginx
Vous avez vu ? Une EXTERNAL-IP ! On va pouvoir taper dessus !

La suite ?


Rook pour gérer le système de fichiers

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


Un cluster k8s, c'est presque "out-of-the-box" quand on veut s'en servir pour lancer des conteneurs qui n'amènent avec eux qu'un traitement. En gros, votre conteneur contient un script python qui va afficher 42 fois le message "toto" et mourir. C'est un exemple idiot, mais ce n'est pas un détail.
Dans le cadre de ce tuto qui me sert à préparer la migration de ce blog dans un cluster k8s, j'ai besoin de pouvoir stocker le contenu de mes billets quelque part. Le mettre dans un conteneur est une aberration et sera synonyme de perte de données quand celui-ci mourra.

Pour m'en sortir, on m'a parlé de Rook.io, un système de cluster Ceph intégré à Kubernetes. On va voir comment s'en servir maintenant.

Installer Rook

Installer les dépendances

Il va falloir installer des paquets sur vos membres du cluster. À l'exception du Master.
apt-get install ceph-fs-common ceph-common

Récupérer le binaire RBD

cd /bin  
sudo curl -O https://raw.githubusercontent.com/ceph/ceph-docker/master/examples/kubernetes-coreos/rbd 
sudo chmod +x /bin/rbd 
rbd #Command to download ceph images
On va partir sur la version beta de l'outil. C'est la plus stable.

Ajouter le dépôt Rook dans Helm

dada@k8smaster:~$ helm repo add rook-beta https://charts.rook.io/beta
"rook-beta" has been added to your repositories

Récupérer Rook

À la manière de APT :
dada@k8smaster:~$ helm install --namespace rook-ceph-system rook-beta/rook-ceph
NAME:   torrid-dragonfly
LAST DEPLOYED: Sun Nov  4 11:22:24 2018
NAMESPACE: rook-ceph-system
STATUS: DEPLOYED
Le message est bien plus long. Je vous invite à prendre le temps de le décortiquer pour y repérer les infos intéressantes.

On peut y récupérer la commande pour valider la présence du pod Operator :
dada@k8smaster:~$ kubectl --namespace rook-ceph-system get pods -l "app=rook-ceph-operator"
NAME                                 READY   STATUS    RESTARTS   AGE
rook-ceph-operator-f4cd7f8d5-zt7f4   1/1     Running   0          2m25
On y trouve aussi les pods nécessaires au cluster dans nos différents nodes :
dada@k8smaster:~$ kubectl get pods --all-namespaces -o wide | grep rook
rook-ceph-system   rook-ceph-agent-pb62s                   1/1     Running   0          4m10s   192.168.0.30   k8snode1    <none
rook-ceph-system   rook-ceph-agent-vccpt                   1/1     Running   0          4m10s   192.168.0.18   k8snode2    <none>
rook-ceph-system   rook-ceph-operator-f4cd7f8d5-zt7f4      1/1     Running   0          4m24s   10.244.2.62    k8snode2    <none>
rook-ceph-system   rook-discover-589mf                     1/1     Running   0          4m10s   10.244.2.63    k8snode2    <none>
rook-ceph-system   rook-discover-qhv9q                     1/1     Running   0          4m10s   10.244.1.232   k8snode1    <none>
On a la base ! Vous devriez avoir un agent et un discover par node. L'operator, lui, reste tout seul.

Création du cluster

Maintenant que Rook tourne, il lui faut lui faire comprendre que nous voulons un cluster qui va bien pour nos volumes.

Je reprends ci-dessous l'exemple de la documentation : ça marche bien comme ça.
#################################################################################
# This example first defines some necessary namespace and RBAC security objects.
# The actual Ceph Cluster CRD example can be found at the bottom of this example.
#################################################################################
apiVersion: v1
kind: Namespace
metadata:
  name: rook-ceph
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: rook-ceph-cluster
  namespace: rook-ceph
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: rook-ceph-cluster
  namespace: rook-ceph
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: [ "get", "list", "watch", "create", "update", "delete" ]
---
# Allow the operator to create resources in this cluster's namespace
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: rook-ceph-cluster-mgmt
  namespace: rook-ceph
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: rook-ceph-cluster-mgmt
subjects:
- kind: ServiceAccount
  name: rook-ceph-system
  namespace: rook-ceph-system
---
# Allow the pods in this namespace to work with configmaps
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: rook-ceph-cluster
  namespace: rook-ceph
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: rook-ceph-cluster
subjects:
- kind: ServiceAccount
  name: rook-ceph-cluster
  namespace: rook-ceph
---
#################################################################################
# The Ceph Cluster CRD example
#################################################################################
apiVersion: ceph.rook.io/v1beta1
kind: Cluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
spec:
  cephVersion:
    # For the latest ceph images, see https://hub.docker.com/r/ceph/ceph/tags
    image: ceph/ceph:v13.2.2-20181023
  dataDirHostPath: /var/lib/rook
  dashboard:
    enabled: true
  storage:
    useAllNodes: true
    useAllDevices: false
    config:
      databaseSizeMB: "1024"
      journalSizeMB: "1024"
On apply tout ça :
kubectl create -f cluster.yaml
Si tout s'est bien passé et que vous avez patienté quelques minutes, voici ce que vous devriez avoir maintenant :
dada@k8smaster:~/rook$ kubectl get pods -n rook-ceph -o wide 
NAME                                   READY   STATUS      RESTARTS   AGE     IP             NODE       NOMINATED NODE
rook-ceph-mgr-a-5f6dd98574-tm9md       1/1     Running     0          3m3s    10.244.2.126   k8snode2   <none>
rook-ceph-mon0-sk798                   1/1     Running     0          4m36s   10.244.1.42    k8snode1   <none>
rook-ceph-mon1-bxgjt                   1/1     Running     0          4m16s   10.244.2.125   k8snode2   <none>
rook-ceph-mon2-snznb                   1/1     Running     0          3m48s   10.244.1.43    k8snode1   <none>
rook-ceph-osd-id-0-54c856d49d-77hfr    1/1     Running     0          2m27s   10.244.1.45    k8snode1   <none>
rook-ceph-osd-id-1-7d98bf85b5-rt4jw    1/1     Running     0          2m26s   10.244.2.128   k8snode2   <none>
rook-ceph-osd-prepare-k8snode1-dzd5v   0/1     Completed   0          2m41s   10.244.1.44    k8snode1   <none>
rook-ceph-osd-prepare-k8snode2-2jgvg   0/1     Completed   0          2m41s   10.244.2.127   k8snode2   <none>

Créer le système de fichiers

Le cluster est en place, mais rien ne nous permet de l'utiliser. On va remédier à ça en lui assignant un système de fichiers. Pour l'exemple, j'ai choisi la méthode dite Block Storage. Elle permet de mettre en place des Persistent Volumes (PV) qui pourront être utilisés par un seul pod à la fois. S'il vous faut plusieurs pods accédant à un PV, dirigez-vous vers le Shared File System.

Pour que ça marche, créez la configuration de la StorageClass :
apiVersion: ceph.rook.io/v1beta1
kind: Pool
metadata:
  name: replicapool
  namespace: rook-ceph
spec:
  replicated:
    size: 3
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: rook-ceph-block
provisioner: ceph.rook.io/bloc
parameters:
  pool: replicapool
  clusterNamespace: rook-ceph
On l'applique :
kubectl create -f storageclass.yaml
On est bon pour le système de fichiers !
On ne va pas créer de pod s'en servant pour le moment. Si vous y allez, vous ne pourrez rien en tirer puisque vous ne pouvez pas encore accéder à votre cluster depuis l'extérieur. C'est la prochaine étape.

Le Dashboard Ceph

Si vous avez pris le temps de lire la configuration du cluster proposée un peu plus haut, vous devriez avoir vu que le Dashboard est activé dans le yaml. Comme pour Kubernetes, Rook intègre un dashboard pour y voir un peu plus clair.

Il est "enable", mais pas activé. Corrigeons ça à l'aide en créant le fichier dashboard-external.yaml :
dada@k8smaster:~/rook$ cat dashboard-external.yaml 
apiVersion: v1
kind: Service
metadata:
  name: rook-ceph-mgr-dashboard-external
  namespace: rook-ceph
  labels:
    app: rook-ceph-mgr
    rook_cluster: rook-ceph
spec:
  ports:
  - name: dashboard
    port: 7000
    protocol: TCP
    targetPort: 7000
  selector:
    app: rook-ceph-mgr
    rook_cluster: rook-ceph
  sessionAffinity: None
  type: NodePort
Récupérez le port exposé :
dada@k8smaster:~/rook$ kubectl -n rook-ceph get service | grep Node
rook-ceph-mgr-dashboard-external   NodePort    10.99.88.135     <none>        7000:31165/TCP   3m41s
Et vous devriez pouvoir joindre le dashboard en utilisant l'IP du master et le port qui va bien : 31165 dans mon cas.

Si tout va bien, vous devriez pouvoir vous promener dans une page web qui ressemble à ça :

Considérations

La gestion du système de fichiers que je vous propose n'est pas sans risque. Les volumes que vous allez créer doivent être configurés sérieusement. Les exemples que vous aller trouver par-ci par-là vous permettront d'avoir un stockage dans votre cluster k8s, certes, mais rendront sans doute vos volumes dépendants de vos pods. Si vous décidez de supprimer le pod pour lequel vous avec un PVC, le PV disparaîtra, et vos données avec.

Prenez le temps de bien réfléchir et de bien plus étudier la question que ce que je vous propose dans mes billets avant de vous lancer dans une installation en production.

La suite ?


Se faciliter la vie avec Helm

Rédigé par dada / 06 novembre 2018 / Aucun commentaire

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

Helm ? Rien à voir avec le Gouffre du même nom. Il s'agit ici de passer par un outil permettant à l'utilisateur de k8s d'installer des pods en passant par son dépôt officiel. C'est une sorte de gestionnaire de paquet, un peu comme APT pour Debian. Ça nous facilite la vie et ça nous permet d'utiliser toute la puissance de l'orchestrateur sans se prendre la tête.

Installer Helm

Récupérer les binaires

Helm a besoin de son exécutable pour fonctionner. Allez le récupérer et déposez-le sur votre master :
dada@k8smaster:~$ mkdir helm
dada@k8smaster:~$ cd helm
dada@k8smaster:~/helm$ wget https://storage.googleapis.com/kubernetes-helm/helm-v2.11.0-linux-amd64.tar.gz
dada@k8smaster:~/helm$ tar -zxvf helm-v2.11.0-linux-amd64.tar.gz
Rendez-le utilisable
root@k8smaster:/home/dada/helm# mv linux-amd64/helm  /usr/local/bin/
Vous devriez maintenant pouvoir vous en servir avec votre utilisateur normal (pas root !)
helm version
Client: &version.Version{SemVer:"v2.11.0", GitCommit:"2e55dbe1fdb5fdb96b75ff144a339489417b146b", GitTreeState:"clean"}

Initialiser Helm

Tout simplement avec la commande helm init :
dada@k8smaster:~$ helm init
$HELM_HOME has been configured at /home/dada/.helm.

Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.

Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
To prevent this, run `helm init` with the --tiller-tls-verify flag.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
Happy Helming!
Happy Helming, comme ils disent !

Si vous avez bien tapé la commande "helm version" donnée quelques lignes plus haut, vous devriez avoir remarqué l'erreur suivante :
Error: could not find tiller
Cachée volontairement jusque là, elle attendait l'initialisation pour disparaître !
dada@k8smaster:~$ helm version
Client: &version.Version{SemVer:"v2.11.0", GitCommit:"2e55dbe1fdb5fdb96b75ff144a339489417b146b", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.11.0", GitCommit:"2e55dbe1fdb5fdb96b75ff144a339489417b146b", GitTreeState:"clean"}
Un nouveau pod est maintenant apparu : tiller !
dada@k8smaster:~$ kubectl get pods --all-namespaces -o wide | grep tiller
kube-system   tiller-deploy-845cffcd48-268tr          1/1     Running   0          4m22s   10.244.2.61    k8snode2    <none>

Configurer les permissions

Je vais rappeler que nous sommes dans le cadre d'un cluster de test. C'est un détail important parce que je ne vais pas m'étendre avec les jeux de permission de Kubernetes. Pour aller plus vite, et pour permettre à Helm d'accéder à l'API à travers laquelle tout transite, je vais vous donner les commandes pour lui donner des droits d'admin. Ce n'est pas à faire en production !

Donner les droits admin à Helm

dada@k8smaster:~$ kubectl create serviceaccount --namespace kube-system tiller
dada@k8smaster:~$ kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
dada@k8smaster:~$ kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'

Mettre à jour la configuration

dada@k8smaster:~$ helm init --service-account tiller --upgrade
$HELM_HOME has been configured at /home/dada/.helm.

Tiller (the Helm server-side component) has been upgraded to the current version.
Happy Helming
Helm devrait maintenant pouvoir s'amuser !

La suite ?

Installer Rook pour prendre en charge nos volumes persistants.

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 ?