Anyone who doesn’t know about kubeconfig file, its a file which is used to configure access to a cluster. kubectlhelm like kubernetes client use this file to access kubernetes and perform operation.

Looks like you are interested in Kubernetes best practices, do not forget to read following 4 topics,

Creating kubeconfig file with limited access

In this exercise I am going to use RBAC configuration and service account to generate kubeconfig file which has limited access.

Create ServiceAccount, Role and RoleBinding

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: goglides

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: goglides-sa
  namespace: goglides

---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: goglides-role
  namespace: goglides
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "delete", "update", "patch"]

- apiGroups: [""] # "" indicates the core API group
  resources: ["configmaps", "secrets"]
  verbs: ["get", "list", "watch", "create", "delete", "update", "patch"]

- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: goglides-rolebinding
  namespace: goglides
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: goglides-role
subjects:
- kind: ServiceAccount
  name: goglides-sa
  namespace: goglides
EOF

Once you create the Service Account we can use kubectl command to fetch certificate-authority and authentication token for user goglides-sa as follows,

export serviceAccount=goglides-sa
export namespace=goglides
export secretName=$(kubectl get sa $serviceAccount -n $namespace -o custom-columns=SECRETNAME:.secrets[].name --no-headers)

Get ca.crt from secret (using OSX base64 with -D flag for decode)

$ kubectl get secret $secretName -n $namespace -o custom-columns=CA:'.data.ca\.crt' --no-headers | base64 -D > ca.crt

Get ServiceAccount token from secret

export userToken=$(kubectl get secret $secretName -n $namespace -o custom-columns=CA:'.data.token' --no-headers | base64 -D)

Get cluster name of context

export name=$(kubectl config get-contexts $context | awk '{print $3}' | tail -n 1)

Get endpoint of current context

export endpoint=$(kubectl config view -o jsonpath="{.clusters[?(@.name == "$name")].cluster.server}")
  • Once you follow above steps you have all the information required to create kubeconfig file. Lets start by creating basic skeleton,
$ kubectl config --kubeconfig=config-demo set-cluster development
Cluster "development" set.

$ cat config-demo
apiVersion: v1
clusters:
- cluster:
    server: ""
  name: development
contexts: []
current-context: ""
kind: Config
preferences: {}
users: []

Set cluster (run in directory where ca.crt is stored)

$ kubectl config --kubeconfig=config-demo set-cluster development \
  --embed-certs=true \
  --server=$endpoint \
  --certificate-authority=./ca.crt

$ cat config-demo

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJd01ERXlNekl3TWpjeU0xb1hEVE13TURFeU1ESXdNamN5TTFvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUJXCnI2eUR0bXhIcEZwbHE2NTVEWHBpR3FIczVpY3BCN3l5K21CMEhQTUl0ZDc2RW9GK0JudWVZSnpvdjk1VWJzVlkKNVFGSU9mTHBISGhIbitEVnM4ZFNPRFA1SUhGMFdOMUNYT0JTR1lZeGFGNHlTQkxwaURSZ1k1dHdvVTVtT2laZwoxTStJa0Rjck5QVWNmemlXc1o4a0NzdDdranNLZzNhSHYvNEY3UGZidkFQcTIvaGtRK3l3ZWZOck8wN2l3N1h0ClUxdkY5d3dOTGZkdWQwZWZxaW1CcFVUWXVITThpUXRjakRCb09jc2FNYk56ZEM5SUFTcW5jbEpEdFFpYlp6MDgKaVhrUml0RmZ4VitVRE5RWGRiRE5JbmgyWGtlQ1JpTGg3V2ZvYi9YOTBPVUhva1g0M0J6c0VlZzA4dEZzVm1BSQpUekQvOU5SVHFJSHF0MEdKYVpjQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFBeCs5alFSZkY3Snp2dUVWdTMrbjNVWjc0ckYKUmVrd2xscnVIVVpLTldRNHY5VkdNYmtpR3NQK0xJQitLOXZpRGNzV0NTSkY4NGtLbzhkQ3RkcVlJcmpqUFYrVAowOTFGOGhMR1NqZ1AyNUZCSmxSR2pMNnoyeUY0L1ZISUdoemtoSHpjdko0bnBQNXBLQWNLcFhRQldVWW5DWWo1Cjc5cUpVdFM4eXAzUmozTkMwTmxZQWEyR1dJMDA3WGQzQzh5SlVXUUJIQkZJMGpESDdsaGJCTVpad0FqcnJLZzMKUXdpZ1VkWVlJd3c5V1N2Uit3MGlPT3lUTEdLVEpkQ2l6OEUxRGsxcnlFTkRCd3IxWWl3WC9jS1RVOWxRamlWbAp2SzlaUEpyZ1hkWVcwR0lWcFNndEZSWFB4VC8yUmw2RW03Nmw2cGN6NE5pN0lGcGxmcjNnTTdUWWJOST0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
    server: https://kubernetes.docker.internal:6443
  name: development
