Desplegar aplicaciones en Kubernetes

KubernetesKubernetesBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprenderás cómo desplegar aplicaciones en un clúster de Kubernetes. Comenzaremos configurando un entorno local de Kubernetes utilizando Minikube. Luego, explorarás comandos esenciales de kubectl para interactuar con tu clúster y gestionar los recursos de Kubernetes. A continuación, crearás un archivo de manifiesto YAML simple, lo aplicarás a tu clúster y comprobarás el estado del despliegue. Finalmente, aprenderás cómo acceder a tu aplicación desplegada utilizando kubectl proxy.

Este laboratorio cubrirá habilidades fundamentales de Kubernetes, incluyendo la configuración del clúster, la gestión básica de recursos y el despliegue de aplicaciones. Al final de este laboratorio, tendrás una comprensión sólida de cómo trabajar con Kubernetes y desplegar tus propias aplicaciones.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL kubernetes(("Kubernetes")) -.-> kubernetes/TroubleshootingandDebuggingCommandsGroup(["Troubleshooting and Debugging Commands"]) kubernetes(("Kubernetes")) -.-> kubernetes/ConfigurationandVersioningGroup(["Configuration and Versioning"]) kubernetes(("Kubernetes")) -.-> kubernetes/BasicCommandsGroup(["Basic Commands"]) kubernetes(("Kubernetes")) -.-> kubernetes/AdvancedCommandsGroup(["Advanced Commands"]) kubernetes/BasicCommandsGroup -.-> kubernetes/get("Get") kubernetes/BasicCommandsGroup -.-> kubernetes/create("Create") kubernetes/AdvancedCommandsGroup -.-> kubernetes/apply("Apply") kubernetes/TroubleshootingandDebuggingCommandsGroup -.-> kubernetes/describe("Describe") kubernetes/TroubleshootingandDebuggingCommandsGroup -.-> kubernetes/proxy("Proxy") kubernetes/ConfigurationandVersioningGroup -.-> kubernetes/version("Version") subgraph Lab Skills kubernetes/get -.-> lab-434644{{"Desplegar aplicaciones en Kubernetes"}} kubernetes/create -.-> lab-434644{{"Desplegar aplicaciones en Kubernetes"}} kubernetes/apply -.-> lab-434644{{"Desplegar aplicaciones en Kubernetes"}} kubernetes/describe -.-> lab-434644{{"Desplegar aplicaciones en Kubernetes"}} kubernetes/proxy -.-> lab-434644{{"Desplegar aplicaciones en Kubernetes"}} kubernetes/version -.-> lab-434644{{"Desplegar aplicaciones en Kubernetes"}} end

Iniciar el clúster de Kubernetes

En este paso, iniciaremos un clúster local de Kubernetes utilizando Minikube. Minikube es una excelente herramienta para el desarrollo y el aprendizaje de Kubernetes, ya que te permite ejecutar un clúster de Kubernetes de un solo nodo en tu máquina local. Luego, verificaremos que el clúster esté funcionando correctamente y listo para su uso.

Primero, abre tu terminal. Aquí es donde escribirás los comandos para interactuar con tu computadora. Para iniciar el clúster de Minikube, escribe el siguiente comando y presiona Enter:

minikube start

Este comando iniciará el proceso de creación e inicio de tu clúster local de Kubernetes. Minikube descargará los componentes necesarios y configurará tu clúster. Verás una salida en tu terminal mientras Minikube se inicia. Aquí tienes un ejemplo de cómo podría verse la 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

Una vez que Minikube se haya iniciado, verifiquemos que está en funcionamiento y que el clúster de Kubernetes dentro de Minikube está listo. Ejecuta los siguientes comandos uno después del otro, presionando Enter después de cada comando:

minikube status
kubectl get nodes

El comando minikube status te indicará el estado de Minikube en sí. El comando kubectl get nodes se comunicará con tu clúster de Kubernetes y recuperará información sobre los nodos (computadoras) en tu clúster. Dado que Minikube es un clúster de un solo nodo, deberías ver un nodo en la lista.

Aquí tienes un ejemplo de la salida que podrías ver:

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

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

Analicemos lo que nos dice esta salida:

  1. El estado de minikube muestra Running para host, kubelet y apiserver. Esto indica que los componentes principales de Minikube están funcionando correctamente.
  2. kubectl get nodes muestra un nodo llamado minikube con un STATUS de Ready. Ready significa que este nodo está listo para ejecutar aplicaciones. control-plane bajo ROLES indica que este nodo está actuando como el plano de control para el clúster de Kubernetes, gestionando y orquestando el clúster.

Estos comandos confirman que:

  1. Minikube está en funcionamiento en tu máquina.
  2. Se ha creado un clúster local de Kubernetes dentro de Minikube.
  3. El clúster de Kubernetes está en estado Ready y listo para su uso.
  4. Tienes un clúster de Kubernetes de un solo nodo donde el nodo minikube está actuando como el plano de control.

