1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/bocloud-open-source-carina

Клонировать/Скачать
user-guide.md 29 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 28.02.2025 15:57 57a69e0

1. Введение

  • Проект предназначен для облачной нативной локальной системы хранения данных, которая позволяет монтировать локальные жесткие диски в контейнерах Kubernetes для чтения и записи.
  • Документ предназначен для ознакомления с процессом установки и использования проекта.

2. Установка проекта

2.1 Требования к установке
  • Кластер Kubernetes (версия CSI_VERSION=1.5.0)
  • Если kubelet запущен в контейнере, требуется смонтировать директорию /dev хоста на /dev.
  • Ядро Linux версии 3.10.0-1160.11.1.el7.x86_64 (тестирование проведено на этой версии, но более ранние версии также поддерживаются)
  • На каждом узле кластера должно быть от одного до N свободных блочных устройств, поддерживаются SSD и HDD (можно использовать команду lsblk --output NAME,ROTA, чтобы проверить тип устройства, где ROTA=1 указывает на HDD, а ROTA=0 — на SSD)
2.2 Выполнение установки
  • Для просмотра прогресса установки можно использовать команду kubectl get pods -n kube-system | grep carina.

    $ cd deploy/kubernetes
    $ ./deploy.sh
    
    $ kubectl get pods -n kube-system |grep carina
    carina-scheduler-6cc9cddb4b-jdt68         0/1     ContainerCreating   0          3s
    csi-carina-node-6bzfn                     0/2     ContainerCreating   0          6s
    csi-carina-node-flqtk                     0/2     ContainerCreating   0          6s
    csi-carina-provisioner-7df5d47dff-7246v   0/4     ContainerCreating   0          12s
  • Удаление проекта

    $ cd deploy/kubernetes
    $ ./deploy.sh uninstall
  • Примечания

    • Установка и удаление сервиса не влияют на уже примонтированные томы.

3. Описание проекта

3.1 Обзор проекта
  • Проект основан на Kubernetes и предназначен для приложений, требующих высокопроизводительных локальных хранилищ, таких как базы данных.
  • При старте служба автоматически группирует все доступные SSD и HDD устройства на узле в VG группы.
  • Поддерживается файловое и блочное хранение, включая форматы файловых систем XFS и EXT4.
  • Возможность онлайн-расширения для файлового и блочного хранения.
3.2 Подробное использование
  • Проект использует концепцию CSI Kubernetes для создания томов с помощью обычных StorageClass и PersistentVolumeClaims.

  • Ниже приведены примеры использования StorageClass и PersistentVolumeClaim.

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: csi-carina-sc
    provisioner: carina.storage.io # Это имя драйвера CSI, которое нельзя менять
    parameters:
      # Это внутренний параметр Kubernetes, мы поддерживаем два типа файловой системы: xfs и ext4
      csi.storage.k8s.io/fstype: xfs
      # Выбор группы дисков, проект автоматически группирует SSD и HDD устройства
      # SSD: ssd, HDD: hdd
      # Если не указано, выбирается случайным образом
      carina.storage.io/disk-group-name: hdd
    reclaimPolicy: Delete
    allowVolumeExpansion: true # Поддерживает расширение, значение true активирует эту возможность
    # WaitForFirstConsumer указывает на создание PV после того, как он будет связан с Pod'ом
    volumeBindingMode: WaitForFirstConsumer
    # Поддерживает настройку параметров монтирования, по умолчанию пустое значение
    # Если нет специфических требований, это значение удовлетворяет большинство случаев
    mountOptions:
      - rw
    • Примечание 1: параметр volumeBindingMode поддерживает значение Immediate, однако для локального хранения обычно используется значение WaitForFirstConsumer.
    • Примечание 2: параметр allowedTopologies поддерживается в StorageClass, но работает только при режиме volumeBindingMode: Immediate.
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: csi-carina-pvc
      namespace: carina
    spec:
      accessModes:
        - ReadWriteOnce # Локальное хранилище может быть примонтировано только одним Pod'ом на одном узле
      resources:
        requests:
          storage: 7Gi
      storageClassName: csi-carina-sc
      volumeMode: Filesystem # если значение равно Block, то создаётся блочный диск
  • Создание и использование bcached устройства. Чтобы создать bcached устройство, необходимо указать специальные параметры в StorageClass.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: csi-carina-sc
