Configurar cgroups graváveis para contêineres

É possível permitir que as cargas de trabalho do Google Kubernetes Engine (GKE) gerenciem recursos, como CPU e memória, para processos filhos usando a API cgroups do Linux. Este documento mostra como fornecer aos contêineres acesso de leitura e gravação à API cgroups sem executar esses contêineres no modo privilegiado.

Quando usar cgroups graváveis

Por padrão, o Kubernetes fornece a todos os contêineres Linux acesso somente leitura à API cgroups montando o sistema de arquivos /sys/fs/cgroup em cada contêiner. Você pode permitir que o GKE monte esse sistema de arquivos no modo de leitura e gravação em pods específicos para que os processos raiz gerenciem e restrinjam recursos para processos filhos.

Esses cgroups graváveis ajudam a melhorar a confiabilidade em aplicativos como o Ray, que executa processos do sistema e código do usuário no mesmo contêiner. Ao gravar no sistema de arquivos /sys/fs/cgroup, o Ray pode reservar partes dos recursos de um contêiner para processos críticos. É possível usar cgroups graváveis para melhorar a confiabilidade nesses aplicativos sem o risco de segurança de usar o modo privilegiado para os contêineres.

Antes de começar

Antes de começar, verifique se você realizou as tarefas a seguir:

  • Ative a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Se você quiser usar a Google Cloud CLI para essa tarefa, instale e inicialize a CLI gcloud. Se você instalou a CLI gcloud anteriormente, instale a versão mais recente executando o comando gcloud components update. Talvez as versões anteriores da CLI gcloud não sejam compatíveis com a execução dos comandos neste documento.

Ativar cgroups graváveis para seus nós

Ative cgroups graváveis nos nós personalizando a configuração do containerd.

No arquivo de configuração do containerd, adicione uma seção writableCgroups e defina o campo enabled como true. Para mais informações, consulte Personalizar a configuração do containerd em nós do GKE.

writableCgroups:
  enabled: true

É possível ativar cgroups graváveis usando qualquer um dos seguintes caminhos compatíveis:

  • Criar um novo cluster:especifique o arquivo de configuração usando a flag --containerd-config-from-file ao criar um novo cluster (use o comando gcloud container clusters create ou gcloud container clusters create-auto).
  • Atualizar um cluster atual:especifique o arquivo de configuração usando a flag --containerd-config-from-file ao atualizar os padrões de nós no nível do cluster. Use o comando gcloud container clusters update. A atualização dos padrões de nós no nível do cluster não afeta os nós atuais. Em clusters padrão, é necessário fazer upgrade dos pools de nós atuais (use o comando gcloud container clusters upgrade com a flag --node-pool) ou recriá-los para receber a configuração.
  • Crie um pool de nós:em clusters padrão, especifique o arquivo de configuração usando a flag --containerd-config-from-file ao criar um pool de nós (use o comando gcloud container node-pools create ).

Usar cgroups graváveis em cargas de trabalho

Depois de ativar os cgroups graváveis para o cluster ou os pools de nós, configure as cargas de trabalho para atender a todos os requisitos a seguir:

  • Selecione um nó com cgroups graváveis ativados.
  • Ative cgroups graváveis para um ou mais contêineres no pod.
  • Use a classe de qualidade de serviço (QoS) garantida atendendo a uma das seguintes condições:

    • Para cargas de trabalho que especificam recursos no nível do pod, defina valores iguais para resources.requests e resources.limits na especificação do pod.
    • Para cargas de trabalho que especificam recursos para cada contêiner, defina valores iguais para resources.requests e resources.limits na especificação de todos os contêineres no pod, incluindo os de inicialização.

