Фильтрация трафика внутри кластера
Цель: Проверить работоспособность Network Policy для приложения, произвести настройку согласно NetworkPolicy.
Важно: применение (enforcement) ресурсов
NetworkPolicy, а тем более политик уровня L7 (CiliumNetworkPolicy), обеспечивает только CNI с их поддержкой. CNI по умолчанию в ALT Orchestra — Flannel — сетевые политики не применяет. Все приведённые ниже примеры (L3 и L7) предполагают, что в кластере установлен Cilium.
Запуск тестового Deployment
Скачать нужный образ nginx:
podman pull --tls-verify=false ghcr.io/linuxserver/nginx:latest && \
curl http://localhost:5002/v2/_catalog | jq && \
curl http://localhost:5002/v2/ghcr.io/linuxserver/nginx/tags/list | jq && \
podman pull --tls-verify=false localhost:5002/ghcr.io/linuxserver/nginx:latestСоздать nginx Deployment:
kubectl create deployment nginx --image=ghcr.io/linuxserver/nginxВывод:
Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
deployment.apps/nginx createdОбеспечить доступ к развертыванию посредством сервиса с именем nginx.
kubectl expose deployment nginx --port=80Вывод:
service/nginx exposedПолучить информацию о сервисах и подах:
kubectl get svc,podПолучен IP-адрес сервиса и состояния пода nginx в статусе Running. Примерный вывод:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d
service/nginx ClusterIP 10.102.3.224 <none> 80/TCP 14m
service/postgres-operator ClusterIP 10.96.233.151 <none> 8080/TCP 6d15h
NAME READY STATUS RESTARTS AGE
pod/nginx-5557d9f6b4-lbhzd 1/1 Running 0 2m31s
pod/postgres-operator-849bdbdbd8-sqj7n 1/1 Running 1 (3d18h ago) 6d15hТестирование доступа с другого пода
Скачать нужный образ busybox:
podman pull --tls-verify=false ghcr.io/containerd/busybox:latest && \
curl http://localhost:5002/v2/_catalog | jq && \
curl http://localhost:5002/v2/ghcr.io/containerd/busybox/tags/list | jq && \
podman pull --tls-verify=false localhost:5002/ghcr.io/containerd/busybox:latestЗапустить контейнер busybox:
kubectl run busybox --rm -ti --image=ghcr.io/containerd/busybox:latest -- /bin/shПроверить доступ к поду nginx:
[busybox]# wget --spider --timeout=1 nginxДоступ к поду Nginx получен:
Connecting to nginx (10.102.3.224:80)
remote file existsОграничение доступа к службе nginx
Создать файл NetworkPolicy:
cat > nginx-policy.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: access-nginx
spec:
podSelector:
matchLabels:
app: nginx
ingress:
- from:
- podSelector:
matchLabels:
access: "true"
EOFПрименить политику:
kubectl apply -f nginx-policy.yamlПолитика создана:
networkpolicy.networking.k8s.io/access-nginx createdПовторное тестирование доступа с другого пода
Запустить контейнер busybox:
kubectl run busybox --rm -ti --image=ghcr.io/containerd/busybox:latest -- /bin/shПроверить доступ к поду nginx:
[busybox]# wget --spider --timeout=1 nginxДоступ к поду Nginx отсутствует:
Connecting to nginx (10.111.250.10:80)
wget: download timed outОбъявить метку и выполнить повторное тестирование с другого пода
Запустить контейнер busybox с меткой access=true:
kubectl run busybox --rm -ti --labels="access=true" --image=ghcr.io/containerd/busybox:latest -- /bin/shПроверить доступ к поду nginx:
[busybox]# wget --spider --timeout=1 nginxДоступ к поду Nginx получен:
Connecting to nginx (10.111.250.10:80)
remote file existsУдалить Deployment Nginx
kubectl delete deployment nginxФильтрация трафика на уровне L7 внутри кластера
Цель: Создать сетевую политику NetworkPolicy, которая ограничивает доступ запросов, проверить доступность.
Ресурс
CiliumNetworkPolicy(cilium.io/v2) предоставляется CNI Cilium и работает только при установленном Cilium.
Создать тестовый Namespace:
kubectl create namespace network-policy-testРазвернуть тестовый под nginx:
kubectl run web-server --image=ghcr.io/linuxserver/nginx -n network-policy-test --labels="app=web-server"Создать сервис web-server:
kubectl expose pod web-server --port=80 --target-port=80 --namespace=network-policy-testРазвернуть клиент:
kubectl run client-pod --image=ghcr.io/curl/curl-container/curl:master -n network-policy-test --labels="app=client" -- sh -c 'while true; do sleep 3600; done'Создание сетевой политики:
kubectl exec -it client-pod -n network-policy-test -- curl --max-time 3 http://web-server | grep -i welcome
kubectl exec -it client-pod -n network-policy-test -- curl --max-time 3 http://web-server/index.html | grep -i welcomeКоманда успешно выполняется и возвращает HTML-код стандартной страницы приветствия Nginx. Это подтверждает, что между подами есть сетевая связность. Вывод:
<title>Welcome to our server</title>
<h1>Welcome to our server</h1>Создать политику L7:
cat > l7-nginx-policy.yaml <<'EOF'
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "allow-get-to-index-html"
namespace: network-policy-test
spec:
endpointSelector:
matchLabels:
app: web-server
ingress:
- fromEndpoints:
- matchLabels:
app: client
toPorts:
- ports:
- port: "80"
protocol: TCP
rules:
http:
- method: "GET"
path: "/index.html"
EOFПрименить политику L7:
kubectl apply -f l7-nginx-policy.yamlПолитика применилась:
ciliumnetworkpolicy.cilium.io/allow-get-to-index-html createdПроверить доступность разрешенного пути:
kubectl exec -it client-pod -n network-policy-test -- curl --max-time 3 http://web-server/index.html | grep -i welcomeПуть доступен:
<title>Welcome to our server</title>
<h1>Welcome to our server</h1>Проверить доступность запрещенного пути методов GET и POST:
kubectl exec -it client-pod -n network-policy-test -- curl --max-time 3 http://web-server/
kubectl exec -it client-pod -n network-policy-test -- curl -X POST --max-time 3 http://web-server/index.htmlДоступ запрещен:
Access deniedУдалить тестовое пространство имён, чтобы удалить все созданные ресурсы:
kubectl delete namespace network-policy-test