AKS i ograniczanie dostępu do usług poprzez NSG

Jednym z częstych pytań przy używaniu Kubernetes, w moim przypadku na Azure jest - Jak ograniczyć dostęp po IP do udostępnionej aplikacji?

W przypadku Azure pierwsze, co ciśnie się na usta, to użycie NSG! Tak i jest to prawda. Jeśli popatrzymy na podstawy architektury Kubernetes w AKS to zauważymy, że przychodzi on z domyślną Network Security Group przypiętą do podsieci, gdzie znajdują się nody.

Architektura sieci w AKS

Żeby zobrazować jak wykonać w praktyce ograniczenia dostępu po IP, zacznę od stworzenia deploymentu z nginx i wystawię go na świat.

kubectl create deployment nginx --image=nginx
kubectl scale --replicas=2 deployment nginx
kubectl expose deployment nginx --type=LoadBalancer --port=80

Jeśli popatrzymy w konfigurację NSG to pojawia się reguła dla ruchu przychodzącego dla naszego deploymentu, czyli Kubernetes potrafi sterować NSG. Można ją rozpoznać po publicznym adresie IP.

Domyślna konfiguracji NSG w AKS

Jeśli wczytamy się w dokumentację Kubernetes to okazuje się, że potrafi on sterować NSG z poziomu konfiguracji kubernetesowego obiektu Service. W konfiguracji serwisu jest pole na konfiguracje dozwolonych zakresów IP i nazywa się ono loadBalancerSourceRanges.

W dokumentacji Kubernetes opis znajduje się tu -> Restrict Access For LoadBalancer Service

Pole loadBalancerSourceRanges w yaml jest listą adresów IP w postaci CIDR, jak poniżej.

loadBalancerSourceRanges:
- 8.8.4.4/32
- 8.8.8.8/32
- 1.1.1.1/32

Cały gotowy yaml do konfiguracji serwisu z ograniczeniem poprzez NSG wygląda tak:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer
  loadBalancerSourceRanges:
  - 8.8.4.4/32
  - 8.8.8.8/32
  - 1.1.1.1/32

Po dodaniu loadBalancerSourceRanges NSG prezentuje się następująco. Widać, że lista IP została ograniczona do tych podanych w konfiguracji.

NSG po konfiguracji przez Kubernetes

Zaletą tego rozwiązania jest to, że konfiguracja reguł idzie razem z resztą konfiguracji aplikacji. Jako główną wadę można wskazać, że “deweloper może coś zmienić”, z którą można się zgodzić lub zgodnie z podejściem ZeroOps brać udział w cyklu życia aplikacji, czyli albo code review, albo może stworzyć jakiś ładny filtr przy commicie lub skrypt do sprawdzenia przed wdrożeniem czy wszystkie potrzebne obiekty znajdują się plikach konfiguracyjnych.

Jako, że NSG jest przypięte do subnetu to nie możemy już dodać swojego, a osobiście odradzam grzebanie w obiektach zarządzanych automatycznie - jedna z przesłanek jest za nie dotykaniem ręcznie bo potem jest szukanie przyczyny dlaczego coś nie działa albo po stworzeniu nowego klastra ktoś zapomni o dodaniu reguł z palca i cała praca na marne.