provisioner: carina.storage.io
parameters:
  # файловая система
  csi.storage.k8s.io/fstype: xfs
  # тип диска для основного хранилища
  carina.storage.io/backend-disk-group-name: hdd
  # тип диска для кэша
  carina.storage.io/cache-disk-group-name: ssd
  # коэффициент отношения размера кэша к размеру основного хранилища (от 1 до 100)
  carina.storage.io/cache-disk-ratio: "50"
  # три режима кэширования: writethrough, writeback, writearound
  carina.storage.io/cache-policy: writethrough
reclaimPolicy: Delete
allowVolumeExpansion: true
# WaitForFirstConsumer указывает на создание PV после того, как он будет связан с Pod'ом
volumeBindingMode: WaitForFirstConsumer
mountOptions:

Примечание 1: вышеуказанная конфигурация представляет собой использование HDD в качестве основного хранилища и SSD в качестве кэша с отношением размера кэша к размеру основного хранилища равным 50%. Например, если pvc.spec.resources.requests.storage = 10G, то будет создан том объемом 10 ГБ для HDD и том объемом 5 ГБ для SSD, который будет использоваться как кэш для HDD.

Примечание 2: существуют три режима кэширования: writethrough, writeback, writearound.

Примечание 3: из-за ограничений технологии bcached, когда PVC расширяется, требуется перезапуск Pod'а для применения изменений. Расширение обычного тома не требует перезапуска Pod'а.

Примечание 4: можно использовать команду echo 0 > /sys/block/loop0/queue/rotational для имитации SSD устройства loop0.

