Grupos de segurança do Pods - Amazon EKS

Grupos de segurança do Pods

Os grupos de segurança para Pods integram os grupos de segurança do Amazon EC2 com os Pods do Kubernetes. Você pode usar grupos de segurança do Amazon EC2 para definir regras que permitem tráfego de rede de entrada e saída de e para Pods implantados em nós executados em muitos tipos de instância do Amazon EC2 e Fargate. Para obter uma explicação detalhada sobre esse recurso, consulte o post do blog Introducing grupo de segurança for Pods (Apresentação de grupos de segurança para pods).

Considerações

  • Antes de implantar grupos de segurança para Pods, considere as seguintes limitações e condições:

  • Os grupos de segurança para Pods não podem ser usados com nós do Windows.

  • Os grupos de segurança para Pods podem ser usados com clusters configurados para a família IPv6 que contém nós do Amazon EC2 usando a versão 1.16.0 ou posterior do plug-in CNI do Amazon VPC. Você pode usar grupos de segurança para IPv6 com clusters configurados para a família Pods que contêm apenas nós Fargate usando a versão 1.7.7 ou posterior do plug-in CNI do Amazon VPC. Para obter mais informações, consulte Endereços IPv6 para clusters, Pods e services.

  • Os grupos de segurança para os Pods são compatíveis com a maioria das famílias de instâncias do Amazon EC2 baseadas no Nitro, mas não com todas as gerações de uma família. Por exemplo, eles são compatíveis com a família e as gerações de instâncias m5, c5, r5, p3, m6g, c6g e r6g. Mas não são compatíveis com nenhum tipo de instância da família t. Para obter uma lista completa de tipos de instância compatíveis, consulte o arquivo limits.go no GitHub. Seus nós devem ser um dos tipos de instâncias listados que têm IsTrunkingCompatible: true nesse arquivo.

  • Se você também estiver usando políticas de segurança de Pod para restringir o acesso à mutação de Pods, o usuário do eks:vpc-resource-controller Kubernetes deverá ser especificado no ClusterRoleBinding do Kubernetes para o role ao qual o psp está atribuído. Se você estiver usando o Amazon EKS padrão psp, role e ClusterRoleBinding, este é o eks:podsecuritypolicy:authenticated ClusterRoleBinding. Por exemplo, você adiciona o usuário à seção subjects:, como mostrado no seguinte exemplo:

    [...] subjects: - kind: Group apiGroup: rbac.authorization.k8s.io name: system:authenticated - apiGroup: rbac.authorization.k8s.io kind: User name: eks:vpc-resource-controller - kind: ServiceAccount name: eks-vpc-resource-controller
  • Se você estiver usando redes personalizadas e grupos de segurança para Pods juntos, o grupo de segurança especificado por grupos de segurança para Pods é usado em vez do grupo de segurança especificado no ENIConfig.

  • Se você estiver utilizando a versão 1.10.2 ou anterior do plug-in Amazon VPC CNI e incluir a configuração terminationGracePeriodSeconds na especificação do Pod, o valor dessa configuração não poderá ser zero.

  • Se estiver utilizando a versão 1.10 ou anterior do plug-in CNI da Amazon VPC ou a versão 1.11 com POD_SECURITY_GROUP_ENFORCING_MODE = strict, que é a configuração padrão, os serviços do Kubernetes do tipo NodePort e LoadBalancer que usam destinos de instância com a externalTrafficPolicy definida como Local não serão compatíveis com os Pods a que você atribuir grupos de segurança. Para obter mais informações sobre como usar um balanceador de carga com destinos de instância, consulte Balanceamento de carga da rede no Amazon EKS.

  • Se estiver utilizando a versão 1.10 ou anterior do plugin Amazon VPC CNI ou a versão 1.11 com POD_SECURITY_GROUP_ENFORCING_MODE=strict, que é a configuração padrão, o NAT de origem estará desabilitado para tráfego de saída de Pods com grupos de segurança atribuídos para que as regras de grupo de segurança de saída sejam aplicadas. Para acessar a Internet, Pods com grupos de segurança atribuídos devem ser iniciados em nós implantados em uma sub-rede privada configurada com um gateway ou instância NAT. Pods com grupos de segurança atribuídos implantados em sub-redes públicas não podem acessar a Internet.

    Se estiver utilizando a versão 1.11 ou posterior do plugin com POD_SECURITY_GROUP_ENFORCING_MODE=standard, o tráfego do Pod destinado para fora da VPC será convertido no endereço IP da interface de rede primária da instância. Para esse tráfego, as regras nos grupos de segurança da interface de rede principal são utilizadas, e não as regras nos grupos de segurança do Pod's.

  • Para usar a política de rede do Calico com Pods que têm grupos de segurança associados, é necessário usar a versão 1.11.0 ou posterior do plug-in Amazon VPC CNI e definir POD_SECURITY_GROUP_ENFORCING_MODE=standard. Caso contrário, o fluxo de tráfego entrando e saindo de Pods com grupos de segurança associados não estará sujeito à política de rede do Calico e estará limitado apenas à imposição do grupo de segurança do Amazon EC2. Para atualizar sua versão do Amazon VPC CNI, consulte Trabalhando com o complemento Amazon VPC CNI plugin for Kubernetes do Amazon EKS.

  • Pods em execução em nós do Amazon EC2 que utilizam grupos de segurança em clusters que utilizam Nodelocal DNSCache apenas têm suporte com a versão 1.11.0 ou posterior do plugin Amazon VPC CNI e com POD_SECURITY_GROUP_ENFORCING_MODE=standard. Para atualizar sua versão do plugin Amazon VPC CNI, consulte Trabalhando com o complemento Amazon VPC CNI plugin for Kubernetes do Amazon EKS.

  • Grupos de segurança para Pods podem levar a uma latência de inicialização mais alta Pod no para o Pods com alta rotatividade. Isso se deve à limitação de taxa no controlador de recursos.

