Часть 11 из серии статей об изучении k8s!
Указатель всей серии
- Основы k8s
- Создать кластер k8s одной командой
- Первое размещение контейнера в k8s
- Зачем нам Pod
- Важные поля конфигурации модуля
- Под проектные объемы
- Проверка работоспособности и восстановление pod-контейнера
- Модель контроллера k8s
- Развертывание k8s
- Топология с отслеживанием состояния k8s
В прошлой статье я рассказал, как StatefulSet
гарантирует топологическое состояние экземпляра приложения и поддерживает его стабильность в процессе удаления и повторного создания Pod. В этой статье я расскажу о механизме управления StatefulSet для состояния хранилища.
Требование постоянного объема
Ранее я упоминал, что чтобы объявить Volume
в модуле, вы просто добавляете поле spec.volumes
в модуль. Затем вы можете определить в этом поле определенный тип объема, например hostPath
. Но что, если вы не знаете, какие типы томов использовать? В частности, как разработчик приложения вы можете даже ничего не знать о проектах постоянного хранения (таких как Ceph
, GlusterFS
и т. Д.), А также не знаете, как построен кластер k8s в вашей компании, и вы, вероятно, не знаете не нужно знать. Например, давайте посмотрим на Ceph RBD
тип объема:
apiVersion: v1 kind: Pod metadata: name: rbd spec: containers: - image: kubernetes/pause name: rbd-rw volumeMounts: - name: rbdpd mountPath: /mnt/rbd volumes: - name: rbdpd rbd: monitors: - '10.16.154.78:6789' - '10.16.154.82:6789' - '10.16.154.83:6789' pool: kube image: foo fsType: ext4 readOnly: true user: admin keyring: /etc/ceph/keyring imageformat: "2" imagefeatures: "layering"
Очевидно, если вы не знаете Ceph RBD
, вы понятия не имеете, что означает приведенный выше YAML. И адрес, имя пользователя и авторизованное расположение файла сервера хранения, соответствующего этому Ceph RBD
, также отображаются через файл YAML. Это типичный пример «передержки» информации.
Вот почему в более поздней версии k8s был представлен набор объектов API, называемых Persistent Volume Claim
(PVC) и Persistent Volume
(PV), что значительно снизило порог для пользователей, позволяющих объявлять и использовать постоянный том.
Например, с PVC и PV разработчик может легко определить объект Volume в k8s:
- Определите PVC и объявите атрибуты желаемого тома
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: pv-claim spec: accessModes: - ReadWriteOnce resources: requests: storage: 2Gi
- В приложении Pod заявите об использовании этого PVC:
apiVersion: v1 kind: Pod metadata: name: pv-pod spec: containers: - name: pv-container image: nginx ports: - containerPort: 80 name: "http-server" volumeMounts: - mountPath: "/usr/share/nginx/html" name: pv-storage volumes: - name: pv-storage persistentVolumeClaim: claimName: pv-claim
Как видите, в приведенном выше определении нам нужно только объявить его тип persistentVolumeClaim
, а затем указать имя PVC, не заботясь об определении самого Volume. На этом этапе, пока вы создаете этот объект PVC, k8s автоматически привяжет к нему квалифицированный том.
Но вы можете спросить, откуда взялись квалифицированные Volume
?
Ответ - это объекты PV (Persistent Volume
), поддерживаемые командой DevOps. Давайте посмотрим на определение PV
:
kind: PersistentVolume apiVersion: v1 metadata: name: pv-volume labels: type: local spec: capacity: storage: 10Gi accessModes: - ReadWriteOnce rbd: monitors: - '10.17.164.78:6789' - '10.17.164.82:6789' - '10.17.164.83:6789' pool: kube image: foo fsType: ext4 readOnly: true user: admin keyring: /etc/ceph/keyring
Это определение размером 10 ГБCeph RBD Volume
. Таким образом, k8s свяжет этот PV
с PVC
объектом, который вы только что создали. Следовательно, конструкция PVC
и PV
в k8s фактически аналогична идее «интерфейса» и «реализации». Разработчикам нужно только знать и использовать «интерфейс», а именно: PVC
; а DevOps несут ответственность за привязку конкретной реализации: PV
.
Такое разделение позволяет избежать скрытых опасностей, вызванных раскрытием разработчикам слишком большого количества деталей системы хранения. Кроме того, такое разделение ответственности часто означает, что легче обнаружить проблемы и уточнить обязанности в случае аварии, тем самым избегая появления «споров».
Хранение StatefulSet
Давайте воспользуемся тем же StatefulSet
примером из моей последней статьи Топология k8s StatefulSet:
apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: "nginx" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.9.1 ports: - containerPort: 80 name: web volumeMounts: - name: www mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: www spec: accessModes: - ReadWriteOnce resources: requests: storage: 2Gi
На этот раз мы добавили дополнительное поле volumeClaimTemplates
в этот StatefulSet
YAML. Как видно из названия, он похож на шаблон Pod в Deployment
. Другими словами, все модули, управляемые этим StatefulSet
, объявят соответствующий PVC
; и определение этого PVC происходит из поля шаблона volumeClaimTemplates
. Что еще более важно, имени PVC будет присвоен номер, точно такой же, как у Pod
.
После того, как PVC
будет успешно привязан к PV
, он войдет в состояние Bound
, что означает, что Pod
можно смонтировать и использовать PV.
Если вы все еще не понимаете PVC
, запомните следующий вывод: PVC на самом деле представляет собой особый том. Просто какой тип тома PVC
, вы можете узнать только после того, как он будет привязан к PV
.
Итак, после того, как мы используем kubectl create
для создания StatefulSet
, мы увидим, что в кластере k8s появятся два PVC:
$ kubectl create -f statefulset_example.yaml $ kubectl get pvc -l app=nginx NAME STATUS VOLUME CAPACITY ACCESSMODES AGE www-web-0 Bound pvc-15c268c7 2Gi RWO 48s www-web-1 Bound pvc-15c79307 2Gi RWO 48s
Мы видим, что оба PVC
находятся в состоянии Bound
. Pod web-0
будет использовать www-web-0
PVC и смонтировать свой PV. То же самое для Pod web-1
.
Теперь, если вы записываете файлы на том Pod, они будут сохранены в его PV.
Что еще более важно, даже если вы удалите два модуля с помощью команды kubectl delete
, эти файлы на томе будут постоянными и будут доступны для новых модулей.
Постоянное хранилище подов
Давайте подробнее рассмотрим, почему файлы на томе являются постоянными.
Прежде всего, когда вы удаляете Pod
, например web-0
, PVC
и PV
, соответствующие этому модулю, не будут удалены, а данные, которые были записаны в этот том, будут по-прежнему храниться в служба удаленного хранения.
После удаления модуля контроллер StatefulSet
обнаружит, что модуль с именем web-0 исчез. Следовательно, контроллер воссоздает новый Pod с именем web-0, чтобы «исправить» это несоответствие. В определении этого нового Pod
объекта имя PVC
, которое он объявляет, по-прежнему называется: www-web-0
. Поскольку определение этого PVC
по-прежнему происходит из шаблона PVC (volumeClaimTemplates
), который является стандартным процессом для StatefulSet
создания Pod
.
Следовательно, после создания этого нового модуля web-0
, когда k8s ищет для него PVC
с именем www-web-0
, он все равно найдет те же самыеPVC
и PV
.
Заключение
Прежде всего, StatefulSet controller
напрямую управляет модулями. Это потому, что разные экземпляры Pod
в StatefulSet
немного отличаются в ReplicaSet
. StatefulSet
отличает эти экземпляры путем добавления заранее определенного числа к имени модуля.
Во-вторых, k8s использует Headless Service
для создания записей DNS с тем же номером на DNS-сервере для этих пронумерованных модулей. Пока StatefulSet
может гарантировать, что числа в именах модулей остаются неизменными, записи DNS, аналогичные web-0.nginx.default.svc.cluster.local
в службе, также не изменятся, а данные модуля будут проанализированы из эта запись не изменится.
В-третьих, StatefulSet
также выделяет и создает PVC
с тем же номером для каждого Pod
. Таким образом, k8s может связать соответствующий PV
с этим PVC
через механизм постоянного тома, тем самым гарантируя, что каждый под имеет независимый том. В этом случае, даже если Pod
будет удален, соответствующие PVC и PV все равно будут сохранены. Таким образом, когда Pod воссоздан, k8s найдет PVC с тем же номером для него, смонтирует том, соответствующий этому PVC, и получит данные, ранее сохраненные в томе.
StatefulSet на самом деле представляет собой особый вид развертывания, и его уникальная особенность состоит в том, что каждый из его подов пронумерован. Более того, этот номер будет отражен в идентификационной информации, такой как имя модуля и имя хоста. Это не только представляет собой порядок создания Pod, но и важный сетевой идентификатор для Pod (то есть уникальный и доступный идентификатор во всем кластере).
С этим механизмом StatefulSet
использует две стандартные функции в k8s: Headless Service
и PV/PVC
для реализации состояния топологии и состояния хранилища Pod.
Надеюсь, вам понравилась моя статья, и до встречи в следующей!
Больше контента на plainenglish.io