Aprender comandos y sintaxis básicos de kubectl

En este paso, explorarás los comandos fundamentales de kubectl. kubectl es la herramienta de línea de comandos que te permite interactuar con tu clúster de Kubernetes. Es esencial para gestionar los recursos de Kubernetes. Demostraremos cómo usar kubectl para ver recursos y comprender la gestión básica de objetos de Kubernetes.

Comencemos explorando los namespaces (espacios de nombres) dentro de tu clúster de Kubernetes. Los namespaces son una forma de organizar tus recursos de Kubernetes. Por defecto, los clústeres de Kubernetes tienen varios namespaces para componentes del sistema y recursos de usuario. Para ver una lista de namespaces, ejecuta el siguiente comando:

kubectl get namespaces

Este comando listará todos los namespaces disponibles en tu clúster. Ejemplo de salida:

NAME              STATUS   AGE
default           Active   10m
kube-node-lease   Active   10m
kube-public       Active   10m
kube-system       Active   10m

Por lo general, verás al menos estos namespaces predeterminados:

  • default: El namespace predeterminado para los recursos creados por el usuario si no se especifica ningún otro namespace.
  • kube-node-lease: Se utiliza para las concesiones de nodos (node leases), que ayudan al plano de control a realizar un seguimiento de la salud de los nodos.
  • kube-public: Destinado a recursos que deben ser accesibles públicamente (aunque rara vez se utiliza para información sensible).
  • kube-system: Contiene recursos de nivel de sistema, como los componentes principales de Kubernetes.

A continuación, veamos los componentes del sistema que se ejecutan en el namespace kube-system. Muchos componentes principales de Kubernetes se ejecutan como pods dentro de este namespace. Para ver los pods en un namespace específico, utiliza la bandera -n o --namespace seguida del nombre del namespace. Ejecuta el siguiente comando para ver los pods en el namespace kube-system:

kubectl get pods -n kube-system

Este comando listará todos los pods que se ejecutan en el namespace kube-system. Ejemplo de salida:

NAME                               READY   STATUS    RESTARTS   AGE
coredns-787d4945fb-j8rhx           1/1     Running   0          15m
etcd-minikube                       1/1     Running   0          15m
kube-apiserver-minikube             1/1     Running   0          15m
kube-controller-manager-minikube    1/1     Running   0          15m
kube-proxy-xb9rz                    1/1     Running   0          15m
kube-scheduler-minikube             1/1     Running   0          15m
storage-provisioner                 1/1     Running   0          15m

Esta salida muestra los nombres de los pods, su estado READY (cuántos contenedores del pod están listos en relación con el total), su STATUS (por ejemplo, Running), cuántas veces se han RESTARTED y su AGE. Estos son los componentes esenciales que hacen que Kubernetes funcione.

Ahora, exploremos algunos patrones básicos de comandos de kubectl. La sintaxis general de los comandos de kubectl es:

kubectl [command] [TYPE] [NAME] [flags]

Analicemos esto:

  • kubectl: La herramienta de línea de comandos en sí.
  • [command]: Especifica la acción que deseas realizar. Los comandos comunes incluyen:
    • get: Muestra uno o varios recursos.
    • describe: Muestra detalles sobre un recurso específico.
    • create: Crea un nuevo recurso.
    • delete: Elimina recursos.
    • apply: Aplica una configuración a un recurso. Lo usaremos mucho más adelante.
  • [TYPE]: Especifica el tipo de recurso de Kubernetes con el que deseas interactuar. Los tipos de recursos comunes incluyen:
    • pods: Las unidades desplegables más pequeñas en Kubernetes.
    • deployments: Gestionan conjuntos de pods para escalado y actualizaciones.
    • services: Exponen aplicaciones que se ejecutan en pods.
    • nodes: Las máquinas trabajadoras en tu clúster de Kubernetes.
    • namespaces: Agrupaciones lógicas de recursos.
  • [NAME]: El nombre de un recurso específico. Esto es opcional; si omites el nombre, kubectl operará en todos los recursos del tipo especificado.
  • [flags]: Banderas opcionales para modificar el comportamiento del comando (por ejemplo, -n <namespace>, -o wide).

Veamos algunos ejemplos:

## Get all resources in the default namespace
kubectl get all

## Describe a specific resource type (the 'minikube' node)
kubectl describe nodes minikube

El comando kubectl get all recuperará información sobre todos los tipos de recursos (servicios, despliegues, pods, etc.) en el namespace default. Un ejemplo de salida podría ser así:

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

Esto muestra que en el namespace default, tenemos un service llamado kubernetes.

El comando kubectl describe nodes minikube proporcionará mucha información detallada sobre el nodo minikube, incluyendo su estado, capacidad, direcciones, etc. Esto es útil para entender el estado y la configuración de tus nodos.

Estos comandos te ayudan a:

  1. Ver los recursos dentro de tu clúster de Kubernetes.
  2. Obtener información detallada sobre los componentes del clúster y su estado actual.
  3. Comprender la estructura y sintaxis básica de los comandos de kubectl.

