Exponer aplicaciones de Kubernetes

KubernetesBeginner
Practicar Ahora

Introducción

En este laboratorio, aprenderás cómo exponer aplicaciones de Kubernetes utilizando diversas técnicas, incluyendo la creación de servicios internos y externos, el trabajo con etiquetas (labels) y la exploración de los conceptos básicos de Ingress. Comenzarás configurando un clúster local de Kubernetes utilizando Minikube, luego desplegarás una aplicación de muestra de NGINX y la expondrás tanto internamente como externamente. También explorarás el uso de etiquetas (labels) para organizar y seleccionar recursos, y finalmente, aprenderás sobre Ingress y verás un ejemplo sencillo de un archivo YAML de Ingress.

Este es un Guided Lab, que proporciona instrucciones paso a paso para ayudarte a aprender y practicar. Sigue las instrucciones cuidadosamente para completar cada paso y obtener experiencia práctica. Los datos históricos muestran que este es un laboratorio de nivel principiante con una tasa de finalización del 95%. Ha recibido una tasa de reseñas positivas del 99% por parte de los estudiantes.

Iniciar el clúster de Kubernetes

En este paso, aprenderás cómo iniciar y verificar un clúster local de Kubernetes utilizando Minikube. Este es un paso esencial para desarrollar y probar aplicaciones de Kubernetes en tu máquina local.

Primero, inicia el clúster de Minikube:

minikube start

Ejemplo de salida:

😄  minikube v1.29.0 on Ubuntu 22.04
✨  Automatically selected the docker driver
📌  Using Docker driver with root permissions
🔥  Creating kubernetes in kubernetes cluster
🔄  Restarting existing kubernetes cluster
🐳  Preparing Kubernetes v1.26.1 on Docker 20.10.23...
🚀  Launching Kubernetes...
🌟  Enabling addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace

Verifica el estado del clúster utilizando varios comandos:

minikube status
kubectl get nodes

Ejemplo de salida para minikube status:

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

Ejemplo de salida para kubectl get nodes:

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   1m    v1.26.1

Estos comandos confirman que:

  1. Minikube está funcionando correctamente.
  2. Se ha creado un clúster local de Kubernetes.
  3. El clúster está listo para usar.
  4. Tienes un clúster de un solo nodo con capacidades de plano de control.

Desplegar una aplicación de muestra

En este paso, aprenderás cómo crear y desplegar una aplicación de Kubernetes utilizando un manifiesto YAML. Crearemos un sencillo despliegue de un servidor web NGINX para demostrar el proceso de definir y aplicar recursos de Kubernetes.

Primero, crea un directorio para tus manifiestos de Kubernetes:

mkdir -p ~/project/k8s-manifests
cd ~/project/k8s-manifests

Crea un archivo YAML para un despliegue de NGINX:

nano nginx-deployment.yaml

Agrega el siguiente manifiesto de despliegue:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80

Guarda el archivo (Ctrl+X, luego Y, luego Enter).

Aplica el despliegue al clúster de Kubernetes:

kubectl apply -f nginx-deployment.yaml

Ejemplo de salida:

deployment.apps/nginx-deployment created

Verifica el despliegue y los pods:

kubectl get deployments
kubectl get pods

Ejemplo de salida para kubectl get deployments:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           1m

Ejemplo de salida para kubectl get pods:

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          1m
nginx-deployment-xxx-zzz            1/1     Running   0          1m
nginx-deployment-xxx-www            1/1     Running   0          1m

Espera a que los pods estén en estado "Running" antes de continuar.

Analicemos el manifiesto YAML:

  • apiVersion: Especifica la versión de la API de Kubernetes.
  • kind: Define el tipo de recurso (Despliegue).
  • metadata: Proporciona el nombre y las etiquetas (labels) para el despliegue.
  • spec.replicas: Establece el número de réplicas de pods.
  • selector: Ayuda al despliegue a gestionar los pods correctos.
  • template: Define la especificación del pod.
  • containers: Especifica la imagen del contenedor y el puerto.

Este despliegue crea tres pods idénticos de NGINX, demostrando cómo Kubernetes gestiona aplicaciones contenerizadas.

Crear un servicio a través de YAML para exponer la aplicación internamente o externamente

