Este documento explica como melhorar a segurança e a gestão do cluster do Kubernetes isolando as cargas de trabalho de contentores em node pools dedicados no Google Distributed Cloud (GDC) air-gapped. O isolamento das cargas de trabalho dá-lhe maior controlo sobre os seus pods e reduz o risco de ataques de escalada de privilégios no cluster do Kubernetes. Para mais informações sobre as vantagens e as limitações dos node pools dedicados, consulte Vista geral do isolamento de nós.
Existem vários fluxos de trabalho envolvidos no isolamento das cargas de trabalho de contentores, incluindo o seguinte:
Contamine e etiquete um node pool: aplique uma contaminação e uma etiqueta a um node pool para que repila os pods, a menos que estes estejam especificamente etiquetados para serem executados nesse node pool.
Adicione uma tolerância e uma regra de afinidade de nós: aplique tolerâncias e regras aos seus pods para forçá-los a serem executados apenas no node pool designado.
Valide o funcionamento da separação: confirme que os node pools contaminados só estão a executar os pods que etiquetou para serem executados nesses node pools.
Estes fluxos de trabalho destinam-se a públicos-alvo como administradores de TI no grupo de administradores da plataforma, responsáveis pela gestão dos node pools de um cluster do Kubernetes, e programadores de aplicações no grupo de operadores de aplicações, responsáveis pela gestão das cargas de trabalho de contentores. Para mais informações, consulte Públicos-alvo da documentação do GDC air-gapped.
Antes de começar
Para concluir as tarefas neste documento, tem de pedir as autorizações necessárias e preparar o seu ambiente.
Peça funções de IAM
Tem de ter funções específicas para receber as autorizações de que precisa para isolar as cargas de trabalho de contentores no cluster do Kubernetes. As funções de que precisa dependem de estar a trabalhar num cluster partilhado com âmbito da organização ou num cluster padrão com âmbito do projeto. Para mais informações, consulte o artigo Configurações do cluster do Kubernetes.
Funções do cluster partilhado
Contacte o administrador de IAM da organização para pedir as seguintes funções para contaminar e etiquetar um node pool num cluster partilhado:
Administrador do cluster do utilizador (
user-cluster-admin): crie, elimine, edite ou veja os recursos de um cluster partilhado alojado no servidor da API de gestão. Esta função dá acesso aos node pools do cluster partilhado.Programador do cluster do utilizador (
user-cluster-developer): crie, elimine, edite ou veja um cluster partilhado. Esta função dá acesso às APIs do plano de dados alojadas no cluster partilhado.
Estas funções não estão associadas a um espaço de nomes.
Funções do cluster padrão
Contacte o administrador de IAM do projeto para pedir as seguintes funções para contaminar e etiquetar um node pool num cluster padrão:
Administrador do cluster (
cluster-admin): crie, elimine, edite ou veja todos os recursos num cluster padrão. Esta função dá acesso às APIs do plano de dados alojadas no cluster padrão que regem os recursos do cluster.Programador do cluster (
cluster-developer): crie, elimine, edite ou veja um cluster padrão. Esta função dá acesso às APIs do plano de dados alojadas no cluster padrão que regem o cluster.Administrador do cluster padrão (
standard-cluster-admin): crie, elimine, edite ou veja os recursos de um cluster padrão alojado no servidor da API de gestão. Esta função dá acesso aos node pools do cluster padrão.
Estas funções estão associadas ao espaço de nomes do projeto.
Prepare o seu ambiente
Para executar comandos num cluster do Kubernetes através da API, certifique-se de que tem os seguintes recursos:
Inicie sessão e gere o ficheiro kubeconfig para o cluster do Kubernetes.
Use o caminho kubeconfig do cluster do Kubernetes para substituir
KUBERNETES_CLUSTER_KUBECONFIGnestas instruções.Inicie sessão e gere o ficheiro kubeconfig para o servidor da API de gestão.
Use o caminho kubeconfig do servidor da API de gestão para substituir
MANAGEMENT_API_SERVERnestas instruções.Escolha um nome específico para a contaminação de nós e a etiqueta de nós que quer usar para os node pools dedicados. Por exemplo,
workloadType=untrusted.
Contamine e etiquete um novo node pool
Quando aplica uma contaminação ou uma etiqueta a um novo node pool, todos os nós, incluindo os nós adicionados posteriormente, recebem automaticamente as contaminações e as etiquetas especificadas. Não pode remover uma contaminação ou uma etiqueta de um node pool depois de a aplicar.
Para adicionar uma contaminação e uma etiqueta a um novo node pool, conclua os passos seguintes:
Edite a secção
nodePoolsdo recurso personalizadoClusterdiretamente ao criar o node pool: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_VALUESubstitua o seguinte:
TAINT_KEY: a parte da chave de contaminação do par de chave-valor associado a umTAINT_EFFECTde agendamento. Por exemplo,workloadType.TAINT_VALUE: a parte do valor de contaminação do par de chave-valor associado a um agendamentoTAINT_EFFECT. Por exemplo,untrusted.TAINT_EFFECT: um dos seguintes valores de efeito :NoSchedule: os pods que não toleram esta contaminação não são agendados no nó; os pods existentes não são removidos do nó.PreferNoSchedule: o Kubernetes evita agendar pods que não toleram esta contaminação no nó.NoExecute: o pod é removido do nó se já estiver a ser executado no nó e não é agendado no nó se ainda não estiver a ser executado no nó.
LABEL_KEY: LABEL_VALUE: os pares de chave-valor para as etiquetas de nós, que correspondem aos seletores que especifica nos manifestos de cargas de trabalho.
Aplique o recurso
Clusterpara criar o novo node pool:kubectl apply -f cluster.yaml --kubeconfig MANAGEMENT_API_SERVERSubstitua
MANAGEMENT_API_SERVERpelo caminho kubeconfig do servidor da API zonal onde o cluster do Kubernetes está alojado.
Contamine e etiquete um node pool existente
Para aplicar uma contaminação ou uma etiqueta a um node pool existente, tem de aplicar as alterações a cada nó existente. Não pode atualizar dinamicamente as configurações do node pool.
Não pode remover uma contaminação ou uma etiqueta de um node pool depois de a aplicar.
Para adicionar uma contaminação e uma etiqueta a um node pool existente, conclua os passos seguintes:
Liste os nós no node pool dedicado:
kubectl get node --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG \ -l baremetal.cluster.gke.io/node-pool=NODE_POOL_NAMESubstitua as seguintes variáveis:
KUBERNETES_CLUSTER_KUBECONFIG: o caminho kubeconfig para o cluster do Kubernetes.NODE_POOL_NAME: o nome do node pool dedicado.
Anote o ID de cada nó de todos os nós no node pool a partir do resultado.
Para cada nó no node pool, aplique as contaminações:
kubectl taint nodes NODE_ID \ TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIGSubstitua as seguintes variáveis:
NODE_ID: o ID do nó de trabalho no node pool dedicado.TAINT_KEY=TAINT_VALUE: um par de chave-valor associado a umTAINT_EFFECT. Por exemplo,workloadType=untrusted.TAINT_EFFECT: um dos seguintes valores de efeito:NoSchedule: os pods que não toleram esta contaminação não são agendados no nó; os pods existentes não são removidos do nó.PreferNoSchedule: o Kubernetes evita agendar pods que não toleram esta contaminação no nó.NoExecute: o pod é removido do nó se já estiver a ser executado no nó e não é agendado no nó se ainda não estiver a ser executado no nó.
KUBERNETES_CLUSTER_KUBECONFIG: o caminho kubeconfig para o cluster do Kubernetes.
Para cada nó no node pool, aplique as etiquetas que correspondem aos seletores que vai definir nas cargas de trabalho de contentores:
kubectl label NODE_ID \ LABEL_KEY:LABEL_VALUE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIGSubstitua as seguintes variáveis:
NODE_ID: o ID do nó de trabalho no node pool dedicado.LABEL_KEY:LABEL_VALUE: os pares de chave-valor para as etiquetas de nós, que correspondem aos seletores que especifica nos manifestos de cargas de trabalho.KUBERNETES_CLUSTER_KUBECONFIG: o caminho kubeconfig para o cluster do Kubernetes.
Adicione uma tolerância e uma regra de afinidade de nós
Depois de contaminar o node pool dedicado, nenhuma carga de trabalho pode ser agendada no mesmo, a menos que tenha uma tolerância correspondente à contaminação que adicionou. Adicione a tolerância à especificação das cargas de trabalho para permitir que esses pods sejam agendados no node pool contaminado.
Se etiquetou o node pool dedicado, também pode adicionar uma regra de afinidade de nós para indicar ao GDC que agende apenas as cargas de trabalho nesse node pool.
Para configurar a carga de trabalho de contentores para ser executada no node pool dedicado, conclua os passos seguintes:
Adicione as seguintes secções à secção
.spec.template.specdo ficheiro de manifesto da carga de trabalho de contentores, como um recurso personalizadoDeployment: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"Substitua o seguinte:
TAINT_KEY: a chave de contaminação que aplicou ao node pool dedicado.TAINT_VALUE: o valor de contaminação que aplicou ao node pool dedicado.TAINT_EFFECT: um dos seguintes valores de efeito:NoSchedule: os pods que não toleram esta contaminação não são agendados no nó; os pods existentes não são removidos do nó.PreferNoSchedule: o Kubernetes evita agendar pods que não toleram esta contaminação no nó.NoExecute: o pod é removido do nó se já estiver a ser executado no nó e não é agendado no nó se ainda não estiver a ser executado no nó.
LABEL_KEY: a chave da etiqueta de nó que aplicou ao node pool dedicado.LABEL_VALUE: o valor da etiqueta de nó que aplicou ao node pool dedicado.
Por exemplo, o seguinte recurso
Deploymentadiciona uma tolerância para a contaminaçãoworkloadType=untrusted:NoExecutee uma regra de afinidade de nós para a etiqueta 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: SECRETAtualize a carga de trabalho de contentores:
kubectl apply -f deployment.yaml -n NAMESPACE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIGSubstitua as seguintes variáveis:
NAMESPACE: o espaço de nomes da carga de trabalho de contentores. Para clusters partilhados, tem de ser um espaço de nomes do projeto. Para clusters padrão, pode ser qualquer espaço de nomes.KUBERNETES_CLUSTER_KUBECONFIG: o caminho kubeconfig para o cluster do Kubernetes.
O GDC recria os pods afetados. A regra de afinidade de nós força os pods para o node pool dedicado que criou. A tolerância permite que apenas esses pods sejam colocados nos nós.
Valide o funcionamento da separação
Valide se os pods que designou estão a ser executados no node pool etiquetado.
Liste os pods no espaço de nomes indicado:
kubectl get pods -o=wide -n NAMESPACE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIGSubstitua as seguintes variáveis:
NAMESPACE: o espaço de nomes da carga de trabalho de contentores. Para clusters partilhados, tem de ser um espaço de nomes do projeto. Para clusters padrão, pode ser qualquer espaço de nomes.KUBERNETES_CLUSTER_KUBECONFIG: o caminho kubeconfig para o cluster do Kubernetes.
O resultado é semelhante ao seguinte:
pod/kube-abc-12tyuj pod/kube-abc-39oplef pod/kube-abc-95rzkapConfirme que as cargas de trabalho estão a ser executadas no node pool dedicado.
O que se segue?
- Cargas de trabalho de contentores no GDC
- Implemente uma aplicação de contentores de elevada disponibilidade
- Cargas de trabalho do Kubernetes para HA