Skip to main content

Práticas recomendadas para políticas de rede do Kubernetes

Escrito por

Peter De Tender

Kubernetes Blog

21 de dezembro de 2022

0 minutos de leitura

Controlar e filtrar o tráfego ao executar cargas de trabalho em contêineres dentro de Pods do Kubernetes é tão importante quanto usar um firewall em uma rede tradicional. A diferença é que, nesse cenário, esses recursos são fornecidos pela API Kubernetes NetworkPolicy.

Neste artigo, vamos explorar o Kubernetes NetworkPolicy criando um exemplo de política de rede e analisando seus principais parâmetros. Em seguida, veremos alguns casos de uso comuns do NetworkPolicy e aprenderemos a monitorá-los com o kubectl. Por fim, vamos descobrir como implementar a Container Network Interface (CNI) usando extensões de terceiros para Kubernetes.

Por que você não deve evitar as políticas de rede do Kubernetes

Implementar políticas de rede é essencial para operar um ambiente Kubernetes. Sem uma política de rede configurada, todos os Pods de um cluster podem se comunicar entre si por padrão. Portanto, quando um Pod contém dados confidenciais, como um banco de dados de back-end com informações sigilosas, precisamos garantir que somente determinados Pods de front-end possam se conectar a ele.

Como alternativa, podemos isolar o tráfego de rede entre os Pods de um ambiente de desenvolvimento e aqueles em execução em um ambiente de produção. Sem políticas de rede, todo o tráfego circula livremente entre todos os pontos da rede.

Felizmente, configurar o Kubernetes NetworkPolicy é uma maneira simples, eficaz e abrangente de garantir que o tráfego de rede flua apenas como esperado.

Como definir políticas de rede do Kubernetes

Vamos analisar um exemplo de NetworkPolicy. Considere uma carga de trabalho de exemplo com um front-end WordPress e um banco de dados MySQL no back-end, executando um conjunto de Pods com serviços Web e de banco de dados, todos implantados no namespace default do Kubernetes. Os protocolos de segurança da empresa exigem o isolamento do tráfego de rede de cargas de trabalho específicas e a permissão apenas do tráfego de entrada e saída estritamente necessário para acessá-las.

Essa estratégia envolve as seguintes condições:

  • Bloquear o comportamento padrão do Kubernetes, que permite todo o tráfego.

  • Garantir que somente os Pods com o rótulo wordpress no namespace default possam se comunicar entre si.

  • Permitir conexões de entrada (ingress) da internet pública nas portas 80/443 e no intervalo de IPs 172.16.0.0.

  • Permitir que somente os Pods com o rótulo wordpress se conectem aos Pods do banco de dados MySQL na porta 3306.

  • Permitir sempre a conexão com o serviço DNS do Kubernetes (porta 53).

  • Bloquear todas as conexões de saída para fora do cluster.

O diagrama de rede abaixo ilustra como essas regras poderiam ser representadas.

Diagrama que mostra políticas padrão de negação de entrada e saída no namespace do Kubernetes, com as portas 80 e 443 selecionadas e o tráfego DNS permitido.

Neste exemplo, podemos distribuir as políticas de rede em arquivos de definição separados ou combinar todas as políticas em um único arquivo de manifesto YAML. Como nosso exemplo usa uma única carga de trabalho (webapp), faz sentido usar um único arquivo de definição de regras. No entanto, como há várias conexões de entrada e saída neste exemplo, também poderíamos criar arquivos de configuração individuais para cada conexão dentro do cluster.

Vamos analisar alguns dos parâmetros usados acima para entender como eles se relacionam com a configuração e afetam o comportamento do tráfego de rede.

API e metadados

Na primeira linha do arquivo YAML abaixo, especificamos a API de rede (networking.k8s.io) e sua versão (v1). Também definimos o tipo de arquivo YAML como NetworkPolicy, informando ao controlador da API do Kubernetes que estamos configurando políticas de rede. Os itens name e namespace na seção metadata contêm o nome que damos a esse conjunto de regras e o namespace ao qual ele está associado.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: sample-network-policy
  namespace: default

