Skip to content

Tema:

Kubernetes Networking - DNS, Service e Ingress


Introducción

La red en Kubernetes es fundamental para la comunicación entre aplicaciones, servicios y usuarios finales. Elementos como DNS, Service e Ingress juegan un papel clave en la conectividad y accesibilidad dentro del clúster y hacia el exterior. El DNS proporciona la resolución de nombres para identificar recursos, los Services habilitan la comunicación estable y confiable entre Pods, y los Ingress controlan el acceso externo mediante reglas de enrutamiento. En esta guía, exploraremos cómo estos componentes trabajan en conjunto para crear una red robusta y eficiente en Kubernetes.


Objetivo

Objetivo General:

  • Capacitar a los participantes en la configuración y gestión de la red en Kubernetes mediante el uso de DNS, Services e Ingress, asegurando una comunicación efectiva entre los componentes del clúster y habilitando accesos externos seguros y escalables para aplicaciones contenerizadas.

IPs para PODs y Servicios

Todos los PODS tienen asignada una dirección IP única dentro del cluster. Esto se logra asignando a cada nodo una subred única del CIDR del CLUSTER, desde la cual se asignan direcciones IP a los pods en ese nodo.

Cada recurso tipo Service, también cuenta con una dirección IP única.

Durante la instalación y configuración inicial de un cluster de Rancher Kubernetes Engine, se definen los segmentos de red para la asignación de IPs para los PODS y para los recursos tipo Services.

Kubernetes Network

Para las direcciones IP de los PODs, cada Nodo del cluster cuenta con un tamaño de subnet para asignar dichas direcciones IPs.

Kubernetes Network

DNS para Services y Pods

Kubernetes crea registros DNS para servicios y pods. Los Servicios pueden accederse y consultarse con nombres DNS con un sentido, en lugar de direcciones IP.

Rancher Kubernetes Engine (RKE) implementa el software CoreDNS por defecto para proporcionar un servicio de resolución de nombres, dentro del cluster es posible ejecutar el siguiente comando para ver la disponibilidad del servicio de CoreDNS:

kubectl get pods -n kube-system | grep coredns

De forma predeterminada, CoreDNS utilizará los servidores de nombres configurados del host (que normalmente residen en /etc/resolv.conf), por defecto se crea un dominio del cluster llamado: cluster.local

También se crea un registro de DNS por cada servicio creado dentro del cluster con la siguiente estructura de nombres:

metrics-server.kube-system.svc.cluster.local

Kubernetes Network

Laboratorio: Resolución de nombres por medio de DNS del Clúster

  1. Asegurarse de estar en el servidor bastion con el usuario student
    student@lab-0-bastion:~>
    
  2. Ingresar como usuario administrador al cluster de Kubernetes con el siguiente comando:
    export KUBECONFIG=/home/student/rke2_conn/cluster1/cluster1_kubeconfig.yaml
    
  3. Crear un nuevo namespace llamado example-dns
    kubectl create ns example-dns
    
  4. Establecer el nuevo namespace por defecto en el contexto actual:
    kubectl config set-context --current --namespace=example-dns
    
  5. Ejecutar el siguiente comando para verificar las configuraciones de DNS que se agregan en los Pods que se crean en el Cluster de Kubernetes:
    kubectl run -it --rm --restart=Never busybox --image=busybox:1.28 -- cat /etc/resolv.conf 2>/dev/null
    
    Deberá obtener un resultado como el siguiente:
    search example-dns.svc.cluster.local svc.cluster.local cluster.local c.mx-g05.internal google.internal
    nameserver 10.39.0.10
    options ndots:5
    
  6. Ejecute el siguiente comando para verificar los servicios dentro del Namespace kube-system:
    kubectl get svc -n kube-system
    
    Deberá obtener una salida como la siguiente:
    NAME                                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
    rke2-coredns-rke2-coredns                 ClusterIP   10.39.0.10      <none>        53/UDP,53/TCP   5h1m
    rke2-ingress-nginx-controller-admission   ClusterIP   10.39.83.78     <none>        443/TCP         4h50m
    rke2-metrics-server                       ClusterIP   10.39.81.82     <none>        443/TCP         4h50m
    rke2-snapshot-validation-webhook          ClusterIP   10.39.197.235   <none>        443/TCP         4h50m
    
  7. Ejecute el siguiente comando para comprobar la resolución de nombres de un Servicio dentro del Namespace kube-system por medio de un nuevo Pod Creado:
    kubectl run -it --rm --restart=Never --image=busybox:1.28 ping-test -- sh
    
    Cuando se encuentre dentro del Pod, ejecutar el comando Ping y verificar la resolución de nombres.
    / # ping -c 4 rke2-metrics-server.kube-system.svc.cluster.local
    
    Debería ver un resultado como el siguiente:
    PING rke2-metrics-server.kube-system.svc.cluster.local (10.39.81.82): 56 data bytes
    
    Verificar que en el resultado coinciden la Ip del servicio rke2-metrics-server
  8. Puede salir del POD creado para las pruebas:
    / # exit
    
    Puede ignorar los posibles errores mostrados
  9. Elimine el Namespace creado para realizar las validaciones de DNS:
    kubectl delete ns example-dns
    

