最新消息



雲端技能學習

【雲端技能學習】Kubernetes 簡單學 : Use curl to Access the K8S API within a pod

Do you need to call the Kubernetes API directly to get the k8s cluster information? This cluster information could be anything you get from the kubectl command. And, Do you need to make this happen in a pod? If your answer is “yes yes”, here is my sample of how I use the curl command to call the K8s API within a pod.

In fact, the kubectl command also provides you the curl command to call the K8s API. Let’s check out the logs.

# means comment, $ means command prompt

# I create an alias "k" for kubectl

$ alias k=kubectl

# I add "-v 9" to change the kubectl verbosity level to 9

$ k get no -v 9

You can see the curl command is in the red block. BTW, I also provide a snapshot of kubectl verbosity level for your information.


The snapshot is from here

# Sample Script

# 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}" -X GET ${APISERVER}/api/v1/namespaces/default/pods/ingress-nginx-ingress-controller-6cbf95f5d4-d628h/log

In order to have pods to access api, we need to define service account, role, rolebinding in the yaml file.

  • sa_role_rolebinding.yaml - I took some time to figure out how to get resource log. In the Role configuration, I added “pods/log” in the resources then it finally worked for me.
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ing-api-call-sa
  #namespace: gitlab-managed-apps
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: ing-api-call-role
  #namespace: gitlab-managed-apps
rules:
  - apiGroups: [""]
    resources:
      - pods
      - pods/log
    verbs:
      - get
      - list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ing-api-call-roldbinding
  #namespace: gitlab-managed-apps
subjects:
  - kind: ServiceAccount
    name: ing-api-call-sa
roleRef:
  kind: Role
  name: ing-api-call-role
  apiGroup: rbac.authorization.k8s.io

  • new_pod.yaml - Just in case, I might use some tools that base linux image doesn’t offer, so I choose to use the ubuntu image for this testing.
apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-test
  #namespace: gitlab-managed-apps
spec:
  serviceAccountName: ing-api-call-sa
  containers:
    - name: ubuntu
      image: ubuntu:latest
      command: ["sleep", "365d"]


Deploy and Test in the K8s cluster

My sample is to collect ingress controller pod logs, so I have to specify the resources to access.

deployment steps

$ alias k=kubectl
$ k apply -f sa_role_rolebinding.yaml
$ k apply -f new_pod.yaml
$ k get pod
$ k exec -it [new_pod] -- bash

In the ubuntu prompt, 

$ apt update && apt upgrade && apt install -y curl vim

$ vi apt-test.sh

cut and paste the sample script. 

$ chmod +x apt-test.sh
$ ./apt-test.sh

Remember to modify the name of ingress-controller pod. If your ingress-controller running in different namespace, you have also to modify the curl arguments.

If you configured the yaml and script correctly, you will see the below figure. Congrat~~

Clean up the test settings

$ k delete -f sa_role_rolebinding.yaml
$ k delete -f new_pod.yaml

more about the curl arguments

I didn’t automate the URL handling for setting up the namespace and pod name. We definately have different pod name, so don’t forget to change the pod name or namespace.

curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces/default/pods/ingress-nginx-ingress-controller-6cbf95f5d4-d628h/log

The url is

${APISERVER}/api/v1/namespaces/default/pods/ingress-nginx-ingress-controller-6cbf95f5d4-d628h/log

my case is

  1. my ingress controller is running in default namespace
  2. find your ingress pod name by k get po -A|grep ingress

I hope this can help. :-) If you don’t know how to set up ingress controller, you can use helm to install it. For more details, please click here

helm upgrade --install ingress-nginx ingress-nginx \
  --repo https://kubernetes.github.io/ingress-nginx \
  --namespace ingress-nginx --create-namespace

Summary

In this article, I shared my example of how I use the curl command to call the K8s API. The next step I would like to make a small docker image instead of the ubuntu one and use the new docker image to run a cronjob to get the IP information periodically.

Please feel free to let us know if you have questions or any.

Reference

https://kubernetes.io/docs/tasks/run-application/access-api-from-pod/
https://itnext.io/running-kubectl-commands-from-within-a-pod-b303e8176088

Contact
Contact