Kubernetes-Security, Teil 3: Im Spannungsfeld von Komplexität und Sicherheit
Seite 4: Eine eigene Kubeconfig-Datei
Jetzt steht ein Token zur Verfügung, und mit folgendem Code muss man eine temporäre Kubeconfig-Datei erzeugen:
kubectl config view --raw > ${KUBECONFIG}.full.tmp
In der Datei konfiguriert man den Kontext zur Benutzung mit etwas Code
kubectl --kubeconfig ${KUBECONFIG}.full.tmp config use-context ${CONTEXT}
und minimiert den Inhalt auf den Kontext wie folgt:
kubectl --kubeconfig ${KUBECONFIG}.full.tmp \
config view --flatten --minify > ${KUBECONFIG}.tmp
Jetzt enthält die temporäre Datei nur noch einen Kontext, was sich leicht überprüfen lässt. Die Keys und Zertifikate würden nur verwirren und sind hier abgekürzt. Der Befehl cat ${KUBECONFIG}.tmp
liefert folgende Ausgabe:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJT...tLS0tCg==
server: https://192.168.2.15:8443
name: minikube
contexts:
- context:
cluster: minikube
user: minikube
name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
user:
client-certificate-data: LS0tLS1CRUdJT...tLS0tLQo=
client-key-data: LS0tLS1CRUdJT...tLS0tLQo=
Den Kontext hat man folgendermaßen umzubenennen:
kubectl config --kubeconfig ${KUBECONFIG}.tmp \
rename-context ${CONTEXT} ${NEW_CONTEXT}
Context "minikube" renamed to "my-context".
Erst jetzt lässt sich das oben erzeugte Token einsetzen und einem neuen Account mitgeben:
kubectl config --kubeconfig ${KUBECONFIG}.tmp \
set-credentials ${CONTEXT}-${NAMESPACE}-token-user \
--token ${TOKEN}
User "minikube-my-namespace-token-user" set.
Der Name in der Kubeconfig-Datei ist beliebig wählbar, denn nur über das Token verbindet sich die Authentifizierung automatisch eindeutig mit einem Service-Account. Mit einer weiteren lokalen Konfigurationsänderung lässt sich der User für den neuen Kontext festlegen:
kubectl config --kubeconfig ${KUBECONFIG}.tmp \
set-context ${NEW_CONTEXT} \
--user ${CONTEXT}-${NAMESPACE}-token-user
Context "my-context" modified.
Zusätzlich kann man den Namespace setzen:
kubectl config --kubeconfig ${KUBECONFIG}.tmp \
set-context ${NEW_CONTEXT} \
--namespace ${NAMESPACE}
Context "my-context" modified.
Alle nicht notwendigen Einträge lassen sich durch Eingabe der folgenden Zeilen entfernen:
kubectl config --kubeconfig ${KUBECONFIG}.tmp \
view --flatten --minify > ${KUBECONFIG}
Die Datei sollte bis auf die Keys und Zertifikate wieder folgende Struktur aufweisen, ihren Inhalt kann man mit dem Befehl cat ${KUBECONFIG}
aufrufen:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJT...tLS0tCg==
server: https://192.168.2.15:8443
name: minikube
contexts:
- context:
cluster: minikube
namespace: my-namespace
user: minikube-my-namespace-token-user
name: my-context
current-context: my-context
kind: Config
preferences: {}
users:
- name: minikube-my-namespace-token-user
user:
token: eyJhbGciOiJSUzI1N...AzHjMnkm6g
Erst jetzt liegt eine minimale Datei vor, die Entwickler für Service-Accounts verwenden können. Die Datei lässt sich herausgeben, und der Account kann per Definition nur in seinem festgelegten Namespace arbeiten. Das lässt sich mit folgendem Code überprüfen:
kubectl --kubeconfig ${KUBECONFIG} get pods
No resources found in my-namespace namespace.
Als Ergebnis erhält man die laufenden Pods in my-namespace
zurück. Wie erwartet ist ein neuer Namespace erst mal leer.
Sollte man hingegen versuchen, unter dem Service-Account in anderen Namespaces Informationen zu sammeln, läuft die Anfrage ins Leere, da das System sie nun automatisch ablehnt:
kubectl
--kubeconfig ${KUBECONFIG} get pods -A
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:my-namespace:my-serviceaccount" cannot list resource "pods" in API group "" at the cluster scope