Kubernetes Ingress y Kubernetes Servicios

Los servicios son los recursos que nos proporciona Kubernetes para conectar diferentes elementos de un Cluster entre ellos y con el exterior.

Un servicio en Kubernetes es un recurso creado con el fin de mantener un único punto constante de acceso a un grupo de pods. Cada servicio tiene una dirección IP y un puerto que nunca cambian.

Todos los servicios de Kubernetes tienen la capacidad de proporcionar acceso a un Cluster desde el exterior, pero cada uno lo hace de una manera diferente.

En Kubernetes existen los siguientes tipos de Servicios:

  • ClusterIP
  • NodePort
  • LoadBalancer

Un Ingress se usa para exponer rutas HTTP y HTTPS desde el exterior a servicios dentro del Cluster. El tráfico entrante es controlado por las reglas que definimos en un archivo de configuración.

Los Ingreess operan en la séptima capa de red (http) y pueden proveer funcionalidades adicionales a los Servicios.

Este recurso funciona de un modo diferente a los Servicios. Cuando creamos un ClusterIP o un NodePort basta con crear un objeto Kubernetes de ese tipo de servicio y aplicarlo al Cluster. Pero antes de poder usar Ingress necesitamos de algo llamado “Controlador”.

Un controlador de Ingress es un Pod o conjunto de Pods que se ejecutan en nuestro Cluster y cuya función es asegurarse de que el tráfico entrante se administra del modo que nosotros hayamos especificado.

En RKE se instala un Ingress Controller por defecto: NGINX Ingress Controller

Kubernetes Network

Laboratorio: Kubernetes Ingress y Servicios

