Aprovisione e use o armazenamento em blocos não processados suportado por SSDs locais

Esta página explica como aprovisionar armazenamento SSD local em clusters do Google Kubernetes Engine (GKE) e como configurar cargas de trabalho para consumir dados do armazenamento em bloco não processado com suporte de SSD local associado a nós no seu cluster.

A utilização desta opção de SSD local dá-lhe mais controlo sobre o armazenamento subjacente e permite-lhe criar a sua própria cache ao nível do nó para os pods oferecerem um melhor desempenho para as suas aplicações. Também pode personalizar esta opção executando um DaemonSet para configurar o RAID e formatar os discos conforme necessário.

Para saber mais sobre o apoio técnico de SSDs locais para acesso a blocos não processados no GKE, consulte o artigo Acerca dos SSDs locais.

Antes de começar

Antes de começar, certifique-se de que realizou as seguintes tarefas:

  • Ative a API Google Kubernetes Engine.
  • Ative a API Google Kubernetes Engine
  • Se quiser usar a CLI gcloud para esta tarefa, instale-a e, em seguida, inicialize-a. Se instalou anteriormente a CLI gcloud, execute o comando gcloud components update para obter a versão mais recente. As versões anteriores da CLI gcloud podem não suportar a execução dos comandos neste documento.

Crie um cluster ou um node pool com armazenamento em bloco não processado suportado por SSD local

Use a CLI gcloud com a opção --local-nvme-ssd-block para criar um cluster com armazenamento em bloco não processado suportado por SSD local.

O comando da CLI gcloud que executa para criar o cluster ou o conjunto de nós depende da geração da série de máquinas a que pertence o tipo de máquina que está a usar. Por exemplo, os tipos de máquinas N1 e N2 pertencem, respetivamente, a uma série de máquinas de primeira e segunda geração, enquanto os tipos de máquinas C3 pertencem a uma série de máquinas de terceira geração.

Crie um cluster com SSD local

1.ª ou 2.ª geração

Se usar um tipo de máquina de uma série de máquinas de primeira ou segunda geração, pode criar o cluster especificando a opção --local-nvme-ssd-block count=NUMBER_OF_DISKS. A opção especifica o número de discos SSD locais a associar a cada nó. O número máximo varia consoante o tipo de máquina e a região.

Para criar um cluster:

gcloud container clusters create CLUSTER_NAME \
    --local-nvme-ssd-block count=NUMBER_OF_DISKS \
    --machine-type=MACHINE_TYPE \
    --release-channel CHANNEL_NAME

Substitua o seguinte:

  • CLUSTER_NAME: o nome do cluster.
  • NUMBER_OF_DISKS: o número de discos SSD locais a aprovisionar em cada nó. O número máximo de discos varia consoante o tipo de máquina e a região.
  • MACHINE_TYPE: o tipo de máquina de primeira ou segunda geração a usar. É necessário especificar este campo porque não pode usar SSDs locais com o tipo e2-medium predefinido.
  • CHANNEL_NAME: um canal de lançamento que inclui versões do GKE posteriores a 1.25.3-gke.1800.

3.ª ou 4.ª geração

Se usar um tipo de máquina de uma série de máquinas de terceira ou quarta geração, use a opção --local-nvme-ssd-block, sem um campo de contagem, para criar um cluster. O GKE aprovisiona automaticamente a capacidade de SSD local para o seu cluster com base no formato da VM. O número máximo varia consoante o tipo de máquina e a região.

gcloud container clusters create CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --cluster-version CLUSTER_VERSION \
    --local-nvme-ssd-block

Substitua o seguinte:

  • CLUSTER_NAME: o nome do cluster.
  • MACHINE_TYPE: o tipo de máquina a usar de uma série de máquinas de terceira ou quarta geração.
  • CLUSTER_VERSION: uma versão do cluster do GKE que suporta SSD local em tipos de máquinas de uma série de máquinas de terceira ou quarta geração.

Crie um node pool com SSD local

1.ª ou 2.ª geração

Para criar um node pool que use discos SSD locais para acesso a blocos não processados, execute o seguinte comando:

gcloud container node-pools create POOL_NAME \
    --cluster=CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --local-nvme-ssd-block count=NUMBER_OF_DISKS

