Exposing the Kubernetes API in a Pod by running kubectl proxy in a sidecar container

Exposing the Kubernetes API in a Pod by running kubectl proxy in a sidecar container

On the page Accessing the Kubernetes API from a Pod in the Kubernetes documentation, we learn:

If you would like to query the API without an official client library, you can run kubectl proxy as the command of a new sidecar container in the Pod. This way, kubectl proxy will authenticate to the API and expose it on the localhost interface of the Pod, so that other containers in the Pod can use it directly.

Here's a complete example of how to expose the Kubernetes API in a Pod via a kubectl proxy, including a service account bound to the built-in cluster-adminClusterRole:

apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    kubernetes.io/enforce-mountable-secrets: "true"
  name: proxy-demo-sa
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: proxy-demo-admin-crb
  namespace: default
subjects:
- kind: ServiceAccount
  name: proxy-demo-sa
  namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Pod
metadata:
  name: proxy-demo
  namespace: default
spec:
  containers:
  - name: fake-main
    image: ubuntu
    command:
      - /bin/bash
      - '-c'
      - |
        apt-get update && \
        apt-get install -y curl && \
        sleep infinity
  - name: sidecar
    image: ubuntu
    command:
      - /bin/bash
      - '-c'
      - |
        apt-get update && \
        apt-get install -y apt-transport-https ca-certificates curl gpg && \
        curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg && \
        echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list && \
        apt-get update && \
        apt-get install -y kubectl && \
        kubectl proxy
  serviceAccountName: proxy-demo-sa

The lengthy instructions for installing kubectl in the sidecar container are taken directly from the Kubernetes documentation. If you need the sidecar permanently, it probably makes sense to create a dedicated image. (There are also numerous pre-made kubectl images available, e.g., bitnami/kubectl.)

You can save the above manifest as kubectl_proxy_sidecar_demo.yaml and deploy using kubectl:

kubectl apply -f kubectl_proxy_sidecar_demo.yaml

In our example, the fake-main container just idles forever. You can connect to a Bash session with

 kubectl exec -it proxy-demo -c fake-main -- bash

and verify that you can access the Kubernetes API using curl:

root@proxy-demo:/# curl http://localhost:8001/api
{
  "kind": "APIVersions",
  "versions": [
    "v1"
  ],
...
}