Provisionamento de volume dinâmico Kubernetes e OpenShift com GlusterFS e Heketi
Bem-vindo ao nosso guia sobre como configurar o provisionamento dinâmico de volumes persistentes usando GlusterFS e Heketi para seus clusters Kubernetes/OpenShift. GlusterFS é um sistema de arquivos de rede escalonável, gratuito e de código aberto, adequado para tarefas com uso intensivo de dados, como armazenamento em nuvem e streaming de mídia. Ele utiliza hardware comum disponível no mercado. Na minha configuração, optei por implantar o GlusterFS como um serviço hiperconvergente nos nós do Kubernetes. Isso desbloqueará o poder dos volumes GlusterFS persistentesprovisionados dinamicamente no Kubernetes.
Usaremos o projeto gluster-kubernetes, que fornece aos administradores do Kubernetes um mecanismo para implantar facilmente o GlusterFS como um serviço de armazenamento nativo em um cluster Kubernetes existente. Aqui, o GlusterFS é gerenciado e orquestrado como qualquer outro aplicativo no Kubernetes. heketi é uma interface de gerenciamento de volume RESTful para GlusterFS. Ele permite criar e gerenciar volumes Gluster usando API.
Requisitos de infraestrutura
Abaixo estão os requisitos básicos para a configuração.
- Deve haver pelo menos três nós
- Cada nó deve ter pelo menos um dispositivo de bloco bruto conectado para uso pelo heketi
- Cada nó deve ter as seguintes portas abertas para comunicações GlusterFS: 2222 para sshd do pod GlusterFS, 24007 para GlusterFS Daemon, 24008 para gerenciamento GlusterFS, 24008 para gerenciamento GlusterFS, 24007 para GlusterFS Daemon, 24008 para gerenciamento GlusterFS.49152 a 49251 para cada tijolo criado no host.
- Os seguintes módulos do kernel devem ser carregados:
- dm_snapshot
- dm_mirror
- dm_thin_pool
- Cada nó requer que o comando
mount.glusterfs
esteja disponível. - A versão do cliente GlusterFS instalada nos nós deve ser o mais próxima possível da versão do servidor.
Etapa 1: configurar cluster Kubernetes/OpenShift
Esta configuração pressupõe que você tenha um cluster Kubernetes/OpenShift(OKD) em execução. Consulte nossos guias sobre como criar rapidamente um cluster para uso em teste/produção.
- Implantar cluster Kubernetes no Rocky/AlmaLinux 8
- Implantar cluster Kubernetes no Ubuntu 22.04
- Implante cluster Kubernetes pronto para produção com Ansible e Kubespray
- Configure o cluster Kubernetes no Ubuntu 18.04
Etapa 2: Instale o glusterfs e configure o firewall
Se você estiver usando uma distribuição Linux baseada em Red Hat, instale o pacote glusterfs-fuse que fornece o comando mount.glusterfs .
sudo yum -y install glusterfs-fuse
Para Ubuntu/Debian:
sudo apt install glusterfs-client
Carregue todos os módulos do kernel necessários
for i in dm_snapshot dm_mirror dm_thin_pool; do sudo modprobe $i; done
Verifique se os módulos estão carregados.
$ sudo lsmod | egrep 'dm_snapshot|dm_mirror|dm_thin_pool'
dm_thin_pool 66358 0
dm_persistent_data 75269 1 dm_thin_pool
dm_bio_prison 18209 1 dm_thin_pool
dm_mirror 22289 0
dm_region_hash 20813 1 dm_mirror
dm_log 18411 2 dm_region_hash,dm_mirror
dm_snapshot 39103 0
dm_bufio 28014 2 dm_persistent_data,dm_snapshot
dm_mod 124461 5 dm_log,dm_mirror,dm_bufio,dm_thin_pool,dm_snapshot
Verifique a versão instalada.
$ glusterfs --version
glusterfs 3.12.2
Abra também as portas necessárias no Firewall – CentOS/RHEL/Fedora
for i in 2222 24007 24008 49152-49251; do
sudo firewall-cmd --add-port=${i}/tcp --permanent
done
sudo firewall-cmd --reload
Etapa 3: verificar o status do cluster Kubernetes
Verifique a instalação do Kubernetes certificando-se de que todos os nós do cluster estejam prontos:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master01 Ready master 146m v1.26.5
worker01 Ready <none> 146m v1.26.5
worker02 Ready <none> 146m v1.26.5
worker03 Ready <none> 146m v1.26.5
Para visualizar a versão exata do Kubernetes em execução, use:
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"24", GitVersion:"v1.24.1", GitCommit:"fcf512e2763f3b98bcc8e3fb087cd8cb80f8ca83", GitTreeState:"clean", BuildDate:"2022-08-15T05:48:10Z", GoVersion:"go1.18.4", Compiler:"gc", Platform:"darwin/amd64"}
Kustomize Version: v4.5.4
Server Version: version.Info{Major:"1", Minor:"26", GitVersion:"v1.26.5", GitCommit:"890a139214b4de1f01543d15003b5bda71aae9c7", GitTreeState:"clean", BuildDate:"2023-05-17T14:08:49Z", GoVersion:"go1.19.9", Compiler:"gc", Platform:"linux/amd64"}
Etapa 4: adicione discos brutos secundários aos seus nós
Cada nó deve ter pelo menos um dispositivo de bloco bruto anexado para uso pelo heketi. Adicionei 2 discos virtuais de 50 GB cada aos meus nós k8s.
[worker01 ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 20G 0 disk
└─vda1 253:1 0 20G 0 part /
vdc 253:32 0 50G 0 disk
vdd 253:48 0 50G 0 disk
[worker02 ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 20G 0 disk
└─vda1 253:1 0 20G 0 part /
vdc 253:32 0 50G 0 disk
vdd 253:48 0 50G 0 disk
[worker03 ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 20G 0 disk
└─vda1 253:1 0 20G 0 part /
vdc 253:32 0 50G 0 disk
vdd 253:48 0 50G 0 disk
Etapa 5: Crie um arquivo de topologia
Você deve fornecer as informações de topologia do cluster GlusterFS que descrevem os nós presentes no cluster GlusterFS e os dispositivos de bloco anexados a eles para uso pelo heketi.
Como estou executando todas as operações no nó mestre do Kubernetes, vamos extrair gluster-kubernetes do Github.
sudo yum -y install git vim
git clone https://github.com/gluster/gluster-kubernetes.git
Copie e edite o modelo de informações de topologia.
cd gluster-kubernetes/deploy/
cp topology.json.sample topology.json
Isso é o que tenho na minha configuração.
{
"clusters": [
{
"nodes": [
{
"node": {
"hostnames": {
"manage": [
"worker01"
],
"storage": [
"10.10.1.193"
]
},
"zone": 1
},
"devices": [
"/dev/vdc",
"/dev/vdd"
]
},
{
"node": {
"hostnames": {
"manage": [
"worker02"
],
"storage": [
"10.10.1.167"
]
},
"zone": 1
},
"devices": [
"/dev/vdc",
"/dev/vdd"
]
},
{
"node": {
"hostnames": {
"manage": [
"worker03"
],
"storage": [
"10.10.1.178"
]
},
"zone": 1
},
"devices": [
"/dev/vdc",
"/dev/vdd"
]
}
]
}
]
}
Quando
- Certifique-se de que o arquivo de topologia liste apenas os dispositivos de bloco destinados ao uso do heketi. heketi precisa de acesso a dispositivos de bloco inteiro (por exemplo, /dev/vdc, /dev/vdd) que ele irá particionar e formatar.
- O array
hostnames
é um pouco enganador.manage
deve ser uma lista de nomes de host para o nó, masstorage
deve ser uma lista de endereços IP no nó para comunicações de armazenamento backend.
Etapa 6: execute o script de implantação
Com o arquivo de topologia criado, você está pronto para executar o script gk-deploy em uma máquina com acesso administrativo ao seu cluster Kubernetes. Se não estiver executando no nó mestre, copie o arquivo de configuração do Kubernetes para ~/.kube/config.
Familiarize-se com as opções disponíveis.
./gk-deploy -h
Opções comuns:
-g, --deploy-gluster: Deploy GlusterFS pods on the nodes in the topology that contain brick devices
--ssh-user USER: User to use for SSH commands to GlusterFS nodes. Non-root users must have sudo permissions on the nodes. Default is 'root'
--user-key USER_KEY: Secret string for general heketi users. This is a required argument.
-l LOG_FILE, --log-file LOG_FILE: Save all output to the specified file.
-v, --verbose: Verbose output
Execute o comando abaixo para iniciar a implantação do GlusterFS/Heketi substituindo MyUserStrongKey e MyAdminStrongKey pelos seus valores-chave.
./gk-deploy -g \
--user-key MyUserStrongKey \
--admin-key MyAdminStrongKey \
-l /tmp/heketi_deployment.log \
-v topology.json
Pressione a tecla Y para aceitar a instalação.
Do you wish to proceed with deployment?
[Y]es, [N]o? [Default: Y]: Y
Se a implantação for bem-sucedida, você deverá receber uma mensagem:
heketi is now running and accessible via http://10.233.108.5:8080
Veja a captura de tela abaixo.
Pods, serviços e endpoints serão criados automaticamente após a implantação bem-sucedida. O GlusterFS e o heketi agora devem estar instalados e prontos para uso.
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
heketi 1/1 1 1 75m
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
glusterfs-44jvh 1/1 Running 0 110m
glusterfs-j56df 1/1 Running 0 110m
glusterfs-lttb5 1/1 Running 0 110m
heketi-b4b94d59d-bqmpz 1/1 Running 0 76m
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
heketi ClusterIP 10.233.42.58 <none> 8080/TCP 76m
heketi-storage-endpoints ClusterIP 10.233.41.189 <none> 1/TCP 76m
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 127m
$ kubectl get endpoints
NAME ENDPOINTS AGE
heketi 10.233.108.5:8080 76m
heketi-storage-endpoints 10.10.1.167:1,10.10.1.178:1,10.10.1.193:1 77m
kubernetes 10.10.1.119:6443 127m
Etapa 7: Instale o heketi-cli para interagir com o GlusterFS
O heketi-cli é usado para interagir com GlusterFS implantado no cluster Kubernetes. Baixe a versão mais recente e coloque o binário em seu PATH.
wget https://github.com/heketi/heketi/releases/download/v10.4.0/heketi-client-v10.4.0-release-10.linux.amd64.tar.gz
Extraia os arquivos baixados – Isso terá cliente e servidor.
for i in `ls | grep heketi | grep .tar.gz`; do tar xvf $i; done
Copie heketi-cli para o diretório /usr/local/bin.
sudo cp ./heketi-client/bin/heketi-cli /usr/local/bin
Você deve conseguir obter a versão heketi-cli como qualquer usuário conectado ao servidor.
$ heketi-cli --version
heketi-cli v10.4.0-release-10
Você pode definir a variável de ambiente HEKETI_CLI_SERVER para o heketi-cli lê-la diretamente.
export HEKETI_CLI_SERVER=$(kubectl get svc/heketi --template 'http://{{.spec.clusterIP}}:{{(index .spec.ports 0).port}}')
Confirme o valor da variável:
$ echo $HEKETI_CLI_SERVER
http://10.233.108.5:8080
Consultar detalhes do cluster
$ heketi-cli cluster list --user admin --secret MyAdminStrongKey
Clusters:
Id:88ed1913182f880ab5eb22ca2f904615 [file][block]
$ heketi-cli cluster info 88ed1913182f880ab5eb22ca2f904615
Cluster id: 88ed1913182f880ab5eb22ca2f904615
Nodes:
1efe9a69341b50b00a0b15f6e7d8c797
2d48f05c7d7d8d1e9f4b4963ef8362e3
cf5753b191eca0b67aa48687c08d4e12
Volumes:
e06893fc6e4f5fa23994432a40877889
Block: true
File: true
Se você salvar o nome de usuário e a chave do administrador Heketi como variáveis de ambiente, não será necessário passar essas opções.
$ export HEKETI_CLI_USER=admin
$ export HEKETI_CLI_KEY=MyAdminStrongKey
$ heketi-cli cluster list
Clusters:
Id:5c94db92049afc5ec53455d88f55f6bb [file][block]
$ heketi-cli cluster info 5c94db92049afc5ec53455d88f55f6bb
Cluster id: 5c94db92049afc5ec53455d88f55f6bb
Nodes:
3bd2d62ea6b8b8c87ca45037c7080804
a795092bad48ed91be962c6a351cbf1b
e98fd47bb4811f7c8adaeb572ca8823c
Volumes:
119c23455c894c33e968a1047b474af2
Block: true
File: true
$ heketi-cli node list
Id:75b2696a9e142e6900ee9fd2d1eb56b6 Cluster:23800e4b6bdeebaec4f6c45b17cabf55
Id:9ca47f98eaa60f0e734ab628897160fc Cluster:23800e4b6bdeebaec4f6c45b17cabf55
Id:c43023282eef0f10d4109c68bcdf0f9d Cluster:23800e4b6bdeebaec4f6c45b17cabf55
Ver informações de topologia:
$ heketi-cli topology info
Cluster Id: 698754cfaf9642b451c4671f96c46a0b
File: true
Block: true
Volumes:
Nodes:
Node Id: 39e8fb3b09ccfe47d1d3f2d8e8b426c8
State: online
Cluster Id: 698754cfaf9642b451c4671f96c46a0b
Zone: 1
Management Hostnames: worker03
Storage Hostnames: 10.10.1.178
Devices:
Node Id: b9c3ac6737d27843ea0ce69a366de48c
State: online
Cluster Id: 698754cfaf9642b451c4671f96c46a0b
Zone: 1
Management Hostnames: worker01
Storage Hostnames: 10.10.1.193
Devices:
Node Id: c94636a003af0ca82e7be6962149869b
State: online
Cluster Id: 698754cfaf9642b451c4671f96c46a0b
Zone: 1
Management Hostnames: worker02
Storage Hostnames: 10.10.1.167
Devices:
Crie StorageClass para provisionamento dinâmico.
$ vim gluster-storage-class.yaml
---
apiVersion: storage.k8s.io/v1beta1
kind: StorageClass
metadata:
name: glusterfs-storage
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://10.233.108.5:8080"
restuser: "admin"
restuserkey: "MyAdminStrongKey"
$ kubectl create -f gluster-storage-class.yaml
storageclass.storage.k8s.io/glusterfs-storage created
$ kubectl get storageclass
NAME PROVISIONER AGE
glusterfs-storage kubernetes.io/glusterfs 18s
$ kubectl describe storageclass.storage.k8s.io/glusterfs-storage
Name: glusterfs-storage
IsDefaultClass: No
Annotations: <none>
Provisioner: kubernetes.io/glusterfs
Parameters: resturl=http://10.233.108.5:8080,restuser=admin,restuserkey=MyAdminStrongKey
AllowVolumeExpansion: <unset>
MountOptions: <none>
ReclaimPolicy: Delete
VolumeBindingMode: Immediate
Events: <none>
Criar PVC
$ cat gluster-pvc.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: glusterpvc01
annotations:
volume.beta.kubernetes.io/storage-class: glusterfs-storage
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
$ kubectl create -f gluster-pvc.yaml
persistentvolumeclaim/glusterpvc01 created
Onde :
- glusterfs-storage é a anotação da classe de armazenamento do Kubernetes e o nome da classe de armazenamento.
- 1Gi é a quantidade de armazenamento solicitada
Para aprender como usar o provisionamento dinâmico em suas implantações, verifique o Hello World com GlusterFS Dynamic Provisioning