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.
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
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
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.
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.
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.
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.
.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 ---
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.
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
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
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é !
11310