Este documento explica como melhorar a segurança e o gerenciamento do seu cluster do Kubernetes isolando cargas de trabalho de contêiner em pools de nós dedicados na Google Distributed Cloud (GDC) isolada por air-gap. Isolar as cargas de trabalho oferece mais controle sobre os pods e reduz o risco de ataques de escalonamento de privilégios no cluster do Kubernetes. Para mais informações sobre os benefícios e as limitações dos pools de nós dedicados, consulte Visão geral do isolamento de nós.
Há vários fluxos de trabalho envolvidos no isolamento das cargas de trabalho de contêineres, incluindo:
Atribuir um taint e um identificador a um pool de nós: aplique um taint e um identificador a um pool de nós para que ele repila os pods, a menos que eles sejam especificamente identificados para execução ali.
Adicione uma tolerância e uma regra de afinidade de nó: aplique tolerâncias e regras aos pods para forçar a execução deles apenas no pool de nós designado.
Verifique se a separação funciona: confirme se os pools de nós corrompidos estão executando apenas os pods que você rotulou para serem executados lá.
Esses fluxos de trabalho são destinados a públicos-alvo como administradores de TI no grupo de administradores da plataforma, responsáveis por gerenciar os pools de nós de um cluster do Kubernetes, e desenvolvedores de aplicativos no grupo de operadores de aplicativos, responsáveis por gerenciar cargas de trabalho de contêineres. Para mais informações, consulte Públicos-alvo da documentação isolada do GDC.
Antes de começar
Antes de começar, veja se você realizou as seguintes tarefas:
Escolha um nome específico para o taint e o identificador do nó que você quer usar nos pools de nós dedicados. Por exemplo,
workloadType=untrusted
Se necessário, peça ao administrador do IAM da organização para conceder a você o papel de desenvolvedor de cluster de usuário (
user-cluster-developer
), que não está vinculado a um namespace.
Atribuir um taint e um identificador a um novo pool de nós
Quando você aplica um taint ou um identificador a um novo pool de nós, todos os nós, incluindo os adicionados posteriormente, recebem automaticamente os taints e identificadores especificados.
Para adicionar um taint e um rótulo a um novo pool de nós, siga estas etapas:
Edite diretamente a seção
nodePools
do recurso personalizadoCluster
ao criar o pool de nós:nodePools: # Several lines of code are omitted here. - machineTypeName: n2-standard-2-gdc name: nodepool-1 nodeCount: 3 taints: - key: "TAINT_KEY" value: "TAINT_VALUE" effect: "TAINT_EFFECT" labels: LABEL_KEY: LABEL_VALUE
Substitua:
TAINT_KEY
: a parte da chave de taint do par de chave-valor associado a umTAINT_EFFECT
de programação. Por exemplo,workloadType
.TAINT_VALUE
: a parte do valor de taint do par de chave-valor associado a umTAINT_EFFECT
de programação. Por exemplo,untrusted
.TAINT_EFFECT
: um dos seguintes valores de efeito:NoSchedule
: pods que não toleram esse taint não são programados no nó. Os pods atuais não são removidos do nó.PreferNoSchedule
: o Kubernetes evita a programação de pods que não toleram esse taint no nó.NoExecute
: o pod é removido do nó quando já está em execução nele e não é programado no nó quando ainda não está em execução nele.
LABEL_KEY: LABEL_VALUE
: os pares de chave-valor para os rótulos de nó, que correspondem aos seletores especificados nos manifestos das cargas de trabalho.
Aplique o recurso
Cluster
para criar o novo pool de nós:kubectl apply -f cluster.yaml --kubeconfig MANAGEMENT_API_SERVER
Substitua
MANAGEMENT_API_SERVER
pelo caminho do kubeconfig do servidor da API zonal em que o cluster do Kubernetes está hospedado. Se você ainda não gerou um arquivo kubeconfig para o servidor da API na zona de destino, consulte Recursos do servidor da API de gerenciamento zonal para mais informações.
Atribuir um taint e um identificador a um pool de nós atual
Para aplicar uma restrição ou um rótulo a um pool de nós, é necessário aplicar as mudanças a cada nó. Não é possível atualizar dinamicamente as configurações do pool de nós.
Para adicionar um taint e um rótulo a um pool de nós atual, siga estas etapas:
Liste os nós no pool de nós dedicado:
kubectl get node --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG \ -l baremetal.cluster.gke.io/node-pool=NODE_POOL_NAME
Substitua as seguintes variáveis:
KUBERNETES_CLUSTER_KUBECONFIG
: o caminho kubeconfig do cluster do Kubernetes.NODE_POOL_NAME
: o nome do pool de nós dedicados.
Anote o ID de cada nó no pool de nós da saída.
Para cada nó no pool de nós, aplique as restrições:
kubectl taint nodes NODE_ID \ TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
Substitua as seguintes variáveis:
NODE_ID
: o ID do nó de trabalho no pool de nós dedicado.TAINT_KEY=TAINT_VALUE
: um par de chave-valor associado a umTAINT_EFFECT
de programação. Por exemplo,workloadType=untrusted
.TAINT_EFFECT
: um dos seguintes valores de efeito:NoSchedule
: pods que não toleram esse taint não são programados no nó. Os pods atuais não são removidos do nó.PreferNoSchedule
: o Kubernetes evita a programação de pods que não toleram esse taint no nó.NoExecute
: o pod é removido do nó quando já está em execução nele e não é programado no nó quando ainda não está em execução nele.
KUBERNETES_CLUSTER_KUBECONFIG
: o caminho kubeconfig do cluster do Kubernetes.
Para cada nó no pool de nós, aplique os rótulos que correspondem aos seletores que você vai definir nas cargas de trabalho de contêiner:
kubectl label NODE_ID \ LABEL_KEY:LABEL_VALUE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
Substitua as seguintes variáveis:
NODE_ID
: o ID do nó de trabalho no pool de nós dedicado.LABEL_KEY:LABEL_VALUE
: os pares de chave-valor para os rótulos de nó, que correspondem aos seletores especificados nos manifestos das cargas de trabalho.KUBERNETES_CLUSTER_KUBECONFIG
: o caminho kubeconfig do cluster do Kubernetes.
Adicionar uma tolerância e uma regra de afinidade de nó
Depois que você atribui um taint ao pool de nós dedicado, nenhuma carga de trabalho poderá ser programada nele, a menos que tenha uma tolerância correspondente ao taint adicionado. Adicione a tolerância à especificação das cargas de trabalho para permitir que esses pods sejam programados no pool de nós com taint.
Se você atribuiu um rótulo ao pool de nós dedicado, também é possível adicionar uma regra de afinidade de nó para instruir o GDC a programar apenas as cargas de trabalho nesse pool de nós.
Para configurar sua carga de trabalho de contêiner para ser executada no pool de nós dedicado, siga estas etapas:
Adicione as seções a seguir à seção
.spec.template.spec
do arquivo de manifesto da carga de trabalho do contêiner, como um recurso personalizadoDeployment
:# Several lines of code are omitted here. spec: template: spec: tolerations: - key: TAINT_KEY operator: Equal value: TAINT_VALUE effect: TAINT_EFFECT affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: LABEL_KEY operator: In values: - "LABEL_VALUE" # Several lines of code are omitted here.
Substitua:
TAINT_KEY
: a chave do taint que você aplicou ao pool de nós dedicado.TAINT_VALUE
: o valor do taint que você aplicou ao pool de nós dedicado.TAINT_EFFECT
: um dos seguintes valores de efeito:NoSchedule
: pods que não toleram esse taint não são programados no nó. Os pods atuais não são removidos do nó.PreferNoSchedule
: o Kubernetes evita a programação de pods que não toleram esse taint no nó.NoExecute
: o pod é removido do nó quando já está em execução nele e não é programado no nó quando ainda não está em execução nele.
LABEL_KEY
: a chave do rótulo do nó que você aplicou ao pool de nós dedicado.LABEL_VALUE
: o valor do rótulo do nó que você aplicou ao pool de nós dedicado.
Por exemplo, o recurso
Deployment
a seguir adiciona uma tolerância ao taintworkloadType=untrusted:NoExecute
e uma regra de afinidade de nó para o identificador de nóworkloadType=untrusted
:kind: Deployment apiVersion: apps/v1 metadata: name: my-app namespace: default labels: app: my-app spec: replicas: 1 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: tolerations: - key: workloadType operator: Equal value: untrusted effect: NoExecute affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: workloadType operator: In values: - "untrusted" containers: - name: my-app image: harbor-1.org-1.zone1.google.gdc.test/harborproject/my-app ports: - containerPort: 80 imagePullSecrets: - name: SECRET
Atualize sua carga de trabalho de contêiner:
kubectl apply -f deployment.yaml -n NAMESPACE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
Substitua as seguintes variáveis:
NAMESPACE
: o namespace do projeto da sua carga de trabalho de contêiner.KUBERNETES_CLUSTER_KUBECONFIG
: o caminho kubeconfig do cluster do Kubernetes.
O GDC recria os pods afetados. A regra de afinidade de nó força os pods no pool de nós dedicado que você criou. A tolerância permite que apenas esses pods sejam posicionados nos nós.
Verificar se a separação funciona
Verifique se os pods designados estão sendo executados no pool de nós rotulado.
Liste os pods no namespace especificado:
kubectl get pods -o=wide -n NAMESPACE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
Substitua as seguintes variáveis:
NAMESPACE
: o namespace do projeto da sua carga de trabalho de contêiner.KUBERNETES_CLUSTER_KUBECONFIG
: o caminho kubeconfig do cluster do Kubernetes.
A saída será assim:
pod/kube-abc-12tyuj pod/kube-abc-39oplef pod/kube-abc-95rzkap
Confirme se as cargas de trabalho estão sendo executadas no pool de nós dedicado.
A seguir
- Cargas de trabalho de contêiner no GDC
- Implantar um aplicativo de contêiner altamente disponível
- Cargas de trabalho do Kubernetes para alta disponibilidade