Это 13-й день, когда я участвую в Gengwen Challenge. Проверьте подробности мероприятия:Обновить вызов
Десять томов хранения POD
Большинство stateful-приложений имеют постоянное хранилище.В Docker мы помещаем том хранилища, необходимый контейнеру, на хост, а не на k8s, потому что PODы будут создаваться и удаляться на разных узлах, поэтому k8s нужен дополнительный механизм тома хранилища, обеспечивающий постоянное хранилище для всего кластера вне узла.
k8s предоставляет множество различных томов хранения.В k8s тома хранения принадлежат POD, а не контейнерам.POD можно монтировать.Почему POD могут иметь тома хранения? Это связано с тем, что образ Pause работает на всех узлах, он является инфраструктурным контейнером POD, ему принадлежит том хранилища, а все контейнеры в одном POD находятся в сетевом пространстве имен.
10.1 Типы томов
Ознакомьтесь с поддерживаемыми типами хранилищ для POD: kubectl, объясните pods.spec.volumes.
- HostPath: создайте новый путь локально на узле и установите отношение ассоциации с контейнером, но данные на узле больше не существуют, поэтому они не являются постоянными.Когда контейнер назначен на другой узел, HostPath нельзя использовать через узлы.
- Локальный: используйте устройство узла напрямую, также поддерживает каталог, аналогичный HostPath.
- EmptyDir: Используется только локально на узле. После удаления POD том хранилища также будет удален. Он не является постоянным, как временный каталог или кеш.
- Сетевое хранилище: iSCSI, NFS, Cifs, glusterfs, cephfs, EBS (AWS), Диск (Azone)
10.2 Варианты установки контейнера
В K8S тома принадлежат POD, а не контейнерам, поэтому тома определяются в POD, и в одном POD может быть определено несколько томов.
- Монтировать и использовать в POD, kubectl объясняет pods.spec.containers.volumeMounts
apiVersion: v1
kind: Pod
metadata:
name: myapp
namespace: default
labels:
app: myapp
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
volumeMounts <[]Object> # 卷挂载对象
mountPath <string> # 挂载路径
mountPropagation <string> # 确定挂载如何从主机传播到容器
name <string> # 挂载哪个卷
readOnly <boolean> # 是否只读挂载
subPath <string> # 挂载在子路径下
subPathExpr <string> # 与 subPath 类似,挂载在子路径下,不同的是可以使用 $(VAR_NAME) 表示容器扩展这个变量
10.3 Хранение узлов
10.3.1 объем хранилища пути хоста
Когда путь хоста смонтирован на POD, данные тома не будут удалены после удаления POD, но если узел узла зависнет, данные могут быть потеряны.Если POD запланирован на другие узлы, исходный том данные недоступны.
- Определите параметры, kubectl объясните pods.spec.volumes.hostPath
path <string> # 主机上目录的路径。 如果路径是符号链接,则会跟随真实路径的链接。
type <string> # 见下表
стоимость | поведение |
---|---|
Пустая строка (по умолчанию) предназначена для обратной совместимости, что означает, что перед монтированием тома hostPath не выполняются никакие проверки. | |
DirectoryOrCreate |
Если по указанному пути ничего не существует, при необходимости будет создан пустой каталог с разрешениями, установленными на 0755, с той же группой и владельцем, что и у Kubelet. |
Directory |
Каталог должен существовать по указанному пути |
FileOrCreate |
Если есть что-то данный путь, он создаст пустой файл по мере необходимости, установленные на 0644, а Kubelet имеет ту же группу и владение. |
File |
Файл должен существовать по указанному пути |
Socket |
Сокеты UNIX должны существовать по указанному пути. |
CharDevice |
По указанному пути должно существовать символьное устройство. |
BlockDevice |
Блочное устройство должно существовать по указанному пути |
- Пример
apiVersion: v1
kind: Pod
metadata:
name: myapp
namespace: default
labels:
app: myapp
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
volumeMounts: # 容器挂载哪些卷
- name: webstore # 挂载哪个卷
mountPath: /usr/share/nginx/html # 挂载到容器内哪个目录
readOnly: false # 是否只读
volumes: # 存储卷属于POD的(不属于容器)
- name: webstore # 存储卷对象名字
hostPath: # hostpath 类型的存储卷对象
path: /data/myapp # 处于宿主机的目录
type: DirectoryOrCreate # 不存在则创建
10.3.2 Грумы Гитрепо
Используйте содержимое репозитория git в качестве хранилища, подключитесь к репозиторию при создании POD, извлеките репозиторий и смонтируйте его в контейнер в качестве тома хранилища.
На самом деле он основан на emptyDir, но операции с томами не синхронизируются с gitrepo.
Примечание. Инструмент git необходимо установить на каждом узле, на котором запущен модуль, для извлечения git.
apiVersion: v1
kind: Pod
metadata:
labels:
run: gitrepo
name: gitrepo
spec:
containers:
- image: nginx:latest
name: gitrepo
volumeMounts:
- name: gitrepo
mountPath: /usr/share/nginx/html
volumes:
- name: gitrepo
gitRepo:
repository: "https://gitee.com/rocket049/mysync.git"
revision: "master"
10.3.3 тома кэша emptyDir
В качестве точки монтирования он использует каталог на хосте, и с окончанием жизненного цикла POD данные в нем будут потеряны, но у него есть очень большое преимущество, что он может использовать память как хранилище для монтирования.
Его можно использовать в POD, когда у двух контейнеров есть данные для совместного использования.
- определить параметр emptyDir,
kubectl explain pods.spec.volumes.emptyDir
medium <string> # 使用 "" 表示使用 Disk 来存储,使用 Memory 表示使用内存
sizeLimit <string> # 限制存储空间的大小
- Пример использования
apiVersion: v1
kind: Pod
metadata:
name: pod-volume-demo
namespace: default
labels:
app: myapp
tier: frontend
spec:
volumes:
- name: html
emptyDir: {} # 使用磁盘,且没有容量限制
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html/
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: html
mountPath: /data/
command:
- "/bin/sh"
- "-c"
- "while true; do date >> /data/index.html; sleep 10; done"
- Пример использования
apiVersion: v1
kind: Pod
metadata:
name: pod-volume-demo
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html/
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: html
mountPath: /data/
command:
- "/bin/sh"
- "-c"
- "while true; do date >> /data/index.html; sleep 10; done"
volumes:
- name: html
emptyDir:
medium: ""
sizeLimit: 1536Mi
10.4 Сетевое хранилище
Сетевое хранилище — это устройство хранения, которое находится вне жизненного цикла узла.Даже если модуль запланирован на другой узел, данные в нем все равно можно смонтировать и использовать.
10.4.1 nfs
Сервер nfs — это сервер, который существует вне кластера, на него не влияет узел node, поэтому он все еще может предоставлять постоянное хранилище для других POD после того, как узел node выйдет из строя.
- Найдите хост в узле k8s, установите и настройте сервер nfs и запустите
$ yum install nfs-utils # 安装 nfs 服务
$ mkdir -p /data/volumes # 创建 volume 卷目录
echo '/data/volumes 172.16.100.0/16(rw,no_root_squash)' >> /etc/exports # 配置 nfs 服务器
$ systemctl start nfs # 启动 nfs 服务器
$ ss -tnl # 确认监听端口,nfs 监听 TCP 2049 端口
- Установите драйвер nfs на узел node кластера k8s, чтобы проверить, нормально ли монтируется
$ yum install nfs-utils
$ mount -t nfs 172.16.100.104:/data/volumes /mnt
- Определите параметры nfs, kubectl объясните pods.spec.volumes.nfs
path <string> # nfs 服务器的路径
readOnly <boolean> # 是否只读
server <string> # nfs 服务器地址
- Пример использования
apiVersion: v1
kind: Pod
metadata:
name: pod-vol-nfs-demo
namespace: default
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html/
volumes:
- name: html
nfs:
path: /data/volumes
server: 172.16.100.104
Примечание⚠️: Каждый узел также необходимо установитьyum install nfs-utils
, не допускайте возникновения исключений при монтировании.
10.5 Распределенное хранилище
Распределенное хранилище может обеспечивать хранение за пределами жизненного цикла узлов и является более надежным, чем сетевое хранилище. Оно распределено и обладает высокой доступностью, но конфигурация распределенного хранилища сложна. В сетевом хранилище, предоставляемом NFS, пользователям требуется хранилище NFS. адрес, назначенный POD, можно использовать только после того, как будет известен адрес хранилища NFS, предоставленный распределенным хранилищем, пользователям необходимо полностью понять параметры конфигурации распределенного хранилища, прежде чем они смогут использовать распределенное хранилище.
Поэтому K8S предоставляет два механизма: PV и PVC, так что обычным пользователям не нужно заботиться о настройке параметров базового хранилища, а нужно только указать, какой объем постоянного хранилища необходимо использовать.
Как правило, PV и PVC связаны в паре. PV относится к всему миру, и ПВХ принадлежит к определенным пространствам имен. Когда PV связан с ПВХ, другие PVC пространств имен не могут быть связаны. Запрос на связывание PV завершается ПВХ, а PV, связанный с ПВХ, называется связывающим состоянием PV.
PVC привязывается к PV, затем POD, определенный в пространстве имен, где расположен PVC, может использовать тома типа persistVolumeClaim, а затем контейнер может монтировать тома типа PVC через VolumeMounts.
Допускает ли том persistenceVolumeClaim многократное чтение и запись, зависит от характеристик чтения и записи при определении PV: однократное чтение, множественное чтение и множественное чтение.
Если POD больше не нужен, мы удаляем его, а также удаляем PVC, тогда у PV в это время тоже может быть своя стратегия утилизации: delete удаляет PV, а Retain ничего не делает.
10.5.1 PersistentVolume
Описание хранилища, добавленное администратором, является глобальным ресурсом на уровне кластера, включая тип хранилища, размер хранилища и режим доступа. Его жизненный цикл не зависит от модуля, т. е. не влияет на PV, когда модуль, использующий его, уничтожается.
См.: kubectl объясняет PersistentVolume.spec
- Определите хранилище в nfs, /etc/exports и экспортируйте определения nfs
/data/volumes/v1 172.16.100.0/16(rw,no_root_squash)
/data/volumes/v2 172.16.100.0/16(rw,no_root_squash)
/data/volumes/v3 172.16.100.0/16(rw,no_root_squash)
/data/volumes/v4 172.16.100.0/16(rw,no_root_squash)
/data/volumes/v5 172.16.100.0/16(rw,no_root_squash)
exportfs -arv
- Определите nfs как PersistentVolume в k8s, см. kubectl, объяснение PersistentVolume.spec.nfs
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-001
labels:
name: pv001
spec:
accessModes:
- ReadWriteMany
- ReadWriteOnce
capacity:
storage: 1Gi
nfs:
path: /data/volumes/v1
server: 172.16.100.104
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-002
labels:
name: pv003
spec:
accessModes:
- ReadWriteMany
- ReadWriteOnce
capacity:
storage: 2Gi
nfs:
path: /data/volumes/v2
server: 172.16.100.104
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-003
labels:
name: pv003
spec:
accessModes:
- ReadWriteMany
- ReadWriteOnce
capacity:
storage: 3Gi
nfs:
path: /data/volumes/v3
server: 172.16.100.104
kubectl get persistentvolume
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-001 1Gi RWO,RWX Retain Available 3m38s
pv-002 2Gi RWO,RWX Retain Available 3m38s
pv-003 3Gi RWO,RWX Retain Available 3m38s
10.5.2. PersistentVolumeClaim
— это ресурс уровня пространства имен, описывающий запрос к PV. Информация запроса включает размер хранилища, режим доступа и т. д.
- Определите PVC, kubectl объясните PersistentVolumeClaim.spec
accessModes <[]string> # 设置访问模式
ReadWriteOnce # 单个节点以读写方式挂载
ReadOnlyMany # - 多节点以只读方式挂载
ReadWriteMany # - 多节点以读写方式挂载
dataSource <Object> # 如果配置程序可以支持 Volume Snapshot 数据源,它将创建一个新卷,并且数据将同时还原到该卷。
resources <Object> # 资源表示 PersistentVolume 应具有的最小资源
selector <Object> # 选择哪个 PersistentVolume
storageClassName <string> # 存储类名称
volumeMode <string> # 定义声明所需的 PersistentVolume 类型才能被选中
volumeName <string> # 后端 PersistentVolume ,就是精确选择 PersistentVolume ,而不是使用 selector 来选定
- Использование PVC в томах, kubectl объясняет pods.spec.volumes.persistentVolumeClaim
persistentVolumeClaim
claimName <string> # 在当前名称空间已经创建号的 PVC 名称
readOnly <boolean> # 是否只读
- Определите PersistentVolumeClaim, см. kubectl, объясните PersistentVolumeClaim.spec
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
namespace: default
spec:
accessModes:
- ReadWriteMany # 访问模式
resources: # 资源条件
requests: # 挑选 PV 时候必须满足的条件,不满足则一直等待
storage: 2Gi # 存储大小
- Определите тома типа persistVolumeClaim в манифесте модуля и смонтируйте тома в контейнере.
apiVersion: v1
kind: Pod
metadata:
name: pod-vol-nfs-demo
namespace: default
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html/
volumes:
- name: html
persistentVolumeClaim:
claimName: my-pvc # 使用的 PVC 的名称
10.5.3 StorageClass
Когда PV приложения PVC, нет необходимости удовлетворять требованиям PV, K8s подготавливает StorageClass для динамического создания PV через StorageClass во время PV приложения PVC.
StorageClass может динамически генерировать PV из CephFS, NFS и других хранилищ (или облачных хранилищ) и требует, чтобы устройство хранения поддерживало интерфейсы в стиле RESTfull.
10.6 StorageClass Ceph RBD
10.6.1 Настройка пулов хранения Ceph
- Создайте пул хранения ceph
yum install -y ceph-common # 在所有节点安装 ceph-common
ceph osd pool create kube 4096 # 创建 pool
ceph osd pool ls # 查看 pool
ceph auth get-or-create client.kube mon 'allow r' osd 'allow rwx pool=kube' -o /etc/ceph/ceph.client.kube.keyring
ceph auth list # 授权 client.kube 用户访问 kube 这个 pool
scp /etc/ceph/ceph.client.kube.keyring node1:/etc/ceph/ # 将用户 keyring 文件拷贝到各个 ceph 节点
scp /etc/ceph/ceph.client.kube.keyring node1:/etc/ceph/
10.6.2 Установка rbd-provisioner
- После версии 1.12 в kube-controller-manager больше нет встроенной команды rbd, поэтому провайдер StorageClass реализуется через внешние плагины
https://github.com/kubernetes-incubator/external-storage/tree/master/ceph/rbd/deploy/rbac # rbd-provisioner
$ git clone https://github.com/kubernetes-incubator/external-storage.git # 下载 rbd-provisioner
$ cat >>external-storage/ceph/rbd/deploy/rbac/clusterrole.yaml<<EOF # 允许 rbd-provisioner 访问 ceph 的密钥
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create", "get", "list", "watch"]
EOF
$ kubectl apply -f external-storage/ceph/rbd/deploy/rbac/ # 安装 rbd-provisioner
10.6.3 Использование StorageClass
- Создать секрет аутентификации CephX
https://github.com/kubernetes-incubator/external-storage/tree/master/ceph/rbd/examples # rbd-provisioner 使用 ceph rbd 的示例
---
apiVersion: v1
kind: Secret
metadata:
name: ceph-admin-secret
namespace: kube-system
type: "kubernetes.io/rbd"
data:
# ceph auth get-key client.admin | base64 # 从这个命令中取得 keyring 认证的 base64 密钥串复制到下面
key: QVFER3U5TmM1NXQ4SlJBQXhHMGltdXZlNFZkUXRvN2tTZ1BENGc9PQ==
---
apiVersion: v1
kind: Secret
metadata:
name: ceph-secret
namespace: kube-system
type: "kubernetes.io/rbd"
data:
# ceph auth get-key client.kube | base64 # 从这个命令中取得 keyring 认证的 base64 密钥串复制到下面
key: QVFCcUM5VmNWVDdQRlJBQWR1NUxFNzVKeThiazdUWVhOa3N2UWc9PQ==
- Создайте StorageClass указывает на RBD-Provisioner,
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: ceph-rbd
provisioner: ceph.com/rbd
reclaimPolicy: Retain
parameters:
monitors: 172.16.100.9:6789
pool: kube
adminId: admin
adminSecretName: ceph-admin-secret
adminSecretNamespace: kube-system
userId: kube
userSecretName: ceph-secret
userSecretNamespace: kube-system
fsType: ext4
imageFormat: "2"
imageFeatures: "layering"
- Создать персистентволумеклайм
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: ceph-rbd-pvc data-kong-postgresql-0
spec:
storageClassName: ceph-rbd
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
- Используйте ПВХ в POD и, наконец, установите ПВХ в контейнер.
---
apiVersion: v1
kind: Pod
metadata:
name: ceph-sc-pvc-demo
namespace: default
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
volumeMounts:
- name: pvc-volume
mountPath: /usr/share/nginx/html/
volumes:
- name: pvc-volume
persistentVolumeClaim:
claimName: ceph-rbd-pvc
разное
Публикуйте свои заметки по адресу:GitHub.com/RedHat Series/Арвин…Добро пожаловать в один клик