K8s em Exemplos: Políticas de Rede

NetworkPolicies são regras de firewall para Pods. Por padrão, todos os Pods podem se comunicar livremente. Policies restringem tráfego a regras de permissão explícitas. Requer um CNI que suporte NetworkPolicy (Calico, Cilium, etc.).

network-policy.yaml

NetworkPolicies usam a API networking.k8s.io/v1. podSelector define quais Pods a policy se aplica. Uma vez selecionados, Pods ficam isolados para os policyTypes especificados.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-policy
  namespace: my-app
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
    - Ingress
    - Egress
network-policy-ingress.yaml

Regras de ingress controlam tráfego de entrada. Este exemplo permite tráfego de Pods frontend na porta 8080. Selector vazio {} seleciona todos os Pods no namespace.

spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080
network-policy-logic.yaml

Múltiplos selectors em um bloco from usam lógica AND (primeiro exemplo: requer AMBOS namespace E pod selector). Múltiplos blocos from usam lógica OR (segundo exemplo: corresponde QUALQUER UM). Cuidado com esta distinção - é uma fonte comum de erros em policies.

ingress:
  - from:
      - namespaceSelector:
          matchLabels:
            env: production
        podSelector:
          matchLabels:
            role: frontend
---
ingress:
  - from:
      - namespaceSelector:
          matchLabels:
            env: production
      - podSelector:
          matchLabels:
            role: frontend
network-policy-namespace.yaml

Permita tráfego de outros namespaces usando namespaceSelector. A label kubernetes.io/metadata.name é auto-aplicada a todos os namespaces. Selector vazio {} corresponde qualquer namespace.

ingress:
  - from:
      - namespaceSelector:
          matchLabels:
            kubernetes.io/metadata.name: monitoring
    ports:
      - protocol: TCP
        port: 9090
  - from:
      - namespaceSelector: {}
        podSelector:
          matchLabels:
            role: ingress-controller
network-policy-egress.yaml

Controle tráfego de egress (saída). Primeira regra permite DNS (porta 53) - crítico ou Pods não conseguem resolver nomes. Segunda regra permite HTTPS externo exceto IPs privados. Use ipBlock para permitir/negar ranges CIDR específicos.

egress:
  - to:
      - namespaceSelector:
          matchLabels:
            kubernetes.io/metadata.name: kube-system
    ports:
      - protocol: UDP
        port: 53
  - to:
      - ipBlock:
          cidr: 0.0.0.0/0
          except:
            - 10.0.0.0/8
            - 172.16.0.0/12
            - 192.168.0.0/16
    ports:
      - protocol: TCP
        port: 443
default-deny.yaml

Policies default deny isolam um namespace. Aplique estas primeiro, depois adicione regras de permissão específicas. Boa prática para clusters multi-tenant e networking zero-trust.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
spec:
  podSelector: {}
  policyTypes:
    - Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
spec:
  podSelector: {}
  policyTypes:
    - Egress
network-policy-ports.yaml

Portas nomeadas referenciam nomes de porta do container ao invés de números. Mais manutenível quando números de porta mudam. Use endPort para corresponder ranges de portas.

ingress:
  - from:
      - podSelector:
          matchLabels:
            app: frontend
    ports:
      - protocol: TCP
        port: http
      - protocol: TCP
        port: 8000
        endPort: 8100
terminal

Debug NetworkPolicies verificando quais policies se aplicam a um Pod e verificando suporte do CNI. Policies são aditivas - se qualquer policy permite tráfego, ele é permitido.

$ kubectl get networkpolicies -n my-app
NAME                   POD-SELECTOR   AGE
api-policy             app=api        5m
default-deny-ingress   <none>         10m

$ kubectl describe networkpolicy api-policy
Spec:
  PodSelector: app=api
  Allowing ingress traffic:
    To Port: 8080/TCP
    From:
      PodSelector: app=frontend

$ kubectl run test --rm -it --image=busybox -- wget -qO- http://api:8080
Hello from API!

$ kubectl get pods -n kube-system -l k8s-app=calico-node
NAME                READY   STATUS    AGE
calico-node-abc12   1/1     Running   30d

Índice | GitHub | Use as setas do teclado para navegar |