contexts: []
current-context: ""
kind: Config
preferences: {}
users: []

Add user details to your configuration file:

$ kubectl config --kubeconfig=config-demo set-credentials $serviceAccount --token=$userToken
User "goglides-sa" set.

$ cat config-demo
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJd01ERXlNekl3TWpjeU0xb1hEVE13TURFeU1ESXdNamN5TTFvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUJXCnI2eUR0bXhIcEZwbHE2NTVEWHBpR3FIczVpY3BCN3l5K21CMEhQTUl0ZDc2RW9GK0JudWVZSnpvdjk1VWJzVlkKNVFGSU9mTHBISGhIbitEVnM4ZFNPRFA1SUhGMFdOMUNYT0JTR1lZeGFGNHlTQkxwaURSZ1k1dHdvVTVtT2laZwoxTStJa0Rjck5QVWNmemlXc1o4a0NzdDdranNLZzNhSHYvNEY3UGZidkFQcTIvaGtRK3l3ZWZOck8wN2l3N1h0ClUxdkY5d3dOTGZkdWQwZWZxaW1CcFVUWXVITThpUXRjakRCb09jc2FNYk56ZEM5SUFTcW5jbEpEdFFpYlp6MDgKaVhrUml0RmZ4VitVRE5RWGRiRE5JbmgyWGtlQ1JpTGg3V2ZvYi9YOTBPVUhva1g0M0J6c0VlZzA4dEZzVm1BSQpUekQvOU5SVHFJSHF0MEdKYVpjQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFBeCs5alFSZkY3Snp2dUVWdTMrbjNVWjc0ckYKUmVrd2xscnVIVVpLTldRNHY5VkdNYmtpR3NQK0xJQitLOXZpRGNzV0NTSkY4NGtLbzhkQ3RkcVlJcmpqUFYrVAowOTFGOGhMR1NqZ1AyNUZCSmxSR2pMNnoyeUY0L1ZISUdoemtoSHpjdko0bnBQNXBLQWNLcFhRQldVWW5DWWo1Cjc5cUpVdFM4eXAzUmozTkMwTmxZQWEyR1dJMDA3WGQzQzh5SlVXUUJIQkZJMGpESDdsaGJCTVpad0FqcnJLZzMKUXdpZ1VkWVlJd3c5V1N2Uit3MGlPT3lUTEdLVEpkQ2l6OEUxRGsxcnlFTkRCd3IxWWl3WC9jS1RVOWxRamlWbAp2SzlaUEpyZ1hkWVcwR0lWcFNndEZSWFB4VC8yUmw2RW03Nmw2cGN6NE5pN0lGcGxmcjNnTTdUWWJOST0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
    server: https://kubernetes.docker.internal:6443
  name: development
contexts: []
current-context: ""
kind: Config
preferences: {}
users:
- name: goglides-sa
  user:
    token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJnb2dsaWRlcyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJnb2dsaWRlcy1zYS10b2tlbi1ncGdqNiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJnb2dsaWRlcy1zYSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjhjOTA1MjViLWJlNGItNDczOC05Y2M2LTYzMWZiMGM3ZmY1NyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpnb2dsaWRlczpnb2dsaWRlcy1zYSJ9.VdkL9tSRNknbP5mYSXSv9jOM2KcBEAjeoo5f8MuExd1M8lP5R9re1l1JcZy0cP_lKjJ34toJY9ROlwoIxG7pZTe5BaDRVNEN2r41R3deTdkfAQj82Le5KvsIBRPTQ0dZKIxbWp9oqiH6CyuWhO6AYNm_z-vU9X0l_gofz6RWCjq_PgHDU8pmRO1o339xcU01xMJz7pVdkyVbx23egFabmnjCONDgtMwJ0cIvxK9yfhuuKFJxt2vHjdDerTFG4QuNoiHpZxwhSJjPgzdCwaaaGkz8UN_M8lO905pXFHXE1MmVvK_Anglp3B1l-hSLKGNoVYU4YgLUOaIi3jQJBZ2aiA