Crear un manifiesto YAML simple

Antes de crear tu primer manifiesto YAML, es importante entender los objetos clave de Kubernetes con los que trabajarás. Estos objetos son los bloques de construcción para gestionar y orquestar tus aplicaciones dentro de Kubernetes.

Comprender los objetos de Kubernetes

  • Pod: La unidad más básica en Kubernetes. Un pod es como una caja que puede contener uno o más contenedores. Estos contenedores dentro de un pod comparten la misma red y almacenamiento. Puedes pensar en un pod como una instancia única de tu aplicación.
  • Deployment: Los despliegues (deployments) se utilizan para gestionar pods. Aseguran que un número deseado de réplicas de pods esté siempre en ejecución. Si un pod falla, un despliegue lo reemplazará automáticamente. Los despliegues también manejan las actualizaciones de tu aplicación de manera controlada, como las actualizaciones graduales (rolling updates).
  • Service: Los servicios proporcionan una forma estable de acceder a tu aplicación que se ejecuta en pods. Debido a que los pods se pueden crear y destruir, sus direcciones IP pueden cambiar. Un servicio proporciona una dirección IP fija y un nombre DNS que siempre apunta al conjunto de pods que gestiona. Esto permite que otras partes de tu aplicación, o usuarios externos, accedan de forma confiable a tu aplicación sin necesidad de seguir las direcciones IP individuales de los pods.

A continuación, se muestra un diagrama para ilustrar las relaciones entre estos objetos:

graph TD; A[Deployment] -->|Manages| B[Pods] B -->|Contains| C[Containers] B -->|Communicates via| D[Services] D -->|Exposes| E[External Clients]

Comprender estos objetos es crucial porque definirás su estado y configuración deseados utilizando manifiestos YAML.

Resumen del manifiesto YAML

Un manifiesto YAML en Kubernetes es un archivo escrito en formato YAML que describe los objetos de Kubernetes que deseas crear o gestionar. YAML es un lenguaje de serialización de datos legible por humanos. Utilizar YAML para los manifiestos de Kubernetes tiene varias ventajas:

  1. Gestión declarativa: Describe el estado deseado de tus recursos en el archivo YAML (por ejemplo, "Quiero que se ejecuten 3 réplicas de mi aplicación"). Luego, Kubernetes trabaja para hacer que el estado real coincida con el estado deseado. Esto se llama gestión declarativa.
  2. Control de versiones: Los archivos YAML son basados en texto y se pueden almacenar fácilmente en sistemas de control de versiones como Git. Esto te permite realizar un seguimiento de los cambios en tus configuraciones de Kubernetes a lo largo del tiempo, revertir a configuraciones anteriores y colaborar con otros.
  3. Reutilización y portabilidad: Puedes reutilizar los manifiestos YAML en diferentes entornos (desarrollo, prueba, producción) con cambios mínimos. Esto hace que tus despliegues sean más consistentes y reproducibles.

Ahora que comprendes los conceptos básicos de los objetos de Kubernetes y los manifiestos YAML, estás listo para crear tu primer manifiesto.

Crear un manifiesto YAML

Primero, navega hasta tu directorio de proyecto. Se asume que tienes un directorio project en tu directorio de inicio (~). Si no lo tienes, créalo ahora utilizando mkdir project. Luego, cambia tu directorio actual a project utilizando cd project:

cd ~/project

A continuación, crea un nuevo directorio para almacenar tus manifiestos de Kubernetes. Llamémoslo k8s-manifests. Utiliza el comando mkdir para crear el directorio y luego cd para moverte a él:

mkdir -p k8s-manifests
cd k8s-manifests

Ahora, crearás tu primer archivo de manifiesto YAML. Comencemos con un manifiesto simple para un pod de NGINX. NGINX es un popular servidor web. Crearemos un pod que ejecute un solo contenedor de NGINX. Utiliza el editor de texto nano para crear un archivo llamado nginx-pod.yaml:

nano nginx-pod.yaml

nano es un editor de texto simple que se ejecuta en tu terminal. Una vez que se abra nano, pega el siguiente contenido en el archivo:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:latest
      ports:
        - containerPort: 80

