Note: This blog is modified to support v1.25 version of kubernetes, which is the latest at the time of writing.
There are some breaking changes in this latest version. Follow this twitter conversation for more information.
Anyone who doesnβt know about kubeconfig file, its a file which is used to configure access to a cluster. kubectl, helm like kubernetes client use this file to access kubernetes and perform operation.
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
---
apiVersion: v1
kind: Secret
metadata:
name: goglides-sa-secret
namespace: goglides
annotations:
kubernetes.io/service-account.name: goglides-sa
type: kubernetes.io/service-account-token
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
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/v1
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=goglides-sa-secret
export name=kind-multinode
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 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
Output:
Cluster "development" set.
cat config-demo
Output:
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
Output:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJd01ERXlNekl3TWpjeU0xb1hEVE13TURFeU1ESXdNamN5TTFvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUJXCnI2eUR0bXhIcEZwbHE2NTVEWHBpR3FIczVpY3BCN3l5K21CMEhQTUl0ZDc2RW9GK0JudWVZSnpvdjk1VWJzVlkKNVFGSU9mTHBISGhIbitEVnM4ZFNPRFA1SUhGMFdOMUNYT0JTR1lZeGFGNHlTQkxwaURSZ1k1dHdvVTVtT2laZwoxTStJa0Rjck5QVWNmemlXc1o4a0NzdDdranNLZzNhSHYvNEY3UGZidkFQcTIvaGtRK3l3ZWZOck8wN2l3N1h0ClUxdkY5d3dOTGZkdWQwZWZxaW1CcFVUWXVITThpUXRjakRCb09jc2FNYk56ZEM5SUFTcW5jbEpEdFFpYlp6MDgKaVhrUml0RmZ4VitVRE5RWGRiRE5JbmgyWGtlQ1JpTGg3V2ZvYi9YOTBPVUhva1g0M0J6c0VlZzA4dEZzVm1BSQpUekQvOU5SVHFJSHF0MEdKYVpjQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFBeCs5alFSZkY3Snp2dUVWdTMrbjNVWjc0ckYKUmVrd2xscnVIVVpLTldRNHY5VkdNYmtpR3NQK0xJQitLOXZpRGNzV0NTSkY4NGtLbzhkQ3RkcVlJcmpqUFYrVAowOTFGOGhMR1NqZ1AyNUZCSmxSR2pMNnoyeUY0L1ZISUdoemtoSHpjdko0bnBQNXBLQWNLcFhRQldVWW5DWWo1Cjc5cUpVdFM4eXAzUmozTkMwTmxZQWEyR1dJMDA3WGQzQzh5SlVXUUJIQkZJMGpESDdsaGJCTVpad0FqcnJLZzMKUXdpZ1VkWVlJd3c5V1N2Uit3MGlPT3lUTEdLVEpkQ2l6OEUxRGsxcnlFTkRCd3IxWWl3WC9jS1RVOWxRamlWbAp2SzlaUEpyZ1hkWVcwR0lWcFNndEZSWFB4VC8yUmw2RW03Nmw2cGN6NE5pN0lGcGxmcjNnTTdUWWJOST0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
server: [https://kubernetes.docker.internal:6443](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
Output:
User "goglides-sa" set.
cat config-demo
Output:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJd01ERXlNekl3TWpjeU0xb1hEVE13TURFeU1ESXdNamN5TTFvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUJXCnI2eUR0bXhIcEZwbHE2NTVEWHBpR3FIczVpY3BCN3l5K21CMEhQTUl0ZDc2RW9GK0JudWVZSnpvdjk1VWJzVlkKNVFGSU9mTHBISGhIbitEVnM4ZFNPRFA1SUhGMFdOMUNYT0JTR1lZeGFGNHlTQkxwaURSZ1k1dHdvVTVtT2laZwoxTStJa0Rjck5QVWNmemlXc1o4a0NzdDdranNLZzNhSHYvNEY3UGZidkFQcTIvaGtRK3l3ZWZOck8wN2l3N1h0ClUxdkY5d3dOTGZkdWQwZWZxaW1CcFVUWXVITThpUXRjakRCb09jc2FNYk56ZEM5SUFTcW5jbEpEdFFpYlp6MDgKaVhrUml0RmZ4VitVRE5RWGRiRE5JbmgyWGtlQ1JpTGg3V2ZvYi9YOTBPVUhva1g0M0J6c0VlZzA4dEZzVm1BSQpUekQvOU5SVHFJSHF0MEdKYVpjQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFBeCs5alFSZkY3Snp2dUVWdTMrbjNVWjc0ckYKUmVrd2xscnVIVVpLTldRNHY5VkdNYmtpR3NQK0xJQitLOXZpRGNzV0NTSkY4NGtLbzhkQ3RkcVlJcmpqUFYrVAowOTFGOGhMR1NqZ1AyNUZCSmxSR2pMNnoyeUY0L1ZISUdoemtoSHpjdko0bnBQNXBLQWNLcFhRQldVWW5DWWo1Cjc5cUpVdFM4eXAzUmozTkMwTmxZQWEyR1dJMDA3WGQzQzh5SlVXUUJIQkZJMGpESDdsaGJCTVpad0FqcnJLZzMKUXdpZ1VkWVlJd3c5V1N2Uit3MGlPT3lUTEdLVEpkQ2l6OEUxRGsxcnlFTkRCd3IxWWl3WC9jS1RVOWxRamlWbAp2SzlaUEpyZ1hkWVcwR0lWcFNndEZSWFB4VC8yUmw2RW03Nmw2cGN6NE5pN0lGcGxmcjNnTTdUWWJOST0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
server: [https://kubernetes.docker.internal:6443](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
Output:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJd01ERXlNekl3TWpjeU0xb1hEVE13TURFeU1ESXdNamN5TTFvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUJXCnI2eUR0bXhIcEZwbHE2NTVEWHBpR3FIczVpY3BCN3l5K21CMEhQTUl0ZDc2RW9GK0JudWVZSnpvdjk1VWJzVlkKNVFGSU9mTHBISGhIbitEVnM4ZFNPRFA1SUhGMFdOMUNYT0JTR1lZeGFGNHlTQkxwaURSZ1k1dHdvVTVtT2laZwoxTStJa0Rjck5QVWNmemlXc1o4a0NzdDdranNLZzNhSHYvNEY3UGZidkFQcTIvaGtRK3l3ZWZOck8wN2l3N1h0ClUxdkY5d3dOTGZkdWQwZWZxaW1CcFVUWXVITThpUXRjakRCb09jc2FNYk56ZEM5SUFTcW5jbEpEdFFpYlp6MDgKaVhrUml0RmZ4VitVRE5RWGRiRE5JbmgyWGtlQ1JpTGg3V2ZvYi9YOTBPVUhva1g0M0J6c0VlZzA4dEZzVm1BSQpUekQvOU5SVHFJSHF0MEdKYVpjQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFBeCs5alFSZkY3Snp2dUVWdTMrbjNVWjc0ckYKUmVrd2xscnVIVVpLTldRNHY5VkdNYmtpR3NQK0xJQitLOXZpRGNzV0NTSkY4NGtLbzhkQ3RkcVlJcmpqUFYrVAowOTFGOGhMR1NqZ1AyNUZCSmxSR2pMNnoyeUY0L1ZISUdoemtoSHpjdko0bnBQNXBLQWNLcFhRQldVWW5DWWo1Cjc5cUpVdFM4eXAzUmozTkMwTmxZQWEyR1dJMDA3WGQzQzh5SlVXUUJIQkZJMGpESDdsaGJCTVpad0FqcnJLZzMKUXdpZ1VkWVlJd3c5V1N2Uit3MGlPT3lUTEdLVEpkQ2l6OEUxRGsxcnlFTkRCd3IxWWl3WC9jS1RVOWxRamlWbAp2SzlaUEpyZ1hkWVcwR0lWcFNndEZSWFB4VC8yUmw2RW03Nmw2cGN6NE5pN0lGcGxmcjNnTTdUWWJOST0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
server: [https://kubernetes.docker.internal:6443](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
Let's run some unauthorized operations based on rbac permission (take a look on yaml definition above)
kubectl get nodes
You should see output, similar to this.
Error from server (Forbidden): nodes is forbidden: User "system:serviceaccount:goglides:goglides-sa" cannot list resource "nodes" in API group "" at the cluster scope
Now try some authorized operation based on rbac permission.
kubectl create secret generic my-secret --from-literal=key1=supersecret --from-literal=key2=topsecret
Output:
secret/my-secret created
kubectl delete secret my-secret
Output:
secret "my-secret" deleted
This confirms your kubeconfig with custom rbac permission is working.
Top comments (0)