Add context details to your configuration file:

$ kubectl config --kubeconfig=config-demo \
    set-context goglides-namespace --cluster=development \
    --user $serviceAccount --namespace $namespace

$ cat config-demo
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJd01ERXlNekl3TWpjeU0xb1hEVE13TURFeU1ESXdNamN5TTFvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUJXCnI2eUR0bXhIcEZwbHE2NTVEWHBpR3FIczVpY3BCN3l5K21CMEhQTUl0ZDc2RW9GK0JudWVZSnpvdjk1VWJzVlkKNVFGSU9mTHBISGhIbitEVnM4ZFNPRFA1SUhGMFdOMUNYT0JTR1lZeGFGNHlTQkxwaURSZ1k1dHdvVTVtT2laZwoxTStJa0Rjck5QVWNmemlXc1o4a0NzdDdranNLZzNhSHYvNEY3UGZidkFQcTIvaGtRK3l3ZWZOck8wN2l3N1h0ClUxdkY5d3dOTGZkdWQwZWZxaW1CcFVUWXVITThpUXRjakRCb09jc2FNYk56ZEM5SUFTcW5jbEpEdFFpYlp6MDgKaVhrUml0RmZ4VitVRE5RWGRiRE5JbmgyWGtlQ1JpTGg3V2ZvYi9YOTBPVUhva1g0M0J6c0VlZzA4dEZzVm1BSQpUekQvOU5SVHFJSHF0MEdKYVpjQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFBeCs5alFSZkY3Snp2dUVWdTMrbjNVWjc0ckYKUmVrd2xscnVIVVpLTldRNHY5VkdNYmtpR3NQK0xJQitLOXZpRGNzV0NTSkY4NGtLbzhkQ3RkcVlJcmpqUFYrVAowOTFGOGhMR1NqZ1AyNUZCSmxSR2pMNnoyeUY0L1ZISUdoemtoSHpjdko0bnBQNXBLQWNLcFhRQldVWW5DWWo1Cjc5cUpVdFM4eXAzUmozTkMwTmxZQWEyR1dJMDA3WGQzQzh5SlVXUUJIQkZJMGpESDdsaGJCTVpad0FqcnJLZzMKUXdpZ1VkWVlJd3c5V1N2Uit3MGlPT3lUTEdLVEpkQ2l6OEUxRGsxcnlFTkRCd3IxWWl3WC9jS1RVOWxRamlWbAp2SzlaUEpyZ1hkWVcwR0lWcFNndEZSWFB4VC8yUmw2RW03Nmw2cGN6NE5pN0lGcGxmcjNnTTdUWWJOST0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
    server: https://kubernetes.docker.internal:6443
  name: development
contexts:
- context:
    cluster: development
    namespace: goglides
    user: goglides-sa
  name: goglides-namespace
current-context: ""
kind: Config
preferences: {}
users:
- name: goglides-sa
  user:
    token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJnb2dsaWRlcyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJnb2dsaWRlcy1zYS10b2tlbi1ncGdqNiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJnb2dsaWRlcy1zYSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjhjOTA1MjViLWJlNGItNDczOC05Y2M2LTYzMWZiMGM3ZmY1NyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpnb2dsaWRlczpnb2dsaWRlcy1zYSJ9.VdkL9tSRNknbP5mYSXSv9jOM2KcBEAjeoo5f8MuExd1M8lP5R9re1l1JcZy0cP_lKjJ34toJY9ROlwoIxG7pZTe5BaDRVNEN2r41R3deTdkfAQj82Le5KvsIBRPTQ0dZKIxbWp9oqiH6CyuWhO6AYNm_z-vU9X0l_gofz6RWCjq_PgHDU8pmRO1o339xcU01xMJz7pVdkyVbx23egFabmnjCONDgtMwJ0cIvxK9yfhuuKFJxt2vHjdDerTFG4QuNoiHpZxwhSJjPgzdCwaaaGkz8UN_M8lO905pXFHXE1MmVvK_Anglp3B1l-hSLKGNoVYU4YgLUOaIi3jQJBZ2aiA

Ok lets validate,

kubectl config get-contexts --kubeconfig=config-demo
CURRENT   NAME                 CLUSTER       AUTHINFO      NAMESPACE
          goglides-namespace   development   goglides-sa   goglides

Switch current-context to goglides-namespace for the user

export KUBECONFIG=config-demo
kubectl config use-context goglides-namespace