Para configurar esses requisitos, siga estas etapas:

  1. Para selecionar nós com cgroups graváveis ativados, adicione o rótulo node.gke.io/enable-writable-cgroups: "true" ao campo spec.nodeSelector na especificação do pod:

    node.gke.io/enable-writable-cgroups: "true"
    
  2. Para ativar cgroups graváveis para sua carga de trabalho, adicione uma das seguintes anotações ao campo metadata.annotations na especificação do pod:

    • Ative para todo o pod:

      node.gke.io/enable-writable-cgroups: "true"
      
    • Ativar para um contêiner específico no pod:

      node.gke.io/enable-writable-cgroups.CONTAINER_NAME: "true"
      

      Substitua CONTAINER_NAME pelo nome do contêiner.

  3. Para configurar a classe de QoS garantida para seu pod, especifique solicitações e limites iguais de CPU e memória para cada contêiner no pod ou para o pod inteiro, como no exemplo a seguir:

    resources:
      requests:
        cpu: "100m"
        memory: "100Mi"
      limits:
        cpu: "100m"
        memory: "100Mi"
    

    Você precisa especificar solicitações e limites iguais para todos os contêineres, mesmo que habilite cgroups graváveis apenas para um dos contêineres no pod.

A especificação final do pod será semelhante aos exemplos a seguir.

  • Este exemplo ativa cgroups graváveis para todos os contêineres no pod:

    apiVersion: v1
    kind: Pod
    metadata:
      name: writable-cgroups-pod
      annotations:
        node.gke.io/enable-writable-cgroups: "true"
    spec:
      nodeSelector:
        node.gke.io/enable-writable-cgroups: "true"
      containers:
      - name: container
        image: busybox:stable
        command: ["/bin/sh", "-c"]
        args:
        -   |
          trap 'echo "Caught SIGTERM, exiting..."; exit 0' TERM
          echo "Waiting for termination signal..."
          while true; do sleep 1; done
        resources:
          requests:
            cpu: "100m"
            memory: "100Mi"
          limits:
            cpu: "100m"
            memory: "100Mi"
    
  • Este exemplo ativa cgroups graváveis para um contêiner específico em um pod de vários contêineres:

    apiVersion: v1
    kind: Pod
    metadata:
      name: writable-cgroups-per-container
      annotations:
        node.gke.io/enable-writable-cgroups.busybox-container: "true"
    spec:
      nodeSelector:
        node.gke.io/enable-writable-cgroups: "true"
      containers:
      - name: busybox-container
        image: busybox:stable
        command: ["/bin/sh", "-c"]
        args:
        -   |
          trap 'echo "Caught SIGTERM, exiting..."; exit 0' TERM
          echo "Waiting for termination signal..."
          while true; do sleep 1; done
        resources:
          requests:
            cpu: "100m"
            memory: "100Mi"
          limits:
            cpu: "100m"
            memory: "100Mi"
      - name: container-disabled
        image: busybox:stable
        command: ["/bin/sh", "-c"]
        args:
        -   |
          trap 'echo "Caught SIGTERM, exiting..."; exit 0' TERM
          echo "Waiting for termination signal..."
          while true; do sleep 1; done
        resources:
          requests:
            cpu: "100m"
            memory: "100Mi"
          limits:
            cpu: "100m"
            memory: "100Mi"
    

Verificar se o sistema de arquivos cgroup pode ser gravado

Para verificar as permissões no sistema de arquivos /sys/fs/cgroup de um pod ou contêiner, siga estas etapas:

  1. Identifique um pod que você quer verificar. Use um dos pods de exemplo da seção Usar cgroups graváveis em cargas de trabalho.
  2. Crie uma sessão do shell no pod:

    kubectl exec -it POD_NAME -- /bin/sh
    

    Substitua POD_NAME pelo nome do pod.

  3. Descreva o sistema de arquivos cgroup montado:

    mount | grep cgroup
    

    O resultado será o seguinte:

    cgroup on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime)
    

    Nesta saída, rw indica que o sistema de arquivos pode ser gravado. Se você vir ro na saída, o sistema de arquivos será somente leitura.

A seguir