Comprendamos cada parte de este manifiesto YAML:

  • apiVersion: v1: Especifica la versión de la API de Kubernetes a utilizar para crear este objeto. v1 es el grupo de API principal y se utiliza para objetos fundamentales como pods, servicios y namespaces.
  • kind: Pod: Indica que estás definiendo un recurso de Pod.
  • metadata:: Contiene datos sobre el Pod, como su nombre y etiquetas.
    • name: nginx-pod: Establece el nombre del Pod en nginx-pod. Así es como te referirás a este pod dentro de Kubernetes.
    • labels:: Las etiquetas son pares clave-valor que se adjuntan a los objetos. Se utilizan para organizar y seleccionar subconjuntos de objetos. Aquí, estamos agregando una etiqueta app: nginx a este pod.
  • spec:: Describe el estado deseado del Pod.
    • containers:: Una lista de contenedores que se ejecutarán dentro del Pod. En este caso, tenemos solo un contenedor.
      • - name: nginx: Establece el nombre del contenedor en nginx.
      • image: nginx:latest: Especifica la imagen del contenedor a utilizar. nginx:latest se refiere a la última versión de la imagen Docker de NGINX de Docker Hub.
      • ports:: Una lista de puertos que este contenedor expondrá.
        • - containerPort: 80: Especifica que el contenedor expondrá el puerto 80. El puerto 80 es el puerto HTTP estándar.

Después de pegar el contenido, guarda el archivo y sal de nano. Para hacer esto, presiona Ctrl+X (salir), luego escribe Y (sí para guardar) y, finalmente, presiona Enter para confirmar el nombre del archivo y guardar.

Ahora que has creado tu archivo nginx-pod.yaml, debes aplicarlo a tu clúster de Kubernetes para crear el pod. Utiliza el comando kubectl apply con la bandera -f, que especifica el archivo que contiene el manifiesto:

kubectl apply -f nginx-pod.yaml

Este comando envía el manifiesto a tu clúster de Kubernetes, y Kubernetes creará el pod según lo definido. Deberías ver una salida similar a esta:

pod/nginx-pod created

Para verificar que el pod se haya creado y esté en ejecución, utiliza el comando kubectl get pods. Esto listará todos los pods en el namespace predeterminado. También puedes utilizar kubectl describe pod nginx-pod para obtener información detallada sobre el nginx-pod. Ejecuta estos comandos:

kubectl get pods
kubectl describe pod nginx-pod

Ejemplo de salida para kubectl get pods:

NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          1m

Esta salida muestra que el nginx-pod está READY (1 de 1 contenedor está listo) y su STATUS es Running. Esto significa que tu pod de NGINX se ha creado correctamente y está en ejecución.

Ahora, creemos un manifiesto para un recurso más complejo: un Despliegue (Deployment). Un Despliegue gestionará un conjunto de pods, asegurando que se ejecuten el número deseado de réplicas. Crea un nuevo archivo llamado nginx-deployment.yaml utilizando nano:

nano nginx-deployment.yaml

Pega el siguiente contenido en nginx-deployment.yaml:

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

Destacamos las principales diferencias y nuevas partes en comparación con el manifiesto nginx-pod.yaml:

  • apiVersion: apps/v1: Para los Despliegues, se utiliza la versión de la API apps/v1, que es parte del grupo de API apps y gestiona recursos de gestión de aplicaciones de nivel superior.
  • kind: Deployment: Indica que estás definiendo un recurso de Despliegue.
  • spec:: La sección spec de un Despliegue es más compleja porque define cómo el Despliegue debe gestionar los pods.
    • replicas: 3: Esto es nuevo. Especifica que deseas que se ejecuten 3 réplicas (copias) de tu pod. El Despliegue asegurará que siempre haya 3 pods que coincidan con los criterios definidos en la plantilla (template).
    • selector:: Un selector se utiliza por el Despliegue para identificar qué pods debe gestionar.
      • matchLabels:: Define las etiquetas que los pods deben tener para ser seleccionados por este Despliegue. Aquí, selecciona los pods con la etiqueta app: nginx.
    • template:: La plantilla (template) define la especificación del pod que el Despliegue utilizará para crear nuevos pods. Es esencialmente la misma definición de pod que en nuestro ejemplo nginx-pod.yaml, incluyendo metadata.labels y spec.containers. Importante: Las etiquetas definidas aquí en template.metadata.labels deben coincidir con selector.matchLabels para que el Despliegue pueda gestionar estos pods.

Guarda y sal de nano (Ctrl+X, Y, Enter).

Ahora, aplica este manifiesto de Despliegue a tu clúster:

kubectl apply -f nginx-deployment.yaml

Deberías ver una salida como esta:

deployment.apps/nginx-deployment created

Verifica el Despliegue y los pods que creó. Utiliza kubectl get deployments para verificar el estado del Despliegue y kubectl get pods para ver los pods.

kubectl get deployments
kubectl get pods

Ejemplo de salida:

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

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
  • kubectl get deployments muestra que el nginx-deployment tiene READY 3/3, UP-TO-DATE 3 y AVAILABLE 3. Esto significa que el Despliegue ha creado y está gestionando 3 pods correctamente, y todos ellos están listos y disponibles.
  • kubectl get pods ahora lista tres pods con nombres que comienzan con nginx-deployment-. Estos son los pods creados y gestionados por tu nginx-deployment.

Aplicar el manifiesto YAML

En este paso, explorarás en detalle el comando kubectl apply y aprenderás diferentes formas de aplicar manifiestos de Kubernetes. A partir de los archivos YAML del paso anterior, demostraremos diversas técnicas para aplicar manifiestos.

