Neste tutorial, mostramos como personalizar os nós de um cluster do Google Kubernetes Engine (GKE) usando DaemonSets. Um DaemonSet ajuda a garantir que todos os nós (ou os nós selecionados) executem uma cópia de um pod. Quando novos nós são adicionados a um cluster, eles também executam um pod do DaemonSet.
Se as ferramentas e os sistemas usados para inicializar os clusters forem diferentes das ferramentas e dos sistemas usados para executar as cargas de trabalho, você aumentará o esforço necessário para gerenciar o ambiente. Por exemplo, se você usa uma ferramenta de gerenciamento de configuração para inicializar os nós do cluster, você depende de um procedimento fora do ambiente de execução em que as outras cargas de trabalho são executadas. Usar um DaemonSet permite usar as mesmas ferramentas para orquestrar as cargas de trabalho que você usa para modificar os nós do GKE.
O objetivo deste tutorial é ajudar administradores de sistemas, engenheiros de sistemas ou operadores de infraestrutura a simplificar a inicialização de clusters do Kubernetes.
Antes de ler esta página, você precisa conhecer:
Neste tutorial, você vai aprender a usar taints e tolerâncias do Kubernetes para garantir que os nós sejam configurados por um DaemonSet antes que as cargas de trabalho de aplicativos possam ser programadas neles.
Objetivos
Neste tutorial, você realizará as seguintes ações:
- Veja como provisionar um cluster do GKE.
- Adicione um taint a um pool de nós para evitar o agendamento de cargas de trabalho antes de aplicar a configuração do nó.
- Implante um DaemonSet que configure os nós e remova a restrição.
- Verifique se os nós do cluster estão configurados e se a taint foi removida.
Custos
Neste documento, você vai usar os seguintes componentes faturáveis do Google Cloud:
Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços.
Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Para mais informações, consulte Limpeza.
Antes de começar
- Faça login na sua conta do Google Cloud . Se você começou a usar o Google Cloud, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Implicações de segurança do DaemonSet privilegiado
Usar a configuração securityContext: privileged: true em um DaemonSet (ou qualquer pod) é
poderoso, mas tem implicações de segurança significativas porque desativa
a maioria dos limites de isolamento de contêineres para esse pod. Você precisa estar ciente das seguintes restrições e riscos de segurança que ele apresenta:
- Escape de contêiner ou comprometimento do host:uma vulnerabilidade no aplicativo ou na imagem do contêiner privilegiado pode levar diretamente ao acesso root no nó do host.
- Violação do princípio de privilégio mínimo:o modo privilegiado concede todas as capacidades, provavelmente muito mais do que o necessário para uma tarefa específica. Esse acesso amplo aumenta o potencial de danos se o contêiner for comprometido.
- Desestabilização do nó:comandos acidentais ou maliciosos podem ser executados no contêiner
privilegiado, por exemplo, valores
sysctlincorretos ou comandos comorm -rf /host/boot. Esses tipos de comandos podem falhar ou corromper o sistema operacional do nó host. - Movimentação lateral:comprometer um nó usando um DaemonSet privilegiado dá a um invasor uma base sólida para atacar outros nós, o plano de controle do Kubernetes ou sistemas conectados.
- Exposição de dados:o acesso irrestrito ao sistema de arquivos do host (
/) pode expor dados sensíveis armazenados no nó, incluindo credenciais, chaves ou dados pertencentes a outros pods se eles usarem volumes hostPath. - Maior superfície de ataque:o modo privilegiado expõe mais chamadas e recursos do sistema do kernel do host a possíveis exploits no contêiner.
Para evitar riscos de segurança, siga estas práticas recomendadas e mitigações:
- Evite usar o modo privilegiado:a abordagem mais segura é evitar completamente a configuração
privileged: true. - Usar recursos do Linux:se forem necessários direitos elevados, conceda
recursos específicos do Linux, como
NET_ADMIN,SYS_ADMIN,SYS_MODULEno camposecurityContext.capabilities.addem vez de privilégio total. Essa abordagem segue o princípio de privilégio mínimo, que recomendamos em vez de conceder permissões amplas. - Limitar o escopo:execute DaemonSets privilegiados apenas em pools de nós dedicados, possivelmente corrompidos, para conter o impacto potencial se um contêiner for comprometido.
- Aplicar políticas:use ferramentas como o Controlador de Políticas ou o Gatekeeper para criar políticas que restringem, auditam ou exigem justificativa para a implantação de contêineres privilegiados.
- Verificar e usar imagens confiáveis:use a autorização binária e a verificação rigorosa de imagens para garantir que apenas imagens de contêiner confiáveis e verificadas sejam executadas com privilégios elevados.
- Minimize as montagens de host:monte apenas os caminhos de host específicos necessários e use
readOnly: truesempre que possível. Evite montar todo o sistema de arquivos raiz (/). - Faça auditorias regulares:revise periodicamente todas as cargas de trabalho em execução com a configuração
privileged: true.
Inicializar o ambiente
Nesta seção, você realizará as ações a seguir:
- Ativar as APIs do Cloud necessárias.
- Provisionar uma conta de serviço com privilégios limitados para os nós no cluster do GKE.
- Preparar o cluster do GKE.
- Conceder privilégios de administração do cluster ao usuário.
Ativar APIs do Cloud
Abra o Cloud Shell.
Selecione o projeto Google Cloud :
gcloud config set project project-id
Substitua
project-idpelo ID do projetoGoogle Cloud que você criou ou selecionou para este tutorial.Ative a API Kubernetes Engine.
gcloud services enable container.googleapis.com
Provisionar uma conta de serviço para gerenciar clusters do GKE
Nesta seção, você criará uma conta de serviço associada aos nós no cluster. Neste tutorial, os nós do GKE usam essa conta de serviço em vez da conta de serviço padrão. Como prática recomendada, conceda à conta de serviço apenas os papéis e as permissões de acesso necessários para executar o aplicativo.
Os papéis necessários para a conta de serviço são os seguintes:
- Leitor do Monitoring (
roles/monitoring.viewer). Esse papel fornece acesso somente leitura aos dados de monitoramento. - Gravador de métricas do Monitoring (
roles/monitoring.metricWriter). Esse papel permite gravar dados de monitoramento. - Gravador de registros (
roles/logging.logWriter). Esse papel concede permissões para gravar registros.
Para provisionar uma conta de serviço, siga estas etapas:
No Cloud Shell, inicialize uma variável de ambiente que armazene o nome da conta de serviço:
GKE_SERVICE_ACCOUNT_NAME=ds-init-tutorial-gkeCrie uma conta de serviço:
gcloud iam service-accounts create "$GKE_SERVICE_ACCOUNT_NAME" \ --display-name="$GKE_SERVICE_ACCOUNT_NAME"Inicialize uma variável de ambiente que armazene o nome da conta de e-mail da conta de serviço:
GKE_SERVICE_ACCOUNT_EMAIL="$(gcloud iam service-accounts list \ --format='value(email)' \ --filter=displayName:"$GKE_SERVICE_ACCOUNT_NAME")"Vincule os papéis de gerenciamento de identidade e acesso (IAM, na sigla em inglês) à conta de serviço:
gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/monitoring.viewer gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/monitoring.metricWriter gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/logging.logWriter
Preparar o cluster do GKE
Nesta seção, você iniciará o cluster do GKE, concederá permissões e finalizará a configuração do cluster.
Para demonstrar o conceito deste tutorial, um cluster com um número relativamente baixo de nós pequenos e de uso geral é suficiente. Crie um cluster com um pool de nós (o padrão).
No Cloud Shell, crie e inicie um cluster do GKE regional:
gcloud container clusters create ds-init-tutorial \ --enable-ip-alias \ --machine-type=n1-standard-2 \ --metadata disable-legacy-endpoints=true \ --node-labels=app=default-init \ --node-locations us-central1-a,us-central1-b,us-central1-c \ --no-enable-basic-auth \ --no-issue-client-certificate \ --num-nodes=1 \ --location us-central1 \ --service-account="$GKE_SERVICE_ACCOUNT_EMAIL"
Aplicar configurações de nós usando um DaemonSet
Nesta seção, você vai impedir que as cargas de trabalho sejam executadas em nós antes da conclusão da configuração aplicando um taint ao pool de nós. Em seguida, implante um DaemonSet que faz o seguinte:
- Programa pods em nós com taint usando uma tolerância para o taint.
- Executa um contêiner init privilegiado que primeiro aplica a configuração do nó usando
sysctle depois remove a restrição do nó usandokubectl. A remoção do taint permite que o nó seja programado para cargas de trabalho. - Programa e executa um contêiner de pausa que permanece inativo e não consome recursos para evitar que o DaemonSet reprograme o pod usado para configuração.
Este tutorial aplica o parâmetro de kernel vm.max_map_count=262144 como uma configuração de exemplo.
Aplique um taint ao pool de nós padrão:
gcloud container node-pools update default-pool \ --cluster=ds-init-tutorial \ --node-taints=node.config.status/stage=configuring:NoSchedule \ --region=us-central1Com esse taint, apenas os pods que o toleram, como o pod DaemonSet, podem ser programados nesse pool de nós.
Verifique se a restrição foi aplicada:
kubectl describe nodes -l cloud.google.com/gke-nodepool=default-pool | grep TaintsO status do nó precisa mostrar
node.config.status/stage=configuring:NoSchedule.Salve o seguinte manifesto como
auto-untaint-daemonset.yaml:# WARNING: This DaemonSet runs as privileged, which has significant # security implications. Only use this on clusters where you have # strict controls over what is deployed. --- apiVersion: v1 kind: ServiceAccount metadata: name: node-config-sa namespace: default --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: node-patcher-role rules: - apiGroups: [""] resources: ["nodes"] # Permissions needed to read and remove a taint from the node. verbs: ["get", "patch", "update"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: node-config-binding subjects: - kind: ServiceAccount name: node-config-sa namespace: default roleRef: kind: ClusterRole name: node-patcher-role apiGroup: rbac.authorization.k8s.io --- apiVersion: apps/v1 kind: DaemonSet metadata: name: auto-untaint-daemonset labels: app: auto-untaint-configurator spec: selector: matchLabels: app: auto-untaint-configurator updateStrategy: type: RollingUpdate template: metadata: labels: app: auto-untaint-configurator spec: serviceAccountName: node-config-sa hostPID: true # Toleration now matches the taint on your node. tolerations: - key: "node.config.status/stage" operator: "Equal" value: "configuring" effect: "NoSchedule" volumes: - name: host-root-fs hostPath: path: / initContainers: - name: configure-and-untaint image: ubuntu:22.04 # Using a standard container image. securityContext: privileged: true # Required for chroot and sysctl. env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName volumeMounts: - name: host-root-fs mountPath: /host command: ["/bin/bash", "-c"] args: - | # Using explicit error checking for each critical command. # Define the configuration and taint details. SYSCTL_PARAM="vm.max_map_count" SYSCTL_VALUE="262144" TAINT_KEY="node.config.status/stage" echo "Running configuration on node: ${NODE_NAME}" # 1. APPLY CONFIGURATION echo "--> Applying ${SYSCTL_PARAM}=${SYSCTL_VALUE}..." if ! chroot /host sysctl -w "${SYSCTL_PARAM}=${SYSCTL_VALUE}"; then echo "ERROR: Failed to apply sysctl parameter." >&2 exit 1 fi echo "--> Configuration applied successfully." # 2. UNTAINT THE NODE # This command removes the taint from the node this Pod is running on. echo "--> Untainting node ${NODE_NAME} by removing taint ${TAINT_KEY}..." if ! /host/home/kubernetes/bin/kubectl taint node "${NODE_NAME}" "${TAINT_KEY}:NoSchedule-"; then echo "ERROR: Failed to untaint the node." >&2 exit 1 fi echo "--> Node has been untainted and is now schedulable." # The main container is minimal; it just keeps the Pod running. containers: - name: pause-container image: registry.k8s.io/pause:3.9Esse manifesto cria uma ServiceAccount, um ClusterRole e um ClusterRoleBinding para conceder ao DaemonSet permissão para remover taints de nós. O DaemonSet implanta um pod em cada nó que tolera a restrição
configuring:NoSchedule. Esse pod executa um contêiner init privilegiado que aplica a configuraçãosysctl(vm.max_map_count=262144) e remove a restrição do nó, o que torna o nó programável. Um contêiner de pausa é iniciado para manter o pod em execução.O contêiner de inicialização é executado no modo privilegiado, o que tem implicações de segurança. Para mais detalhes, consulte Compensações e restrições de segurança do DaemonSet privilegiado.
Aplique o manifesto:
kubectl apply -f auto-untaint-daemonset.yamlVerifique se os pods do DaemonSet foram criados e aguarde até que eles alcancem o estado
Running:kubectl get pods -l app=auto-untaint-configurator -o wideO estado
Runningindica que o contêiner de inicialização foi concluído. Anote o nome do pod para usá-lo na verificação da inicialização na próxima seção.
Validar e verificar o procedimento de inicialização
Depois que a configuração do nó for concluída, verifique os resultados conferindo os registros.
Verifique os registros do contêiner de inicialização de um dos pods para conferir a saída:
kubectl logs POD_NAME -c configure-and-untaintSubstitua
POD_NAMEpelo nome do pod.Você vai ver uma saída indicando a configuração bem-sucedida e a remoção da restrição do nó.
Verifique se a restrição foi removida:
kubectl describe nodes -l cloud.google.com/gke-nodepool=default-pool | grep TaintsO status do nó deve mostrar
Taints: <none>ou mostrar restrições com a chavenode.config.status/stage.
Limpar
Para evitar cobranças na sua conta do Google Cloud pelos recursos usados neste tutorial, exclua o projeto criado para ele. Se você criou um projeto dedicado para este tutorial, é possível excluí-lo totalmente. Se você usou um projeto existente, mas não quer excluí-lo, siga as etapas a seguir para limpar o projeto.
Limpar o projeto
Para limpar um projeto sem excluí-lo, remova os recursos criados neste tutorial.
No Cloud Shell, exclua o cluster do GKE:
gcloud container clusters delete ds-init-tutorial --quiet --region us-central1Exclua a conta de serviço:
gcloud iam service-accounts delete "$GKE_SERVICE_ACCOUNT_EMAIL" --quiet
Excluir o projeto
A maneira mais fácil de eliminar o faturamento é excluir o projeto criado para o tutorial.
- No console Google Cloud , acesse a página Gerenciar recursos.
- Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
- Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.
A seguir
- Leia sobre o GKE.
- Implemente uma cadeia de suprimentos de software segura.
- Saiba como aumentar a segurança do cluster do GKE.
- Confira arquiteturas de referência, diagramas e práticas recomendadas do Google Cloud. Confira o Centro de arquitetura do Cloud.