Использование эфемерных и постоянных томов в подах

KubernetesBeginner
Практиковаться сейчас

Введение

Контейнеры имеют записываемую файловую систему, но это хранилище привязано к самому контейнеру. Тома Kubernetes предоставляют подам более удобный способ управления файлами. Некоторые тома являются эфемерными и предназначены для временных данных внутри одного пода. Другие тома являются постоянными (persistent) и позволяют сохранять данные даже после удаления и повторного создания пода.

В этой лабораторной работе вы будете использовать том emptyDir для временных данных пода, а затем создадите PersistentVolumeClaim и подключите его к двум разным подам, чтобы убедиться, что данные сохраняются после замены пода.

Подготовка пространства имен для работы с томами

На этом этапе вы подготовите чистое пространство имен и убедитесь, что в кластере есть все необходимые компоненты для хранения данных.

Начните работу в директории /home/labex/project. В этой директории вы будете создавать манифесты подов и PVC.

mkdir -p /home/labex/project
cd /home/labex/project

Проверьте доступность API-сервера Kubernetes. Если виртуальная машина только что запустилась и узел еще не готов, подождите несколько секунд и повторите команду.

kubectl get nodes --request-timeout=5s

Ожидаемый вывод:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

Дождитесь готовности пода сетевого взаимодействия кластера:

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

Ожидаемый вывод:

pod/calico-node-... condition met

В этой лабораторной работе позже будет использоваться PersistentVolumeClaim. Убедитесь, что существует стандартный StorageClass standard, а затем дождитесь готовности пода провизионера хранилища minikube.

kubectl get storageclass standard
kubectl wait --namespace kube-system --for=condition=Ready pod/storage-provisioner --timeout=120s

Ожидаемый вывод:

NAME                 PROVISIONER                RECLAIMPOLICY   VOLUMEBINDINGMODE   ...
standard (default)   k8s.io/minikube-hostpath   Delete          Immediate           ...
pod/storage-provisioner condition met

Создайте пространство имен с именем ckad-prep-volumes:

kubectl create namespace ckad-prep-volumes

Установите это пространство имен в качестве текущего контекста:

kubectl config set-context --current --namespace=ckad-prep-volumes

Проверьте текущее пространство имен:

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

Ожидаемый вывод:

ckad-prep-volumes

Использование emptyDir для временных данных пода

На этом этапе вы создадите под, который использует том emptyDir.

Том emptyDir создается пустым при запуске пода. Контейнеры внутри одного пода могут использовать его как общее пространство для временных файлов, кэша или рабочей директории. Он не предназначен для сохранения данных после удаления пода.

Создайте файл emptydir-pod.yaml:

cat > emptydir-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: scratch-worker
  labels:
    app: scratch-worker
spec:
  terminationGracePeriodSeconds: 0
  volumes:
  - name: scratch-space
    emptyDir: {}
  containers:
  - name: worker
    image: busybox:1.36
    command:
    - /bin/sh
    - -c
    - 'echo scratch-ready > /scratch/status.txt; sleep 3600'
    volumeMounts:
    - name: scratch-space
      mountPath: /scratch
EOF

Примените манифест:

kubectl apply -f emptydir-pod.yaml

Ожидаемый вывод:

pod/scratch-worker created

Дождитесь готовности пода:

kubectl wait --for=condition=Ready pod/scratch-worker --timeout=120s

Ожидаемый вывод:

pod/scratch-worker condition met

Прочитайте файл из смонтированного тома emptyDir:

kubectl exec scratch-worker -c worker -- cat /scratch/status.txt

Ожидаемый вывод:

scratch-ready

Проверьте тип тома пода. Выражение jsonpath выведет имя тома и подтвердит, что это emptyDir.

kubectl get pod scratch-worker -o 'jsonpath={.spec.volumes[0].name}{" emptyDir\n"}'

Ожидаемый вывод:

scratch-space emptyDir

Запись данных в PersistentVolumeClaim

На этом этапе вы создадите PersistentVolumeClaim (PVC) и подключите его к поду-писателю.

