Network Policies são uma construção centrada na aplicação que permite especificar como um pod pode se comunicar com várias "entidades" de rede.
Pré-requisitos
Este tutorial é uma continuaçāo dos meus artigos:
Esses artigos tinham como objetivo ajudar você a usar o Ansible¹ para criar um Cluster Kubernetes na Google Cloud Platform (GCP)² e implantar um Pod Nginx³. Portanto, se você ainda não fez isso, reveja os artigos mencionados antes de prosseguir.
O código usado para criar este tutorial está disponível neste repositório.
A partir deste ponto, assumo que você já tem um cluster GKE em execução e um Pod Nginx.
Kubernetes Network Policies
Por padrão, Pods não são isolados; eles aceitam tráfego de qualquer origem. No entanto, esse é um recurso que não funciona para todos os cenários. Como podemos ver no diagrama acima, não queremos que nosso Pod Nginx receba tráfego do Pod busybox no mesmo namespace.
Para atender a esse requisito, configure uma NetworkPolicy em nosso cluster Kubernetes. Com essa configuração ativa, dizemos que o Pod agora está isolado.
Este artigo fornecerá um exemplo básico de como configurar, usar e testar uma NetworkPolicy.
Habilitar NetworkPolicy no GKE
Dependendo da configuração do seu cluster GKE, a opção de usar o NetworkPolicy pode não estar ativada. Consulte a documentação do Google GKE para saber como ativá-la.
Se você estiver usando o cluster GKE criado na seção de Pré-requisitos, essa opção já estará ativada.
Estrutura de Diretórios do Ansible
Consulte o repositório no GitHub para ver os detalhes da estrutura do Ansible.
Ansible Roles
Crie uma nova Ansible role on ansible/roles/k8s-policies com o seguinte arquivo main.yml no sub-diretório tasks. Esta role será responsável por criar o namespace external, lancer um Pod busybox no namespace nginx e outro no namespace external namespace, e finalmente a NetworkPolicy.
---
- name: Create busybox pod on Nginx namespace
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: "{{ namespace }}"
labels:
app: busybox
spec:
containers:
- name: busybox
image: busybox
imagePullPolicy: Always
command:
- sleep
- "3600"
- name: Create external namespace
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Namespace
metadata:
name: external
- name: Create busybox pod on External namespace
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: external
labels:
app: busybox
spec:
containers:
- name: busybox
image: busybox
imagePullPolicy: Always
command:
- sleep
- "3600"
- name: Create network policy to deny ingress
kubernetes.core.k8s:
state: present
definition:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-traffic-nginx
namespace: "{{ namespace }}"
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
app: "{{ namespace }}"
Uma label foi adicionado ao namespace nginx em ansible/roles/k8s-deployments.
...
metadata:
name: "{{ app }}"
namespace: "{{ namespace }}"
labels:
app: "{{ app }}"
Ansible Playbook
O último passo é criar um Ansible Playbook para executar a role k8s-policies. Na pasta ansible, criei um arquivo chamado secure-app-k8s.yml:
---
- name: deploy application
hosts: localhost
gather_facts: false
environment:
GOOGLE_CREDENTIALS: "{{ credentials_file }}"
roles:
- k8s-policies
Testando a NetworkPolicy
Liste o endereço IP do Pod nginx:
kubectl get pods --namespace nginx -l "app=nginx" -o jsonpath="{.items[0].status.podIP}"
10.40.1.10
Testando comunicaçāo a partir do Pod no namespace Nginx
Use o container busybox para conectar com o Pod nginx:
kubectl -n nginx exec busybox -- wget --spider 10.40.1.10
Saída:
Connecting to 10.40.1.10 (10.40.1.10:80)
remote file exists
Testando comunicaçāo a partir do Pod no namespace External
kubectl -n external exec busybox -- wget --spider 10.40.1.13
Saída:
Connecting to 10.40.1.13 (10.40.1.13:80)
wget: can't connect to remote host (10.40.1.13): Connection timed out
command terminated with exit code 1
Este é o comportamento esperado. O nosso objetivo era de somente permitir acesso a partir de Pod(s) no namespace nginx.
Removendo as configurações
Execute o seguinte playbook para remover a NetworkPolicy e execute novamente o comando wget no namespace external e veja o que acontece!
ansible-playbook ansible/unsecure-app-k8s.yml -i ansible/inventory/<your-inventory-filename>
Conclusāo
Este artigo mostrou como configurar e testar uma NetworkPolicy no Kubernetes e como ela pode ser eficaz no controle de quem pode acessar seus Pods.
A NetworkPolicy é um recurso poderoso para começar a proteger seu cluster Kubernetes. Por favor, consulte a documentação oficial do Kubernetes NetworkPolicies⁴ para mais detalhes sobre este recurso.
Comentários