Accessing the Kubernetes API from a Pod

Prathap
3 min readDec 11, 2022

--

Lets first create a pod using ubuntu image and below is the YAML file (ubuntu-pod.yaml),

apiVersion: v1
kind: Pod
metadata:
name: ubuntu
labels:
app: ubuntu
spec:
containers:
- name: ubuntu
image: ubuntu:latest
command: ["/bin/sleep", "3650d"]
imagePullPolicy: IfNotPresent
restartPolicy: Always

Now create the pod:

The pod is up and running as shown above.

  • While running in a Pod, the Kubernetes apiserver is accessible via a Service named kubernetes in the default namespace.
  • Therefore, Pods can use the kubernetes.default.svc hostname to query the API server.

Now lets try accessing the api server using the above hostname from a Pod,

  • exec into the pod,

Try accessing the API server using curl https://kubernetes.default.svc/api ,

The above error suggests that the API is serving traffic over https with an unrecognized certificate (e.g. self-signed), so curl aborted the request.

Let’s temporarily ignore the certificate verification with -k and inspect the response:

You have a response from the server, but:

  1. You are forbidden to access the API endpoint (i.e. the status code is 403).
  2. You are identified as the system:anonymous, and this identity is not allowed to acess the API.

Note: Install curl package before performing action if curl package not available,

apt-get update
apt-get install -y curl

Lets use Service account to authenticate to the API server:

  • The recommended way to authenticate to the API server is with a service account credential. By default, a Pod is associated with a service account, and a credential (token) for that service account is placed into the filesystem tree of each container in that Pod, at /var/run/secrets/kubernetes.io/serviceaccount/token.
  • If available, a certificate bundle is placed into the filesystem tree of each container at /var/run/secrets/kubernetes.io/serviceaccount/ca.crt, and should be used to verify the serving certificate of the API server.
  • Finally, the default namespace to be used for namespaced API operations is placed in a file at /var/run/secrets/kubernetes.io/serviceaccount/namespace in each container.

Lets create a shell script to query the API server from a Pod,

# Point to the internal API server hostname
APISERVER=https://kubernetes.default.svc

# Path to ServiceAccount token
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount

# Read this Pod's namespace
NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)

# Read the ServiceAccount bearer token
TOKEN=$(cat ${SERVICEACCOUNT}/token)

# Reference the internal certificate authority (CA)
CACERT=${SERVICEACCOUNT}/ca.crt

# Explore the API with TOKEN
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" ${APISERVER}/api

Now access the api-server:

  • Modify the permissions to execute the shell script,

Run the shell script to access the API server,

Its success now and we are able to access/query the API server from the Pod.

--

--