Kubernetes Network Policy
Si desea controlar el flujo de tráfico en la dirección IP o el nivel de puerto (capa 3 o 4 de OSI), entonces podría considerar usar Kubernetes NetworkPolicies para aplicaciones particulares en su clúster. NetworkPolicies es una construcción centrada en la aplicación que le permite especificar cómo un pod puede comunicarse con varias "entidades" de la red (usamos la palabra "entidad" aquí para evitar sobrecargar los términos más comunes, como "puntos finales" y "servicios", que tienen connotaciones específicas de Kubernetes) a través de la red. Las políticas de red se aplican a una conexión con un pod en uno o ambos extremos y no son relevantes para otras conexiones.
Las entidades con las que un Pod puede comunicarse se identifican mediante una combinación de los siguientes 3 identificadores:
- Otros pods que están permitidos
- Espacios de nombres que están permitidos
- Bloques de IP (excepción: siempre se permite el tráfico hacia y desde el nodo donde se ejecuta un Pod, independientemente de la dirección IP del Pod o del nodo).
Al definir una NetworkPolicy basada en espacios de nombres o pods, se utiliza un selector para especificar qué tráfico está permitido hacia y desde los pods que coinciden con el selector.
Mientras tanto, cuando se crean NetworkPolicies basadas en IP, definimos políticas basadas en bloques de IP (rangos CIDR).
A continuación se muestra un ejemplo del recurso Network Policy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
Examinando las secciones:
# Estas son las 2 network policies que se definen para kubernetes,
# para decir si afecta el tráfico de salida y entrada, si no se especifica se toma por defecto ingress.
policyTypes:
- Ingress
- Egress
# En esta sección se define cuales son las reglas para tráfico de entrada ,
# esta regla permite tráfico de un puerto , definido por un ip via el ipblock,
# luego por un namespace y finalmente por un pod.
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
# En el egress se define el tráfico hacia la ip y el puerto al que tendrá acceso.
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
Resumiendo el ejemplo anterior: El recurso tipo network policy aísla los pods con “role=db” en el namespace default para el tráfico de entrada y salida.
La regla de ingress permite conexión a todos los pods en el namespace default con el label “role=db” en el puerto tcp 6379 desde:
- Cualquier pod en el namespace default con el label “role=frontend”
- Cualquier pod en cualquier namespace con el label “project=myproject”
- Direcciones ip en los rangos 172.17.0.0–172.17.0.255 and 172.17.2.0–172.17.255.255
La regla egress permite conexiones de cualquier pod en el namespace default con el label “role=db” a la dirección 10.0.0.0/24 en el puerto 5978.
Políticas predeterminadas * Denegar por defecto todo el tráfico de entrada
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
-
Permitir todo el tráfico de entrada
--- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all-ingress spec: podSelector: {} ingress: - {} policyTypes: - Ingress -
Denegar por defecto todo el tráfico de salida
--- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-egress spec: podSelector: {} policyTypes: - Egress -
Permitir todo el tráfico de salida
--- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all-egress spec: podSelector: {} egress: - {} policyTypes: - Egress -
Denegar por defecto todo el tráfico de entrada y salida
--- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-all spec: podSelector: {} policyTypes: - Ingress - Egress
Laboratorio: Kubernetes Network Policy
Descripción
La siguiente guía explica que es y como se usa un Network Policy para restringir el acceso a recursos desplegados dentro de un Namespace.
Objetivo
- Aplicar un Network Policy sobre un Namespace
Antes de comenzar
- Contar con el acceso al ambiente del laboratorio
- Haber realizado la guía de Instalación Rancher Kubernetes Engine (RKE)
- Haber realizado la guía de Acceso a rancher y kubernetes cluster
-
Ingrese al CLI del sistema operativo del servidor usado como Bastion con el usuario y la contraseña proporcionados. Ingresar al cluster de Kubernetes cluster-users con sus respectivas credenciales
-
Crear un namespace llamado example-networkpolicy-web
kubectl create ns example-networkpolicy-web -
Crear otro namespace llamado example-networkpolicy-other
kubectl create namespace example-networkpolicy-other -
Agregue un label al Namespace creado
kubectl label namespace/example-networkpolicy-other team=operations -
Desplegar una aplicación web en el primer Namespace creado
kubectl run web --image=nginx --labels="app=web" --expose --port=80 -n example-networkpolicy-web -
Obtenga los pods del Namespace
kubectl get pods -n example-networkpolicy-web -
Obtenga los servicios del Namespace
kubectl get svc -n example-networkpolicy-web -
Crear un archivo YAML llamado web-allow-all-ns-monitoring.yaml con el siguiente contenido:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: web-allow-all-ns-monitoring namespace: example-networkpolicy-web spec: podSelector: matchLabels: app: web ingress: - from: - namespaceSelector: # chooses all pods in namespaces labelled with team=operations matchLabels: team: operations podSelector: # chooses pods with type=monitoring matchLabels: type: monitoring -
Crear un Network Policy en el primer Namespace creado
kubectl apply -f web-allow-all-ns-monitoring.yaml -
Probando el web server desde el Namespace default sin el label type=monitoring
kubectl run test-$RANDOM --rm -i -t --image=alpine -- shEl resultado seráwget -qO- --timeout=2 http://web.example-networkpolicy-webwget: download timed outexit -
Probando el web server desde el Namespace default con el label type=monitoring
kubectl run test-$RANDOM --labels="type=monitoring" --rm -i -t --image=alpine -- shEl resultado seráwget -qO- --timeout=2 http://web.example-networkpolicy-webwget: download timed outexit -
Probando el web server desde el Namespace example-networkpolicy-other sin el label type=monitoring
kubectl run test-$RANDOM --namespace=example-networkpolicy-other --rm -i -t --image=alpine -- shEl resultado seráwget -qO- --timeout=2 http://web.example-networkpolicy-webwget: download timed outexit -
Probando el web server desde el Namespace example-networkpolicy-other son el label type=monitoring
kubectl run test-$RANDOM --namespace=example-networkpolicy-other --labels="type=monitoring" --rm -i -t --image=alpine -- shEl resultado debe ser exitoso con una salida similar a la siguiente:wget -qO- --timeout=2 http://web.example-networkpolicy-web<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>exit - Realizar limpieza
kubectl delete namespace example-networkpolicy-web kubectl delete namespace example-networkpolicy-other