Entenda as Políticas de Rede Calico

A NetworkPolicy do Kubernetes é um recurso essencial para definir como os pods em diferentes namespaces se comunicam, tanto internamente quanto com tráfego externo. Essas políticas usam seletores de rótulos para identificar pods específicos e determinar se o tráfego é permitido ou negado, controlando conexões de entrada (ingress) e saída (egress). Sem elas, todos os pods podem se comunicar livremente, o que pode ser um risco de segurança.

Conceitos Básicos da NetworkPolicy do Kubernetes

O que é uma NetworkPolicy do Kubernetes?

Uma NetworkPolicy do Kubernetes é um recurso que define como os pods dentro de um namespace podem se comunicar com outros pods em diferentes namespaces e, em alguns casos, com tráfego externo. Esses objetos dependem de seletores de rótulos para identificar os pods e determinar se o tráfego é permitido ou negado para conexões de entrada (ingress) ou saída (egress).

Por padrão, no Kubernetes, todos os pods podem se comunicar uns com os outros sem restrições. Uma NetworkPolicy do Kubernetes introduz regras que restringem ou permitem o tráfego entre os pods com base em critérios como rótulos, namespaces e IPblocks.

Exemplo Básico de uma NetworkPolicy do Kubernetes

Aqui está um exemplo simples de uma NetworkPolicy do Kubernetes que permite todo o tráfego de entrada para o pod app-backed no namespace padrão. Este exemplo utiliza a API networking.k8s.io em vez da API do Calico.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
    - Ingress
  ingress: []
  • podSelector tem como alvo os pods rotulados com app=backend.
  • policyTypes: ["Ingress"] informa ao Kubernetes que esta política se aplicará apenas ao tráfego de entrada.
  • Uma lista ingress vazia (ingress:[]) significa que nenhum tráfego de entrada é permitido para os pods correspondentes.
  • Nota: Se um pod for selecionado por esta NetworkPolicy do Kubernetes, nenhum tráfego poderá entrar no pod de qualquer lugar, a menos que haja outra NetworkPolicy do Kubernetes que permita a entrada de tráfego.

Terminologia Essencial do Calico

O Calico expande a NetworkPolicy do Kubernetes padrão de maneiras importantes, introduzindo suas próprias APIs e conceitos.

Endpoints

  • Workload Endpoint (WEPs): São interfaces de rede para pods. Ao anexar um pod à rede Calico, o Calico cria um workload endpoint nos bastidores.
  • Host Endpoints (HEPs): Representam as interfaces dos próprios hosts ou nós. Quando o Calico aplica as políticas, ele as aplica não apenas aos pods, mas também aos nós do Kubernetes. Isso é útil quando você deseja restringir o tráfego que entra ou sai diretamente dos nós do cluster.

Políticas com Namespace vs. Globais

O Calico possui dois objetos de política primários:

  • NetworkPolicy (também chamada de Calico NetworkPolicy):
  • Semelhante à NetworkPolicy do Kubernetes, mas com funcionalidades expandidas.
  • Aplica-se aos pods, que são os workload endpoints dentro de um namespace específico.
  • GlobalNetworkPolicy:
  • Possui escopo em todo o cluster e não está vinculada a um namespace específico.
  • Pode ser aplicada a namespaces e até mesmo a host endpoints. Isso torna a GlobalNetworkPolicy uma ótima ferramenta para implementar regras de segurança em nível de cluster, como negações padrão, auditoria ou políticas de conformidade.

Considere um exemplo de uma NetworkPolicy do Kubernetes específica do Calico com namespace.

No código abaixo, observe a diferença entre a política padrão do Kubernetes, especificamente apiVerison: projectcalico.org/v3, e campos adicionais como selector.

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: allow-frontend
  namespace: default
spec:
  selector: role == 'frontend'
  types:
    - Ingress
  ingress:
    - action: Allow
      protocol: TCP
      source:
        selector: role == 'backend'
      destination:
        ports:
          - 8080
  • selective:role == 'frontend' substitui o prodSelector do Kubernetes. Os seletores de rótulos do Calico podem ser aplicados a vários tipos de recursos e oferecem operadores mais avançados.
  • action:Allow é explicitamente declarado.
  • source.selector:role == 'backend' significa que o tráfego é permitido apenas de pods rotulados com role=backend.
  • destination.ports: [8080] restringe as portas permitidas à porta TCP 8080.

Seletores

Os seletores estão no centro das políticas do Calico. Eles definem a quais endpoints as regras se aplicam. O Calico possui uma sintaxe rica de correspondência baseada em rótulos.

  • has(label) – corresponde aos recursos que possuem o rótulo fornecido.
  • label == 'value' – correspondência exata para o valor do rótulo.
  • label in {"v1","v2"} – corresponde se o valor do rótulo estiver dentro de um conjunto.
  • Operadores de negação também estão disponíveis, como ! e outros operadores como &&, ==, != e outros.

Ingress and Egress Overview

Visão Geral de Ingress e Egress

Definindo as Regras de Ingress (Entrada)

  • As regras de ingress governam o tráfego que entra nos pods ou nos seus endpoints.
  • Por exemplo, se você deseja que o tráfego venha apenas de certos pods, namespaces específicos ou endereços IP designados, você pode definir regras de ingress que correspondam a esses critérios.
  • Aqui está um exemplo da estrutura de uma regra de ingress dentro de uma política:
ingress:
  - action: Allow
    source:
      selector: label == 'some-value'
    destination:
      ports: [80, 443]

Definindo as Regras de Egress (Saída)

  • As regras de egress governam o tráfego que sai dos pods ou dos seus endpoints.
  • Isso é útil para restringir o tráfego externo. Por exemplo, você pode permitir apenas o tráfego para um intervalo CIDR conhecido ou blocos de IP específicos.
egress:
  - action: Deny
    destination:
      nets:
        - 0.0.0.0/0

O trecho acima nega efetivamente todo o tráfego de saída se incluído em uma especificação de política. Você pode refiná-lo para permitir determinados IPs ou portas.

Negação Padrão vs. Permissão Padrão

  • Por padrão, no Kubernetes sem políticas, tudo é efetivamente permitido.
  • A melhor prática para produção é começar com uma negação padrão e, em seguida, adicionar permissões explícitas para o tráfego necessário.
  • Você pode fazer isso com uma política Calico que nega todo o ingress/egress e, em seguida, adicionar políticas adicionais para o tráfego específico que você deseja permitir.
  • O Calico facilita a aplicação de negações padrão em todo o cluster e, em seguida, a aplicação da exceção conforme adequado para cada namespace ou endpoint.

Order of Enforcement

Ordem de Aplicação

Diferente da NetworkPolicy do Kubernetes nativa, onde não há um mecanismo de ordenação explícito, o Calico possui um campo de ordem onde você define a ordem ou prioridade para cada política. Uma ordem ou prioridade menor significa que a política é aplicada primeiro.

Exemplo

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: high-priority-policy
  namespace: my-namespace
spec:
  order: 100
  selector: app == "critical"
  ingress:
    - action: Deny

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: lower-priority-allow
  namespace: my-namespace
spec:
  # A lower order number means this policy is evaluated first
  order: 50
  selector: app == "critical"
  types:
    - Ingress
  ingress:
    - action: Allow

Se houver várias políticas que correspondam ao mesmo tráfego, o Calico as aplicará começando com a política que possui o número de ordem mais baixo. A primeira ação terminal encontrada, por exemplo, “allow” ou “deny”, determina o que acontece com o pacote.

No exemplo acima, a ação “allow” será implementada, pois a política com o número mais baixo (50) tem a ação “allow”.

Comparação com a Ordenação Nativa do Kubernetes

  • Na NetworkPolicy do Kubernetes nativa, os objetos não têm uma ordenação inerente. Várias políticas podem ser aplicadas simultaneamente, e o tráfego é permitido apenas se for permitido por todas as diferentes políticas.
  • A abordagem do Calico é mais flexível. O Calico primeiro analisa a ordem mais baixa e, uma vez que o tráfego é permitido ou negado pela regra terminal, o Calico não continua avaliando as políticas de rede subsequentes.

Instalação e Configuração do Cluster Calico

Instalando o Calico

Para instalar o Calico, você pode usar o Helm ou o kubectl apply, dependendo da sua preferência e do ambiente do cluster.

Abaixo está uma visão geral de ambos os métodos.

Instalação Usando kubectl apply

Baixando os Manifestos do Calico

  • Geralmente, você precisa obter um arquivo como tiger-operator.yaml e outro contendo seus recursos personalizados custom-resources.yml da versão oficial do projeto Calico.

Aplicando os Manifestos

kubectl apply -f tigera-oprator.yaml
kubectl apply -f custom-resources.yaml
  • O primeiro comando instala o Tigera Operator, que gerencia os componentes do Calico.
  • O segundo comando configura o Calico com os padrões ou seus parâmetros personalizados, por exemplo, IP pools ou intervalos CIDR.

Aguarde a Inicialização dos Pods

  • Os componentes do Calico normalmente são executados no namespace calico–system ou tigera-operator.

Instalação Usando o Helm

  1. Adicione o repositório Helm do Calico:
helm repo add projectcalico https://projectcalico.docs.tigera.io/charts
  1. Instale o gráfico
helm install calico projectcalico/tigera-operator --version <CHART_VERSION>
  • Este comando implanta o Tiger operator e os recursos adicionais necessários para executar o Calico.
  • Se você tiver valores para substituir os padrões, você pode especificá-los com -f custom-values.yaml.
  1. Verifique a instalação
  • Verifique se o operator e os pods do Calico estão em execução nos namespaces relevantes.

Verify Calico functionality

Verificando a Funcionalidade do Calico

Após a instalação, é importante confirmar se o Calico foi iniciado com sucesso e está sendo executado como a Container Network Interface (CNI) primária.

Verificando os Pods em Execução

  1. Liste os pods nos namespaces relevantes.
kubectl get pods -n calico-system

ou

kubectl get pods -n tigera-operator

O namespace exato depende do método usado. Em muitas configurações, você pode encontrar os pods calico-node, calico-cube-controllers ou tigers-operator.

  1. Status Detalhado do Pod
kubectl describe pod <pod-name> -n calico-system

Se algum pod estiver em CrashLoopBackOff ou Pending, inspecione a seção Events para obter dicas sobre o que pode ter sido configurado incorretamente.

Confirmando o Calico como o CNI

  1. Verifique as configurações do nó
kubectl get nodes -o wide

Você pode ver os detalhes de rede específicos do Calico no endereço interno do nó ou na anotação que referencia chi.projectcalico.org.

  1. Inspecione um pod de teste
kubectl run testpod --image=busybox --restart=Never -it
kubectl describe pod testpod

Procure referências ao Calico na descrição do pod de teste nas anotações de rede, por exemplo, k8s.v1.cni.projectcalico.org/....

Para confirmar se seus pods estão agora sendo conectados em rede via Calico, procure referências a chi.projectcalico.org.

Comportamento Padrão do Calico

Por padrão, todas as implantações do Calico começam com o modo allow all. Isso significa que:

  • Nenhuma regra de política de rede está restringindo ativamente qualquer tipo de tráfego, a menos que você crie explicitamente as regras.
  • A menos que você use uma distribuição Kubernetes que imponha restrições padrão, todos os Pods no seu Cluster podem se comunicar uns com os outros em todos os namespaces.

Testando a Conectividade de Linha de Base

Antes de começar a criar e aplicar qualquer objeto Calico NetworkPolicy do Kubernetes, é bom verificar se a rede padrão do seu cluster se comporta como esperado.

  1. Crie vários pods de teste em diferentes namespaces.
kubectl create namespace dev
kubectl create namespace prod

kubectl run test1 --image=busybox --restart=Never -n dev -- sleep 3600
kubectl run test2 --image=busybox --restart=Never -n prod -- sleep 3600
  1. Verifique a conectividade entre test1 e test2.
kubectl exec -n dev test1 -- ping -c 3 test2.prod.svc.cluster.local

Você pode confirmar se os pods conseguem se alcançar em todos os namespaces quando vir respostas de ping bem-sucedidas.

Por Que Uma Linha de Base é Importante

Ter uma linha de base para a comunicação pod a pod significa que, se você aplicar uma política de rede e a conectividade for interrompida, você saberá que a política é a causa, em vez de qualquer outro problema do cluster. Isso ajuda você a solucionar problemas facilmente.

Criando uma NetworkPolicy do Kubernetes Básica com Exemplo

Política de Negação de Namespaces

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: deny-inbound
  namespace: app-namespace
spec:
  selector: app == "my-service"
  types:
    - Ingress
  ingress:
    - action: Deny

Explicação Campo a Campo

  • apiVersion: projectcalico.org/v3 / kind: NetworkPolicy
  • Isso mostra que a política está usando a definição de recurso personalizado do Calico para suas políticas de rede.
  • As políticas de rede do Calico são totalmente compatíveis com as políticas de rede do Kubernetes, apenas oferece alguns recursos estendidos.
  • metadata
  • name: deny-inbound: Este deny-inbound é o nome da política.
  • namespace:app-namespace: Isso significa que esta política se aplicará apenas ao namespace app-namespace.
  • spec:
  • selector: app == “my-service”
  • O Calico usa um seletor baseado em rótulos para direcionar os pods.
  • No namespace app-namespace, qualquer pod rotulado com app=my-service terá esta política.
  • Isso é como o podSelector do Kubernetes, mas tem uma sintaxe de seletor Calico mais flexível.
  • types: [“Ingress”]
  • Especifica que a política afeta o tráfego de entrada.
  • “Egress” controla o tráfego que sai do pod. Você também pode ter Ingress e Egress no mesmo array, se quiser especificar uma política para ambos.
  • ingress:
  • Aqui definimos uma regra com action: Deny.
  • Como não há regras Allow depois dela, todo o tráfego que deseja entrar nos pods que correspondem a app=my-service será descartado.

Testando a Política

Vamos agora testar a política.

kubectl apply -f deny-inbound.yaml

e

kubectl get networkpolicy -n app-namespace

Você pode ver o deny-inbound listado com outras políticas de rede ativas.

Usando kubectl exec

Criando um pod de teste no namespace.

kubectl run test-client --image=busybox --restart=Never -it

Tentando uma conexão com o pod rotulado com app=my-service.

# For example, if the "my-service" pod is named my-service-pod:
kubectl exec -it test-client -- wget -qO- http://<my-service-pod-ip> 

E por causa da política, você pode ver a conexão falhar ou travar, mostrando que o ingress é negado.

Rotulagem Consistente

Certificando-se de que seus rótulos correspondam exatamente a app: my-service na especificação do pod e que.

Dicas Práticas e Próximos Passos

  • Adicione Políticas Adicionais: Em cenários do mundo real, você pode precisar adicionar várias políticas de rede – algumas permitem portas específicas ou determinado tráfego de pods ou endereços IP específicos.
  • Monitore os Logs do Pod: Se os pods tiverem logs ou métricas sobre solicitações de entrada e saída, você poderá verificar se as políticas que você definiu estão funcionando corretamente.

Recursos Avançados da Política

Políticas de Rede Globais

Uma GlobalNetworkPolicy é um recurso Calico que se aplica a todos os namespaces e host endpoints dentro de um cluster Kubernetes, em comparação com a NetworkPolicy do Kubernetes, que tem namespace.

Aqui estão alguns dos casos de uso:

  • Aplicando uma negação padrão em todo o cluster.
  • Aplicando regras de auditoria/logging em todos os namespaces por motivos de conformidade.

Exemplo: Uma Política Global para Auditoria

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: audit-global-policy
spec:
  selector: all()
  types:
    - Ingress
  ingress:
    - action: Log

Pontos Chave

  • selector: all()
  • O seletor all() significa que ele terá como alvo todos os recursos no cluster, incluindo todos os pods, host endpoints, etc.
  • types [“Ingress”]
  • Ingress significa que ele se concentra no tráfego de entrada.
  • action:log
  • Isso apenas registra todo o tráfego.

Correspondência Avançada de Rótulos

O Calico permite combinar vários tipos de seletores como selector, namespaceselector e serviceAccountSelector. Isso ajuda você a controlar clusters multi-inquilinos ou ambientes de grande escala.

Exemplo: namespaceSelector + Seletor Padrão

Aqui está um código de exemplo ilustrando como você pode permitir o tráfego apenas para pods rotulados com role=frontend.

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: allow-prod-frontend
  namespace: my-namespace
spec:
  selector: role == 'frontend'
  namespaceSelector: environment == 'production'
  types:
    - Ingress
  ingress:
    - action: Allow
      # Additional rule details...

Nuances de Ingress vs. Egress

Ingress vs. Egress no Calico

  • As regras de ingress definem qual tráfego é permitido nos pods/endpoints.
  • As regras de egress definem qual tráfego sai dos pods/endpoints.

Como as aplicações modernas geralmente dependem de serviços externos, as políticas de egress são essenciais para impedir que os pods façam conexões não autorizadas.

Cenário de Exemplo: Pods app=web com Egress Restrito

Aqui, estamos considerando um exemplo em que queremos permitir que os pods rotulados com app=web apenas saiam para um intervalo de IP externo que hospeda uma API 10.0.0.23/24, enquanto bloqueamos todo o outro egress externo.

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: restrict-web-egress
  namespace: prod-apps
spec:
  selector: app == "web"
  types:
    - Egress
  egress:
    # Deny everything first
    - action: Deny
    # Then allow traffic to the known IP block
    - action: Allow
      destination:
        nets:
          - 10.0.10.0/24

Aplicando Ações: Allow, Deny, Pass, Log

O Calico oferece suporte para as principais ações terminais na política. Estas são:

  • Allow: Permite que o tráfego flua e interrompe a avaliação adicional das regras subsequentes.
  • Deny: Descartar o tráfego imediatamente e interrompe a avaliação adicional das regras subsequentes.
  • Log: Registra o tráfego, mas continua a avaliar regras adicionais, se presentes. Se isso for usado como parte de uma regra, o tráfego que corresponde a essa regra é registrado.
  • Pass: Esta regra é dedicada ao Calico; quando encontrada, ela apenas ignora todas as políticas do Calico e avalia o perfil anexado à carga de trabalho. As regras Pass transferem a decisão final para as regras de nível de perfil.

Para aprender mais sobre como gerenciar a segurança da sua rede, você pode conferir este artigo sobre a revolução do software e como a IA está transformando tudo. Além disso, se você está interessado em soluções de armazenamento, pode encontrar informações relevantes sobre a tecnologia de resfriamento líquido da Super Micro, que dobra a potência de servidores. E para aqueles que buscam melhorar a duração da bateria de seus dispositivos Android, temos um artigo com 12 dicas essenciais.

Este conteúdo foi auxiliado por Inteligência Artificial, mas escrito e revisado por um humano.

Via dev.to

Leave a Comment