La presenta guía muestra como habilitar el ingreso por parte de usuarios finales a una aplicación desplegada dentro de un cluster de Kubernetes.

  1. Asegurarse de estar en el servidor bastion con el usuario student
    student@lab-0-bastion:~>
    
  2. Ingresar como usuario administrador al cluster de Kubernetes con el siguiente comando:
    export KUBECONFIG=/home/student/rke2_conn/cluster1/cluster1_kubeconfig.yaml
    
  3. Crear un nuevo namespace llamado example-ingress
    kubectl create ns example-ingress
    
    Establecer el nuevo namespace por defecto en el contexto actual:
    kubectl config set-context --current --namespace=example-ingress
    
  4. Descargar y verificar el siguiente manifiesto:
    wget https://k8s.io/examples/controllers/nginx-deployment.yaml
    
  5. Después de examinar el archivo puedes ejecutar el Deployment con el siguiente comando:
    kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
    
  6. Verificar el estado del Deployment con el siguiente comando:
    kubectl get deployments
    
    La salida debe ser parecida a la siguiente:
    NAME               READY   UP-TO-DATE   AVAILABLE   AGE 
    nginx-deployment   3/3     3            3           1s
    
  7. Exponer el deployment por medio de un servicio tipo ClusterIP con el siguiente comando:
    kubectl expose deployment nginx-deployment --port=80 --target-port=80
    
    Verificar el servicio creado anteriormente:
    kubectl get svc
    
  8. Además es posible exponer este ejemplo de Deployment utilizando un tipo de servicio llamado NodePort, el cual utiliza un puerto de los HOST para publicar las aplicaciones
    kubectl create service nodeport nginx --tcp=30080:80 --node-port=30080 --dry-run=client -o yaml > nodeport.yaml
    
  9. Verificar y explorar el archivo creado anteriormente:
    cat nodeport.yaml
    
  10. Luego puede crear este servicio tipo NodePort con el siguiente comando:
    kubectl apply -f nodeport.yaml
    
  11. Listar los Servicios existentes en el Namespace actual
    kubectl get svc
    
  12. Verificar la conexión al servicio tipo NodePort con el siguiente comando, el cual hace un curl al puerto que hemos expuesto del Nodo, asegurarse de cambiar ${LAB} por el que corresponde de su laboratorio.:
    curl http://lab-${LAB}-node1:30080/
    
    Del comando anterior, debería de obtener un resultado como el siguiente:
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    
  13. Verificar en detalle el servicio tipo ClusterIP nginx-deployment creado anteriormente
    kubectl describe svc nginx-deployment
    
  14. Verificar el Wildcard Domain para las aplicaciones correspondiente a su laboratorio en el archivo CSV de inventario que le fue entregado, por ejemplo: apps.lab-0.mx-g05.ws.itmlabs.io y a continuación incorporarlo a la variable CLUSTER_WILDCARD:
    export CLUSTER_WILDCARD=apps.lab-0.mx-g05.ws.itmlabs.io
    
    Comprobar el contenido de la variable:
    echo $CLUSTER_WILDCARD
    
  15. Crear el recurso Ingress para exponer el aplicativo desplegado anteriormente por medio del Ingress Controller
    kubectl create ingress example-ingress --rule="example-ingress.$CLUSTER_WILDCARD/=nginx-deployment:80,tls"
    
  16. Verificar el Ingress creado
    kubectl get ingress
    
  17. Obtener la URL y abrir una nueva ventana del Navegador Web:
    echo https://example-ingress.$CLUSTER_WILDCARD
    
    # Reemplazar el valor de $CLUSTER_WILDCARD
    https://example-ingress.$CLUSTER_WILDCARD
    
  18. Deberá mostrarse la página de bienvenida de Nginx
    Welcome to nginx!
    
    If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
    
    For online documentation and support please refer to nginx.org.
    Commercial support is available at nginx.com.
    
    Thank you for using nginx.
    
  19. Eliminar el namespace llamado example-ingress
    kubectl delete ns example-ingress
    
  20. Eliminar los archivos creados en este laboratorio
    rm -f nginx-deployment.yaml nodeport.yaml
    

Conclusión

En este laboratorio, exploramos cómo Kubernetes utiliza Ingress y Servicios para gestionar y exponer aplicaciones de manera eficiente dentro y fuera del clúster. Estos recursos son fundamentales para enrutar el tráfico hacia los Pods y garantizar una conectividad flexible y segura.

El uso de Ingress y Servicios en Kubernetes proporciona una capa de abstracción poderosa para gestionar aplicaciones distribuidas. Permite manejar la conectividad, el enrutamiento y la seguridad de forma eficiente, escalable y flexible.

Este conocimiento es fundamental para diseñar arquitecturas modernas y asegurar una experiencia de usuario óptima, tanto en entornos de desarrollo como en producción. Practicar estas habilidades nos prepara para implementar y gestionar aplicaciones expuestas al mundo exterior de manera segura y confiable.