Primero, asegúrate de estar en el directorio correcto:

cd ~/project/k8s-manifests

Creemos un nuevo subdirectorio para organizar mejor nuestros manifiestos. Crea un directorio llamado manifests y navega hacia él:

mkdir -p manifests
cd manifests

Ahora, creemos un manifiesto para una aplicación web simple que incluya tanto un Despliegue (Deployment) como un Servicio (Service) en un solo archivo. Crea un nuevo archivo llamado web-app.yaml usando nano:

nano web-app.yaml

Agrega el siguiente contenido a web-app.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: nginx:alpine
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80

Este manifiesto define dos recursos de Kubernetes en un solo archivo, separados por ---. Esta es una forma común de agrupar recursos relacionados. Analicemos lo nuevo:

  • Múltiples recursos en un solo archivo: El archivo web-app.yaml ahora contiene dos definiciones de recursos de Kubernetes separadas: un Despliegue y un Servicio. El separador --- se utiliza para distinguirlos.
  • kind: Service: Esto define un recurso de Servicio.
    • spec.selector.app: web: Este Servicio apuntará a los pods que tengan la etiqueta app: web. Esto coincide con las etiquetas que establecimos para los pods creados por el Despliegue web-app.
    • spec.type: ClusterIP: Especifica el tipo de servicio como ClusterIP. Esto significa que el servicio se expondrá en una dirección IP interna dentro del clúster y se utiliza típicamente para la comunicación entre servicios dentro del clúster.
    • spec.ports: Define cómo el servicio mapea puertos a los pods de destino.
      • port: 80: El puerto en el propio Servicio al que accederás.
      • targetPort: 80: El puerto en los pods de destino al que el servicio reenviará el tráfico.

Ahora, apliquemos este manifiesto utilizando diferentes métodos.

Método 1: Aplicar el archivo completo

Esta es la forma más común de aplicar un manifiesto. Utiliza kubectl apply -f seguido del nombre del archivo:

kubectl apply -f web-app.yaml

Este comando creará tanto el Despliegue como el Servicio definidos en web-app.yaml. Deberías ver una salida como esta:

deployment.apps/web-app created
service/web-service created

Método 2: Aplicar desde un directorio

Puedes aplicar todos los manifiestos en un directorio a la vez. Si tienes múltiples archivos de manifiesto en el directorio manifests, puedes aplicarlos todos especificando el directorio en lugar de un archivo específico:

kubectl apply -f.

El . representa el directorio actual. kubectl buscará archivos YAML en este directorio y los aplicará todos. Esto es útil cuando has organizado tus manifiestos en múltiples archivos dentro de un directorio.

Método 3: Aplicar desde una URL (Opcional)

kubectl apply también puede aplicar manifiestos directamente desde una URL. Esto es útil para desplegar rápidamente aplicaciones de ejemplo o configuraciones alojadas en línea. Por ejemplo, puedes desplegar el despliegue del maestro de Redis desde el repositorio de ejemplos de Kubernetes:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook/redis-master-deployment.yaml

Esto descargará el manifiesto desde la URL y lo aplicará a tu clúster. Nota: Ten precaución al aplicar manifiestos desde URLs no confiables, ya que pueden modificar potencialmente tu clúster.

Exploremos algunas opciones adicionales para kubectl apply.

Ejecución simulada (Dry Run)

Puedes usar la bandera --dry-run=client para simular la aplicación de un manifiesto sin realizar cambios reales en el clúster. Esto es útil para comprobar si tu manifiesto es válido y para ver qué recursos se crearían o modificarían:

kubectl apply -f web-app.yaml --dry-run=client

Este comando mostrará lo que se crearía o cambiaría, pero no aplicará realmente los cambios a tu clúster.

Salida detallada (Verbose Output)

Para obtener una salida más detallada de kubectl apply, puedes usar la bandera -v seguida de un nivel de detalle (por ejemplo, -v=7). Los niveles de detalle más altos proporcionan más información, lo que puede ser útil para la depuración:

kubectl apply -f web-app.yaml -v=7

Esto imprimirá mucha más información sobre las solicitudes de API que se están realizando y el procesamiento del manifiesto.

Verifica los recursos creados al aplicar web-app.yaml. Utiliza kubectl get deployments y kubectl get services para listar los Despliegues y Servicios en tu clúster:

## List deployments
kubectl get deployments

## List services
kubectl get services

## Describe the deployment to see more details
kubectl describe deployment web-app

Ejemplo de salida para kubectl get deployments:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           3m33s
redis-master       0/1     1            0           23s
web-app            2/2     2            2           42s

Ejemplo de salida para kubectl get services:

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP   8m28s
web-service   ClusterIP   10.106.220.33   <none>        80/TCP    46s

Observa que ahora tienes un Despliegue web-app con 2/2 réplicas READY y un Servicio web-service de tipo ClusterIP.