A próxima parte do arquivo YAML contém a seção de especificações (specs), onde podemos definir os filtros aos quais a política de rede será aplicada.

O trecho abaixo contém vários parâmetros importantes:

  • podSelector — especifica quais Pods estão sujeitos às políticas de tráfego definidas. Nosso exemplo usa o parâmetro matchLabels para garantir que a política de rede se aplique a todos os Pods com o rótulo app: wordpress. Como resultado adicional, o parâmetro exclui todos os outros Pods dessa política de rede.

  • policyTypes — contém duas categorias: Ingress e Egress

  • Ingress — define todo o tráfego de entrada entre Pods, namespaces e conjuntos de Pods

  • Egress — define todo o tráfego de saída entre Pods, namespaces e conjuntos de Pods

spec:
  podSelector:
    matchLabels:
      app: wordpress
  policyTypes:
    - Egress
    - Ingress

Em seguida, a seção ingress da política de rede define os tipos de tráfego de entrada permitidos. O trecho abaixo permite conexões de entrada nas portas 443 e 80 provenientes de:

  • Todos os Pods com o rótulo wordpress

  • Todo o tráfego da internet pública (cidr: 0.0.0.0/0)

  • Todos os endereços IP no intervalo 172.16.0.0/16, que pode representar um intervalo de IPs corporativo (VPN, VLAN ou sub-rede).

O trecho YAML que permite o tráfego acima ficaria assim:

  ingress:
    - from:
      - podSelector:
          matchLabels:
            app: wordpress
      ports:
        - port: 443
        - port: 80  
    - from:
      - ipBlock:
          cidr: 172.16.0.0/16
      ports:
        - port: 443
        - port: 80
    - from:
      - ipBlock:
          cidr: 0.0.0.0/0
      ports:
        - port: 443
        - port: 80

Por fim, detalhamos a seção egress com as regras de tráfego de saída. Permitimos toda a comunicação de saída dos Pods com o rótulo webapp nas portas 1433 (SQL) e 53 (DNS).

Especificar o rótulo webapp garante que nenhum outro Pod possa se comunicar com as instâncias do SQL Server, eliminando todos os riscos de segurança associados. Da mesma forma, a configuração permite que a porta 53 se conecte a todos os Pods do cluster.

Há mais um ponto importante a considerar nesta definição de política. Depois de integrar uma política de rede para controlar a conectividade dos Pods, precisamos configurar as regras de permissão e bloqueio nos dois sentidos. Permitir tráfego de saída do front-end sem permitir tráfego de entrada no back-end impedirá a comunicação.

O trecho YAML desta parte do tráfego é parecido com o exemplo abaixo:

  egress: 
    - to:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - port: 53
          protocol: UDP

    - to:
        - podSelector:
            matchLabels:
              app: wordpress
      ports:
        - port: 3306

Como aplicar políticas de rede do Kubernetes

Agora concluímos o manifesto YAML de exemplo da Network Policy, que ficou assim:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: sample-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: webapp
  policyTypes:
    - Egress
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: webapp
      ports:
        - port: 443
        - port: 80
    - from:
        - podSelector: {}
    - from:
        - ipBlock:
            cidr: 172.16.0.0/16
      ports:
        - port: 443
        - port: 80
    - from:
        - ipBlock:
            cidr: 0.0.0.0/0
      ports:
        - port: 443
        - port: 80
  egress:
    - to:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - port: 53
          protocol: UDP
    - to:
        - podSelector: {}
    - to:
        - podSelector:
            matchLabels:
              app: webapp
      ports:
        - port: 443
        - port: 80

Agora, precisamos inserir nosso arquivo no cluster Kubernetes. Para isso, primeiro salve-o como sample-network-policy.yaml.

Agora, aplicamos o arquivo de definição como fazemos com a maioria das outras configurações do Kubernetes: usando a interface de linha de comando (CLI) do kubectl.