Substitua o seguinte:

  • POOL_NAME: o nome do novo conjunto de nós.
  • CLUSTER_NAME: o nome do cluster.
  • MACHINE_TYPE: o tipo de máquina de primeira ou segunda geração a usar. É necessário especificar este campo, uma vez que não é possível usar o SSD local com o tipo e2-medium predefinido.
  • NUMBER_OF_DISKS: o número de discos SSD locais a aprovisionar em cada nó. O número máximo de discos varia consoante o tipo de máquina e a região.

3.ª ou 4.ª geração

Se usar um tipo de máquina de uma série de máquinas de terceira ou quarta geração, use a opção --local-nvme-ssd-block, sem um campo de contagem, para criar um cluster:

gcloud container node-pools create POOL_NAME \
    --cluster=CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --node-version NODE_VERSION \
    --local-nvme-ssd-block

Substitua o seguinte:

  • POOL_NAME: o nome do novo conjunto de nós.
  • CLUSTER_NAME: o nome do cluster.
  • MACHINE_TYPE: o tipo de máquina a usar a partir de um tipo de máquina de terceira ou quarta geração.
  • NODE_VERSION: uma versão do conjunto de nós do GKE que suporta SSD local em tipos de máquinas de uma série de máquinas de terceira ou quarta geração.

Os nós no node pool são criados com uma etiqueta.cloud.google.com/gke-local-nvme-ssd=true Pode validar as etiquetas executando o seguinte comando:

kubectl describe node NODE_NAME

Para cada SSD local associado ao conjunto de nós, o SO anfitrião cria um link simbólico (symlink) para aceder ao disco numa pasta ordinal e um symlink com um identificador exclusivo universal (UUID). Por exemplo, se criar um node pool com três SSDs locais através da opção --local-nvme-ssd-block, o SO do anfitrião cria os seguintes links simbólicos para os discos:

  • /dev/disk/by-id/google-local-ssd-block0
  • /dev/disk/by-id/google-local-ssd-block1
  • /dev/disk/by-id/google-local-ssd-block2

Por conseguinte, o SO anfitrião também cria os seguintes links simbólicos com UUIDs para os discos:

  • /dev/disk/by-uuid/google-local-ssds-nvme-block/local-ssd-GENERATED_UUID1
  • /dev/disk/by-uuid/google-local-ssds-nvme-block/local-ssd-GENERATED_UUID2
  • /dev/disk/by-uuid/google-local-ssds-nvme-block/local-ssd-GENERATED_UUID3

Isto garante que é possível aceder aos discos através de um identificador exclusivo.

Aceda a volumes de SSD local

O exemplo seguinte mostra como pode aceder ao armazenamento de blocos não processados suportado por SSD local.

Volumes persistentes locais

Os volumes de SSD local podem ser montados como pods através de PersistentVolumes.

Pode criar PersistentVolumes a partir de SSDs locais criando manualmente um PersistentVolume ou executando o local volume static provisioner.

Limitações dos PersistentVolumes locais

  • Os objetos PersistentVolume locais não são limpos automaticamente quando um nó é eliminado, atualizado, reparado ou reduzido. Recomendamos que analise e elimine periodicamente os objetos Local PersistentVolume obsoletos associados a nós eliminados.

Crie manualmente o PersistentVolume

Pode criar manualmente um PersistentVolume para cada SSD local em cada nó no cluster.

Use o campo nodeAffinity num objeto PersistentVolume para fazer referência a um SSD local num nó específico. O exemplo seguinte mostra a especificação PersistentVolume para SSD local em nós com o Linux:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: "example-local-pv"
spec:
  capacity:
    storage: 375Gi
  accessModes:
  - "ReadWriteOnce"
  persistentVolumeReclaimPolicy: "Retain"
  storageClassName: "local-storage"
  local:
    path: "/mnt/disks/ssd0"
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: "kubernetes.io/hostname"
          operator: "In"
          values:
          - "gke-test-cluster-default-pool-926ddf80-f166"

Neste exemplo, os discos SSD local são configurados manualmente para RAID e formatados e, em seguida, montados em /mnt/disks/ssd0 no nó gke-test-cluster-default-pool-926ddf80-f166. O campo nodeAffinity é usado para ajudar a atribuir cargas de trabalho a nós com SSDs locais configurados manualmente para RAID. Se tiver apenas um nó no cluster ou se tiver configurado o RAID para todos os nós, o campo nodeAffinity não é necessário.

