In this article I will show you how to give limited access to a team member within the Kubernetes. You don’t have to mess with service accounts of your cloud provider to achieve this (whether you’re using AWS or GCP it doesn’t matter). It’s almost vendor agnostic. You can achieve this using Kubernetes ServiceAccount
resource.
You can also use this method to authenticate and authorize processes that you’re using in your CI/CD pipeline.
First, create a development namespace.
kubectl create namespace development
Then create a service account:
# 01-service-account.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: development
name: developer
Apply this config with kubectl apply -f 01-service-account.yaml
. When service account is created Kubernetes will generate a Secret in addition to it, which holds base64 encoded token. You will use this token to authenticate the user.
Obtain the name of the secret, and token, and store them in variables for later:
SECRET=$( kubectl get serviceaccounts/developer -n development -o jsonpath="{.secrets[0].name}" )
TOKEN=$( kubectl get secrets/${SECRET} -n development -o jsonpath="{.data.token}" | base64 -d )
In order to limit the privileges of the account, you have to assign it a role. This is done in two steps: first create a Role resource, which describes the role. The second step is to associate ServiceAccount with specific Role using RoleBinding.
# 02-role.yaml
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
namespace: development
name: developer
rules:
- apiGroups: [""] # the core API group
resources: ["pods"]
verbs: ["get", "describe", "list", "watch", "exec"]
With this role you will give developer access to pods. They may need direct access to the pod during development and debugging, however, they cannot edit ingresses/services or other resources.
# 03-role-binding.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: development
name: developer
roleRef:
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
namespace: development
name: developer
Now you can apply these two resources to your cluster:
kubectl apply -f 02-role.yaml
kubectl apply -f 03-role-binding.yaml
Before you generate configuration file which you can distribute to your developers, you have to obtain certificate for your cluster. In this tutorial I will assume you’re using GCP:
CERTIFICATE=$( gcloud container clusters describe <CLUSTER> --zone=<ZONE> --format='value(masterAuth.clusterCaCertificate)' )
Replace placeholders with appropriate names. You can also skip this process, but in your configuration file you’ll need to add insecure-skip-tls-verify: "true"
.
Finally, generate the configuration file:
cat > config <<EOF
---
apiVersion: v1
kind: Config
clusters:
- cluster:
name: dev
certificate-authority-data: ${CERTIFICATE}
# uncomment following if you don't have certificate
# insecure-skip-tls-verify: "true"
server: https://127.0.0.1 # replace this with your cluster IP
contexts:
- context:
name: dev
cluster: dev
namespace: development
user: developer
current-context: dev
preferences: {}
users:
- name: developer
user:
token: ${TOKEN}
EOF
Send this config file to your developers (as a tip, encrypt any file before distributing it, you can easily do this with gpg -c <file>
). The end user of this config should put it on ${HOME}/.kube/config
and they should be ready to start using it with kubectl
.