Configurar o Amazon VPC CNI plugin for Kubernetes para grupos de segurança de Pods

Para implantar grupos de segurança para Pods

Se você estiver usando grupos de segurança somente para Pods Fargate e não tiver nenhum nó do Amazon EC2 em seu cluster, pule para a Implantar uma aplicação de exemplo.

  1. Verifique a versão atual de Amazon VPC CNI plugin for Kubernetes com o comando a seguir:

    kubectl describe daemonset aws-node --namespace kube-system | grep amazon-k8s-cni: | cut -d : -f 3

    Veja um exemplo de saída abaixo.

    v1.7.6

    Se a versão do Amazon VPC CNI plugin for Kubernetes for anterior à 1.7.7, atualize o plugin para a versão 1.7.7 ou posterior. Para obter mais informações, consulte Trabalhando com o complemento Amazon VPC CNI plugin for Kubernetes do Amazon EKS.

  2. Adicione a política gerenciada do IAM AmazonEKSVPCResourceController à função do cluster que estiver associada ao cluster do Amazon EKS. A política permite que a função gerencie interfaces de rede, seus endereços IP privados e seu anexo e desprendimento de e para instâncias de rede.

    1. Recupere o nome do perfil do IAM do cluster e armazene-o em uma variável. Substitua o my-cluster pelo nome do cluster.

      cluster_role=$(aws eks describe-cluster --name my-cluster --query cluster.roleArn --output text | cut -d / -f 2)
    2. Anexe a política ao perfil.

      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSVPCResourceController --role-name $cluster_role
  3. Habilite o complemento Amazon VPC CNI para gerenciar interfaces de rede para Pods, definindo a variável ENABLE_POD_ENI como true no aws-nodeDaemonSet Uma vez que essa configuração é definida como true, para cada nó no cluster, o complemento cria um recurso personalizado cninode. O controlador de recursos da VPC cria e anexa uma interface de rede especial chamada Interface de rede com a descrição aws-k8s-trunk-eni.

    kubectl set env daemonset aws-node -n kube-system ENABLE_POD_ENI=true
    nota

    A interface de rede de tronco está incluída no número máximo de interfaces de rede suportadas pelo tipo de instância. Para obter uma lista do número máximo de interfaces de rede com suporte por cada tipo de instância, consulte IP addresses per network interface per instance type (Endereços IP por interface de rede por tipo de instância) no Manual do usuário do Amazon EC2 para instâncias do Linux. Se o nó já tiver o número máximo de interfaces de rede padrão anexadas a ele, o controlador de recursos da VPC reservará um espaço. Você terá que reduzir seus Pods de execução o suficiente para que o controlador desconecte e exclua uma interface de rede padrão, crie a interface de rede de tronco e anexe-a à instância.

  4. Você pode ver quais de seus nós possuem um recurso personalizado do CNINode com o comando a seguir. Se No resources found for retornado, aguarde alguns segundos e tente de novo. A etapa anterior requer a reinicialização dos Amazon VPC CNI plugin for de KubernetesPods, o que demora vários segundos.

    $ kubectl get cninode -A NAME FEATURES ip-192-168-64-141.us-west-2.compute.internal [{"name":"SecurityGroupsForPods"}] ip-192-168-7-203.us-west-2.compute.internal [{"name":"SecurityGroupsForPods"}]

    Se você estiver usando versões do VPC CNI anteriores a 1.15, rótulos de nós foram usados em vez do recurso CNINode personalizado. Você pode ver quais de seus nós têm o rótulo de nó aws-k8s-trunk-eni definido para true com o comando a seguir. Se No resources found for retornado, aguarde alguns segundos e tente de novo. A etapa anterior requer a reinicialização dos Amazon VPC CNI plugin for de KubernetesPods, o que demora vários segundos.

    kubectl get nodes -o wide -l vpc.amazonaws.com/has-trunk-attached=true -

    Depois que a interface de rede de tronco for criada, os Pods receberão endereços IP secundários a partir das interfaces de tronco ou de rede padrão. A interface de tronco é excluída automaticamente se o nó for excluído.

    Quando você implanta um grupo de segurança para um Pod em uma etapa superior, o controlador de recursos da VPC cria uma interface de rede especial chamada interface de rede da ramificação, com uma descrição de aws-k8s-branch-eni e associa os grupos de segurança a ela. As interfaces de rede da ramificação são criadas como um adicional para as interfaces de rede padrão e de tronco conectadas ao nó.

    Se você estiver usando testes de liveness ou prontidão, também precisará desabilitar o TCP early demux, de modo que o kubelet possa se conectar a Pods em interfaces de rede de ramificações usando TCP. Para desativar o TCP early demux, execute o seguinte comando:

    kubectl patch daemonset aws-node -n kube-system \ -p '{"spec": {"template": {"spec": {"initContainers": [{"env":[{"name":"DISABLE_TCP_EARLY_DEMUX","value":"true"}],"name":"aws-vpc-cni-init"}]}}}}'
    nota

    Se estiver usando a versão 1.11.0 ou posterior do complemento Amazon VPC CNI plugin for Kubernetes e definir POD_SECURITY_GROUP_ENFORCING_MODE=standard, conforme descrito na próxima etapa, não será necessário executar o comando anterior.

  5. Se o cluster usar NodeLocal DNSCache ou se você desejar usar a política de rede do Calico com Pods que têm seus próprios grupos de segurança ou se tiver serviços do Kubernetes do tipo NodePort e LoadBalancer que usam destinos de instâncias com um externalTrafficPolicy definido como Local para Pods aos quais deseja atribuir grupos de segurança, você deverá estar usando a versão 1.11.0 ou posterior do complemento Amazon VPC CNI plugin for Kubernetes e habilitar a seguinte configuração:

    kubectl set env daemonset aws-node -n kube-system POD_SECURITY_GROUP_ENFORCING_MODE=standard
    Importante
    • Regras de grupos de segurança de Pod não são aplicadas ao tráfego entre Pods ou Pods e services, por exemplo, kubelet ou nodeLocalDNS, que estejam no mesmo nó. Pods que usam diferentes grupos de segurança no mesmo nó não conseguem se comunicar porque estão configurados em sub-redes diferentes e o roteamento está desativado entre essas sub-redes.

    • O tráfego de saída de Pods para endereços fora da VPC é o endereço de rede convertido no endereço IP da interface de rede primária da instância (a menos que você também tenha definido AWS_VPC_K8S_CNI_EXTERNALSNAT=true). Para esse tráfego, as regras nos grupos de segurança da interface de rede principal são utilizadas, e não as regras nos grupos de segurança do Pod's.

    • Para que essa configuração seja aplicada a Pods existentes, é necessário reiniciar osPods ou os nós que nos quais esses Pods estão sendo executados.

