How to create a kubectl config file for serviceaccount

26,144

Solution 1

# your server name goes here
server=https://localhost:8443
# the name of the secret containing the service account token goes here
name=default-token-sg96k

ca=$(kubectl get secret/$name -o jsonpath='{.data.ca\.crt}')
token=$(kubectl get secret/$name -o jsonpath='{.data.token}' | base64 --decode)
namespace=$(kubectl get secret/$name -o jsonpath='{.data.namespace}' | base64 --decode)

echo "
apiVersion: v1
kind: Config
clusters:
- name: default-cluster
  cluster:
    certificate-authority-data: ${ca}
    server: ${server}
contexts:
- name: default-context
  context:
    cluster: default-cluster
    namespace: default
    user: default-user
current-context: default-context
users:
- name: default-user
  user:
    token: ${token}
" > sa.kubeconfig

Solution 2

I cleaned up Jordan Liggitt's script a little.

Unfortunately I am not yet allowed to comment so this is an extra answer:

# The script returns a kubeconfig for the service account given
# you need to have kubectl on PATH with the context set to the cluster you want to create the config for

# Cosmetics for the created config
clusterName=some-cluster
# your server address goes here get it via `kubectl cluster-info`
server=https://157.90.17.72:6443
# the Namespace and ServiceAccount name that is used for the config
namespace=kube-system
serviceAccount=developer

######################
# actual script starts
set -o errexit

secretName=$(kubectl --namespace $namespace get serviceAccount $serviceAccount -o jsonpath='{.secrets[0].name}')
ca=$(kubectl --namespace $namespace get secret/$secretName -o jsonpath='{.data.ca\.crt}')
token=$(kubectl --namespace $namespace get secret/$secretName -o jsonpath='{.data.token}' | base64 --decode)

echo "
---
apiVersion: v1
kind: Config
clusters:
  - name: ${clusterName}
    cluster:
      certificate-authority-data: ${ca}
      server: ${server}
contexts:
  - name: ${serviceAccount}@${clusterName}
    context:
      cluster: ${clusterName}
      namespace: ${namespace}
      user: ${serviceAccount}
users:
  - name: ${serviceAccount}
    user:
      token: ${token}
current-context: ${serviceAccount}@${clusterName}
"

Solution 3

Kubectl can be initialized to use a cluster account. To do so, get the cluster url, cluster certificate and account token.

KUBE_API_EP='URL+PORT'
KUBE_API_TOKEN='TOKEN'
KUBE_CERT='REDACTED'

echo $KUBE_CERT >deploy.crt
kubectl config set-cluster k8s --server=https://$KUBE_API_EP \ 
    --certificate-authority=deploy.crt  \
    --embed-certs=true
kubectl config set-credentials gitlab-deployer --token=$KUBE_API_TOKEN
kubectl config set-context k8s --cluster k8s --user gitlab-deployer
kubectl config use-context k8s

The cluster file is stored under: ~/.kube/config. Now the cluster can be accessed using:

kubectl --context=k8s get pods -n test-namespace

add this flag --insecure-skip-tls-verify if you are using self signed certificate.

Share:
26,144
bramvdk
Author by

bramvdk

Updated on July 09, 2022

Comments

  • bramvdk
    bramvdk almost 2 years

    I have a kubernetes cluster on Azure and I created 2 namespaces and 2 service accounts because I have two teams deploying on the cluster. I want to give each team their own kubeconfig file for the serviceaccount I created.

    I am pretty new to Kubernetes and haven't been able to find a clear instruction on the kubernetes website. How do I create a kube config file for a serviceaccount? Hopefully someone can help me out :), I rather not give the default kube config file to the teams.

    With kind regards,

    Bram

  • rookie099
    rookie099 about 5 years
    Commands ca=..., token=..., and namespace=... will fail if the secret resides in an namespace other than default. IMO you have to set also namespace up front instead of calculating it. And BTW here is a related, still unanswered question.
  • Alex Grönholm
    Alex Grönholm about 5 years
    This is what I got: base64: invalid option -- 'D' Try 'base64 --help' for more information. It's -d, not -D.
  • Dominik
    Dominik about 5 years
    base64 --decode is more desktop OS compatible (Debian, FreeBSD & MacOS) than -D (only MacOS?) or -d (Debian & FreeBSD, Busybox => also Alpine) (cc: @AlexGrönholm)
  • Jorge Alberto Díaz Orozco
    Jorge Alberto Díaz Orozco about 4 years
    The name can also be extracted using kubectl get sa -n namespace service_account_name -o jsonpath='{.secrets[0].name}'
  • learner
    learner over 3 years
    When I use the above yaml, I get error as below: error: unable to recognize "sa.kubeconfig": no matches for kind "Config" in version "v1"
  • Tomas Jansson
    Tomas Jansson about 3 years
    I'm trying to do something like this, but I get error: You must be logged in to the server (Unauthorized). Isn't the config supposed to be the authorization?