Zum Inhalt

Lab 08: NGINX StatefulSet mit Headless Service

Das Manifest erzeugt ein StatefulSet mit drei Replicas eines nginx-Pods, der den Container-Port 80 belegt. Außerdem wird ein Service definiert, der im sogenannten Headless-Modus läuft. Das bedeutet, dass er keine ClusterIP erhält (clusterIP: None). Wir schauen uns nun an, was genau dies bedeutet.

manifest.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx-headless
  labels:
    app: nginx
spec:
  clusterIP: None
  selector:
    app: nginx # Bindet den Service an die Pods, die das StatefulSet anlegt
  ports:
    - port: 80
      name: http

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx
spec:
  serviceName: "nginx-headless"
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx # Erzeugt die Labels, die das StatefulSet und der Service braucht, um die Pods zu selektieren
    spec:
      securityContext:
        seccompProfile:
          type: RuntimeDefault
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: kubernetes.io/hostname
          whenUnsatisfiable: ScheduleAnyway
          labelSelector:
            matchLabels:
              app: nginx
      containers:
        - name: nginx
          image: nginx:1.21
          ports:
            - containerPort: 80
              name: http
          readinessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 10
            periodSeconds: 20
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "200m"
              memory: "256Mi"

Manifest anwenden

Zuerst legen wir die benötigten Ressourcen an und prüfen, ob sie korrekt erzeugt wurden.

kubectl apply -f manifest.yaml

Danach schauen wir, ob Service und Pods erfolgreich angelegt bzw. gestartet wurden.

kubectl get service nginx-headless
kubectl get pod --selector=app=nginx

DNS untersuchen mit busybox

Wir verwenden kubectl debug, um einen Hilfscontainer zu starten. Wir untersuchen den ersten Pod des StatefulSet nginx-0 und benutzen busybox, ein Image zum Debuggen von Netzwerkproblemen.

kubectl debug nginx-0 -it --image=busybox

Der DNS-Name des Services, den wir angelegt haben, ist nginx-headless.default.svc.cluster.local und wir werden sehen, dass dieser auf drei IP-Adressen verweist: eine pro Pod. Der Service selbst hat keine ClusterIP! Nur die Pods haben eine IP, wie sie es immer haben (zumindest fast...).

nslookup nginx-headless.default.svc.cluster.local
Name:   nginx-headless.default.svc.cluster.local
Address: 10.244.0.65
Name:   nginx-headless.default.svc.cluster.local
Address: 10.244.0.66
Name:   nginx-headless.default.svc.cluster.local
Address: 10.244.0.64

Darüber hinaus legt der Headless Service einen DNS-Namen pro Pod an mit einem laufenden Index:

<STATEFULSETNAME>-<INDEX>.<SERVICENAME>.<NAMESPACE>.svc.cluster.local

also z.B.

nginx-0.nginx-headless.default.svc.cluster.local

Und das können wir auch mit nslookup belegen

nslookup nginx-0.nginx-headless.default.svc.cluster.local

```Server: 10.96.0.10 Address: 10.96.0.10:53

Name: nginx-0.nginx-headless.default.svc.cluster.local Address: 10.244.0.64 # hier ist die Adresse des Pods!

## Aufräumen

```shell
kubectl delete statefulset.apps/nginx
kubectl delete service/nginx-headless

Bonus

-Dokumentation zu StatefulSets