I have a service called my-service
with an endpoint called refreshCache
. my-service
is hosted on multiple servers, and occasionally I want an event in my-service
on one of the servers to trigger refreshCache
on my-service
on all servers. To do this I manually maintain a list of all the servers that host my-service
, pull that list, and send a REST request to <server>/.../refreshCache
for each server.
I'm now migrating my service to k8s. Similarly to before, where I was running refreshCache
on all servers that hosted my-service
, I now want to be able to run refreshCache
on all the pods that host my-service
. Unfortunately I cannot manually maintain a list of pod IPs, as my understanding is that IPs are ephemeral in k8s, so I need to be able to dynamically get the IPs of all pods in a node, from within a container in one of those pods. Is this possible?
Note: I'm aware this information is available with kubectl get endpoints ...
, however kubectl
will not be available within my container.
You don't need kubectl
to access the Kubernetes API. You can do it with any tool that can make HTTP requests.
The Kubernetes API is a simple HTTP REST API, and all the authentication information that you need is present in the container if it runs as a Pod in the cluster.
To get the Endpoints object named my-service
from within a container in the cluster, you can do:
curl -k -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
https://kubernetes.default.svc:443/api/v1/namespaces/{namespace}/endpoints/my-service
Note: replace {namespace}
with the namespace of the my-service
Endpoints resource.
And to extract the IP addresses of the returned JSON, you could pipe the output to a tool like jq
:
... | jq -r '.subsets[].addresses[].ip'
Note that the Pod from which you are executing this needs read permissions for the Endpoints resource, otherwise the API request is denied.
You can do this with a ClusterRole, ClusterRoleBinding, and Service Account (you need to set this up only once):
kubectl create sa endpoint-reader
kubectl create clusterrole endpoint-reader --verb=get,list --resource=endpoints
kubectl create clusterrolebinding endpoint-reader --serviceaccount=default:endpoint-reader --clusterrole=endpoint-reader
Then, use the endpoint-reader
ServiceAccount for the Pod from which you want to execute the above curl
command by specifying it in the pod.spec.serviceAccountName
field.
Granting permissions for any other API operations (i.e. combinations of verbs and resources) works in the same way.