Pesquisa de site

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:
  1. dm_snapshot
  2. dm_mirror
  3. 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ó, mas storage 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

Artigos relacionados: