Skip to main content

Command Palette

Search for a command to run...

Network Policies: microsegmentação em clusters Kubernetes

Updated
7 min read
Network Policies: microsegmentação em clusters Kubernetes

Conforme nosso ambiente evoluí, mais e mais aplicações passam a ser executadas em nossos clusters, o que em larga escala, pode se tornar complicado para gerir. Visando fornecer uma maneira mais eficiente de controlar o acesso aos recursos do seu cluster, vamos falar sobre as Network Policies, que com um toque de Cilium, nos permitem garantir a boa proteção dos nosso ambientes, independente da complexidade.


Microssegmentação

É uma nova forma de segregação de redes amplamente utilizado em ambientes de nuvem pública. Em uma era onde segurança entra acima de todo o restante e o principal “norte” para os times de engenharia são os pilares do zero trust, proteger a base da sua infraestrutura é essencial.

Independente do tamanho do ambiente, precisamos garantir a aplicação dos princípios do zero trust, implementando de forma eficiente os controles necessários para evitar que atores indesejados consumam nossos recursos, que as aplicações da organização fiquem expostas à possíveis vulnerabilidades e ainda pior, exponham os demais recursos do ambiente a esses atores.

A microssegmentação olha ao nível “mais baixo” dos recursos, atuando como uma malha entre todos os serviços da sua nuvem e permitindo o controle de acesso entre os recursos de maneira flexível e detalhada.

O desenho acima exemplifica em alto nível como a microssegmentação atua nos ambientes. Com ela, é possível definir um perímetro ao redor de cada um dos recursos, controlando o acesso por origem, IP, protocolo e outras informações.

💡
Configurar a microssegmentação nos ambientes é uma tarefa extremamente trabalhosa e exaustiva. Hoje, empresas líderes de mercado como a Akamai oferecem soluções de microssegmentação indepentendente da nuvem que você utilize. Essas soluções tornam mais simples a implementação e a gestão da configuração dos ambientes. Veja: Akamai Guardicore.

Network Policies

Reduzindo nosso escopo de atuação apenas aos clusters Kubernetes, precisamos falar das Network Policies.

Entendendo o recurso

As Network Policies são recursos padrão existentes nos clusters Kubernetes, que possibilitam a segmentação dos recursos sendo executados no cluster (namespaces, pods, svc, etc). Com as policies padrão já estamos habilitados a incrementar a segurança do nosso ambiente, porém segurança nunca é demais.

Para termos um maior nível de detalhes na criação das políticas, podemos utilizar a versão deste recurso fornecida pelo Cilium, solução que tratamos no post passado. Ao utilizarmos o Cilium como a solução de Container Network Interface dos nossos clusters, podemos implementar regras em diferentes camadas (L3, L4 e L7) e utilizando informações adicionais, trafegadas nas requisições feitas entre os recursos. Não apenas isso, se tivermos a Cluster Mesh habilitada entre nossos clusters que executam o Cilium, podemos criar policies que ultrapassam os limites de cada um dos ambientes Kubernetes. Bom, né?

Antes de passarmos para a real configuração das policies, gostaria de trazer conceitos gerais sobre elas, que facilitarão o seu entendimento no momento de configuração dos recursos.

Funcionamento

Como explicado anteriormente, as policies permitem que nós controlemos o acesso feito aos recursos do cluster e saindo dos recursos. São “regras” criadas com um escopo específico e que validarão TUDO que passar por ali.

No desenho acima podemos visualizar um cluster com 3 namespaces com policies aplicadas e o fluxo de rede que é permitido/proibido em cada uma delas.

Podemos confirmar que a policy do namespace 2 permite consumo vindo de pods com a label color:green. Essa policy também permite o acesso ao mundo externo (fora do cluster) pelos pods que ali estão. A policy aplicada no namespace 2 não declara em momento algum o permissionamento para que os pods restantes no namespace 1 possam acessar seus recursos, o que por padrão, proíbe a chamada.

Para dar uma ideia, uma policy parecida com a que seria aplicada no namespace 2 seria:

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: namespace2-policy
  namespace: <NAMESPACE>
spec:
  endpointSelector:
    matchLabels: {}
  ingress:
    - fromEndpoints:
      - matchLabels:
          color: green
  egress:
    - toEntities:
      - "world"

A policy representada acima será aplicada no <NAMESPACE> determinado e permitirá as chamadas vindas de recursos com a label color:green (Ingress) e permitirá também chamadas feitas dos pods presentes no namespace para fora do cluster.

💡
Entraremos nos detalhes da criação das policies em um artigo futuro, neste momento se concentre em entender o padrão dos templates e as similaridades entre eles.

Agora que entendemos como as policies são construídas e aplicadas, vamos detalhar mais os diferentes tipos e as diferenças entre elas.

Comportamento padrão

O funcionamento padrão dos clusters Kubernetes é permitir todas as chamadas de origem interna. Para contornarmos essa situação, é necessário aplicar uma policy qualquer no escopo desejado. Uma vez que temos uma policy aplicada, o cluster passará a levar em conta APENAS o que está determinado nela.

Esse comportamento pode parecer problemático, porém alterá-lo “cegamente” pode desencadear uma série de problemas que não foram mapeados anteriormente pelos times. Existem recursos do cluster que precisam acessar endpoints externos para que sua execução ocorra da forma esperada. Ao aplicar uma policy que modifique esse comportamento, estaremos modificando o funcionamento do cluster, interrompendo as operações de negócio que são apoiadas pelas aplicações ali executadas.

Portanto, CUIDADO!

O escopo de aplicação das policies também é importante. Dentro do Kubernetes, temos recursos que são namespaced, restritos ao namespace onde foram criados e cluster-wide, ou seja, disponíveis pelo cluster todo. A aplicação das policies também cai nesse cenário. Uma policydefault” será configurada no namespace onde o usuário executar sua criação, a não ser que ela seja do tipo CiliumClusterwideNetworkPolicy. As policies protegerão seus próprios namespaces, então tenha em mente que liberar chamadas no namespace destino pode não ser suficiente, havendo a necessidade de alterar a policy cadastrada na origem.

Ingress/Egress

A direção do tráfego é parte crucial na montagem das policies. Precisamos declarar para qual direção aquelas regras deverão ser aplicadas.

  • Ingress - todas as chamadas que estão entrando no determinado escopo.

  • Egress - chamadas oriundas do escopo de aplicação da policy, independente do destino.

Essa declaração nos permite entender o fluxo das chamadas feitas pelas aplicações que ali estão hospedadas.

Seguindo o exemplo das seções acima, o template que aplicaria essa policy seria:

 ingress:
    - fromEndpoints:
      - matchLabels:
          color: green
  egress:
    - toEntities:
      - "world"

Scoped Network Policies

Passando a falar sobre as policies em si, temos o primeiro “tipo”, que são as policies com escopo. Essas são aquelas policies aplicadas em namespaces específicos, que aplicarão os controles aos recursos ali contidos.

Todo o tráfego de entrada e de saída do namespace especificado será tratado pela policy.

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: namespace2-policy
  namespace: <NAMESPACE>
spec:
  endpointSelector:
    matchLabels: {}
  ingress:
    - fromEndpoints:
      - matchLabels:
          color: green
  egress:
    - toEntities:
      - "world"

Esse é o tipo “padrão” das policies, levando em si o comportamento default aplicado no cluster.

Cluster-wide Network Policies

Para cenários onde é necessária a configuração de restrições de acesso independente do recurso, podemos utilizar as policies de escopo cluster-wide.

💡
Essas políticas terão impacto no cluster como um todo, portanto é preciso ser cuidadoso ao utilizá-la, visto que outros recursos podem sofrer impacto com suas regras.
apiVersion: "cilium.io/v2"
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: cluster-policy
spec:
  endpointSelector:
    matchLabels: {}
  ingressDeny:
    - fromEntities:
      - "world"
  egress:
    - toEntities:
      - "world"

Por trás dos panos, a policy é identica às policies namespace scoped, com sua principal diferença sendo seu kind que agora é CiliumClusterwideNetworkPolicy e a disponibilidade de uso do recurso nodeSelector, que nos permite especificar os nodes para quais a política será aplicada.

Cross-cluster Network Policies

Chegamos a um extremo diferencial entre as policies default e as policies oferecidas pelo Cilium.

Utilizando as capacidades de cluster mesh, podemos configurar policies dentre os diferentes clusters que fazem parte da nossa mesh. A integração é possibilitada pelo uso da label io.cilium.k8s.policy.cluster que nos permitirá identificar o cluster que originou a requisição.

Esse recurso é especialmente útil para ambientes consumidos por diversas outras áreas, que precisam garantir que apenas os recursos disponibilizados estão sendo consumidos. Ambientes com grandes quantidades de clusters também podem usufruir dos benefícios gerados pela utilização das cluster-wide policies.

Ter a cluster mesh habilitada é um pré-requisito para utilizar as cluster-wide policies, porém a habilitação deste recurso ficará para os próximos artigos.


Por enquanto é só. Espero que tenha gostado do texto.

Até logo!

DevOps / Platform Engineering

Part 7 of 8

Aqui você encontrará todos os artigos relacionados a DevOps, Platform Engineering, Open Source, Cloud Native e muito mais assuntos do mundo da engenharia!

Up next

Azure Kubernetes Service + Cilium

Vamos descobrir como observabilidade e segurança podem ser garantidas de forma simples, eficiente e cloud native.