En este paso, aprenderás cómo crear servicios de Kubernetes para exponer tu despliegue de NGINX tanto internamente como externamente. Demostraremos dos tipos comunes de servicios: ClusterIP y NodePort.

Primero, navega hasta el directorio de tu proyecto:

cd ~/project/k8s-manifests

Crea un archivo YAML para el servicio ClusterIP:

nano nginx-clusterip-service.yaml

Agrega el siguiente manifiesto de servicio:

apiVersion: v1
kind: Service
metadata:
  name: nginx-clusterip-service
spec:
  selector:
    app: nginx
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80

Ahora, crea un archivo YAML para el servicio NodePort:

nano nginx-nodeport-service.yaml

Agrega el siguiente manifiesto de servicio:

apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport-service
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080

Aplica ambas configuraciones de servicio:

kubectl apply -f nginx-clusterip-service.yaml
kubectl apply -f nginx-nodeport-service.yaml

Ejemplo de salida:

service/nginx-clusterip-service created
service/nginx-nodeport-service created

Verifica los servicios:

kubectl get services

Ejemplo de salida:

NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes                  ClusterIP   10.96.0.1        <none>        443/TCP        30m
nginx-clusterip-service     ClusterIP   10.104.xxx.xxx   <none>        80/TCP         1m
nginx-nodeport-service      NodePort    10.108.yyy.yyy   <none>        80:30080/TCP   1m

Para acceder al servicio NodePort, obtén la IP de Minikube:

minikube ip

Ejemplo de salida:

192.168.49.2

Diferencias clave entre los tipos de servicio:

  • ClusterIP: Acceso interno al clúster únicamente.
  • NodePort: Expone el servicio en un puerto estático en la IP de cada nodo.
  • Rango de NodePort: 30000 - 32767.

Verificar la configuración del servicio

En este paso, aprenderás cómo utilizar kubectl describe service para inspeccionar la configuración detallada de los servicios de Kubernetes y comprender sus propiedades de red.

Primero, asegúrate de estar en el directorio del proyecto:

cd ~/project/k8s-manifests

Describe en detalle el servicio ClusterIP:

kubectl describe service nginx-clusterip-service

Ejemplo de salida:

Name:              nginx-clusterip-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.104.xxx.xxx
IPs:               10.104.xxx.xxx
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.0.7:80,10.244.0.8:80,10.244.0.9:80
Session Affinity:  None
Events:            <none>

Ahora, describe el servicio NodePort:

kubectl describe service nginx-nodeport-service

Ejemplo de salida:

Name:                     nginx-nodeport-service
Namespace:                default
Labels:                   <none>
Annotations:              <none>
Selector:                 app=nginx
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.108.yyy.yyy
IPs:                      10.108.yyy.yyy
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30080/TCP
Endpoints:                10.244.0.7:80,10.244.0.8:80,10.244.0.9:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

Inspecciona los puntos finales (endpoints) del servicio para verificar la conectividad de red:

kubectl get endpoints

Ejemplo de salida:

NAME                        ENDPOINTS                               AGE
kubernetes                  192.168.49.2:8443                       45m
nginx-clusterip-service     10.244.0.7:80,10.244.0.8:80,10.244.0.9:80   15m
nginx-nodeport-service      10.244.0.7:80,10.244.0.8:80,10.244.0.9:80   15m

Información clave para comprender a partir de la descripción del servicio:

  • Selector: Muestra qué pods forman parte del servicio.
  • IP: Dirección IP interna del clúster del servicio.
  • Endpoints: Lista de direcciones IP y puertos de los pods que sirven el servicio.
  • Port y TargetPort: Definen cómo se enruta el tráfico.
  • NodePort: Puerto externo para el tipo de servicio NodePort.

Utilizar etiquetas (labels) para organizar y seleccionar recursos

En este paso, aprenderás cómo utilizar etiquetas (labels) en Kubernetes para organizar y seleccionar recursos de manera eficiente. Las etiquetas son pares clave-valor que te ayudan a gestionar y organizar objetos de Kubernetes.

Primero, verifica las etiquetas actuales en tus pods:

kubectl get pods --show-labels

Ejemplo de salida:

NAME                                READY   STATUS    RESTARTS   AGE   LABELS
nginx-deployment-xxx-yyy            1/1     Running   0          30m   app=nginx,pod-template-hash=xxx
nginx-deployment-xxx-zzz            1/1     Running   0          30m   app=nginx,pod-template-hash=yyy
nginx-deployment-xxx-www            1/1     Running   0          30m   app=nginx,pod-template-hash=zzz

