Una de las necesidades que cubren los servicios dentro de Kubernetes es la capacidad de dar acceso a tus pods que residen en el clúster. Esto es sencillo de ver cuando tienes una IP pública o privada a la que apuntar. Sin embargo, otra de las capacidades que te dan estos servicios es que otros pods puedan internamente acceder a ellos sin necesidad de conocer dichas IPs, a través de diferentes mecanismos. En este artículo quiero contarte cómo descubrir tus servicios en Kubernetes.
Descubrir tus servicios a través de variables de entorno
Lo primero que debes saber es que cada vez que creas un nuevo servicio dentro de Kubernetes, su IPs y puertos son almacenados en todos los pods en forma de variables de entorno. Para comprobarlo, vamos a utilizar el mismo ejemplo que en el artículo anterior:
#nginx-discovering-services.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
type: frontend
template:
metadata:
labels:
app: nginx
type: frontend
spec:
containers:
- name: nginx
image: nginx
ports:
- name: http
containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
type: frontend
type: LoadBalancer
ports:
- protocol: TCP
port: 80
targetPort: http
Para crear los recursos del YAML anterior puedes utilizar este comando:
kubectl create -f nginx-discovering-services.yaml
Si listas tus servicios, comprobarás que actualmente tienes dos disponibles: kubernetes y nginx-service:

Como primera prueba, vamos a comprobar las variables de entorno de las que dispone cualquiera de nuestros pods del deployment que acabamos de crear. Para ello, escoge uno cualquiera y ejecuta el comando env dentro del mismo:
kubectl exec nginx-deployment-68f6bbbc7f-7c85v env

Si te fijas, cada uno de los servicios están dados de alta con diferentes valores pero con un mismo patrón:
- NOMBRE_DEL_SERVICIO_HOST
- NOMBRE_DEL_SERVICIO_PORT_NUMERO_DE_PUERTO_PORT
- NOMBRE_DEL_SERVICIO_PORT_NUMERO_DE_PUERTO_ADDR
Una prueba sencilla sería intentar de invocar, en este caso a nuestro servidor de nginx, dentro de un pod utilizando estas variables. Para ello, vamos a crear un nuevo pod con curl desde el cual hacer nuestras pruebas:
kubectl run curl --image=radial/busyboxplus:curl -i --tty --rm
Desde la línea de comandos del pod que acabamos de crear ejecuta lo siguiente:
curl -s http://$NGINX_SERVICE_SERVICE_HOST
Comprobarás que a través de la variable de entorno hemos podido invocar a otro pod, obteniendo como resultado la página de inicio de Nginx:

Si bien esto es posible, a mi personalmente no me parece muy cómodo utilizar este mecanismo para llamar a los servicios de otros pods. No obstante, existe otra forma que es utilizando el servidor DNS que reside en nuestro Kubernetes.
Servidor de DNS dentro de Kubernetes
Para hacer nuestra vida un poco más fácil, uno de los pods que se instala como parte del sistema es un servidor DNS. Puedes comprobarlo a través del siguiente comando:
kubectl get po -n kube-system

Todos los pods de tu clúster tienen configurado dicho servidor para su uso. Para comprobarlo, puedes visualizar el contenido del archivo /etc/resolv.conf

Existen diferentes maneras de utilizarlo, dependiendo de quién, y donde, quiera consumir el servicio. Para que entiendas bien las diferentes formas de llamar a un servicio, dependiendo desde qué pod lo llame, prueba los siguientes supuestos:
Nombre completo del servicio
curl http://nginx-service.default.svc.cluster.local
Esta es la forma larga con la que podrás llamar al pod desde cualquier parte de tu clúster. Si te fijas, default es el nombre del namespace donde reside el servicio.
Nombre del servicio y namespace
La forma anterior se puede acortar y es necesaria cada vez que quieras invocar a un servicio que reside en un namespace diferente del que se hace la llamada:
curl http://nginx-service.default
Solo con el nombre del servicio
Si el pod que quiere realizar la petición convive en el mismo namespace donde está el servicio objetivo basta con utilizar únicamente el nombre del mismo:
curl http://nginx-service
De esta forma evitas trabajar con IPs directamente, desacoplando de esta forma la llamadas a servicios dentro de tu Kubernetes.
¡Saludos!

Bootcamp DevOps
Si tienes ganas de meterte en el área de DevOps, formo parte del
equipo de docentes del Bootcamp DevOps Lemoncode, ¿Te animas a
aprender con nosotros?