Container Storage Interface (CSI) é uma interface unificada entre Kubernetes e sistemas de armazenamento. Já falamos sobre isso brevemente
O artigo fornece exemplos reais, embora um pouco simplificados, para facilitar a percepção. Não consideramos instalar e configurar clusters Ceph e Kubernetes.
Você está se perguntando como isso funciona?
Então você tem um cluster Kubernetes ao seu alcance, implantado, por exemplo,
Se você tem tudo isso, vamos lá!
Primeiro, vamos até um dos nós do cluster Ceph e verificamos se está tudo em ordem:
ceph health
ceph -s
A seguir, criaremos imediatamente um pool para discos RBD:
ceph osd pool create kube 32
ceph osd pool application enable kube rbd
Vamos passar para o cluster Kubernetes. Lá, em primeiro lugar, instalaremos o driver Ceph CSI para RBD. Instalaremos, conforme esperado, através do Helm.
Adicionamos um repositório com um gráfico, obtemos um conjunto de variáveis para o gráfico ceph-csi-rbd:
helm repo add ceph-csi https://ceph.github.io/csi-charts
helm inspect values ceph-csi/ceph-csi-rbd > cephrbd.yml
Agora você precisa preencher o arquivo cephrbd.yml. Para fazer isso, descubra o ID do cluster e os endereços IP dos monitores no Ceph:
ceph fsid # так мы узнаем clusterID
ceph mon dump # а так увидим IP-адреса мониторов
Inserimos os valores obtidos no arquivo cephrbd.yml. Ao mesmo tempo, possibilitamos a criação de políticas PSP (Pod Security Policies). Opções em seções plug-in de nó и provedor já no arquivo, eles podem ser corrigidos conforme mostrado abaixo:
csiConfig:
- clusterID: "bcd0d202-fba8-4352-b25d-75c89258d5ab"
monitors:
- "v2:172.18.8.5:3300/0,v1:172.18.8.5:6789/0"
- "v2:172.18.8.6:3300/0,v1:172.18.8.6:6789/0"
- "v2:172.18.8.7:3300/0,v1:172.18.8.7:6789/0"
nodeplugin:
podSecurityPolicy:
enabled: true
provisioner:
podSecurityPolicy:
enabled: true
A seguir, só nos resta instalar o gráfico no cluster Kubernetes.
helm upgrade -i ceph-csi-rbd ceph-csi/ceph-csi-rbd -f cephrbd.yml -n ceph-csi-rbd --create-namespace
Ótimo, o driver RBD funciona!
Vamos criar um novo StorageClass no Kubernetes. Novamente, isso requer alguns ajustes no Ceph.
Criamos um novo usuário no Ceph e damos a ele direitos para gravar no pool Kube:
ceph auth get-or-create client.rbdkube mon 'profile rbd' osd 'profile rbd pool=kube'
Agora vamos ver se a chave de acesso ainda está lá:
ceph auth get-key client.rbdkube
O comando produzirá algo assim:
AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==
Vamos adicionar esse valor ao Secret no cluster Kubernetes – onde precisarmos dele chave do usuário:
---
apiVersion: v1
kind: Secret
metadata:
name: csi-rbd-secret
namespace: ceph-csi-rbd
stringData:
# Значения ключей соответствуют имени пользователя и его ключу, как указано в
# кластере Ceph. ID юзера должен иметь доступ к пулу,
# указанному в storage class
userID: rbdkube
userKey: <user-key>
E criamos nosso segredo:
kubectl apply -f secret.yaml
A seguir, precisamos de um manifesto StorageClass mais ou menos assim:
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
clusterID: <cluster-id>
pool: kube
imageFeatures: layering
# Эти секреты должны содержать данные для авторизации
# в ваш пул.
csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-rbd
csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-rbd
csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-rbd
csi.storage.k8s.io/fstype: ext4
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- discard
Precisa ser preenchido ID do cluster, o que já aprendemos pela equipe ceph-fside aplique este manifesto ao cluster Kubernetes:
kubectl apply -f storageclass.yaml
Para verificar como os clusters funcionam juntos, vamos criar o seguinte PVC (Persistent Volume Claim):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-rbd-sc
Vamos ver imediatamente como o Kubernetes criou o volume solicitado no Ceph:
kubectl get pvc
kubectl get pv
Tudo parece estar ótimo! Como é isso no lado do Ceph?
Obtemos uma lista de volumes no pool e visualizamos informações sobre nosso volume:
rbd ls -p kube
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653 # тут, конечно же, будет другой ID тома, который выдала предыдущая команда
Agora vamos ver como funciona o redimensionamento de um volume RBD.
Altere o tamanho do volume no manifesto pvc.yaml para 2Gi e aplique-o:
kubectl apply -f pvc.yaml
Vamos esperar que as alterações tenham efeito e observar novamente o tamanho do volume.
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653
kubectl get pv
kubectl get pvc
Vemos que o tamanho do PVC não mudou. Para descobrir o porquê, você pode consultar o Kubernetes para obter uma descrição YAML do PVC:
kubectl get pvc rbd-pvc -o yaml
Aqui está o problema:
mensagem: Aguardando que o usuário (re) inicie um pod para concluir o redimensionamento do volume do sistema de arquivos no nó. tipo: FileSystemResizePending
Ou seja, o disco cresceu, mas o sistema de arquivos nele não.
Para aumentar o sistema de arquivos, você precisa montar o volume. Em nosso país, o PVC/PV criado atualmente não é utilizado de forma alguma.
Podemos criar um pod de teste, por exemplo assim:
---
apiVersion: v1
kind: Pod
metadata:
name: csi-rbd-demo-pod
spec:
containers:
- name: web-server
image: nginx:1.17.6
volumeMounts:
- name: mypvc
mountPath: /data
volumes:
- name: mypvc
persistentVolumeClaim:
claimName: rbd-pvc
readOnly: false
E agora vamos dar uma olhada no PVC:
kubectl get pvc
O tamanho mudou, está tudo bem.
Na primeira parte trabalhamos com o dispositivo de bloco RBD (significa Rados Block Device), mas isso não pode ser feito se diferentes microsserviços precisarem trabalhar com este disco simultaneamente. CephFS é muito mais adequado para trabalhar com arquivos do que com imagens de disco.
Usando o exemplo dos clusters Ceph e Kubernetes, configuraremos o CSI e outras entidades necessárias para trabalhar com o CephFS.
Vamos obter os valores do novo gráfico Helm que precisamos:
helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.yml
Novamente você precisa preencher o arquivo cephfs.yml. Como antes, os comandos do Ceph ajudarão:
ceph fsid
ceph mon dump
Preencha o arquivo com valores como este:
csiConfig:
- clusterID: "bcd0d202-fba8-4352-b25d-75c89258d5ab"
monitors:
- "172.18.8.5:6789"
- "172.18.8.6:6789"
- "172.18.8.7:6789"
nodeplugin:
httpMetrics:
enabled: true
containerPort: 8091
podSecurityPolicy:
enabled: true
provisioner:
replicaCount: 1
podSecurityPolicy:
enabled: true
Observe que os endereços dos monitores são especificados no formato simples endereço:porta. Para montar cephfs em um nó, esses endereços são transferidos para o módulo do kernel, que ainda não sabe trabalhar com o protocolo monitor v2.
Alteramos a porta para httpMetrics (o Prometheus irá lá para monitorar métricas) para que não entre em conflito com o nginx-proxy, que é instalado pelo Kubespray. Você pode não precisar disso.
Instale o gráfico Helm no cluster Kubernetes:
helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml -n ceph-csi-cephfs --create-namespace
Vamos ao armazenamento de dados do Ceph para criar um usuário separado. A documentação afirma que o provisionador CephFS requer direitos de acesso de administrador de cluster. Mas criaremos um usuário separado fs com direitos limitados:
ceph auth get-or-create client.fs mon 'allow r' mgr 'allow rw' mds 'allow rws' osd 'allow rw pool=cephfs_data, allow rw pool=cephfs_metadata'
E vamos dar uma olhada imediata em sua chave de acesso, precisaremos dela mais tarde:
ceph auth get-key client.fs
Vamos criar Secret e StorageClass separados.
Nada de novo, já vimos isso no exemplo do RBD:
---
apiVersion: v1
kind: Secret
metadata:
name: csi-cephfs-secret
namespace: ceph-csi-cephfs
stringData:
# Необходимо для динамически создаваемых томов
adminID: fs
adminKey: <вывод предыдущей команды>
Aplicando o manifesto:
kubectl apply -f secret.yaml
E agora - um StorageClass separado:
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
clusterID: <cluster-id>
# Имя файловой системы CephFS, в которой будет создан том
fsName: cephfs
# (необязательно) Пул Ceph, в котором будут храниться данные тома
# pool: cephfs_data
# (необязательно) Разделенные запятыми опции монтирования для Ceph-fuse
# например:
# fuseMountOptions: debug
# (необязательно) Разделенные запятыми опции монтирования CephFS для ядра
# См. man mount.ceph чтобы узнать список этих опций. Например:
# kernelMountOptions: readdir_max_bytes=1048576,norbytes
# Секреты должны содержать доступы для админа и/или юзера Ceph.
csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret
csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-cephfs
csi.storage.k8s.io/controller-expand-secret-name: csi-cephfs-secret
csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-cephfs
csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret
csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-cephfs
# (необязательно) Драйвер может использовать либо ceph-fuse (fuse),
# либо ceph kernelclient (kernel).
# Если не указано, будет использоваться монтирование томов по умолчанию,
# это определяется поиском ceph-fuse и mount.ceph
# mounter: kernel
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- debug
Vamos preencher aqui ID do cluster e aplicável no Kubernetes:
kubectl apply -f storageclass.yaml
Проверка
Para verificar, como no exemplo anterior, vamos criar um PVC:
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: csi-cephfs-sc
E verifique a presença de PVC/PV:
kubectl get pvc
kubectl get pv
Se quiser ver arquivos e diretórios no CephFS, você pode montar esse sistema de arquivos em algum lugar. Por exemplo, conforme mostrado abaixo.
Vamos para um dos nós do cluster Ceph e realizar as seguintes ações:
# Точка монтирования
mkdir -p /mnt/cephfs
# Создаём файл с ключом администратора
ceph auth get-key client.admin >/etc/ceph/secret.key
# Добавляем запись в /etc/fstab
# !! Изменяем ip адрес на адрес нашего узла
echo "172.18.8.6:6789:/ /mnt/cephfs ceph name=admin,secretfile=/etc/ceph/secret.key,noatime,_netdev 0 2" >> /etc/fstab
mount /mnt/cephfs
Obviamente, montar o FS em um nó Ceph como esse só é adequado para fins de treinamento, que é o que fazemos em nosso
E por fim, vamos verificar como funciona o redimensionamento de volumes no caso do CephFS. Vamos voltar ao Kubernetes e editar nosso manifesto para PVC - aumente o tamanho lá, por exemplo, para 7Gi.
Vamos aplicar o arquivo editado:
kubectl apply -f pvc.yaml
Vejamos o diretório montado para ver como a cota mudou:
getfattr -n ceph.quota.max_bytes <каталог-с-данными>
Para que este comando funcione, pode ser necessário instalar o pacote em seu sistema atr.
Os olhos estão com medo e as mãos estão fazendo
Todos esses feitiços e longos manifestos YAML parecem complicados superficialmente, mas na prática, os alunos do Slurm pegam o jeito rapidamente.
Neste artigo não nos aprofundamos na selva - existe documentação oficial para isso. Se você estiver interessado nos detalhes de configuração do armazenamento Ceph com um cluster Kubernetes, estes links o ajudarão:
No curso Slurm
E se você estiver mais interessado em armazenamento de dados, inscreva-se no
Autor do artigo: Alexander Shvalov, engenheiro praticante
Fonte: habr.com