Ce TP va consister à créer des objets Kubernetes pour déployer une stack d’exemple : monster_stack
.
Elle est composée :
Vous pouvez utiliser au choix votre environnement Cloud ou Minikube.
Lens est une interface graphique sympathique pour Kubernetes.
Elle se connecte en utilisant la configuration ~/.kube/config
par défaut et nous permettra d’accéder à un dashboard bien plus agréable à utiliser.
Vous pouvez l’installer en lançant ces commandes :
sudo apt-get update; sudo apt-get install -y libxss-dev
curl -fSL https://github.com/lensapp/lens/releases/download/v4.0.6/Lens-4.0.6.AppImage -o ~/Lens.AppImage
chmod +x ~/Lens.AppImage
~/Lens.AppImage &
monsterstack
Les pods sont des ensembles de conteneurs toujours gardés ensembles.
Nous voudrions déployer notre stack monster_app
. Nous allons commencer par créer un pod avec seulement notre conteneur monstericon
.
Créez un projet vide monster_app_k8s
.
Créez le fichier de déploiement suivant:
monstericon.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: monstericon
labels:
<labels>
Ce fichier exprime un objet déploiement vide.
Ajoutez le label app: monsterstack
à cet objet Deployment
.
Pour le moment notre déploiement n’est pas défini car il n’a pas de section spec:
.
La première étape consiste à proposer un modèle de ReplicaSet
pour notre déploiement. Ajoutez à la suite (spec:
doit être à la même hauteur que kind:
et metadata:
) :
spec:
template:
spec:
Remplissons la section spec
de notre pod monstericon
à partir d’un modèle de pod lançant un conteneur Nginx :
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
monstericon
, et l’image de conteneur par tecpi/monster_icon:0.1
, cela récupérera l’image préalablement uploadée sur le Docker Hub (à la version 0.1)Complétez le port en mettant le port de production de notre application, 9090
Les objets dans Kubernetes sont hautement dynamiques. Pour les associer et les désigner on leur associe des labels
c’est-à-dire des étiquettes avec lesquelles on peut les retrouver ou les matcher précisément. C’est grâce à des labels que k8s associe les pods
aux ReplicaSets
. Ajoutez à la suite au même niveau que la spec du pod :
metadata:
labels:
app: monsterstack
partie: monstericon
A ce stade nous avons décrit les pods de notre déploiement avec leurs labels (un label commun à tous les objets de l’app, un label plus spécifique à la sous-partie de l’app).
Maintenant il s’agit de rajouter quelques options pour paramétrer notre déploiement (à la hauteur de template:
) :
selector:
matchLabels:
app: monsterstack
partie: monstericon
strategy:
type: Recreate
Cette section indique les labels à utiliser pour repérer les pods de ce déploiement parmi les autres.
Puis est précisée la stratégie de mise à jour (rollout) des pods pour le déploiement : Recreate
désigne la stratégie la plus brutale de suppression complète des pods puis de redéploiement.
Enfin, juste avant la ligne selector:
et à la hauteur du mot-clé strategy:
, ajouter replicas: 3
. Kubernetes crééra 3 pods identiques lors du déploiement monstericon
.
Le fichier monstericon.yaml
jusqu’à présent :
apiVersion: apps/v1
kind: Deployment
metadata:
name: monstericon
labels:
app: monsterstack
spec:
template:
spec:
containers:
- name: monstericon
image: tecpi/monster_icon:0.1
ports:
- containerPort: 9090
metadata:
labels:
app: monsterstack
partie: monstericon
selector:
matchLabels:
app: monsterstack
partie: monstericon
strategy:
type: Recreate
replicas: 3
apply -f
appliquez notre fichier de déploiement.kubectl get deploy -o wide
.kubectl get pods --watch
pour vérifier que les conteneurs tournent.readinessProbe
au conteneur dans le pod avec la syntaxe suivante (le mot-clé readinessProbe
doit être à la hauteur du i
de image:
) : readinessProbe:
failureThreshold: 5 # Reessayer 5 fois
httpGet:
path: /
port: 9090
scheme: HTTP
initialDelaySeconds: 30 # Attendre 30s avant de tester
periodSeconds: 10 # Attendre 10s entre chaque essai
timeoutSeconds: 5 # Attendre 5s la reponse
Ainsi, k8s sera capable de savoir si le conteneur fonctionne bien en appelant la route /
. C’est une bonne pratique pour que Kubernetes sache quand redémarrer un pod.
image:
: resources:
requests:
cpu: "100m"
memory: "50Mi"
Nos pods auront alors la garantie de disposer d’un dixième de CPU et de 50 mégaoctets de RAM.
kubectl apply -f monstericon.yaml
pour appliquer.kubectl get pods --watch
, observons en direct la stratégie de déploiement type: Recreate
kubectl describe deployment monstericon
, lisons les résultats de notre readinessProbe
, ainsi que comment s’est passée la stratégie de déploiement type: Recreate
monstericon.yaml
final :
apiVersion: apps/v1
kind: Deployment
metadata:
name: monstericon
labels:
app: monsterstack
spec:
template:
spec:
containers:
- name: monstericon
image: tecpi/monster_icon:0.1
ports:
- containerPort: 9090
readinessProbe:
failureThreshold: 5 # Reessayer 5 fois
httpGet:
path: /
port: 9090
scheme: HTTP
initialDelaySeconds: 30 # Attendre 30s avant de tester
periodSeconds: 10 # Attendre 10s entre chaque essai
timeoutSeconds: 5 # Attendre 5s la reponse
resources:
requests:
cpu: "100m"
memory: "50Mi"
metadata:
labels:
app: monsterstack
partie: monstericon
selector:
matchLabels:
app: monsterstack
partie: monstericon
strategy:
type: Recreate
replicas: 5
Maintenant nous allons également créer un déploiement pour dnmonster
:
dnmonster.yaml
et collez-y le code suivant :dnmonster.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: dnmonster
labels:
app: monsterstack
spec:
selector:
matchLabels:
app: monsterstack
partie: dnmonster
strategy:
type: Recreate
replicas: 5
template:
metadata:
labels:
app: monsterstack
partie: dnmonster
spec:
containers:
- image: amouat/dnmonster:1.0
name: dnmonster
ports:
- containerPort: 8080
Enfin, configurons un troisième deployment redis
:
redis.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
labels:
app: monsterstack
spec:
selector:
matchLabels:
app: monsterstack
partie: redis
strategy:
type: Recreate
replicas: 1
template:
metadata:
labels:
app: monsterstack
partie: redis
spec:
containers:
- image: redis:latest
name: redis
ports:
- containerPort: 6379
Les services K8s sont des endpoints réseaux qui balancent le trafic automatiquement vers un ensemble de pods désignés par certains labels.
Pour créer un objet Service
, utilisons le code suivant, à compléter :
apiVersion: v1
kind: Service
metadata:
name: <nom_service>
labels:
app: monsterstack
spec:
ports:
- port: <port>
selector:
app: <app_selector>
partie: <tier_selector>
type: <type>
---
Ajoutez le code suivant au début de chaque fichier déploiement. Complétez pour chaque partie de notre application :
- le nom du service et le nom de la partie
par le nom de notre programme (monstericon
, dnmonster
et redis
)
- le port par le port du service
- les selectors app
et partie
par ceux du ReplicaSet correspondant.
Le type sera : ClusterIP
pour dnmonster
et redis
, car ce sont des services qui n’ont à être accédés qu’en interne, et LoadBalancer
pour monstericon
.
Appliquez vos trois fichiers.
kubectl get services
.minikube service <nom-du-service-monstericon>
.Une kustomization permet de résumer un objet contenu dans de multiples fichiers en un seul lieu pour pouvoir le lancer facilement:
Créez un dossier monster_stack
pour ranger les trois fichiers:
Créez également un fichier kustomization.yaml
avec à l’intérieur:
resources:
- monstericon.yaml
- dnmonster.yaml
- redis.yaml
kubectl apply -k .
depuis le dossier monster_stack
.Installons le contrôleur Ingress Nginx avec minikube addons enable ingress
.
Il s’agit d’une implémentation de loadbalancer dynamique basée sur nginx configurée pour s’interfacer avec un cluster k8s.
Ajoutez également l’objet de configuration du loadbalancer suivant dans le fichier monster-ingress.yaml
:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: monster-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /monstericon
backend:
serviceName: monstericon
servicePort: 9090
Ajoutez ce fichier à notre kustomization.yaml
Relancez la kustomization.
Vous pouvez normalement accéder à l’application en faisant minikube service monstericon --url
et en ajoutant /monstericon
pour y accéder.
Le dépôt Git des solutions est accessible ici : https://github.com/Uptime-Formation/tp2_k8s_monsterstack_correction