3.3 Тестирование проекта
  • Точки тестирования:

    • ① При запуске службы на каждом узле автоматически добавляются все доступные SSD и HDD устройства в VG группы.

    • ② Каждые 5 минут производится сканирование локальных дисков, новые найденные устройства добавляются в VG группы. Интервал сканирования настраивается минимумом в 5 минут.

    • ③ После запуска службы информация о емкости дисков сохраняется в node.status.capacity. Можно использовать следующую команду для её получения:

      $ kubectl get node 10.20.9.154 -o template --template={{.status.capacity}}
      map[carina.storage.io/carina-vg-hdd:160 carina.storage.io/carina-vg-ssd:0 cpu:2 ephemeral-storage:208655340Ki hugepages-1Gi:0 hugepages-2Mi:0 memory:3880376Ki pods:110]
      ``````markdown
      $ kubectl get node 10.20.9.154 -o template --template="{{.status.allocatable}}"
      map[carina.storage.io/carina-vg-hdd:150 carina.storage.io/carina-vg-ssd:0 cpu:2 ephemeral-storage:192296761026 hugepages-1Gi:0 hugepages-2Mi:0 memory:3777976Ki pods:110]
      
      • HDD диск: carina.storage.io/carina-vg-hdd:160, SSD диск: carina.storage.io/carina-vg-ssd:0, единицы измерения GiB.
      • capacity — общая емкость, allocatable — доступная для использования емкость, которую используют компоненты, такие как планировщик.
      • Разница между capacity и allocatable составляет 10 ГБ, что зарезервировано системой.
      • Когда новый PV успешно создан, node.status.allocatable обновляется, изменения могут иметь некоторый запаздывание.
    • ④ Конфигурационные файлы при запуске проекта

      $ kubectl get configmap carina-csi-config -n kube-system
      NAME                DATA   AGE
      carina-csi-config   1      116m
      • config.json
        config.json: |-
          {
            "diskSelector": ["loop*", "vd*"], # стратегия выбора дисков, поддерживает регулярные выражения
            "diskScanInterval": "300", # 300 секунд, интервал сканирования дисков, 0 — выключение локального сканирования
            "diskGroupPolicy": "type", # стратегия группировки дисков, поддерживает группировку по типу диска, изменение других значений недействительно
            "schedulerStrategy": "spreadout" # binpack, spreadout поддерживают эти параметры
          }
      
       # v0.9.1 конфигурация была изменена, подробная документация доступна [docs/design/design-diskGroup-zh.md]
       {
        "diskSelector": [
          {
            "name": "carina-vg-ssd",
            "re": ["loop2+"],
            "policy": "LVM",
            "nodeLabel": "kubernetes.io/hostname"
          },
          {
            "name": "carina-vg-hdd",
            "re": ["loop3+"],
            "policy": "LVM",
            "nodeLabel": "kubernetes.io/hostname"
          },
          {
            "name": "exist-vg-group",
            "re": ["loop4+"],
            "policy": "LVM",
            "nodeLabel": "kubernetes.io/hostname"
          },
          {
            "name": "new-vg-group",
            "re": ["loop5+"],
            "policy": "LVM",
            "nodeLabel": "kubernetes.io/hostname"
          },
          {
            "name": "raw",
            "re": ["vdb+", "sd+"],
            "policy": "RAW",
            "nodeLabel": "kubernetes.io/hostname"
          }
        ],
        "diskScanInterval": "300",
        "schedulerStrategy": "spreadout"
      }
      • Примечание 1: если диск A уже добавлен в VG группу, изменение diskSelector так, чтобы диск A больше не соответствовал этому шаблону, приведёт к тому, что этот диск будет удалён из VG группы, если он ещё не используется.
      • Примечание 2: параметр schedulerStrategy имеет значения binpack и spreadout. binpack выбирает узел, где объём диска точно соответствует запросу requests.storage, а spreadout выбирает узел с наибольшим остаточным объёмом.
      • Примечание 3: параметр schedulerStrategy в режиме storageclass volumeBindingMode: Immediate выбирается только на основе объёма диска, то есть при использовании spreadout стратегии PVC будет немедленно создан на узле с наибольшим остаточным объёмом.
      • Примечание 4: параметр schedulerStrategy в режиме storageclass volumeBindingMode: WaitForFirstConsumer зависит от планировщика Pod'ов, его влияние можно увидеть в логах планировщика kubectl logs -f carina-scheduler-6cc9cddb4b-jdt68 -n kube-system.
      • Примечание 5: если несколько узлов имеют объём диска, превышающий запрос на 10 раз, то они будут иметь одинаковый рейтинг для планировщика.
    • ⑤ После успешного запуска всех компонентов сервера, собирается информация о состоянии каждого узла и обновляется в configmap:carina-node-storage.

      $ kubectl get configmap carina-node-storage -n kube-system -o yaml
      data:
        node: '[{
      	"allocatable.carina.storage.io/carina-vg-hdd": "150",
      	"allocatable.carina.storage.io/carina-vg-ssd": "0",
      	"capacity.carina.storage.io/carina-vg-hdd": "160",
      	"capacity.carina.storage.io/carina-vg-ssd": "0",
      	"nodeName": "10.20.9.154"
      }, {
      	"allocatable.carina.storage.io/carina-vg-hdd": "146",
      	"allocatable.carina.storage.io/carina-vg-ssd": "0",
      	"capacity.carina.storage.io/carina-vg-hdd": "170",
      	"capacity.carina.storage.io/carina-vg-ssd": "0",
      	"nodeName": "10.20.9.153"
      }]'
      
      ```- Примечание 1: Этот configmap используется другими службами для получения информации о группах разделов и использовании места на каждом узле. В настоящее время собираются данные из `node.status.capacity` и `node.status.allocatable`.
  • Примечание 2: После создания одного PV этот configmap будет обновлен через 30-60 секунд. Это сделано для совместимости с массовым созданием PV, чтобы избежать повторного обновления configmap, а также для того, чтобы избежать ненужных обновлений configmap в случае, если состояние узла не было обновлено своевременно.

  • Примечание 3: Этот configmap автоматически поддерживается и обновляется драйвером, поэтому пользователям следует только читать его, но не изменять.

    • ⑥ Информация о том, как использовать topo (topologyKey: topology.carina.storage.io/node) см. пример examples/kubernetes/topostatefulset.yaml.
  • Выполнение тестов

    • Можно выполнить скрипт тестирования для базовой проверки функциональности.

      $ cd examples/kubernetes
      $ ./test.sh help
      -------------------------------
      ./test.sh           ===> установка всех тестовых YAML
      ./test.sh uninstall ===> удаление всех тестовых YAML
      ./test.sh expand    ===> расширение всех PVC
      ./test.sh scale     ===> масштабирование реплик StatefulSet
      ./test.sh delete    ===> удаление всех Pod
      ./test.sh exec      ===> отображение файловой системы Pod
  • Подробности тестирования

    • В этом проекте есть CRD-ресурс, который можно просмотреть командой kubectl get lv.

      $ kubectl get lv
      NAME                                       SIZE   ГРУППА           УЗЕЛ          СТАТУС
      pvc-319c5deb-f637-423b-8b52-42ecfcf0d3b7   7Gi    carina-vg-hdd   10.20.9.154   Успешно
      pvc-5b3703d8-f262-48e3-818f-dfbc35c67d90   3Gi    carina-vg-hdd   10.20.9.154   Успешно
      • Этот ресурс соответствует каждому PVC/PV, что позволяет быстро проверить, был ли создан volume успешно. Здесь статус "Успешно" указывает на то, что LVM-объем уже создан.
    • Просмотр созданных LVM-объемов

      $  kubectl exec -it csi-carina-node-cmgmm -c csi-carina-node -n kube-system bash
      $ pvs
        PV         VG            Fmt  Attr PSize   PFree  
        /dev/vdc   carina-vg-hdd lvm2 a--  <80.00г <79.95г
        /dev/vdd   carina-vg-hdd lvm2 a--  <80.00г  41.98г
      $ vgs
        VG            #PV #LV #SN Attr   VSize   VFree   
        carina-vg-hdd   2  10   0 wz--n- 159.99г <121.93г
      $ lvs
        LV                                              VG            Attr       LSize  Pool                                          Origin Data%  Meta%  Move Log Cpy%Sync Convert
        thin-pvc-319c5deb-f637-423b-8b52-42ecfcf0d3b7   carina-vg-hdd twi-aotz--  7.00г                                                      0.15   10.79                                                     
        volume-pvc-319c5deb-f637-423b-8b52-42ecfcf0d3b7 carina-vg-hdd Vwi-aotz--  7.00г thin-pvc-319c5deb-f637-423b-8b52-42ecfcf0d3b7        0.15                          
      • Особое примечание: Если на узле кластера установлен сервис lvm2, то при выполнении команды lvs, вы можете видеть различие между объемами внутри контейнера и на узле. Это связано с кэшированием lvm на узле, которое можно обновить командой lvscan.
      • Каждый PV соответствует одному thin pool и LVM-объему, название которого состоит из volume- и имени PV.
Расширенные возможности
  • Ограничение скорости чтения/записи дисков

    • Поддерживает ограничение скорости для устройств, добавив следующие аннотации в метаданные Pod (см. пример examples/kubernetes/deploymentspeedlimit.yaml).

          metadata:
            annotations:
              carina.storage.io/blkio.throttle.read_bps_device: "10485760"
              carina.storage.io/blkio.throttle.read_iops_device: "10000"
              carina.storage.io/blkio.throttle.write_bps_device: "10485760"
              carina.storage.io/blkio.throttle.write_iops_device: "100000"
       ---
       # Эти аннотации будут применены к следующим файлам
       /sys/fs/cgroup/blkio/blkio.throttle.read_bps_device
       /sys/fs/cgroup/blkio/blkio.throttle.read_iops_device
       /sys/fs/cgroup/blkio/blkio.throttle.write_bps_device
       /sys/fs/cgroup/blkio/blkio.throttle.write_iops_device
      • Примечание 1: Поддерживает установку одного или нескольких аннотаций, изменения которых будут применены к cgroups в течение одной минуты.
      • Примечание 2: Поддерживает ограничение скорости только для прямого доступа к блочным устройствам, тестовым командом dd if=/dev/zero of=out.file bs=1M count=512 oflag=dsync.
      • Примечание 3: Используется cgroup v1, из-за недостатков cgroup v1 невозможно ограничивать скорость буферизации IO, многие компоненты пока используют cgroup v1 вместо cgroup v2.
      • Примечание 4: Известно, что в kernel версии 3.10 возможно ограничение скорости прямого доступа к дискам, однако в kernel версии 4.18 это невозможно.
  • Удаление сиротских объемов

    • Каждые десять минут происходит проход по локальным объемам, затем проверяется наличие соответствующего logicvolume в k8s. Если он отсутствует, локальный объем удаляется.

    • Каждые десять минут происходит проход по logicvolume в k8s, затем проверяется наличие соответствующего PV. Если он отсутствует, logicvolume удаляется.

    • При удалении узла все объемы на нем будут восстановлены на других узлах.

      # Пример
      $ kubectl get lv
      NAME                                       SIZE   ГРУППА           УЗЕЛ          СТАТУС
      pvc-177854eb-f811-4612-92c5-b8bb98126b94   5Gi    carina-vg-hdd   10.20.9.154   Успешно
      pvc-1fed3234-ff89-4c58-8c65-e21ca338b099   5Gi    carina-vg-hdd   10.20.9.153   Успешно
      pvc-527b5989-3ac3-4d7a-a64d-24e0f665788b   10Gi   carina-vg-hdd   10.20.9.154   Успешно
      pvc-b987d27b-39f3-4e74-9465-91b3e6b13837   3Gi    carina-vg-hdd   10.20.9.154   Успешно
      
      $ kubectl delete node 10.20.9.154
      # Объемы будут восстановлены, что приведет к потере данных.
      $ kubectl get lv
      NAME                                       SIZE   ГРУППА           УЗЕЛ          СТАТУС
      pvc-177854eb-f811-4612-92c5-b8bb98126b94   5Gi    carina-vg-hdd   10.20.9.153   Успешно
      pvc-1fed3234-ff89-4c58-8c65-e21ca338b099   5Gi    carina-vg-hdd   10.20.9.153   Успешно
      pvc-527b5989-3ac3-4d7a-a64d-24e0f665788b   10Gi   carina-vg-hdd   10.20.9.153   Успешно
      pvc-b987d27b-39f3-4e74-9465-91b3e6b13837   3Gi    carina-vg-hdd   10.20.9.153   Успешно
  • Мониторинг метрик

    • Carina-node разворачивается в режиме host сети и слушает порт 8080, где 8080 являются метриками, которые могут быть изменены следующими конфигурациями:

              - "--metrics-addr=:8080"

      Примечание: Если меняете порт прослушивания, обязательно измените сервис: csi-carina-node.

    • Carina-controller слушает 8080 8443, где 8080 являются метриками, а 8443 — webhook, которые могут быть изменены следующими конфигурациями:

              - "--metrics-addr=:8080"
              - "--webhook-addr=:8443"
    • Для Carina-node и Carina-controller можно настроить свои метрики:

      	# свободное место в VG: carina-devicegroup-vg_free_bytes
      	# общее место в VG: carina-devicegroup-vg_total_bytes
      	# размер volume: carina-volume-volume_total_bytes
      	# используемое место в volume: carina-volume-volume_used_bytes
      • Примечание 1: использование volume может отличаться от статистики df -h, погрешность составляет несколько десятков мегабайт.
      • Примечание 2: Carina-controller фактически собирает данные со всех Carina-node, поэтому достаточно получить метрики через Carina-controller.
      • Примечание 3: Чтобы использовать Prometheus для сбора метрик, можно развернуть servicemonitor (deployment/kubernetes/prometheus.yaml.tmpl)

4. Часто задаваемые вопросы

  • ① Какие компоненты включены в этот проект? Какова роль каждого из них?

    • Всего три компонента: carina-scheduler, carina-controller, carina-node.

    • Carina-scheduler: пользовательский планировщик, который выполняет планирование для Pod, связанных с этим драйвером.

    • Carina-controller: отслеживает создание PVC и создает CRD (logicvolume) после успешной распределения PV на узел.

    • Carina-node: управляет локальными узлами и слушает CRD (logicvolume), управляя локальными LVM-объемами.

    • Просмотр логов каждого сервиса позволит получить подробную информацию о работе сервиса.

  • ② Есть известные проблемы: в случае очень плохих производительностей кластера или диска, может возникнуть проблема с созданием PV.

    • Запросы к LVM-объемам могут длиться до минуты, и они повторяются каждые десять секунд. Если запрос не удается несколько раз, он считается неудачным.
    • Можно наблюдать ошибочные ответы с помощью команды kubectl get lv.
  • ③ Может ли Pod перемещаться после успешного создания PV?

    • После успешного создания PV, Pod может работать только на этом узле, вне зависимости от того, был ли он удален или перезапущен.
    • Поддержка перемещения PV не предусмотрена.
  • ④ Как сделать так, чтобы Pod и PVC запускались на определенном узле?

    • Указывайте имя узла в spec.nodeName Pod, чтобы пропустить планировщика.
    • Для StorageClass с политикой WaitForFirstConsumer, можно указать узел в аннотациях PVC: volume.kubernetes.io/selected-node: nodeName.
    • Изменение PVC рекомендуется только при полном понимании применения этой стратегии.
  • ⑤ Что делать, если узел кластера удаляется вместе с запланированными на него PV?

    • Если объем больше не используется, можно просто удалить PVC и заново создать его.
  • ⑥ Как создать диск для удобства тестирования?

    • Можно создать loop device следующим образом:
    for i in $(seq 1 10); do
      truncate --size=200G /tmp/disk$i.device && \
      losetup -f /tmp/disk$i.device
    done

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/bocloud-open-source-carina.git
git@api.gitlife.ru:oschina-mirror/bocloud-open-source-carina.git
oschina-mirror
bocloud-open-source-carina
bocloud-open-source-carina
main