Lab 16: RBAC mit Pods¶
In dieser Aufgabe lernt ihr, einem Pod mittels eines ServiceAccounts ein Recht zu geben, dass es normalerweise nicht hat: über die Kubernetes-API andere Pods abfragen.
1) Pod anlegen¶
Schaue dir das Manifest für den ersten Pod an. Der Pod definiert ein Container, dessen Image kubectl enthält. Wende das Manifest nun an:
pod1.yaml:
apiVersion: v1
kind: Pod
metadata:
name: kubectl-pod
namespace: default
spec:
containers:
- name: kubectl-container
image: bitnami/kubectl:latest
command: ["/bin/sh", "-c", "trap : TERM INT; sleep infinity & wait"]
readinessProbe:
exec:
command: ["/bin/sh", "-c", "true"]
initialDelaySeconds: 1
periodSeconds: 10
livenessProbe:
exec:
command: ["/bin/sh", "-c", "true"]
initialDelaySeconds: 5
periodSeconds: 20
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
restartPolicy: Always
kubectl apply -f pod1.yaml
Es sollte nun ein neuer Pod namens "kubectl-pod" im default-Namespace laufen:
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# kubectl-pod 1/1 Running 0 52s
Versuchen wir nun, ob dieser Pod auch die anderen Pods per kubectl abfragen darf. Bauen wir dazu zunächst eine Verbindung mit dem Container auf und öffnen eine Shell-Sitzung:
kubectl exec -it kubectl-pod -- bash
Nun versuchen wir in der Shell-Sitzung mit kubectl die Pods des default-Namespaces aufzulisten:
kubectl get pods
# Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:default" cannot list resource "pods" in API group "" in the namespace "default"
Um dieses Ergebnis zu verstehen, müssen wir uns eine Sache in Erinnerung rufen: Wir haben diesen Befehl gerade nicht auf unserem Schulungsrechner ausgeführt, sondern innerhalb des Pods. kubectl innerhalb des Pods hat standardmäßig gar keine Rechte – anders als auf dem Schulungsrechner, wo Minikube uns als Admin konfiguriert hat. Da kubectl innerhalb des Pods keine Rechte hat, kann es auch keine Pods auflisten.
Trennt die Verbindung nun mit exit und löscht den Pod:
kubectl delete pod kubectl-pod
2) Service Account, Role und RoleBinding anlegen¶
Damit der Pod Zugriff erhält, braucht er einen ServiceAccount. Dieser Account muss mit Hilfe einer Rolle das Recht erhalten, Pods aufzulisten.
Schaut euch dazu folgendes Manifest an.
sa.yaml:
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-kubectl-sa
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
subjects:
- kind: ServiceAccount
name: my-kubectl-sa
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Erstens wird dort ein ServiceAccount angelegt.
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-kubectl-sa
Der interessantere Teil ist aber die Rolle.
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
Sie erlaubt es, pods aufzulisten im default-Namespace, da kein anderer Namespace angegeben ist. Das RoleBinding verbindet die Rolle mit dem ServiceAccount.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
subjects:
- kind: ServiceAccount
name: my-kubectl-sa
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Wenn ihr alle Teile verstanden habt, wendet das Manifest nun an:
kubectl apply -f sa.yaml
3) Pod mit Service Account starten¶
In pod2.yaml findet ihr ein Manifest für den gleichen Pod wie in Schritt 1 -- nur dass diesmal der ServiceAccount genutzt wird, den wir in Schritt 2 angelegt haben:
pod2.yaml:
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-kubectl-sa
namespace: default
---
apiVersion: v1
kind: Pod
metadata:
name: kubectl-pod
namespace: default
spec:
serviceAccountName: my-kubectl-sa
containers:
- name: kubectl-container
image: bitnami/kubectl:latest
command: ["/bin/sh", "-c", "trap : TERM INT; sleep infinity & wait"]
readinessProbe:
exec:
command: ["/bin/sh", "-c", "true"]
initialDelaySeconds: 1
periodSeconds: 10
livenessProbe:
exec:
command: ["/bin/sh", "-c", "true"]
initialDelaySeconds: 5
periodSeconds: 20
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
restartPolicy: Always
Ein Auszug daraus:
spec:
serviceAccountName: my-kubectl-sa
containers:
- name: kubectl-container
image: bitnami/kubectl:latest
command: ["/bin/sh", "-c", "trap : TERM INT; sleep infinity & wait"]
restartPolicy: Always
Wendet das Manifest nun an und verbindet euch dann wieder mit dem Pod:
kubectl apply -f pod2.yaml
kubectl exec -it kubectl-pod -- bash
Führt in der Shell-Sitzung nun wieder kubectl aus, um alle Pods aufzulisten. Es sollte nun funktionieren:
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# busybox 0/1 Completed 0 21h
# busybox2 0/1 Error 0 21h
# kubectl-pod 1/1 Running 0 52s
Aufräumen¶
Löscht zuletzt den Test-Pod:
kubectl delete pod kubectl-pod