PersistentVolumeClaim — это запрос приложения на предоставление хранилища. В этой лабораторной работе StorageClass standard динамически предоставляет хранилище для этого запроса. Ваш под монтирует этот ресурс в директорию /data и записывает туда файл.

Создайте файл notes-pvc.yaml:

cat > notes-pvc.yaml <<'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: notes-pvc
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: standard
  resources:
    requests:
      storage: 1Mi
EOF

Примените PVC:

kubectl apply -f notes-pvc.yaml

Ожидаемый вывод:

persistentvolumeclaim/notes-pvc created

Дождитесь, пока статус PVC станет Bound:

kubectl wait --for=jsonpath='{.status.phase}'=Bound pvc/notes-pvc --timeout=120s

Ожидаемый вывод:

persistentvolumeclaim/notes-pvc condition met

Создайте под-писатель, который монтирует этот PVC:

cat > pvc-writer-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: pvc-writer
  labels:
    app: pvc-writer
spec:
  terminationGracePeriodSeconds: 0
  volumes:
  - name: notes-storage
    persistentVolumeClaim:
      claimName: notes-pvc
  containers:
  - name: writer
    image: busybox:1.36
    command:
    - /bin/sh
    - -c
    - 'echo persistent-note > /data/note.txt; sleep 3600'
    volumeMounts:
    - name: notes-storage
      mountPath: /data
EOF

Примените манифест пода-писателя и дождитесь его готовности:

kubectl apply -f pvc-writer-pod.yaml
kubectl wait --for=condition=Ready pod/pvc-writer --timeout=120s

Ожидаемый вывод:

pod/pvc-writer created
pod/pvc-writer condition met

Прочитайте файл из смонтированного PVC:

kubectl exec pvc-writer -c writer -- cat /data/note.txt

Ожидаемый вывод:

persistent-note

Повторное использование PVC в новом поде

На этом этапе вы удалите под-писатель, создадите новый под-читатель, который монтирует тот же PVC, и убедитесь, что файл по-прежнему доступен.

В этом заключается практическая разница между временными данными пода и постоянным хранилищем. Под-писатель может быть удален, но PVC останется. Новый под может смонтировать тот же ресурс и прочитать данные.

Удалите под-писатель:

kubectl delete pod pvc-writer

Ожидаемый вывод:

pod "pvc-writer" deleted

Создайте под-читатель, который монтирует тот же PVC:

cat > pvc-reader-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: pvc-reader
  labels:
    app: pvc-reader
spec:
  terminationGracePeriodSeconds: 0
  volumes:
  - name: notes-storage
    persistentVolumeClaim:
      claimName: notes-pvc
  containers:
  - name: reader
    image: busybox:1.36
    command:
    - /bin/sh
    - -c
    - 'cat /data/note.txt; sleep 3600'
    volumeMounts:
    - name: notes-storage
      mountPath: /data
EOF

Примените манифест пода-читателя и дождитесь его готовности:

kubectl apply -f pvc-reader-pod.yaml
kubectl wait --for=condition=Ready pod/pvc-reader --timeout=120s

Ожидаемый вывод:

pod/pvc-reader created
pod/pvc-reader condition met

Прочитайте файл из нового пода:

kubectl exec pvc-reader -c reader -- cat /data/note.txt

Ожидаемый вывод:

persistent-note

Проверьте состояние PVC. Он должен оставаться в статусе Bound, даже несмотря на то, что исходный под-писатель был удален.

kubectl get pvc notes-pvc

Ожидаемый вывод:

NAME        STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
notes-pvc   Bound    ...      1Mi        RWO            standard       <unset>                 ...

Резюме

Вы использовали том emptyDir для временных данных пода, создали PVC для постоянного хранения, записали данные через один под, удалили этот под и прочитали те же данные из нового пода, который смонтировал тот же ресурс. Теперь вы знаете, когда использовать эфемерное хранилище для временных данных пода, а когда запрашивать постоянное хранилище для данных, которые должны сохраняться после замены пода.