Comment je deploie sous Docker avec Kubernetes

Kubernetes (K8s) est une solution de déploiement et d’orchestration de conteneurs. C’est une solution open source développée par Google. Souvent utilisée avec Docker et prend largement en charge l’API Docker.

Cette solution est orientée Cluster (c’est-à-dire qu’elle gère un ensemble de serveurs Docker appelé des Nœuds).

Je ne vais pas reprendre tous les composants de K8s, mais je vais reprendre quelques bases, un rappel est toujours utile.

kubernetes-logo

Tu m’expliques ?

Je vais expliquer rapidement quelques composants de base sans entrer dans les détails, je vais essayer de le faire en parcours en profondeur. Je vais commencer par les couches les plus hautes, puis descendre jusqu’au cœur des applications, à savoir les conteneurs.

Vous pouvez tout fois aller plus loin et approfondir vos connaissances sur la page dédié à K8s sur wikipedia
Ou alors sur la documentation K8s

Les composants de K8s :

  1. ingress-nginx:
    Sur une infrastructure traditionnelle, ingress sera votre reverse proxy. Il permet de router vos sous-domaines/domaines vers des services spécifique.
    ce composant expose le port 80 et 443 sur l’IP publique

  2. les contrôleurs ingress:
    ingress-nginx utilise ce qu’on appelle des contrôleurs ingress, un contrôleur sert justement à router un ou plusieurs sous-domaines/domaines vers un ou plusieurs services.
    par défaut un contrôleur default existe et sert à router tout autres sous-domaine/domaine non configuré qui point sur l’IP publique.

  3. Les pods:
    Les pods sont des groupes de un ou plusieurs conteneurs identiques qui peuvent être regroupés sur un nœud, ou dispatché sur plusieurs.
    Les pods sont l’unité de base en K8s.
    Coté réseau, chaque pod possède une adresse IP interne au cluster.

  4. les services:
    Un service est un groupe de un ou plusieurs pods, c’est une sort de load-bancer (en round-robine). Il permet la résolution de noms interne au cluster. Il assigne une IP au nom du service.
    Il permet d’exposer un port sur un l’IP externe d’un nœud ou sur une IP interne au cluster.
    Il fait le lien entre un contrôleur nginx par exemple et les pods, ce lien entre service et pods se fait grâce à des sélecteurs (un label et sa valeur qui doit être la même sur les pods)
    Le service est une partie très importante de l’architecture de K8s.

  5. les configmap:
    C’est une abstraction du fichier .env sous Docker Compose. configmap est une structure qui permet de stocker des variables d’environnement passées aux conteneurs lors de leurs créations.
    Celle-ci n’est pas obligatoire mais permet centraliser les variables d’environnement et de gagner du temps lorsqu’on veut les faire passer sur plusieurs Pods.

Les fichier .yaml

Un fichier .yaml sont des états du cluster. Globalement lorsqu’on applique un fichier .yaml, Kubernetes reçoit un nouvel état sur lequel il va faire converger les pods, les services ... etc.

Un déploiement est un ou plusieurs fichiers .yaml
Vous pouvez très bien séparer vos fichiers en fonction du composant à déployer.
Par exemple on va imaginer un ensemble de fichiers : nextcloud-configmap.yaml, nextcloud-deploiment.yaml, nextcloud-service.yaml ... etc

Ou alors regrouper tous ces fichiers-là dans un seul et même fichier, qu’on va appeler nextcloud-deploy.yaml parce que … j’en ai envie, après tout c’est mon blog, et pour ce faire il suffit de séparer les différents composant avec trois tirets ---

Bon c’est bien beau tout ça, mais comment je fais ?

On va déployer nextcloud, (avec mariadb et memcahed) sur un cluster Kubernetes à deux nœuds que je vais appeler ps1 et ps2

Donc on a besoin de 3 fichiers, un pour memcached, un pour mariadb et le dernier pour nextcloud.
Les stockages persistants sont des points de montage dans /mnt/data