Hablemos brevemente sobre la diferencia entre la gestión declarativa e imperativa en Kubernetes, especialmente en el contexto de kubectl apply y kubectl create.

  • kubectl apply: Utiliza un enfoque declarativo. Defines el estado deseado en tus archivos de manifiesto, y kubectl apply intenta alcanzar ese estado. Si ejecutas kubectl apply varias veces con el mismo manifiesto, Kubernetes solo realizará cambios si hay diferencias entre el estado deseado en el manifiesto y el estado actual en el clúster. kubectl apply generalmente se recomienda para gestionar recursos de Kubernetes porque es más robusto y más fácil de gestionar los cambios con el tiempo. Realiza un seguimiento de la configuración de tus recursos y permite actualizaciones incrementales.
  • kubectl create: Utiliza un enfoque imperativo. Instructas directamente a Kubernetes a crear un recurso. Si intentas ejecutar kubectl create para un recurso que ya existe, generalmente resultará en un error. kubectl create es menos flexible para gestionar actualizaciones y cambios en comparación con kubectl apply.

En la mayoría de los casos, especialmente para la gestión de despliegues de aplicaciones, kubectl apply es el método preferido y recomendado debido a su naturaleza declarativa y mejor manejo de actualizaciones y gestión de configuración.

Verificar el estado del despliegue

En este paso, aprenderás cómo inspeccionar y verificar el estado de los despliegues (deployments) y otros recursos de Kubernetes utilizando varios comandos de kubectl. Explorarás diferentes formas de recopilar información sobre tus aplicaciones en ejecución y su estado de salud dentro del clúster de Kubernetes.

Primero, asegúrate de estar en el directorio manifests dentro de tu proyecto:

cd ~/project/k8s-manifests/manifests

Comencemos listando todos los despliegues en el namespace actual (que es default a menos que lo hayas cambiado). Utiliza kubectl get deployments:

kubectl get deployments

Este comando proporciona una visión general concisa de tus despliegues. Ejemplo de salida:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           4m44s
redis-master       1/1     1            1           94s
web-app            2/2     2            2           113s

A continuación, se explica lo que significa cada columna:

  • NAME: El nombre del despliegue.
  • READY: Muestra el número de réplicas listas en comparación con el número deseado de réplicas (por ejemplo, 3/3 significa que 3 réplicas deseadas están listas).
  • UP-TO-DATE: Indica cuántas réplicas se han actualizado al último estado deseado.
  • AVAILABLE: Muestra cuántas réplicas están actualmente disponibles para atender tráfico.
  • AGE: Cuánto tiempo ha estado en ejecución el despliegue.

Para obtener información más detallada en un formato más amplio, puedes usar la bandera -o wide con kubectl get deployments:

kubectl get deployments -o wide

Ejemplo de salida:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                      SELECTOR
nginx-deployment   3/3     3            3           4m58s   nginx        nginx:latest                app=nginx
redis-master       1/1     1            1           108s    master       registry.k8s.io/redis:e2e   app=redis,role=master,tier=backend
web-app            2/2     2            2           2m7s    web          nginx:alpine                app=web

La salida con -o wide incluye columnas adicionales como CONTAINERS, IMAGES y SELECTOR, que proporcionan más contexto sobre el despliegue.

Para inspeccionar los pods que forman parte de un despliegue específico, puedes usar etiquetas. Recuerda que en nuestro manifiesto de Despliegue web-app, establecimos la etiqueta app: web para los pods. Puedes usar esta etiqueta para filtrar pods utilizando kubectl get pods -l <label_selector>. Para ver los pods asociados con el despliegue web-app, ejecuta:

kubectl get pods -l app=web

Ejemplo de salida:

NAME                      READY   STATUS    RESTARTS   AGE
web-app-xxx-yyy           1/1     Running   0          10m
web-app-xxx-zzz           1/1     Running   0          10m

Esto lista los pods que coinciden con el selector de etiquetas app=web, que son los pods gestionados por el Despliegue web-app.

Para obtener información detallada sobre un despliegue específico, utiliza kubectl describe deployment <deployment_name>. Describamos el despliegue web-app:

kubectl describe deployment web-app

kubectl describe proporciona una gran cantidad de información sobre el despliegue, incluyendo:

  • Name, Namespace, CreationTimestamp, Labels, Annotations: Metadatos básicos sobre el despliegue.
  • Selector: El selector de etiquetas utilizado para identificar los pods gestionados por este despliegue.
  • Replicas: Recuentos de réplicas deseadas, actualizadas, totales, disponibles y no disponibles.
  • StrategyType, RollingUpdateStrategy: Detalles sobre la estrategia de actualización (por ejemplo, RollingUpdate).
  • Pod Template: La especificación utilizada para crear pods para este despliegue.
  • Conditions: Condiciones que indican el estado del despliegue (por ejemplo, Available, Progressing).
  • Events: Una lista de eventos relacionados con el despliegue, que puede ser útil para la resolución de problemas.