Selecciona pods utilizando etiquetas específicas:

kubectl get pods -l app=nginx

Ejemplo de salida:

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          30m
nginx-deployment-xxx-zzz            1/1     Running   0          30m
nginx-deployment-xxx-www            1/1     Running   0          30m

Vamos a agregar una etiqueta personalizada a uno de los pods:

kubectl label pods nginx-deployment-xxx-yyy environment=development

Reemplaza nginx-deployment-xxx-yyy con el nombre de uno de tus pods.

Ejemplo de salida:

pod/nginx-deployment-xxx-yyy labeled

Ahora, selecciona pods con múltiples selectores de etiquetas:

kubectl get pods -l app=nginx,environment=development

Ejemplo de salida:

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          30m

Elimina una etiqueta de un pod:

kubectl label pods nginx-deployment-xxx-yyy environment-

Ejemplo de salida:

pod/nginx-deployment-xxx-yyy unlabeled

Demuestra la selección de etiquetas en servicios:

kubectl describe service nginx-clusterip-service

Busca la sección "Selector", que muestra cómo los servicios utilizan etiquetas para identificar pods.

Puntos clave sobre las etiquetas:

  • Las etiquetas son pares clave-valor adjuntos a objetos de Kubernetes.
  • Se utilizan para organizar, seleccionar y filtrar recursos.
  • Pueden agregarse, modificarse o eliminarse dinámicamente.
  • Los servicios y despliegues utilizan etiquetas para gestionar los pods relacionados.

Eliminar y gestionar servicios

En este paso, aprenderá cómo eliminar y gestionar servicios de Kubernetes utilizando comandos de kubectl. Comprender la gestión de servicios es crucial para mantener y limpiar sus recursos de Kubernetes.

Primero, liste los servicios actuales:

kubectl get services

Ejemplo de salida:

NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes                  ClusterIP   10.96.0.1        <none>        443/TCP        1h
nginx-clusterip-service     ClusterIP   10.104.xxx.xxx   <none>        80/TCP         45m
nginx-nodeport-service      NodePort    10.108.yyy.yyy   <none>        80:30080/TCP   45m

Elimine un servicio específico utilizando kubectl delete:

kubectl delete service nginx-clusterip-service

Ejemplo de salida:

service "nginx-clusterip-service" deleted

Verifique la eliminación del servicio:

kubectl get services

Ejemplo de salida:

NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes                  ClusterIP   10.96.0.1        <none>        443/TCP        1h
nginx-nodeport-service      NodePort    10.108.yyy.yyy   <none>        80:30080/TCP   45m

Para demostrar más claramente la eliminación de múltiples servicios, recreemos nuestros servicios y luego eliminémoslos juntos:

## Recrear servicios
kubectl apply -f nginx-clusterip-service.yaml
kubectl apply -f nginx-nodeport-service.yaml
## Eliminar múltiples servicios a la vez
kubectl delete service nginx-clusterip-service nginx-nodeport-service

Ejemplo de salida:

service "nginx-clusterip-service" deleted
service "nginx-nodeport-service" deleted

Verifique que todos los servicios se hayan eliminado (excepto el servicio kubernetes predeterminado):

kubectl get services

Ejemplo de salida:

NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   1h

Puntos clave sobre la eliminación de servicios:

  • Eliminar un servicio elimina el punto final de red
  • Los pods no se eliminan cuando se elimina un servicio
  • El servicio kubernetes predeterminado no se puede eliminar
  • Puede eliminar servicios utilizando el nombre, un archivo YAML o etiquetas
  • Se pueden eliminar múltiples servicios simultáneamente enumerándolos o utilizando selectores de etiquetas

Introducción a los conceptos básicos de Ingress y muestra de un ejemplo sencillo de YAML de Ingress

En este paso, aprenderá sobre Kubernetes Ingress, una forma poderosa de gestionar el acceso externo a los servicios en un clúster de Kubernetes.

¿Qué es Ingress?

