/dev
хоста на /dev
.lsblk --output NAME,ROTA
, чтобы проверить тип устройства, где ROTA=1 указывает на HDD, а ROTA=0 — на SSD)Для просмотра прогресса установки можно использовать команду 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
Примечания
Проект использует концепцию 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
volumeBindingMode
поддерживает значение Immediate
, однако для локального хранения обычно используется значение WaitForFirstConsumer
.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.
Точки тестирования:
① При запуске службы на каждом узле автоматически добавляются все доступные 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]
carina.storage.io/carina-vg-hdd:160
, SSD диск: carina.storage.io/carina-vg-ssd:0
, единицы измерения GiB.capacity
— общая емкость, allocatable
— доступная для использования емкость, которую используют компоненты, такие как планировщик.capacity
и allocatable
составляет 10 ГБ, что зарезервировано системой.node.status.allocatable
обновляется, изменения могут иметь некоторый запаздывание.④ Конфигурационные файлы при запуске проекта
$ kubectl get configmap carina-csi-config -n kube-system
NAME DATA AGE
carina-csi-config 1 116m
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"
}
diskSelector
так, чтобы диск A больше не соответствовал этому шаблону, приведёт к тому, что этот диск будет удалён из VG группы, если он ещё не используется.schedulerStrategy
имеет значения binpack
и spreadout
. binpack
выбирает узел, где объём диска точно соответствует запросу requests.storage
, а spreadout
выбирает узел с наибольшим остаточным объёмом.schedulerStrategy
в режиме storageclass volumeBindingMode: Immediate
выбирается только на основе объёма диска, то есть при использовании spreadout
стратегии PVC будет немедленно создан на узле с наибольшим остаточным объёмом.schedulerStrategy
в режиме storageclass volumeBindingMode: WaitForFirstConsumer
зависит от планировщика Pod'ов, его влияние можно увидеть в логах планировщика kubectl logs -f carina-scheduler-6cc9cddb4b-jdt68 -n kube-system
.⑤ После успешного запуска всех компонентов сервера, собирается информация о состоянии каждого узла и обновляется в 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 автоматически поддерживается и обновляется драйвером, поэтому пользователям следует только читать его, но не изменять.
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 Успешно
Просмотр созданных 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
lvs
, вы можете видеть различие между объемами внутри контейнера и на узле. Это связано с кэшированием lvm на узле, которое можно обновить командой lvscan
.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
dd if=/dev/zero of=out.file bs=1M count=512 oflag=dsync
.Удаление сиротских объемов
Каждые десять минут происходит проход по локальным объемам, затем проверяется наличие соответствующего 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
df -h
, погрешность составляет несколько десятков мегабайт.① Какие компоненты включены в этот проект? Какова роль каждого из них?
Всего три компонента: carina-scheduler, carina-controller, carina-node.
Carina-scheduler: пользовательский планировщик, который выполняет планирование для Pod, связанных с этим драйвером.
Carina-controller: отслеживает создание PVC и создает CRD (logicvolume) после успешной распределения PV на узел.
Carina-node: управляет локальными узлами и слушает CRD (logicvolume), управляя локальными LVM-объемами.
Просмотр логов каждого сервиса позволит получить подробную информацию о работе сервиса.
② Есть известные проблемы: в случае очень плохих производительностей кластера или диска, может возникнуть проблема с созданием PV.
kubectl get lv
.③ Может ли Pod перемещаться после успешного создания PV?
④ Как сделать так, чтобы Pod и PVC запускались на определенном узле?
spec.nodeName
Pod, чтобы пропустить планировщика.WaitForFirstConsumer
, можно указать узел в аннотациях PVC: volume.kubernetes.io/selected-node: nodeName
.⑤ Что делать, если узел кластера удаляется вместе с запланированными на него PV?
⑥ Как создать диск для удобства тестирования?
loop device
следующим образом:for i in $(seq 1 10); do
truncate --size=200G /tmp/disk$i.device && \
losetup -f /tmp/disk$i.device
done
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )