Isole cargas de trabalho em node pools dedicados
Esta página mostra como reduzir o risco de ataques de escalada de privilégios no seu cluster configurando o GKE no Azure para agendar as suas cargas de trabalho num conjunto de nós dedicado separado das cargas de trabalho geridas privilegiadas.
Vista geral
Os clusters do GKE on Azure usam cargas de trabalho privilegiadas que gerimos para ativar funcionalidades e funcionalidades específicas do cluster, como a recolha de métricas. Estas cargas de trabalho recebem autorizações especiais para serem executadas corretamente no cluster.
As cargas de trabalho que implementa nos seus nós podem ser potencialmente comprometidas por uma entidade maliciosa. A execução destas cargas de trabalho juntamente com cargas de trabalho de sistema privilegiadas significa que um atacante que saia de um contentor comprometido pode usar as credenciais da carga de trabalho privilegiada no nó para aumentar os privilégios no seu cluster.
Prevenção de fugas de contentores
A sua defesa principal deve ser as suas aplicações. O GKE no Azure tem várias funcionalidades que pode usar para proteger os seus clusters e pods. Na maioria dos casos, recomendamos vivamente a utilização do Policy Controller e das funcionalidades de segurança do kernel para proteger as suas cargas de trabalho. Para mais recomendações de segurança, consulte a vista geral da segurança.
Evitar ataques de escalamento de privilégios
Se quiser uma camada adicional de isolamento para além de outras medidas de reforço, pode usar contaminações de nós e afinidade de nós para agendar as suas cargas de trabalho num conjunto de nós dedicado.
Uma restrição de nó indica ao GKE no Azure que deve evitar agendar cargas de trabalho sem uma tolerância correspondente (como cargas de trabalho geridas pelo GKE no Azure) nesses nós. A afinidade de nós nas suas próprias cargas de trabalho indica ao GKE no Azure que agende os seus pods nos nós dedicados.
Limitações do isolamento de nós
- Os atacantes continuam a poder iniciar ataques de negação de serviço (DoS) a partir do nó comprometido.
- Os nós comprometidos ainda podem ler muitos recursos, incluindo todos os pods e namespaces no cluster.
- Os nós comprometidos podem aceder a segredos e credenciais usados por todos os pods em execução nesse nó.
- A utilização de um node pool separado para isolar as cargas de trabalho pode afetar a eficiência de custos, o dimensionamento automático e a utilização de recursos.
- Os nós comprometidos podem continuar a ignorar as políticas de rede de saída.
- Algumas cargas de trabalho geridas pelo GKE on Azure têm de ser executadas em todos os nós do cluster e estão configuradas para tolerar todas as manchas.
- Se implementar DaemonSets com autorizações elevadas e que possam tolerar qualquer contaminação, esses pods podem ser uma via para a escalada de privilégios a partir de um nó comprometido.
Como funciona o isolamento de nós
Para implementar o isolamento de nós para as suas cargas de trabalho, tem de fazer o seguinte:
- Contamine e etiquete um conjunto de nós para as suas cargas de trabalho.
- Atualize as suas cargas de trabalho com a regra de tolerância e afinidade de nós correspondente.
Este guia pressupõe que começa com um node pool no seu cluster. A utilização da afinidade de nós, além das restrições de nós, não é obrigatória, mas recomendamos que o faça porque beneficia de um maior controlo sobre o agendamento.
Antes de começar
Para realizar os passos nesta página, conclua primeiro o seguinte:
- Crie um cluster.
- Crie um node pool.
Escolha um nome para a restrição de nós e a etiqueta de nós que quer usar para os conjuntos de nós dedicados. Para este exemplo, usamos
workloadType=untrusted
.
Contamine e etiquete um conjunto de nós para as suas cargas de trabalho
Crie um novo node pool para as suas cargas de trabalho e aplique uma restrição de nó e uma etiqueta de nó. Quando aplica uma restrição ou uma etiqueta ao nível do conjunto de nós, todos os novos nós, como os criados pelo dimensionamento automático, recebem automaticamente as restrições e as etiquetas especificadas.
Também pode adicionar taints de nós e etiquetas de nós a pools de nós existentes. Se usar o efeito NoExecute
, o GKE no Azure despeja todos os pods em execução nesses nós que não tenham uma tolerância para a nova mancha.
Para adicionar uma restrição e uma etiqueta a um novo conjunto de nós, execute o seguinte comando:
gcloud container azure node-pools create POOL_NAME \
--cluster CLUSTER_NAME \
--node-taints TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \
--node-labels LABEL_KEY=LABEL_VALUE
Substitua o seguinte:
POOL_NAME
: o nome do novo conjunto de nós para as suas cargas de trabalho.CLUSTER_NAME
: o nome do seu cluster do GKE no Azure.TAINT_KEY=TAINT_VALUE
: um par de chave-valor associado a uma programaçãoTAINT_EFFECT
. Por exemplo,workloadType=untrusted
.TAINT_EFFECT
: um dos seguintes valores de efeito:NoSchedule
,PreferNoSchedule
ouNoExecute
.NoExecute
oferece uma garantia de despejo melhor do queNoSchedule
.LABEL_KEY
=LABEL_VALUE
: pares de chaves-valores para as etiquetas dos nós, que correspondem aos seletores que especifica nos manifestos da carga de trabalho.
Adicione uma tolerância e uma regra de afinidade de nós às suas cargas de trabalho
Depois de contaminar o pool de nós 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 suas cargas de trabalho para permitir que esses pods sejam agendados no seu conjunto de nós contaminado.
Se etiquetou o conjunto de nós dedicado, também pode adicionar uma regra de afinidade de nós para indicar ao GKE no Azure que agende apenas as suas cargas de trabalho nesse conjunto de nós.
O exemplo seguinte adiciona uma tolerância para a restrição workloadType=untrusted:NoExecute
e 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: TAINT_KEY
operator: Equal
value: TAINT_VALUE
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: LABEL_KEY
operator: In
values:
- "LABEL_VALUE"
containers:
- name: sleep
image: ubuntu
command: ["/bin/sleep", "inf"]
Substitua o seguinte:
TAINT_KEY
: a chave de contaminação que aplicou ao seu conjunto de nós dedicado.TAINT_VALUE
: o valor de contaminação que aplicou ao seu grupo de nós dedicado.LABEL_KEY
: a chave da etiqueta do nó que aplicou ao seu node pool dedicado.LABEL_VALUE
: o valor da etiqueta do nó que aplicou ao seu node pool dedicado.
Quando atualiza a sua implementação com kubectl apply
, o GKE no Azure
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.
Verifique se a separação funciona
Para verificar se o agendamento funciona corretamente, execute o seguinte comando e verifique se as suas cargas de trabalho estão no conjunto de nós dedicado:
kubectl get pods -o=wide
Recomendações e práticas recomendadas
Depois de configurar o isolamento de nós, recomendamos que faça o seguinte:
- Restrinja pools de nós específicos a cargas de trabalho geridas pelo GKE on Azure apenas adicionando a
contaminação
components.gke.io/gke-managed-components
. A adição desta mancha impede que os seus próprios pods sejam agendados nesses nós, o que melhora o isolamento. - Ao criar novos pools de nós, impeça que a maioria das cargas de trabalho geridas pelo GKE on Azure sejam executadas nesses nós adicionando a sua própria mancha a esses pools de nós.
- Sempre que implementar novas cargas de trabalho no cluster, como quando instala ferramentas de terceiros, audite as autorizações que os pods requerem. Sempre que possível, evite implementar cargas de trabalho que usem autorizações elevadas em nós partilhados.