Запуск одноекземплярного застосунку зі збереженням стану

На цій сторінці показано, як запустити одноекземплярний застосунок зі збереженням стану (Stateful) в Kubernetes, використовуючи PersistentVolume та Deployment. Застосунок — MySQL.

Цілі

  • Створити PersistentVolume, посилаючись на диск у вашому середовищі.
  • Створити Deployment MySQL.
  • Використання MySQL для інших Podʼів в кластері за відомим DNS-імʼям.

Перш ніж ви розпочнете

  • Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

    Для перевірки версії введіть kubectl version.

  • Вам потрібно мати або динамічний провізор PersistentVolume з типовим StorageClass, або статично надавати PersistentVolume самостійно, щоб задовольнити PersistentVolumeClaims, що використовується тут.

Розгортання MySQL

Ви можете запустити stateful застосунок, створивши Deployment Kubernetes та підʼєднавши його до наявного PersistentVolume за допомогою PersistentVolumeClaim. Наприклад, цей файл YAML описує Deployment, що запускає MySQL та посилається на PersistentVolumeClaim. Файл визначає монтування тому для /var/lib/mysql, а потім створює PersistentVolumeClaim, який шукає том 20G. Ця заявка виконується будь-яким наявним томом, який відповідає вимогам, або за допомогою динамічного провізора.

Примітка: пароль визначений в файлі конфігурації yaml, і це не є безпечним. Див. Kubernetes Secrets для безпечнішого рішення.

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:
          # Використання secret у реальному використанні
        - 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
  1. Розгорніть PV та PVC з файлу YAML:

    kubectl apply -f https://k8s.io/examples/application/mysql/mysql-pv.yaml
    
  2. Розгорніть вміст файлу YAML:

    kubectl apply -f https://k8s.io/examples/application/mysql/mysql-deployment.yaml
    
  3. Показати інформацію про Deployment:

    kubectl describe deployment mysql
    

    Вивід схожий на:

    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
    
  4. Перегляньте Podʼи, створені Deployment:

    kubectl get pods -l app=mysql
    

    Вивід схожий на:

    NAME                   READY     STATUS    RESTARTS   AGE
    mysql-63082529-2z3ki   1/1       Running   0          3m
    
  5. Перевірка PersistentVolumeClaim:

    kubectl describe pvc mysql-pv-claim
    

    Вивід схожий на:

    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>
    

Доступ до екземпляра MySQL

Попередній YAML-файл створює Service, який дозволяє іншим Podʼам в кластері отримувати доступ до бази даних. Опція Service clusterIP: None дозволяє імені DNS Serviceʼа безпосередньо посилатись на IP-адресу Podʼа. Це оптимально, коли у вас є лише один Pod за Service і ви не маєте наміру збільшувати кількість Podʼів.

Запустіть клієнта MySQL, щоб підʼєднатися до сервера:

kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -ppassword

Ця команда створює новий Pod у кластері, що виконує клієнта MySQL та підʼєднується до сервера через Service. Якщо підʼєднання вдалося, ви знаєте, що ваша stateful база даних MySQL працює.

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>

Оновлення

Образ або будь-яку іншу частину Deployment можна оновити як зазвичай за допомогою команди kubectl apply. Ось деякі заходи обережності, які специфічні для застосунків зі збереженням стану:

  • Не масштабуйте застосунок. Цей варіант призначений лише для застосунків з одним екземпляром. Основний PersistentVolume можна примонтувати лише до одного Podʼа. Для кластеризованих застосунків зі збереженням стану див. документацію StatefulSet.
  • Використовуйте strategy: type: Recreate в файлі конфігурації YAML Deployment. Це вказує Kubernetes не використовувати постійні (rolling) оновлення. Такі оновлення не працюватимуть, оскільки ви не можете мати більше одного Podʼа, що працює одночасно. Стратегія Recreate зупинить перший Pod перед створенням нового з оновленою конфігурацією.

Видалення Deployment

Видаліть розгорнуті обʼєкти за іменем:

kubectl delete deployment,svc mysql
kubectl delete pvc mysql-pv-claim
kubectl delete pv mysql-pv-volume

Якщо ви вручну вказували PersistentVolume, вам також потрібно вручну видалити його, а також звільнити основний ресурс. Якщо ви використовували динамічного провізора, він автоматично видаляє PersistentVolume, коли бачить, що ви видалили PersistentVolumeClaim. Деякі динамічні провізори (наприклад, ті, що стосуються EBS та PD) також звільняють основний ресурс після видалення PersistentVolume.

Що далі

Змінено August 10, 2024 at 8:09 PM PST: Local links were prefixed with "uk" (7d9a96f799)