Execute o seguinte comando:

kubectl apply -f sample-network-policy.yaml
Terminal mostrando o kubectl apply criando a política de rede de exemplo do Kubernetes

Como validar e monitorar políticas de rede do Kubernetes

Assim como no gerenciamento tradicional de firewalls, validar e monitorar políticas de rede do Kubernetes exige supervisão operacional. De tempos em tempos, precisamos reavaliar as regras de rede existentes para decidir se ainda se aplicam à carga de trabalho associada.

Também pode ser necessário validar o conjunto de regras para solucionar problemas de tráfego ou investigar conflitos entre diferentes políticas de rede. Felizmente, podemos validar as Network Policies usando a CLI do kubectl. A execução do comando a seguir analisa e monitora suas políticas de rede atuais:

kubectl describe networkpolicy <networkpolicy name as listed in the YAML manifest>

Veja abaixo um exemplo de saída para o tipo de política ingress.

Saída do terminal mostrando uma NetworkPolicy do Kubernetes com “Permitir tráfego de entrada” destacado e regras para as portas 443 e 80.

Além disso, esta imagem mostra um exemplo de saída para o tipo de política egress:

Saída do terminal mostrando tráfego de saída permitido para kube-dns e pods de aplicativos web, com tipos de política de saída e entrada

Práticas recomendadas para aplicar políticas de rede do Kubernetes

Assim como em qualquer configuração de segurança de rede, devemos adotar algumas práticas recomendadas para as políticas de rede do Kubernetes:

  • Use a política de rede padrão deny-all para garantir que somente as comunicações explicitamente permitidas ocorram.

  • Agrupe os Pods que precisam se comunicar entre si usando o parâmetro PodSelector.

  • Permita a comunicação entre namespaces somente quando necessário.

  • Não permita comunicações de rede desnecessárias — nem mesmo dentro do cluster Kubernetes.

  • Tenha cuidado ao permitir que Pods dentro do cluster recebam tráfego de rede externo ao cluster.

  • Bloquear o tráfego de saída para a internet pública pode interferir em determinadas atualizações de aplicativos ou processos de validação.

Plugins CNI do Kubernetes otimizam o gerenciamento de políticas de rede

Uma das vantagens dos plugins CNI é que eles abstraem os detalhes de implementação da Network Policy, permitindo que os administradores do cluster escolham a melhor solução para suas necessidades sem lidar com a complexidade das tecnologias subjacentes.

No entanto, as instalações padrão do Kubernetes não incluem um plugin CNI pré-instalado, a menos que sua distribuição ou seu provedor tenha adicionado um. Isso significa que você precisará escolher e instalar o plugin mais adequado às suas necessidades. Além disso, mesmo que sua distribuição tenha um plugin padrão, talvez outro atenda melhor aos seus requisitos.

Há diversos provedores de CNI, e alguns dos mais populares são:

Cada plugin tem recursos específicos, então talvez você precise testar alguns para decidir qual opção atende melhor às suas necessidades de rede e segurança de rede.

Conclusão

Configurar uma topologia de rede corporativa com roteamento complexo, regras de tráfego e integrações de segurança pode ser trabalhoso. Felizmente, em um ambiente Kubernetes, as políticas de rede oferecem os mesmos recursos que os firewalls proporcionavam na infraestrutura tradicional.

É claro que configurar políticas de rede é apenas a primeira etapa de um processo que exige reavaliação e manutenção periódicas. Embora o plugin kubenet integrado ofereça alguns recursos de rede para o gerenciamento de políticas, outros plugins CNI disponibilizam funcionalidades mais avançadas. Felizmente, a combinação certa de políticas e gerenciamento mantém o tráfego de rede seguro e eficiente.

Mais recursos sobre segurança do Kubernetes

Proteja a infraestrutura desde a origem

A Snyk automatiza a segurança e a conformidade de IaC nos fluxos de trabalho e detecta recursos com configurações divergentes ou ausentes.