Kubernetes Pod to Kube API Server Communication - CloudCommandos/JohnChan GitHub Wiki
For some use cases we would want to get our K8s cluster information or make changes to it from within a pod. This article will show you how to do that!
All pods are run with service accounts. As of now (06-08-2019) each pod can only run with one service account. If a service account is not specified for a pod, the default service account of the pod's namespace will be used. All namespaces have default service accounts that are created along with the namespaces.
Creating a Service Account
Creating a service account is easy. However, most likely you'll need to give specific permissions to the new service account for it to serve its purpose. Create Role, ClusterRole, RoleBinding, and/or ClusterRoleBinding based on your needs. The declaration below shows a ClusterRole that includes some of the permissions already granted by the Role just as an example.
apiVersion: v1
kind: ServiceAccount
metadata:
name: your-service-account-name
namespace: your-namespace
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: your-namespace
name: pod-access
rules:
- apiGroups: ["extensions"] # "" indicates the core API group
resources: ["deployments", "deployments/scale", "replicasets"]
verbs: ["*"]
- apiGroups: [""] # "" indicates the core API group
resources: ["pods", "pods/log", "pods/exec", "services", "secrets"]
verbs: ["*"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: access-pods
namespace: your-namespace
subjects:
- kind: ServiceAccount
name: your-service-account-name
roleRef:
kind: Role #this must be Role or ClusterRole
name: pod-access # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-access
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["nodes/proxy"]
verbs: ["get", "watch", "list"]
- apiGroups: ["extensions"] # "" indicates the core API group
resources: ["deployments", "deployments/scale", "replicasets"]
verbs: ["*"]
- apiGroups: [""] # "" indicates the core API group
resources: ["pods", "pods/log", "pods/exec", "services"]
verbs: ["*"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: access-pods
subjects:
- kind: ServiceAccount
name: your-service-account-name
namespace: your-namespace
roleRef:
kind: ClusterRole #this must be Role or ClusterRole
name: pod-access # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
Specifying Service Account for a Pod
Use the serviceAccountName property to specify which service account to use. Kubernetes will use the service account matching the specified name under the pod's namespace.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: your-namespace
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy:
type: Recreate
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
imagePullPolicy: IfNotPresent
serviceAccountName: your-service-account-name
How is a Service Account Related to a Pod?
When a service account is created, a corresponding secret will also be created. This secret contains the CA certificate of the cluster, the namespace of the service account, and a token. When a pod is created, the corresponding service account's secret contents will be copied into the pod at /var/run/secrets/kubernetes.io/serviceaccount/.
How to Query the Kube API Server From Within a Pod?
Using REST API
The K8s internal DNS record for the Kube API Server is kubernetes.default.svc.cluster.local. All pods can use their service account token to query the Kube API Server's REST API. Below is an example https request made from within a pod to get the cluster's API information.
curl -ik --header "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc.cluster.local/api
Refer to Kubernetes API Reference Docs for details on the available APIs.
Using Kubectl
There are container images in Docker Hub with pre-installed kubectl that you can use. Just run the pod using a service account that has the appropriate permissions. If you want to build your own container image with pre-installed kubectl you can use this Dockerfile:
FROM bash:4
RUN apk --no-cache add gettext ca-certificates openssl \
&& wget https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 -O /usr/local/bin/dumb-init \
&& wget https://storage.googleapis.com/kubernetes-release/release/v1.14.1/bin/linux/amd64/kubectl -O /usr/local/bin/kubectl \
&& chmod a+x /usr/local/bin/kubectl /usr/local/bin/dumb-init \
&& apk --no-cache del ca-certificates openssl
ENTRYPOINT ["/usr/local/bin/dumb-init","--","/usr/local/bin/docker-entrypoint.sh"]
CMD ["/bin/bash","-c","while true; do sleep 30; echo sleeping; done;"]