Implantar uma aplicação de exemplo

Para utilizar grupos de segurança para Pods, é necessário ter um grupo de segurança existente e Implantar um SecurityGroupPolicy do Amazon EKS no cluster, conforme descrito no procedimento a seguir. As etapas seguintes mostram como utilizar a política de grupo de segurança para um Pod: A menos que indicado de outra forma, conclua todas as etapas no mesmo terminal, pois são utilizadas nas etapas a seguir variáveis que não persistem entre terminais.

Para implantar um Pod de exemplo com um grupo de segurança
  1. Crie um namespace do Kubernetes no qual implantar recursos. Você pode substituir my-namespace pelo nome de um namespace que deseje usar.

    kubectl create namespace my-namespace
  2. Implante uma SecurityGroupPolicy do Amazon EKS no cluster.

    1. Copie o conteúdo a seguir para o seu dispositivo. Você pode substituir podSelector por serviceAccountSelector se preferir selecionar Pods com base em rótulos de conta de serviço. É preciso especificar um seletor ou outro. Uma podSelector vazia (exemplo: podSelector: {}) seleciona todos os Pods no namespace. Você pode alterar my-role para o nome do seu perfil. Uma serviceAccountSelector vazia seleciona todas as contas de serviço no namespace. Você pode substituir my-security-group-policy por um nome para a SecurityGroupPolicy e my-namespace pelo namespace no qual você deseja criar a SecurityGroupPolicy.

      Você deve substituir my_pod_security_group_id pelo ID de um grupo de segurança existente. Se você ainda não tiver um grupo de segurança, deverá criar um. Para obter mais informações, consulte Grupos de segurança do Amazon EC2 para instâncias do Linux no Manual do usuário para instâncias do Linux do Amazon EC2. Você deve especificar de 1 a 5 IDs de grupo de segurança. Se você especificar mais de um ID, a combinação de todas as regras em todos os grupos de segurança será efetiva para os Pods selecionados.

      cat >my-security-group-policy.yaml <<EOF apiVersion: vpcresources.k8s.aws/v1beta1 kind: SecurityGroupPolicy metadata: name: my-security-group-policy namespace: my-namespace spec: podSelector: matchLabels: role: my-role securityGroups: groupIds: - my_pod_security_group_id EOF
      Importante

      Os grupos de segurança que você especificar para seus Pods devem atender aos seguintes critérios:

      • Eles devem existir. Se eles não existirem, então, quando você implantar um Pod que corresponda ao seletor, o Pod permanecerá preso no processo de criação. Se você descrever o Pod, verá uma mensagem de erro semelhante à seguinte: An error occurred (InvalidSecurityGroupID.NotFound) when calling the CreateNetworkInterface operation: The securityGroup ID 'sg-05b1d815d1EXAMPLE' does not exist.

      • Eles devem permitir comunicação de entrada do grupo de segurança aplicado aos nós (para kubelet) por todas as portas para as quais você configurou sondagens.

      • Eles devem permitir comunicação de saída pelas portas TCP e UDP 53 com um grupo de segurança atribuído aos Pods (ou nós em que os Pods são executados) sendo executados no CoreDNS. O grupo de segurança dos Pods CoreDNS devem permitir tráfego de entrada na porta TCP e UDP 53 do grupo de segurança que você especificar.

      • Eles devem ter regras de entrada e saída necessárias para comunicação com outros Pods com os quais precisam se comunicar.

      • Eles devem ter regras que permitam que os Pods se comuniquem com o ambiente de gerenciamento do Kubernetes se você estiver usando esse grupo de segurança com o Fargate. A maneira mais fácil de fazer isso é especificar o grupo de segurança de cluster como um dos grupos de segurança.

      As políticas de grupo de segurança só se aplicam a pods recém-agendados Pods. Eles não afetam os Pods em execução.

    2. Implante a política.

      kubectl apply -f my-security-group-policy.yaml
  3. Implante um exemplo de aplicação com um rótulo que corresponda ao valor de my-role para o podSelector que você especificou na etapa anterior.

    1. Copie o conteúdo a seguir para o seu dispositivo. Substitua os exemplos de valor pelos seus próprios e execute o comando modificado. Se você substituir my-role, certifique-se de que seja o mesmo valor que você especificou para o seletor em uma etapa anterior.

      cat >sample-application.yaml <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment namespace: my-namespace labels: app: my-app spec: replicas: 4 selector: matchLabels: app: my-app template: metadata: labels: app: my-app role: my-role spec: terminationGracePeriodSeconds: 120 containers: - name: nginx image: public.ecr.aws/nginx/nginx:1.23 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-app namespace: my-namespace labels: app: my-app spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 80 EOF
    2. Implante a aplicação com o comando a seguir. Quando você implanta a aplicação, Amazon VPC CNI plugin for Kubernetes corresponde à etiqueta role e os grupos de segurança especificados na etapa anterior são aplicados ao Pod.

      kubectl apply -f sample-application.yaml
  4. Visualizar os Pods Implantados com a aplicação de amostra. Para o restante do tópico, esse terminal é indicado como TerminalA.

    kubectl get pods -n my-namespace -o wide

    Veja um exemplo de saída abaixo.

    NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-deployment-5df6f7687b-4fbjm 1/1 Running 0 7m51s 192.168.53.48 ip-192-168-33-28.region-code.compute.internal <none> <none> my-deployment-5df6f7687b-j9fl4 1/1 Running 0 7m51s 192.168.70.145 ip-192-168-92-33.region-code.compute.internal <none> <none> my-deployment-5df6f7687b-rjxcz 1/1 Running 0 7m51s 192.168.73.207 ip-192-168-92-33.region-code.compute.internal <none> <none> my-deployment-5df6f7687b-zmb42 1/1 Running 0 7m51s 192.168.63.27 ip-192-168-33-28.region-code.compute.internal <none> <none>
    nota
    • Se houver Pods travados no estado Waiting, execute kubectl describe pod my-deployment-xxxxxxxxxx-xxxxx -n my-namespace. Se você observar Insufficient permissions: Unable to create Elastic Network Interface., confirme se adicionou a política do IAM à função de cluster do IAM em uma etapa anterior.

    • Se houver algum Pods preso no estado Pending, confirme se o tipo de instância do nó está listado em limits.go e se o número máximo de interfaces de rede de ramificação aceito pelo o tipo de instância multiplicado pelo número de nós do grupo de nós ainda não foi atingido. Por exemplo, um m5.large suporta nove interfaces de rede de ramificação. Se o grupo de nós tiver cinco nós, um máximo de 45 interfaces de rede de ramificação poderá ser criado para o grupo de nós. O 46º Pod que você tentar implantar ficará no estado Pending até que outro Pod que tenha grupos de segurança associados seja excluído.

    Se você executar kubectl describe pod my-deployment-xxxxxxxxxx-xxxxx -n my-namespace e ver uma mensagem semelhante à seguinte, ela pode ser ignorada com segurança: Essa mensagem pode aparecer quando o Amazon VPC CNI plugin for Kubernetes tenta configurar a rede de host e falha enquanto a interface de rede está sendo criada. O plugin CNI registra esse evento até que a interface de rede seja criada.

    Failed to create Pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "e24268322e55c8185721f52df6493684f6c2c3bf4fd59c9c121fd4cdc894579f" network for Pod "my-deployment-5df6f7687b-4fbjm": networkPlugin
    cni failed to set up Pod "my-deployment-5df6f7687b-4fbjm-c89wx_my-namespace" network: add cmd: failed to assign an IP address to container

    Você não pode exceder o número máximo de Pods que podem ser executados no tipo de instância. Para obter uma lista do número máximo de Pods que você pode executar em cada tipo de instância, consulte eni-max-pods.txt no GitHub. Quando você exclui um Pod que tenha grupos de segurança associados ou exclui o nó em que o Pod está sendo executado, o controlador de recursos da VPC exclui a interface de rede da ramificação. Se você excluir um cluster com Pods usando Pods para grupos de segurança, o controlador não excluirá as interfaces de rede da ramificação, portanto, você precisará excluí-las você mesmo. Para obter mais informações sobre como excluir interfaces de rede, consulte Interfaces de rede elásticas no Manual do usuário para instâncias do Linux do Amazon EC2.

  5. Em um terminal à parte, faça shell em um dos Pods. Para o restante do tópico, esse terminal é indicado como TerminalB. Substitua 5df6f7687b-4fbjm pelo ID de um dos Pods retornados na saída da etapa anterior.

    kubectl exec -it -n my-namespace my-deployment-5df6f7687b-4fbjm -- /bin/bash
  6. No shell em TerminalB, confirme se a aplicação de amostra funciona.

    curl my-app

    Veja um exemplo de saída abaixo.

    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    [...]

    Você recebeu a saída porque todos Pods que executam a aplicação estão associados ao grupo de segurança que você criou. Esse grupo contém uma regra que permite todo o tráfego entre todos Pods aos quais o grupo de segurança está associado. O tráfego DNS pode sair desse grupo de segurança para o grupo de segurança do cluster, que está associado aos seus nós. Os nós estão executando os Pods CoreDNS, para os quais seus Pods fizeram uma pesquisa de nome.

  7. No TerminalA, remova as regras de grupo de segurança que permitem a comunicação DNS com o grupo de segurança de cluster do grupo de segurança. Se você não tiver adicionado as regras de DNS ao grupo de segurança de cluster em uma etapa anterior, substitua $my_cluster_security_group_id pelo ID do grupo de segurança no qual as regras foram criadas.

    aws ec2 revoke-security-group-ingress --group-id $my_cluster_security_group_id --security-group-rule-ids $my_tcp_rule_id aws ec2 revoke-security-group-ingress --group-id $my_cluster_security_group_id --security-group-rule-ids $my_udp_rule_id
  8. No TerminalB, tente acessar a aplicação novamente.

    curl my-app

    Veja um exemplo de saída abaixo.

    curl: (6) Could not resolve host: my-app

    A tentativa falha porque o Pod não é mais capaz de acessar os Pods CoreDNS, que têm o grupo de segurança de cluster associado. O grupo de segurança do cluster não tem mais as regras de grupo de segurança que permitem a comunicação DNS do grupo de segurança associado ao Pod.

    Se você tentar acessar a aplicação utilizando os endereços IP retornados para um dos Pods em uma etapa anterior, ainda receberá uma resposta, pois todas as portas são permitidas entre Pods que têm o grupo de segurança associado a eles, e uma pesquisa de nome não é necessária.

  9. Quando você terminar os testes, poderá remover o exemplo de política de grupo de segurança, a aplicação e o grupo de segurança criados. Execute os comandos a seguir no TerminalA.

    kubectl delete namespace my-namespace aws ec2 revoke-security-group-ingress --group-id $my_pod_security_group_id --security-group-rule-ids $my_inbound_self_rule_id wait sleep 45s aws ec2 delete-security-group --group-id $my_pod_security_group_id