A especificação PersistentVolumeClaim correspondente tem o seguinte aspeto:

  kind: PersistentVolumeClaim
  apiVersion: v1
  metadata:
    name: ssd-local-claim
  spec:
    accessModes:
    - ReadWriteOnce
    storageClassName: local-storage
    resources:
      requests:
        storage: 37Gi

Se eliminar o PersistentVolume, tem de apagar manualmente os dados do disco.

Execute o aprovisionador estático de volume local

Pode criar PersistentVolumes para SSD local automaticamente através do aprovisionador estático de volumes locais. O aprovisionador é um DaemonSet que gere os discos SSD locais em cada nó, cria e elimina os PersistentVolumes para os mesmos e limpa os dados nos discos SSD locais quando o PersistentVolume é libertado.

Para executar o aprovisionador estático de volumes locais:

  1. Use um DaemonSet para configurar o RAID e formatar os discos:

    1. Transfira a especificação gke-daemonset-raid-disks.yaml.
    2. Implemente o DaemonSet de discos RAID. O DaemonSet define uma matriz RAID 0 em todos os discos SSD locais e formata o dispositivo para um sistema de ficheiros ext4.

      kubectl create -f gke-daemonset-raid-disks.yaml
      
  2. Transfira a especificação gke-nvme-ssd-block-raid.yaml e modifique os campos do espaço de nomes da especificação, conforme necessário.

    A especificação inclui estes recursos:

    • ServiceAccount para o aprovisionador
    • ClusterRole e ClusterRoleBindings para autorizações para:
      • Crie e elimine objetos PersistentVolume
      • Obtenha objetos Node
    • ConfigMap com definições do aprovisionador para o GKE
    • DaemonSet para executar o aprovisionador
  3. Implemente o aprovisionador:

    kubectl create -f gke-nvme-ssd-block-raid.yaml
    

    Depois de o aprovisionador ser executado com êxito, cria um objeto PersistentVolume para o dispositivo SSD local RAID no cluster.

  4. Guarde o seguinte manifesto PersistentVolumeClaim como provisioner-pvc-example.yaml:

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: PVC_NAME
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 50Gi
      storageClassName: nvme-ssd-block
    

    Substitua PVC_NAME pelo nome do seu PersistentVolumeClaim.

  5. Crie o PersistentVolumeClaim:

    kubectl create -f provisioner-pvc-example.yaml
    
  6. Guarde o seguinte manifesto do agrupamento como provisioner-pod-example.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: POD_NAME
    spec:
      containers:
      - name: "shell"
        image: "ubuntu:14.04"
        command: ["/bin/sh", "-c"]
        args: ["echo 'hello world' > /cache/test.txt && sleep 1 && cat /cache/test.txt && sleep 3600"]
        volumeMounts:
        - mountPath: /cache
          name: local-ssd-storage
      volumes:
      - name: local-ssd-storage
        persistentVolumeClaim:
          claimName: PVC_NAME
    

    Substitua POD_NAME pelo nome do seu Pod.

  7. Crie o grupo:

    kubectl create -f provisioner-pod-example.yaml
    

Ative a vinculação de volume atrasada

Para uma melhor programação, recomendamos que também crie uma StorageClass com volumeBindingMode: WaitForFirstConsumer. Isto atrasa a associação de PersistentVolumeClaim até ao agendamento de Pods, para que seja escolhido um SSD local a partir de um nó adequado que possa executar o Pod. Este comportamento de agendamento melhorado tem em conta os pedidos de CPU e memória do pod, a afinidade de nós, a afinidade e a antiafinidade de pods, e vários pedidos de PersistentVolumeClaim, juntamente com os nós que têm SSDs locais disponíveis, quando seleciona um nó para um pod executável.

Este exemplo usa o modo de associação de volume atrasado:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: "local-nvme"
provisioner: "kubernetes.io/no-provisioner"
volumeBindingMode: "WaitForFirstConsumer"

Para criar uma StorageClass com associação atrasada, guarde o manifesto YAML num ficheiro local e aplique-o ao cluster através do seguinte comando:

kubectl apply -f filename

Resolução de problemas

Para ver instruções de resolução de problemas, consulte o artigo Resolva problemas de armazenamento no GKE.

O que se segue?