Creare un service account
Attualmente il nostro Kubernetes Management presenta un problema di persistenza degli account utente creati tramite il portale. Questa pagina è dedicata a questo problema e propone una soluzione alternativa per creare service account persistenti.
Ottenere la configurazione admin dal portale
Acceda al Cloud-Portal e apra la sua Kubernetes Dashboard.
Se dispone già di un Kubernetes, può scaricare il kubeconfig di questo cluster.

Clicchi su Download Kubeconfig

Poi clicchi su Download Admin Kubeconfig
Scaricare e installare Kubectl
Scarichi kubectl da K8s.io
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
rendere kubectl utilizzabile
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
Copiare la configurazione admin in .kube/config
Per accedere al cluster con kubectl, deve creare una directory .kube nella sua home e copiarvi la sua configurazione.
cd ~
mkdir .kube
cp admin-kube.yml .kube/config
Esempio con uno script Bash
salvi lo script bash in addUser.sh
bash addUser.sh --user testuser --role cluster-admin
Esempio di output dello 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
Installi il pacchetto jq per lo 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)