Configure a service account which can access the Kubernetes API to pull back data to be exposed to developers.
In my previous insight, I detailed out the high level approach for our k8s dev tools application. This relies on a Kubernetes service account which is used to make API calls to the Kubernetes API server. This can be granted specific permissions depending on what data it needs access to. Service Accounts are assigned to pods to allow that pod to automatically make requests without human interaction. This is how we expose specific data to developers without the developers needing access to the underlying API.
The simplest way to create a service account is defining it in a yaml file and using kubectl apply to configure it in your k8s cluster. In my examples, I'll be creating a service account named dev-tools in the default namespace. The yaml for this is:
apiVersion: v1
kind: ServiceAccount
metadata:
name: dev-tools
namespace: default
This simply creates the service account, to add permissions, a Role object also needs to be created. For now, we won't assign any permissions. The yaml for this is:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: dev-tools-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: [""]
verbs: ["get", "watch", "list"]
Then to tie permissions to the service account, one final yaml needs to be created:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-tools
namespace: default
subjects:
- kind: ServiceAccount
name: dev-tools
namespace: default
roleRef:
kind: Role
name: dev-tools-reader
These should each be run using the following kubectl command:
kubectl apply -f <filename>.yaml
Then to assign the service account to a pod, this can be added in a deployment/stateful set under spec.template.spec.serviceAccountName or in a pod under spec.serviceAccountName and redeploying the deployment/stateful set/pod.
Once the service account has been configured and associated with a pod, we can validate it can make a basic call to the k8s API. To do this, first connect to the pod (ideally a linux pod although similar commands could likely be run in a Windows pod) using kubectl:
kubectl exec --stdin --tty <pod name> -- /bin/bash
Then run the following commands from the pod's command line:
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
TOKEN=$(cat ${SERVICEACCOUNT}/token)
CACERT=${SERVICEACCOUNT}/ca.crt
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET https://kubernetes.default.svc/api/v1/namespaces/default/pods
This should return something like:
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "192.168.49.2:8443"
}
]
We'll be further exploring permissions and API endpoints in the next couple articles:
Pods: https://www.teamim.com/insights/kubernetes-developer-tools-displaying-application-version
Logs: https://www.teamim.com/insights/kubernetes-developer-tools-retrieving-application-logs