Pas de prise en charge du https ici. On va l'aborder ultérieurement.

Memcached

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: memcached-app
  name: memcached-deploy
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      labels:
        app: memcached-app
    spec:
      containers:
        - image: memcached:alpine
          name: memcached-worker
          resources: {}
      restartPolicy: Always
      nodeName: ps1
status: {}
---
kind: Service
apiVersion: v1
metadata:
  name: memcached
  labels:
    app: memcached-app
spec:
  selector:
    app: memcached-app
  ports:
    - name: memcached
      protocol: TCP
      port: 11211
      targetPort: 11211

Mariadb

apiVersion: v1
data:
  DB_0_NAME: nextcloud
  DB_0_PASS: password-for-nextcloud-db
  ROOT_PASSWORD: password-for-root
kind: ConfigMap
metadata:
  creationTimestamp: null
  labels:
    app: mariadb-app
  name: mariadb-config

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mariadb-deploy
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mariadb-app
    spec:
      containers:
        - envFrom:
            - configMapRef:
                name: mariadb-config
                optional: false
          image: samirkherraz/mariadb
          name: mariadb-worker
          resources: {}
          volumeMounts:
            - mountPath: /var/lib/mysql-backup/
              name: backup
            - mountPath: /var/lib/mysql/
              name: data
            - mountPath: /etc/mysql/
              name: config
            - mountPath: /etc/periodic/daily/
              name: periodics
      nodeName: ps2
      restartPolicy: Always
      volumes:
        - hostPath:
            path: /mnt/data/mariadb/backup/
            type: DirectoryOrCreate
          name: backup
        - hostPath:
            path: /mnt/data/mariadb/data/
            type: DirectoryOrCreate
          name: data
        - hostPath:
            path: /mnt/data/mariadb/config/
            type: DirectoryOrCreate
          name: config
        - hostPath:
            path: /mnt/data/mariadb/periodic
            type: DirectoryOrCreate
          name: periodics
status: {}
---
kind: Service
apiVersion: v1
metadata:
  name: mariadb
  labels:
    app: mariadb-app
spec:
  selector:
    app: mariadb-app
  ports:
    - name: mysql
      protocol: TCP
      port: 3306
      targetPort: 3306

Nextcloud

apiVersion: v1
data:
  ADMIN_PASSWORD: password-for-nextcloud-admin
  ADMIN_USERNAME: admin
  DATABASE_HOST: mariadb
  DATABASE_NAME: nextcloud
  DATABASE_PASSWORD: password-for-nextcloud-db
  DATABASE_USERNAME: nextcloud
  TRUSTED_DOMAIN_0: box.exemple.org
kind: ConfigMap
metadata:
  labels:
    app: nextcloud-app
  name: nextcloud-config
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: nextcloud-app
  name: nextcloud-deploy
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nextcloud-app
    spec:
      containers:
        - envFrom:
            - configMapRef:
                name: nextcloud-config
                optional: false
          image: samirkherraz/nextcloud
          name: nextcloud-worker
          resources: {}
          volumeMounts:
            - mountPath: /var/www/nextcloud/
              name: config
            - mountPath: /var/www/nextcloud/data/
              name: data
      nodeName: ps1
      restartPolicy: Always
      volumes:
        - hostPath:
            path: /mnt/data/nextcloud/config/
            type: ""
          name: config
        - hostPath:
            path: /mnt/data/nextcloud/data/
            type: ""
          name: data
status: {}
---
kind: Service
apiVersion: v1
metadata:
  name: nextcloud
  labels:
    app: nextcloud-app
spec:
  selector:
    app: nextcloud-app
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nextcloud-ingress
  labels:
    app: nextcloud-app
spec:
  rules:
    - host: box.exemple.org
      http:
        paths:
          - path: /
            backend:
              serviceName: nextcloud
              servicePort: http

un petit kubectl apply -f nom_du_fichier.yaml pour chaque fichier dans votre ligne de commandes et le tour est joué !

10960

5.0(23 votes)

Article précédentArticle suivant