Ingress es un objeto de la API que gestiona el acceso externo a los servicios en un clúster de Kubernetes, normalmente HTTP. Ingress proporciona:

  • Balanceo de carga: Distribuye el tráfico a múltiples servicios de back-end.
  • Finalización de SSL/TLS: Maneja conexiones seguras.
  • Virtual hosting basado en nombres: Enruta las solicitudes a diferentes servicios según el nombre de host.
  • Enrutamiento basado en rutas: Enruta las solicitudes a diferentes servicios según la ruta de la URL.

Ingress consta de dos componentes:

  1. Recurso de Ingress: Un objeto de la API de Kubernetes que define las reglas de enrutamiento.
  2. Controlador de Ingress: La implementación que hace cumplir las reglas definidas en el Recurso de Ingress.

Nota: Este laboratorio solo proporciona una introducción básica a Ingress. En entornos de producción, las configuraciones de Ingress pueden ser mucho más complejas, incluyendo enrutamiento avanzado, autenticación, limitación de velocidad y mucho más.

Habilitemos el complemento de Ingress en Minikube:

minikube addons enable ingress

Ejemplo de salida:

💡  ingress es un complemento mantenido por Kubernetes. Para cualquier problema, contacte a minikube en GitHub.
🔉  ingress se ha habilitado correctamente

Cree una implementación para dos aplicaciones de muestra:

kubectl create deployment web1 --image=nginx:alpine
kubectl create deployment web2 --image=httpd:alpine

Exponer estas implementaciones como servicios:

kubectl expose deployment web1 --port=80 --type=ClusterIP --name=web1-service
kubectl expose deployment web2 --port=80 --type=ClusterIP --name=web2-service

Cree un archivo YAML de Ingress:

nano ingress-example.yaml

Agregue la siguiente configuración de Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - http:
        paths:
          - path: /web1
            pathType: Prefix
            backend:
              service:
                name: web1-service
                port:
                  number: 80
          - path: /web2
            pathType: Prefix
            backend:
              service:
                name: web2-service
                port:
                  number: 80

Componentes clave de esta configuración de Ingress:

  • metadata.annotations: Configuraciones específicas para el controlador de Ingress.
  • spec.rules: Definen cómo se enruta el tráfico a los servicios.
  • path: Ruta de la URL que se coincidirá.
  • pathType: Cómo se debe coincidir la ruta (Prefix, Exact o ImplementationSpecific).
  • backend.service: El servicio y el puerto a los que se enrutará el tráfico.

Aplique la configuración de Ingress:

kubectl apply -f ingress-example.yaml

Verifique el recurso de Ingress:

kubectl get ingress

Ejemplo de salida:

NAME              CLASS   HOSTS   ADDRESS        PORTS   AGE
example-ingress   nginx   *       192.168.49.2   80      1m

Consulte los detalles de Ingress:

kubectl describe ingress example-ingress

La salida de ejemplo mostrará las reglas de enrutamiento y los servicios de back-end.

Prueba del Ingress:

## Obtener la IP de Minikube
minikube ip

## Probar el acceso a los servicios a través de Ingress
curl $(minikube ip)/web1
curl $(minikube ip)/web2

Cada comando debe devolver la página predeterminada del respectivo servidor web.

En entornos de producción, Ingress se puede configurar con:

  • Múltiples reglas basadas en nombres de host.
  • Certificados TLS para HTTPS.
  • Mecanismos de autenticación.
  • Limitación de velocidad.
  • Configuraciones de tiempo de espera personalizadas.
  • Afinidad de sesión.
  • Y muchas más características avanzadas.

Para una cobertura más completa de Ingress, consulte la documentación de Kubernetes y considere explorar la documentación de controladores de Ingress dedicados como NGINX Ingress o Traefik.

Resumen

En este laboratorio, aprendiste cómo iniciar y verificar un clúster local de Kubernetes utilizando Minikube, lo cual es esencial para desarrollar y probar aplicaciones de Kubernetes en tu máquina local. Luego, creaste y desplegaste un sencillo despliegue de un servidor web NGINX utilizando un manifiesto YAML, demostrando el proceso de definir y aplicar recursos de Kubernetes. Además, aprendiste cómo crear un servicio de Kubernetes para exponer tu aplicación internamente o externamente, y cómo utilizar etiquetas (labels) para organizar y seleccionar recursos. Finalmente, exploraste los conceptos básicos de Kubernetes Ingress y viste un ejemplo sencillo de Ingress en YAML.