41 Übung 3: Securing the Application

41.1 Aufgabenbeschreibung

In dieser Übung werden Sie lernen, wie Sie Ihre Anwendung in Kubernetes absichern können. Die Aufgabe umfasst die folgenden Schritte:

  1. Erstellen Sie einen Kubernetes Secret.
  2. Verwenden Sie das Secret in einem Deployment.
  3. Konfigurieren Sie RBAC (Role-Based Access Control) für den Zugriff auf das Secret.
  4. Überprüfen Sie, dass nur autorisierte Pods auf das Secret zugreifen können.

Schritt-für-Schritt-Anleitung:

  1. Erstellen Sie ein Secret mit sensiblen Daten (z.B. Datenbank-Anmeldeinformationen).
  2. Erstellen Sie ein Deployment, das das Secret verwendet.
  3. Konfigurieren Sie RBAC, um den Zugriff auf das Secret zu steuern.
  4. Verifizieren Sie, dass nur autorisierte Pods auf das Secret zugreifen können.

41.2 Hinweise

41.3 Musterlösung

1. Erstellen eines Secrets:

Erstellen Sie ein Secret für die Datenbank-Anmeldeinformationen:

kubectl create secret generic db-secret --from-literal=username=myuser --from-literal=password=mypassword

2. Erstellen eines Deployments, das das Secret verwendet:

Erstellen Sie eine Datei deployment.yaml mit folgendem Inhalt:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: secure-app
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: secure-app
  template:
    metadata:
      labels:
        app: secure-app
    spec:
      containers:
      - name: secure-app
        image: myapp:latest
        env:
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: username
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password

Deployen Sie die Anwendung:

kubectl apply -f deployment.yaml

3. Konfigurieren von RBAC für den Zugriff auf das Secret:

Erstellen Sie eine Datei role.yaml mit folgendem Inhalt:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get"]

Erstellen Sie eine Datei rolebinding.yaml mit folgendem Inhalt:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-secrets
  namespace: default
subjects:
- kind: ServiceAccount
  name: default
  namespace: default
roleRef:
  kind: Role
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

Erstellen Sie die Role und das RoleBinding:

kubectl apply -f role.yaml
kubectl apply -f rolebinding.yaml

4. Überprüfen des Zugriffs auf das Secret:

Starten Sie einen Pod, der versucht, auf das Secret zuzugreifen:

apiVersion: v1
kind: Pod
metadata:
  name: secret-access
  namespace: default
spec:
  containers:
  - name: secret-access
    image: busybox
    command: ["sh", "-c", "sleep 3600"]

Verwenden Sie kubectl exec, um auf den Pod zuzugreifen und das Secret zu überprüfen:

kubectl exec -it secret-access -- sh

Innerhalb des Pods:

cat /var/run/secrets/kubernetes.io/serviceaccount/namespace

Wenn der Zugriff korrekt konfiguriert ist, sollten Sie die Werte des Secrets anzeigen können.

Diese Übung demonstriert die Grundlagen der Absicherung von Anwendungen in Kubernetes durch die Verwendung von Secrets und RBAC. Indem Sie sensible Daten in Secrets speichern und den Zugriff mit RBAC kontrollieren, können Sie die Sicherheit Ihrer Anwendungen und Daten im Kubernetes-Cluster erheblich verbessern.

41.4 Integration von Ingress in die Nginx-Webserver-Konfiguration

Ingress-Objekte in Kubernetes ermöglichen es, den Zugriff auf HTTP- und HTTPS-basierte Dienste von außerhalb des Clusters zu steuern. Sie bieten eine höhere Ebene der Abstraktion als Services und können eine Vielzahl von Services unter einer einheitlichen IP-Adresse zusammenführen. Im Folgenden wird ein Ingress-Objekt konfiguriert, das den externen HTTP-Zugriff auf den bereits definierten Nginx-Webserver über einen ClusterIP Service steuert.

41.4.1 Ingress Controller

Bevor ein Ingress-Objekt erstellt wird, muss ein Ingress Controller im Cluster vorhanden sein. Der Ingress Controller ist verantwortlich für die Implementierung der Regeln, die in den Ingress-Ressourcen definiert sind. Gängige Ingress Controller sind Nginx, Traefik oder HAProxy.

41.4.2 Ingress Ressource für Nginx

Angenommen, der Ingress Controller ist bereits im Cluster installiert und konfiguriert, kann nun eine Ingress-Ressource definiert werden, die den Zugriff auf den Nginx Service regelt.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80

41.4.3 Erläuterung des Ingress-Objekts

Dieses Ingress-Objekt hat folgende Bedeutung:

41.4.4 Zugriff auf den Nginx-Webserver über Ingress

Sobald der Ingress definiert und vom Ingress Controller übernommen wurde, können Clients den Nginx-Webserver erreichen, indem sie Anfragen an die vom Ingress Controller bereitgestellte IP-Adresse senden, mit dem Pfad /web. Der Controller leitet die Anfragen entsprechend an den ClusterIP Service und von dort an den Nginx Pod weiter.

In diesem aktualisierten Diagramm:

41.5 Konfiguration eines Ingress-Objekts mit spezifischem DNS-Namen

Um Ingress-Ressourcen auf einen konkreten DNS-Namen zu setzen, werden Host-Regeln in der Ingress-Konfiguration definiert. Hier ist ein Beispiel für einen Ingress, der für den DNS-Namen example.com konfiguriert ist und den Verkehr an den bereits vorhandenen Nginx-Service weiterleitet:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80

41.5.1 Erläuterung des DNS-spezifischen Ingress-Objekts

41.5.2 DNS-Integration

Um den Ingress unter dem spezifizierten DNS-Namen erreichbar zu machen, muss dieser DNS-Name in der DNS-Zone, die für die Domain example.com zuständig ist, auf die IP-Adresse des Ingress Controllers gesetzt werden. Dies geschieht in der Regel außerhalb von Kubernetes bei dem DNS-Provider, der die Domain verwaltet. Nachdem der DNS-Eintrag propagiert wurde, kann der Ingress-Controller Anfragen, die an example.com gerichtet sind, an den nginx-service weiterleiten.