Limit Team Members Access to Kubernetes


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.

We're not spammers, and you can opt-out at any moment. We hate spam as much as you do.

powered by TinyLetter

See also