Use a topologia CSI
O Trident pode criar e anexar volumes seletivamente a nós presentes em um cluster do Kubernetes, utilizando o "Recurso de topologia CSI".
Visão geral
Usando o recurso de topologia de CSI, o acesso a volumes pode ser limitado a um subconjunto de nós, com base em regiões e zonas de disponibilidade. Hoje em dia, os provedores de nuvem permitem que os administradores do Kubernetes gerem nós baseados em zonas. Os nós podem ser localizados em diferentes zonas de disponibilidade dentro de uma região ou em várias regiões. Para facilitar o provisionamento de volumes para workloads em uma arquitetura de várias zonas, o Trident usa a topologia de CSI.
Saiba mais sobre o recurso de topologia de CSI "aqui" . |
O Kubernetes oferece dois modos exclusivos de vinculação de volume:
-
Com
VolumeBindingMode
definido comoImmediate
, o Trident cria o volume sem qualquer reconhecimento de topologia. A vinculação de volume e o provisionamento dinâmico são tratados quando o PVC é criado. Esse é o padrãoVolumeBindingMode
e é adequado para clusters que não impõem restrições de topologia. Os volumes persistentes são criados sem depender dos requisitos de agendamento do pod solicitante. -
Com
VolumeBindingMode
definido comoWaitForFirstConsumer
, a criação e a vinculação de um volume persistente para um PVC é adiada até que um pod que usa o PVC seja programado e criado. Dessa forma, os volumes são criados para atender às restrições de agendamento impostas pelos requisitos de topologia.
O WaitForFirstConsumer modo de encadernação não requer rótulos de topologia. Isso pode ser usado independentemente do recurso de topologia de CSI.
|
Para fazer uso da topologia de CSI, você precisa do seguinte:
-
Um cluster de Kubernetes executando um "Versão do Kubernetes compatível"
kubectl version Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:50:19Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:41:49Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
-
Os nós no cluster devem ter rótulos que introduzam reconhecimento da topologia (
topology.kubernetes.io/region`e `topology.kubernetes.io/zone
). Esses rótulos devem estar presentes nos nós no cluster antes que o Trident seja instalado para que o Trident esteja ciente da topologia.kubectl get nodes -o=jsonpath='{range .items[*]}[{.metadata.name}, {.metadata.labels}]{"\n"}{end}' | grep --color "topology.kubernetes.io" [node1, {"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","kubernetes.io/arch":"amd64","kubernetes.io/hostname":"node1","kubernetes.io/os":"linux","node-role.kubernetes.io/master":"","topology.kubernetes.io/region":"us-east1","topology.kubernetes.io/zone":"us-east1-a"}] [node2, {"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","kubernetes.io/arch":"amd64","kubernetes.io/hostname":"node2","kubernetes.io/os":"linux","node-role.kubernetes.io/worker":"","topology.kubernetes.io/region":"us-east1","topology.kubernetes.io/zone":"us-east1-b"}] [node3, {"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","kubernetes.io/arch":"amd64","kubernetes.io/hostname":"node3","kubernetes.io/os":"linux","node-role.kubernetes.io/worker":"","topology.kubernetes.io/region":"us-east1","topology.kubernetes.io/zone":"us-east1-c"}]
Etapa 1: Crie um back-end com reconhecimento de topologia
Os back-ends de storage do Trident podem ser projetados para provisionar volumes seletivamente de acordo com as zonas de disponibilidade. Cada back-end pode transportar um bloco opcional supportedTopologies
que representa uma lista de zonas e regiões com suporte. Para o StorageClasses que fazem uso de tal back-end, um volume só seria criado se solicitado por um aplicativo agendado em uma região/zona suportada.
Aqui está um exemplo de definição de backend:
--- version: 1 storageDriverName: ontap-san backendName: san-backend-us-east1 managementLIF: 192.168.27.5 svm: iscsi_svm username: admin password: password supportedTopologies: - topology.kubernetes.io/region: us-east1 topology.kubernetes.io/zone: us-east1-a - topology.kubernetes.io/region: us-east1 topology.kubernetes.io/zone: us-east1-b
{ "version": 1, "storageDriverName": "ontap-san", "backendName": "san-backend-us-east1", "managementLIF": "192.168.27.5", "svm": "iscsi_svm", "username": "admin", "password": "password", "supportedTopologies": [ {"topology.kubernetes.io/region": "us-east1", "topology.kubernetes.io/zone": "us-east1-a"}, {"topology.kubernetes.io/region": "us-east1", "topology.kubernetes.io/zone": "us-east1-b"} ] }
supportedTopologies é usado para fornecer uma lista de regiões e zonas por backend. Essas regiões e zonas representam a lista de valores permitidos que podem ser fornecidos em um StorageClass. Para os StorageClasses que contêm um subconjunto das regiões e zonas fornecidas em um back-end, o Trident cria um volume no back-end.
|
Você também pode definir supportedTopologies
por pool de armazenamento. Veja o exemplo a seguir:
--- version: 1 storageDriverName: ontap-nas backendName: nas-backend-us-central1 managementLIF: 172.16.238.5 svm: nfs_svm username: admin password: password supportedTopologies: - topology.kubernetes.io/region: us-central1 topology.kubernetes.io/zone: us-central1-a - topology.kubernetes.io/region: us-central1 topology.kubernetes.io/zone: us-central1-b storage: - labels: workload: production supportedTopologies: - topology.kubernetes.io/region: us-central1 topology.kubernetes.io/zone: us-central1-a - labels: workload: dev supportedTopologies: - topology.kubernetes.io/region: us-central1 topology.kubernetes.io/zone: us-central1-b
Neste exemplo, as region
etiquetas e zone
representam a localização do conjunto de armazenamento. topology.kubernetes.io/region
topology.kubernetes.io/zone
e dite de onde os pools de storage podem ser consumidos.
Etapa 2: Defina StorageClasses que estejam cientes da topologia
Com base nas etiquetas de topologia fornecidas aos nós no cluster, o StorageClasses pode ser definido para conter informações de topologia. Isso determinará os pools de storage que atuam como candidatos a solicitações de PVC feitas e o subconjunto de nós que podem fazer uso dos volumes provisionados pelo Trident.
Veja o exemplo a seguir:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: netapp-san-us-east1 provisioner: csi.trident.netapp.io volumeBindingMode: WaitForFirstConsumer allowedTopologies: - matchLabelExpressions: - key: topology.kubernetes.io/zone values: - us-east1-a - us-east1-b - key: topology.kubernetes.io/region values: - us-east1 parameters: fsType: "ext4"
Na definição StorageClass fornecida acima, volumeBindingMode
está definida como WaitForFirstConsumer
. Os PVCs solicitados com este StorageClass não serão utilizados até que sejam referenciados em um pod. E, allowedTopologies
fornece as zonas e a região a serem usadas. O netapp-san-us-east1
StorageClass cria PVCs no san-backend-us-east1
back-end definido acima.
Passo 3: Criar e usar um PVC
Com o StorageClass criado e mapeado para um back-end, agora você pode criar PVCs.
Veja o exemplo spec
abaixo:
--- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: pvc-san spec: accessModes: - ReadWriteOnce resources: requests: storage: 300Mi storageClassName: netapp-san-us-east1
Criar um PVC usando este manifesto resultaria no seguinte:
kubectl create -f pvc.yaml persistentvolumeclaim/pvc-san created kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-san Pending netapp-san-us-east1 2s kubectl describe pvc Name: pvc-san Namespace: default StorageClass: netapp-san-us-east1 Status: Pending Volume: Labels: <none> Annotations: <none> Finalizers: [kubernetes.io/pvc-protection] Capacity: Access Modes: VolumeMode: Filesystem Mounted By: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal WaitForFirstConsumer 6s persistentvolume-controller waiting for first consumer to be created before binding
Para o Trident criar um volume e vinculá-lo ao PVC, use o PVC em um pod. Veja o exemplo a seguir:
apiVersion: v1 kind: Pod metadata: name: app-pod-1 spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: topology.kubernetes.io/region operator: In values: - us-east1 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: topology.kubernetes.io/zone operator: In values: - us-east1-a - us-east1-b securityContext: runAsUser: 1000 runAsGroup: 3000 fsGroup: 2000 volumes: - name: vol1 persistentVolumeClaim: claimName: pvc-san containers: - name: sec-ctx-demo image: busybox command: [ "sh", "-c", "sleep 1h" ] volumeMounts: - name: vol1 mountPath: /data/demo securityContext: allowPrivilegeEscalation: false
Este podSpec instrui o Kubernetes a agendar o pod em nós presentes na us-east1
região e escolher entre qualquer nó presente nas us-east1-a
zonas ou us-east1-b
.
Veja a seguinte saída:
kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES app-pod-1 1/1 Running 0 19s 192.168.25.131 node2 <none> <none> kubectl get pvc -o wide NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE pvc-san Bound pvc-ecb1e1a0-840c-463b-8b65-b3d033e2e62b 300Mi RWO netapp-san-us-east1 48s Filesystem
Atualize os backends para incluir supportedTopologies
Os backends pré-existentes podem ser atualizados para incluir uma lista supportedTopologies
de uso `tridentctl backend update`do . Isso não afetará os volumes que já foram provisionados e só será usado para PVCs subsequentes.