Observa las secciones Conditions y Events en la salida de describe. Estas secciones a menudo proporcionan pistas si hay problemas con tu despliegue. Por ejemplo, si un despliegue no se vuelve Available, los Events pueden mostrar errores relacionados con la extracción de imágenes, fallas en la creación de pods, etc.

Para verificar el estado del Servicio, puedes usar comandos similares. Primero, lista todos 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   10m
web-service   ClusterIP   10.106.220.33   <none>        80/TCP    2m47s

Esto muestra el web-service junto con su TYPE (ClusterIP), CLUSTER-IP y PORT(S) expuestos.

Para obtener más detalles sobre un servicio, utiliza kubectl describe service <service_name>:

kubectl describe service web-service

La salida de describe service incluye:

  • Name, Namespace, Labels, Annotations: Metadatos básicos.
  • Selector: El selector de etiquetas utilizado para identificar los pods de destino.
  • Type: El tipo de servicio (ClusterIP en este caso).
  • IP, IPs: La dirección IP del clúster asignada al servicio.
  • Port, TargetPort: Mapeos de puertos definidos para el servicio.
  • Endpoints: Muestra las direcciones IP y puertos de los pods que actualmente respaldan este servicio. Esto es muy importante. Si no ves ningún endpoint, significa que el servicio no está conectado correctamente a ningún pod, probablemente debido a una coincidencia incorrecta del selector.
  • Session Affinity, Events: Otras configuraciones y eventos del servicio.

Al verificar el estado del despliegue, las cosas clave a buscar son:

  • Estado READY del Despliegue: Asegúrate de que muestre el número deseado de réplicas (por ejemplo, 2/2 para web-app).
  • Estado STATUS de los Pods: Todos los pods deben estar en estado Running.
  • Endpoints del Servicio: Verifica que el servicio tenga endpoints y que correspondan a las direcciones IP de tus pods en ejecución. Si no hay endpoints, soluciona los problemas del selector del servicio y las etiquetas de los pods.
  • Busca advertencias o errores: Examina la salida de kubectl describe deployment <deployment_name> y kubectl describe service <service_name> para detectar cualquier condición inusual o error en las secciones Events.

Al utilizar estos comandos de kubectl, puedes monitorear y verificar de manera efectiva el estado de tus despliegues y servicios en Kubernetes, asegurando que tus aplicaciones se ejecuten como se espera.

Acceder a la aplicación utilizando kubectl proxy

En este paso, aprenderás cómo acceder a tus aplicaciones de Kubernetes utilizando kubectl proxy. kubectl proxy crea una conexión proxy segura al servidor de la API de Kubernetes, lo que te permite acceder a los servicios y pods del clúster desde tu máquina local. Esto es muy útil para el desarrollo y la depuración, especialmente cuando deseas acceder a servicios que no están expuestos externamente.

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

cd ~/project/k8s-manifests/manifests

Inicia kubectl proxy en segundo plano. Este comando ejecutará el proxy en un proceso separado, lo que te permitirá seguir utilizando tu terminal.

kubectl proxy --port=8080 &

El & al final del comando lo ejecuta en segundo plano. Deberías ver una salida como esta:

Starting to serve on 127.0.0.1:8080

Si tu terminal parece congelarse después de ejecutar este comando, es posible que debas presionar Ctrl+C una vez para volver al indicador de comando. El proxy debería seguir ejecutándose en segundo plano.

Ahora, encontremos los nombres de los pods que forman parte de tu despliegue web-app. Puedes usar kubectl get pods -l app=web de nuevo:

## Get pod names for the 'web-app'
kubectl get pods -l app=web

Ejemplo de salida:

NAME                      READY   STATUS    RESTARTS   AGE
web-app-xxx-yyy           1/1     Running   0          20m
web-app-xxx-zzz           1/1     Running   0          20m

Toma nota de uno de los nombres de los pods, por ejemplo, web-app-xxx-yyy. Utilizarás este nombre de pod para construir la ruta de la API para acceder al servidor web NGINX que se ejecuta en ese pod.

Los recursos de la API de Kubernetes son accesibles a través de rutas específicas. Para acceder a un pod a través de kubectl proxy, debes construir una URL como esta:

http://localhost:8080/api/v1/namespaces/<namespace>/pods/<pod_name>/proxy/

Analicemos esta URL:

  • http://localhost:8080: La dirección donde se está ejecutando kubectl proxy. Por defecto, escucha en el puerto 8080 de tu máquina local.
  • /api/v1: Especifica la versión de la API de Kubernetes (v1).
  • /namespaces/<namespace>: El namespace donde se está ejecutando tu pod. En nuestro caso, es default.
  • /pods/<pod_name>: El nombre del pod al que deseas acceder. Reemplaza <pod_name> con el nombre real de tu pod (por ejemplo, web-app-xxx-yyy).
  • /proxy/: Indica que deseas proxy una conexión al pod.

