Configurando Network Policies K8S

Sun, Feb 7, 2021 3-minute read

Por padrão, os pods não são isolados, eles aceitam tráfego de qualquer origem. Podemos então usar Network Policies ( netpol ) para controlar o fluxo de dados de IPs ou Portas em nosso cluster K8S, ou seja, Network policy é quem ditar como o pod vai se comunicar com os demais recursos do cluster.

O netpol (NetworkPolicy) aceita as seguintes formas de filtro:

  • podSelector: filtro a partir de pod;
  • namespaceSelector: filtro a nível de namespace;
  • ipBlocks: filtro baseado em range de IP (CIDR ranges).

Para usar NetworkPolicy você teve de usar um Network plugin que suporte este recurso, veja a lista de network plugins para verificar se o CNI usado suporta NetworkPolicies.

Entendendo então esse tal de netpol:

  1. Crie um deployment e exporte o serviço:
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: http-app
  name: http-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: http-app
  strategy: {}
  template:
    metadata:
      creationTimestamp: null 
      labels:
        app: http-app
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80
        resources: {}
status: {}
---
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: http-app
  name: http-app
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: http-app
  type: ClusterIP
status:
  loadBalancer: {}
  1. Verifique o deployment e o serviço criado:
kubectl get pod,deploy,svc
NAME                           READY   STATUS    RESTARTS   AGE
pod/http-app-df4c685f5-qkqgm   1/1     Running   0          26m

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/http-app   1/1     1            1           26m

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/http-app     ClusterIP   10.110.82.93   <none>        80/TCP    26m
service/kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   25d
  1. Agora teste o funcionamento do serviço:
kubectl run busybox --rm -ti --image=busybox -- /bin/sh
/ # wget -qO- http-app --timeout=5
...
<h1>Welcome to nginx!</h1>
...
  1. Crie uma netpol que limite todo o acesso à aplicação http-app:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: access-http-app
spec:
  podSelector:
    matchLabels:
      app: http-app
  policyTypes:
  - Ingress
  1. Teste novamente o funcionamento do serviço:
kubectl run busybox --rm -ti --image=busybox -- /bin/sh
/ # wget -qO- http-app --timeout=5
wget: download timed out
  1. Altere a netpol que libere o acesso apenas dos pod com a label access=true:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: access-http-app
spec:
  podSelector:
    matchLabels:
      app: http-app
  ingress:
  - from:
    - podSelector:
        matchLabels:
          access: "true"
  1. Re-faça os testes, mas dessa usando um pod com a label access=true
kubectl run busybox --rm -ti --labels="access=true" --image=busybox -- /bin/sh
/ # wget -qO- http-app --timeout=5
...
<h1>Welcome to nginx!</h1>
...

Basicamente oque fizemos foi permitir apenas os pods com a label “access=true” acessarem o pods com a label “app=http-app”

Exemplo com outras labels

Todo recurso do k8s devemos informar apiversion, kind e metadata, no netpol além desses campos também devemos informar os seguintes campos:

spec: campo inicial para definir as regras do NetworkPolicy

podSelector: Filtro dos pods que vão ser alvo da regra, aqui onde vamos dizer que apenas os pods com a labels run=frontend vai realizar o filtro de acesso. Se o campo estiver vazio o K8S vai entender a regra como valida para todos os pods do namespave.

policyTypes: Indica se a regra vai ser de entrada ou saida de dados.

ingress: Corresponde as regras de entrada, o controle é feito via “from” e “ports”, o “from” indica quais pod, namespaces ou IPs podem acessar a aplicação selecionada no nosso primeiro podSelector.

egress: Corresponde as regras de saida, o controle é feito via “to” e “ports”, o “to” indica quais pod, namespaces ou IPs podemos acessar apartir da aplicação selecionada no nosso primeiro podSelector.

Links de referencia:

https://kubernetes.io/docs/concepts/services-networking/network-policies/

https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy/

https://kubernetes.io/docs/concepts/services-networking/network-policies/#default-policies

https://ahmet.im/blog/kubernetes-network-policy/

https://docs.projectcalico.org/security/calico-network-policy