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

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

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

Цілі

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

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

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

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

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

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

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

Примітка: пароль визначено у файлі конфігурації 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:9
        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
  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:9
        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 створює сервіс, який дає іншим Podʼам у кластері змогу отримувати доступ до бази даних. Параметр Service clusterIP: None дозволяє DNS-імені Service розвʼязуватися безпосередньо в IP-адресу Podʼа. Це оптимально, коли за Service стоїть лише один Pod і ви не маєте наміру збільшувати кількість Podʼів.

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

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

Ця команда створює в кластері новий Pod, у якому працює клієнт MySQL, і підʼєднує його до сервера через Service. Якщо зʼєднання встановлено, значить, ваша база даних 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 не використовувати поетапні оновлення. Поетапні оновлення не працюватимуть, оскільки одночасно не може працювати більше одного Podʼа. Стратегія Recreate зупинить перший Pod перед створенням нового з оновленою конфігурацією.

Видалення Deployment

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

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

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

Що далі

Змінено November 03, 2026 at 9:39 PM PST: [uk] Add run a single-instance stateful application page (e207a94dae)