Para facilitar el uso del nombre del pod en la URL, almacenemos el nombre del primer pod en una variable de shell. Ejecuta este comando, que utiliza kubectl get pods y jsonpath para extraer el nombre del primer pod con la etiqueta app=web:

## Get the name of the first pod with label 'app=web'
POD_NAME=$(kubectl get pods -l app=web -o jsonpath='{.items[0].metadata.name}')
echo $POD_NAME ## Optional: print the pod name to verify

Ahora, puedes usar la variable $POD_NAME en tu comando curl para acceder a la página predeterminada de NGINX servida por tu pod. Utiliza curl para enviar una solicitud HTTP a la URL del proxy. Reemplaza ${POD_NAME} en la URL con la variable que acabamos de establecer:

curl http://localhost:8080/api/v1/namespaces/default/pods/${POD_NAME}/proxy/

Si todo funciona correctamente, este comando debería devolver el contenido HTML de la página de bienvenida predeterminada de NGINX. El ejemplo de salida será contenido HTML que comience con:

<!doctype html>
<html>
  <head>
    <title>Welcome to nginx!</title>
    ...
  </head>
  <body>
    <h1>Welcome to nginx!</h1>
    ...
  </body>
</html>

Esta salida confirma que has accedido con éxito al servidor web NGINX que se ejecuta dentro de tu pod a través de kubectl proxy.

Exploremos algunas otras cosas que puedes hacer con kubectl proxy.

Listar todos los pods en el namespace predeterminado a través del proxy:

Puedes acceder directamente a la API de Kubernetes a través del proxy. Por ejemplo, para listar todos los pods en el namespace default, puedes usar esta URL:

curl http://localhost:8080/api/v1/namespaces/default/pods/

Esto devolverá una respuesta JSON que contiene información sobre todos los pods en el namespace default.

Obtener información detallada sobre un pod específico a través del proxy:

Para obtener información detallada sobre un pod específico (similar a kubectl describe pod), puedes acceder directamente al punto final de la API del pod:

curl http://localhost:8080/api/v1/namespaces/default/pods/${POD_NAME}

Esto devolverá una respuesta JSON con información detallada sobre el pod especificado.

Detener kubectl proxy:

Cuando hayas terminado de usar kubectl proxy, debes detenerlo. Dado que lo iniciamos en segundo plano, debes encontrar su identificador de proceso (PID) y terminarlo. Puedes usar el comando jobs para listar los procesos en segundo plano:

jobs

Esto mostrará los procesos en segundo plano que se están ejecutando desde tu sesión de terminal actual. Deberías ver kubectl proxy en la lista. Para detenerlo, puedes usar el comando kill seguido del identificador de proceso. Por ejemplo, si jobs muestra [1] Running kubectl proxy --port=8080 &, entonces el identificador de proceso es 1. Usarías:

kill %1

Reemplaza %1 con el ID de trabajo mostrado por el comando jobs. Alternativamente, puedes encontrar el identificador de proceso utilizando ps aux | grep kubectl proxy y luego usar kill <PID>.

Puntos clave a recordar sobre kubectl proxy:

  • kubectl proxy crea una conexión segura y autenticada al servidor de la API de Kubernetes.
  • Te permite acceder a los recursos del clúster (pods, servicios, etc.) desde tu máquina local como si estuvieras dentro de la red del clúster.
  • Es muy útil para la depuración, el desarrollo y la exploración de la API de Kubernetes.
  • Por razones de seguridad, kubectl proxy solo es accesible en localhost (127.0.0.1). No está diseñado para exponer servicios públicamente.

Resumen

En este laboratorio, has aprendido con éxito cómo desplegar aplicaciones en un clúster de Kubernetes utilizando Minikube. Comenzaste configurando un clúster de Kubernetes local con Minikube y verificaste su estado. Luego, exploraste comandos esenciales de kubectl para interactuar con tu clúster y gestionar recursos. Aprendiste a listar namespaces, obtener detalles sobre nodos y pods, y comprender la estructura básica de los comandos de kubectl. Estos pasos te proporcionaron una base sólida para trabajar con Kubernetes.

Luego, creaste manifiestos YAML simples para un Pod y un Despliegue, los aplicaste a tu clúster utilizando kubectl apply y verificaste el estado del despliegue utilizando varios comandos de kubectl como get y describe. Esta experiencia práctica te permitió comprender el enfoque declarativo para desplegar aplicaciones en Kubernetes y cómo interactuar de manera efectiva con el clúster.

Finalmente, aprendiste cómo acceder a tu aplicación desplegada utilizando kubectl proxy, que proporciona una forma segura de interactuar con la API de tu clúster y acceder a servicios y pods desde tu máquina local. Esta es una técnica valiosa para el desarrollo, la depuración y la exploración de tu entorno de Kubernetes.

Al completar este laboratorio, has adquirido experiencia práctica con conceptos y herramientas esenciales de Kubernetes, lo que te coloca en el camino para desplegar y gestionar aplicaciones más complejas en Kubernetes.