Criar cargas de trabalho com estado

Neste documento, explicamos como criar e gerenciar cargas de trabalho com estado em um cluster do Kubernetes com isolamento físico do Google Distributed Cloud (GDC). As cargas de trabalho com estado permitem escalonar a implantação do aplicativo com armazenamento permanente. O armazenamento permanente fornece ao aplicativo identidades consistentes e nomes de host estáveis, independentemente de onde as cargas de trabalho estão programadas.

Este documento é destinado a desenvolvedores do grupo de operadores de aplicativos, responsáveis por criar cargas de trabalho de aplicativos para a organização. Para mais informações, consulte Públicos-alvo da documentação do GDC com isolamento físico.

Antes de começar

Para concluir as tarefas neste documento, solicite as permissões necessárias e prepare o ambiente.

Solicitar papéis do IAM

Você precisa de papéis específicos para receber as permissões necessárias para criar cargas de trabalho com estado. Os papéis necessários dependem de você estar trabalhando em um cluster compartilhado com escopo da organização ou em um cluster padrão com escopo do projeto. Para mais informações, consulte Configurações de cluster do Kubernetes.

Papéis de cluster compartilhado

Para criar, excluir, editar ou visualizar cargas de trabalho com estado em um cluster compartilhado, peça ao administrador do IAM do projeto para conceder o papel de administrador do namespace (namespace-admin). Esse papel está vinculado ao namespace do projeto.

Papéis de cluster padrão

Para criar, excluir, editar ou visualizar cargas de trabalho com estado em um cluster padrão, peça ao administrador do IAM do projeto para conceder o papel de desenvolvedor do cluster (cluster-developer). Esse papel está vinculado ao namespace do projeto.

Preparar o ambiente

Para executar comandos em um cluster do Kubernetes usando a API, verifique se você tem os seguintes recursos:

  • Localize o nome do cluster do Kubernetes ou pergunte a um membro do grupo de administradores da plataforma qual é o nome do cluster.

  • Faça login e gere o arquivo kubeconfig do cluster do Kubernetes.

  • Use o caminho kubeconfig do cluster do Kubernetes para substituir KUBERNETES_CLUSTER_KUBECONFIG nestas instruções.

Criar um recurso StatefulSet

Crie um objeto StatefulSet gravando um manifesto StatefulSet e executando kubectl apply para criar o recurso. Para fornecer uma maneira estável para os clientes enviarem solicitações aos pods do recurso StatefulSet, também é necessário criar um objeto Service.

O comando kubectl apply usa arquivos de manifesto para criar, atualizar e excluir recursos no cluster do Kubernetes. Esse é um método declarativo de configuração de objetos. Esse método retém gravações feitas em objetos ativos sem mesclar as alterações nos arquivos de configuração do objeto.

Para criar um recurso StatefulSet e Service, execute:

kubectl --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG -n NAMESPACE \
    apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: SERVICE_NAME
  labels:
    app: APP_NAME
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: APP_NAME
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: STATEFULSET_NAME
spec:
  selector:
    matchLabels:
      app: APP_LABEL_NAME
  serviceName: "SERVICE_NAME"
  replicas: NUMBER_OF_REPLICAS
  template:
    metadata:
      labels:
        app: APP_LABEL_NAME
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: CONTAINER_NAME
        image: CONTAINER_IMAGE
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: CONTAINER_STORAGE_VOLUME_PATH
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi
EOF

Substitua:

  • KUBERNETES_CLUSTER_KUBECONFIG: o arquivo kubeconfig para o cluster em que você está implantando cargas de trabalho de contêiner.

  • NAMESPACE: o namespace em que as cargas de trabalho de contêiner serão implantadas. Para clusters compartilhados, esse precisa ser um namespace do projeto. Para clusters padrão, ele pode ser qualquer namespace.

  • SERVICE_NAME: o nome do objeto Service. Verifique se o objeto StatefulSet também define o objeto Service no serviceName.

  • APP_NAME: o nome do aplicativo a ser executado na implantação.

  • APP_LABEL_NAME: o seletor de rótulos que determina a quais pods o objeto StatefulSet pertence.

  • STATEFULSET_NAME: o nome do objeto StatefulSet.

  • NUMBER_OF_REPLICAS: o número de objetos Pod replicados que a implantação gerencia.

  • CONTAINER_NAME: o nome do contêiner.

  • CONTAINER_IMAGE: o nome da imagem do contêiner. É necessário incluir o caminho do registro de contêiner e a versão da imagem, como REGISTRY_PATH/nginx:1.23. Para mais informações sobre como definir o caminho do registro de contêiner, consulte a visão geral do serviço gerenciado do Harbor.

  • CONTAINER_STORAGE_VOLUME_PATH: o caminho dentro do contêiner em que um volume de armazenamento é montado.

Como exemplo, o objeto StatefulSet a seguir e o objeto Service correspondente criam cargas de trabalho de contêiner com estado:

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: REGISTRY_PATH/nginx:1.23
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

Neste exemplo:

  • Um objeto Service chamado nginx é criado, indicado pelo campo metadata: name. O objeto Service tem como destino um app chamado nginx, indicado por labels.app: nginx e selector.app: nginx. O objeto Service expõe a porta 80 e a nomeia web. Esse objeto Service controla o domínio da rede e encaminha o tráfego da Internet para o aplicativo em contêineres implantado pelo objeto StatefulSet.
  • Um StatefulSet chamado web é criado com três objetos Pod replicados, conforme definido pelo campo replicas: 3.
  • O modelo Pod, definido pela seção .spec.template, indica que os objetos Pod são rotulados como app: nginx.
  • A especificação Pod, definida pela seção .template.spec, indica que os pods do StatefulSet executam um contêiner, nginx, que executa a imagem nginx na versão 1.23.
  • A especificação Pod usa a porta da Web aberta pelo objeto Service.
  • A seção .template.spec.volumeMounts especifica um campo mountPath, que é chamado de www. O mountPath é o caminho no contêiner em que um volume de armazenamento é montado.
  • O StatefulSet provisiona três objetos PersistentVolumeClaim, chamados web-www-0, web-www-1 e web-www-2, com 1 GB de armazenamento provisionado cada.

Depois de criado, o StatefulSet garante que o número de objetos Pod de destino esteja em execução e disponível o tempo todo. O StatefulSet substitui automaticamente os objetos Pod que falham ou são expulsos dos respectivos nós e associa novos objetos Pod aos recursos de armazenamento, solicitações e limites de recursos e outras configurações definidas na especificação Pod do objeto StatefulSet.

Solicitar armazenamento permanente em um recurso StatefulSet

O armazenamento permanente pode ser provisionado de forma dinâmica, de modo que os volumes subjacentes sejam criados sob demanda. Os aplicativos podem solicitar armazenamento permanente com um objeto PersistentVolumeClaim.

Normalmente, é necessário criar objetos PersistentVolumeClaim além de criar o objeto Pod. No entanto, os objetos StatefulSet incluem uma matriz volumeClaimTemplates que gera os objetos PersistentVolumeClaim. Cada réplica StatefulSet recebe seu próprio objeto PersistentVolumeClaim.

Para mais informações, consulte Configurar o armazenamento de contêiner.

A seguir