Créer un service account
Notre Kubernetes Management rencontre actuellement un problème de persistance des comptes utilisateurs créés via le portail. Cette page est consacrée à ce problème et propose une solution de contournement pour créer des service accounts persistants.
Obtenir la configuration admin depuis le portail
Connectez-vous au Cloud-Portal et ouvrez votre Kubernetes Dashboard.
Si vous disposez déjà d'un Kubernetes, vous pouvez télécharger le kubeconfig de ce cluster.

Cliquez sur Download Kubeconfig

Cliquez ensuite sur Download Admin Kubeconfig
Télécharger et installer Kubectl
Téléchargez kubectl depuis K8s.io
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
rendre kubectl utilisable
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
Copier la configuration admin vers .kube/config
Pour accéder au cluster avec kubectl, vous devez créer un répertoire .kube dans votre home et y copier votre configuration.
cd ~
mkdir .kube
cp admin-kube.yml .kube/config
Exemple avec un script Bash
enregistrez le script bash dans addUser.sh
bash addUser.sh --user testuser --role cluster-admin
Exemple de sortie du script :
## KUBECONFIG generated on Wed Feb 5 09:10:03 CET 2025
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: XXXXXXXXXXX=
server: https://api.kube5.ewt9qdm.gardener.stage.ewcs.ch
name: garden-414d97167c7345de93300fd42872e325--<clustername>-external
contexts:
- context:
cluster: garden-414d97167c7345de93300fd42872e325--<clustername>-external
user: <username>-garden-414d97167c7345de93300fd42872e325--<clustername>-external
name: garden-414d97167c7345de93300fd42872e325--<clustername>-external
current-context: garden-414d97167c7345de93300fd42872e325--<clustername>-external
kind: Config
preferences: {}
users:
- name: <username>-garden-414d97167c7345de93300fd42872e325--<clustername>-external
user:
token: XXXXXX
Script Bash
Veuillez installer le paquet jq pour le script bash
sudo apt install jq
#!/bin/bash
KUBECTL="/usr/local/bin/kubectl"
usage() {
echo "Usage: $0 --user USERNAME [--role ROLE] [--delete]"
exit 1
}
SERVICE_ACC_NAME=""
ROLE_NAME="view"
DELETE_IT=false
while [[ $# -gt 0 ]]; do
case "$1" in
--user)
SERVICE_ACC_NAME="$2"
shift 2
;;
--role)
ROLE_NAME="$2"
shift 2
;;
--delete)
DELETE_IT=true
shift
;;
*)
usage
;;
esac
done
if [ -z "$SERVICE_ACC_NAME" ]; then
usage
fi
if $DELETE_IT; then
$KUBECTL delete serviceaccount "$SERVICE_ACC_NAME"
$KUBECTL delete secret "$SERVICE_ACC_NAME-secret"
$KUBECTL delete clusterrolebinding "view-$SERVICE_ACC_NAME-global"
exit 0
fi
$KUBECTL create serviceaccount "$SERVICE_ACC_NAME" -n default -o json
cat <<EOF | $KUBECTL create -n default -o json -f -
apiVersion: v1
kind: Secret
metadata:
name: $SERVICE_ACC_NAME-secret
annotations:
kubernetes.io/service-account.name: $SERVICE_ACC_NAME
type: kubernetes.io/service-account-token
EOF
SECRET_JSON=$($KUBECTL get secret "$SERVICE_ACC_NAME-secret" -o json)
CA_CRT=$(echo "$SECRET_JSON" | jq -r '.data["ca.crt"]')
USER_TOKEN=$(echo "$SECRET_JSON" | jq -r '.data.token | @base64d')
KUBECONFIG_JSON=$($KUBECTL config view --minify -o json)
CLUSTER_API=$(echo "$KUBECONFIG_JSON" | jq -r '.clusters[0].cluster.server')
CLUSTER_NAME=$(echo "$KUBECONFIG_JSON" | jq -r '.clusters[0].name')
cat <<EOF | $KUBECTL create -n default -o json -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: view-$SERVICE_ACC_NAME-global
subjects:
- kind: ServiceAccount
name: $SERVICE_ACC_NAME
namespace: default
roleRef:
kind: ClusterRole
name: $ROLE_NAME
apiGroup: rbac.authorization.k8s.io
EOF
echo "## KUBECONFIG generated on $(date)"
cat <<EOF
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: $CA_CRT
server: $CLUSTER_API
name: $CLUSTER_NAME
contexts:
- context:
cluster: $CLUSTER_NAME
user: $SERVICE_ACC_NAME-$CLUSTER_NAME
name: $CLUSTER_NAME
current-context: $CLUSTER_NAME
kind: Config
preferences: {}
users:
- name: $SERVICE_ACC_NAME-$CLUSTER_NAME
user:
token: $USER_TOKEN
EOF
Script Python
import sys
import json
import subprocess
import base64
from datetime import datetime
def exec_command(args, std_input=None):
print("# " + " ".join(args))
result = subprocess.run(args, input=std_input, text=True, capture_output=True)
if result.returncode == 0:
try:
return json.loads(result.stdout)
except json.JSONDecodeError:
return result.stdout.strip()
else:
print(result.stderr, file=sys.stderr)
sys.exit(1)
KUBECTL = "/usr/bin/kubectl"
if len(sys.argv) < 2 or sys.argv[1] == "--delete":
print("please provide username as an argument, for example: python script.py USER_NAME [--delete]")
sys.exit(1)
service_acc_name = sys.argv[1]
role_name = sys.argv[2] if len(sys.argv) > 2 else "view"
delete_it = len(sys.argv) > 3 and sys.argv[3] == "--delete"
if delete_it:
exec_command([KUBECTL, "delete", "serviceaccount", service_acc_name])
exec_command([KUBECTL, "delete", "secret", f"{service_acc_name}-secret"])
exec_command([KUBECTL, "delete", "clusterrolebinding", f"view-{service_acc_name}-global"])
sys.exit(0)
exec_command([KUBECTL, "create", "serviceaccount", service_acc_name, "-o", "json"])
exec_command([KUBECTL, "create", "-o", "json", "-f", "-"], f"""apiVersion: v1
kind: Secret
metadata:
name: {service_acc_name}-secret
annotations:
kubernetes.io/service-account.name: {service_acc_name}
type: kubernetes.io/service-account-token""")
secret = exec_command([KUBECTL, "get", "secret", f"{service_acc_name}-secret", "-o", "json"])
ca_crt = secret["data"]["ca.crt"]
user_token = base64.b64decode(secret["data"]["token"]).decode()
kube_config = exec_command([KUBECTL, "config", "view", "--minify", "-o", "json"])
cluster_api = kube_config["clusters"][0]["cluster"]["server"]
cluster_name = kube_config["clusters"][0]["name"]
exec_command([KUBECTL, "create", "-o", "json", "-f", "-"], f"""apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {role_name}-{service_acc_name}-global
subjects:
- kind: ServiceAccount
name: {service_acc_name}
namespace: default
roleRef:
kind: ClusterRole
name: {role_name}
apiGroup: rbac.authorization.k8s.io""")
kubeconfig_output = f"""
## KUBECONFIG generated on {datetime.now()}
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: {ca_crt}
server: {cluster_api}
name: {cluster_name}
contexts:
- context:
cluster: {cluster_name}
user: {service_acc_name}-{cluster_name}
name: {cluster_name}
current-context: {cluster_name}
kind: Config
preferences: {}
users:
- name: {service_acc_name}-{cluster_name}
user:
token: {user_token}
"""
print(kubeconfig_output)