Exécutez une application stateful mono-instance
Cette page montre comment exécuter une application mono-instance, avec gestion d'état (stateful) dans Kubernetes en utilisant un PersistentVolume et un Deployment. L'application utilisée est MySQL.
Objectifs
- Créer un PersistentVolume en référençant un disque dans votre environnement.
- Créer un déploiement MySQL.
- Exposer MySQL à d'autres pods dans le cluster sous un nom DNS connu.
Pré-requis
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster. Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant Minikube, ou vous pouvez utiliser l'un de ces environnements Kubernetes:
Pour consulter la version, entrezkubectl version
.Vous devez disposer soit d'un fournisseur PersistentVolume dynamique avec une valeur par défaut StorageClass, soit préparer un PersistentVolumes statique pour satisfaire les PersistentVolumeClaims utilisés ici.
Déployer MySQL
Vous pouvez exécuter une application stateful en créant un Deployment Kubernetes et en le connectant à un PersistentVolume existant à l'aide d'un PersistentVolumeClaim. Par exemple, ce fichier YAML décrit un Deployment qui exécute MySQL et référence le PersistentVolumeClaim. Le fichier définit un point de montage pour /var/lib/mysql, puis crée un PersistentVolumeClaim qui réclame un volume de 20G. Cette demande est satisfaite par n'importe quel volume existant qui répond aux exigences, ou par un provisionneur dynamique.
Remarque: le mot de passe MySQL est défini dans le fichier de configuration YAML, ce qui n'est pas sécurisé. Voir les secrets Kubernetes pour une approche sécurisée.
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
clusterIP: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
# Use secret in real usage
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
Déployez le PV et le PVC du fichier YAML:
kubectl apply -f https://k8s.io/examples/application/mysql/mysql-pv.yaml
Déployez les resources du fichier YAML:
kubectl apply -f https://k8s.io/examples/application/mysql/mysql-deployment.yaml
Affichez les informations liées au Deployment:
kubectl describe deployment mysql
Le résultat sera similaire à ceci:
Name: mysql Namespace: default CreationTimestamp: Tue, 01 Nov 2016 11:18:45 -0700 Labels: app=mysql Annotations: deployment.kubernetes.io/revision=1 Selector: app=mysql Replicas: 1 desired | 1 updated | 1 total | 0 available | 1 unavailable StrategyType: Recreate MinReadySeconds: 0 Pod Template: Labels: app=mysql Containers: mysql: Image: mysql:5.6 Port: 3306/TCP Environment: MYSQL_ROOT_PASSWORD: password Mounts: /var/lib/mysql from mysql-persistent-storage (rw) Volumes: mysql-persistent-storage: Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) ClaimName: mysql-pv-claim ReadOnly: false Conditions: Type Status Reason ---- ------ ------ Available False MinimumReplicasUnavailable Progressing True ReplicaSetUpdated OldReplicaSets: <none> NewReplicaSet: mysql-63082529 (1/1 replicas created) Events: FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 33s 33s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set mysql-63082529 to 1
Listez les Pods créés par le Deployment:
kubectl get pods -l app=mysql
Le résultat sera similaire à ceci:
NAME READY STATUS RESTARTS AGE mysql-63082529-2z3ki 1/1 Running 0 3m
Inspectez le PersistentVolumeClaim:
kubectl describe pvc mysql-pv-claim
Le résultat sera similaire à ceci:
Name: mysql-pv-claim Namespace: default StorageClass: Status: Bound Volume: mysql-pv-volume Labels: <none> Annotations: pv.kubernetes.io/bind-completed=yes pv.kubernetes.io/bound-by-controller=yes Capacity: 20Gi Access Modes: RWO Events: <none>
Accès à l'instance MySQL
Le fichier YAML précédent crée un service qui permet à d'autres
pods dans le cluster d'accéder à la base de données.
L'option clusterIP: None
du service permet à son nom DNS
de résoudre directement l'adresse IP du pod.
C'est optimal lorsque vous n'avez qu'un seul pod derrière
un service et que vous n'avez pas l'intention
d'augmenter le nombre de pods.
Exécutez un client MySQL pour vous connecter au serveur :
kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -ppassword
Cette commande crée un nouveau pod dans le cluster exécutant un client MySQL et le connecte au serveur via le Service. Si la connexion réussit, cela signifie que votre base de données MySQL est opérationnelle.
Waiting for pod default/mysql-client-274442439-zyp6i to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.
mysql>
Mises à jour
L'image ou toute autre partie du Deployment peut être mise à jour
comme d'habitude avec la commande kubectl apply
.
Voici quelques précautions spécifiques aux applications stateful :
- Ne pas mettre à l'échelle l'application. Cette configuration est conçue pour des applications à une seule instance seulement. Le PersistentVolume sous-jacent ne peut être monté que sur un Pod. Pour les applications stateful clusterisées, consultez la documentation sur les StatefulSets.
- Utilisez
strategy
:type: Recreate
dans le fichier de configuration YAML du Deployment. Cela indique à Kubernetes de ne pas utiliser des mises à jour continues. Les mises à jour en roulement ne fonctionneront pas, car vous ne pouvez pas avoir plus d'un Pod en cours d'exécution à la fois. La stratégieRecreate
arrêtera le premier pod avant d'en créer un nouveau avec la configuration mise à jour.
Suppression d'un déploiement
Supprimez les ressources déployées avec leur noms:
kubectl delete deployment,svc mysql
kubectl delete pvc mysql-pv-claim
kubectl delete pv mysql-pv-volume
Si vous avez provisionné manuellement un PersistentVolume, vous devrez également le supprimer manuellement, ainsi que libérer la ressource sous-jacente. Si vous avez utilisé un provisionneur dynamique, il supprimera automatiquement le PersistentVolume lorsqu'il verra que vous avez supprimé le PersistentVolumeClaim. Certains provisionneurs dynamiques (comme ceux pour EBS et PD) libèrent également la ressource sous-jacente lors de la suppression du PersistentVolume.
A suivre
En savoir plus sur les Deployments.
En savoir plus sur le déploiement d'applications
Documentation des Volumes et des Volumes persistants