Kubernetes supports 2 primary modes of finding a Service:
The former works out of the box while the latter requires the CoreDNS cluster add-on (automatically installed when creating the EKS cluster).
When a Pod runs on a Node, the kubelet
adds a set of environment variables for each active Service. This introduces an ordering problem. To see why, inspect the environment of your running nginx Pods (your Pod name will be different):
Let’s view the pods again:
kubectl -n my-nginx get pods -l run=my-nginx -o wide
Output:
Now let’s inspect the environment of one of your running nginx Pods:
export mypod=$(kubectl -n my-nginx get pods -l run=my-nginx -o jsonpath='{.items[0].metadata.name}')
kubectl -n my-nginx exec ${mypod} -- printenv | grep SERVICE
Note there’s no mention of your Service. This is because you created the replicas before the Service.
Another disadvantage of doing this is that the scheduler might put both Pods on the same machine, which will take your entire Service down if it dies. We can do this the right way by killing the 2 Pods and waiting for the Deployment to recreate them. This time around the Service exists before the replicas. This will give you scheduler-level Service spreading of your Pods (provided all your nodes have equal capacity), as well as the right environment variables:
kubectl -n my-nginx rollout restart deployment my-nginx
kubectl -n my-nginx get pods -l run=my-nginx -o wide
Output just in the moment of change:
You may notice that the pods have different names, since they are destroyed and recreated.
Now let’s inspect the environment of one of your running nginx Pods one more time:
export mypod=$(kubectl -n my-nginx get pods -l run=my-nginx -o jsonpath='{.items[0].metadata.name}')
kubectl -n my-nginx exec ${mypod} -- printenv | grep SERVICE
We now have an environment variable referencing the nginx Service IP called MY_NGINX_SERVICE_HOST
.
Kubernetes offers a DNS cluster add-on Service that automatically assigns dns names to other Services. You can check if it’s running on your cluster:
To check if your cluster is already running CoreDNS, use the following command.
kubectl get service -n kube-system -l k8s-app=kube-dns
The service for CoreDNS is still called kube-dns
for backward compatibility.
If it isn’t running, you can enable it. The rest of this section will assume you have a Service with a long lived IP (my-nginx), and a DNS server that has assigned a name to that IP (the CoreDNS cluster add-on), so you can talk to the Service from any pod in your cluster using standard methods (e.g. gethostbyname). Let’s run another curl application to test this:
kubectl -n my-nginx run curl --image=radial/busyboxplus:curl -i --tty
Then, hit enter and run.
nslookup my-nginx
Output:
Type exit to log out of the container.
exit