Заметки Kubernetes (10) — Объем хранилища POD

Kubernetes
Заметки Kubernetes (10) — Объем хранилища POD

Это 13-й день, когда я участвую в Gengwen Challenge. Проверьте подробности мероприятия:Обновить вызов

Десять томов хранения POD

Большинство stateful-приложений имеют постоянное хранилище.В Docker мы помещаем том хранилища, необходимый контейнеру, на хост, а не на k8s, потому что PODы будут создаваться и удаляться на разных узлах, поэтому k8s нужен дополнительный механизм тома хранилища, обеспечивающий постоянное хранилище для всего кластера вне узла.

k8s предоставляет множество различных томов хранения.В k8s тома хранения принадлежат POD, а не контейнерам.POD можно монтировать.Почему POD могут иметь тома хранения? Это связано с тем, что образ Pause работает на всех узлах, он является инфраструктурным контейнером POD, ему принадлежит том хранилища, а все контейнеры в одном POD находятся в сетевом пространстве имен.

10.1 Типы томов

Ознакомьтесь с поддерживаемыми типами хранилищ для POD: kubectl, объясните pods.spec.volumes.

  1. HostPath: создайте новый путь локально на узле и установите отношение ассоциации с контейнером, но данные на узле больше не существуют, поэтому они не являются постоянными.Когда контейнер назначен на другой узел, HostPath нельзя использовать через узлы.
  2. Локальный: используйте устройство узла напрямую, также поддерживает каталог, аналогичный HostPath.
  3. EmptyDir: Используется только локально на узле. После удаления POD том хранилища также будет удален. Он не является постоянным, как временный каталог или кеш.
  4. Сетевое хранилище: 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 запланирован на другие узлы, исходный том данные недоступны.

Какой особенный. IO/docs/con обзор…

  • Определите параметры, 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/Арвин…Добро пожаловать в один клик