Desplegar Aplicaciones en Kubernetes

KubernetesBeginner
Practicar Ahora

Introducción

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

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

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 82%. Ha recibido una tasa de reseñas positivas del 97% por parte de los estudiantes.

Iniciar el Clúster de Kubernetes

En este paso, iniciaremos un clúster de Kubernetes utilizando Minikube. Minikube es una herramienta excelente para el desarrollo y el aprendizaje de Kubernetes, ya que permite ejecutar un clúster de Kubernetes de un solo nodo en un entorno virtualizado. Luego, verificaremos que el clúster se está ejecutando correctamente y está listo para su uso.

Primero, abra su terminal. Aquí es donde escribirá comandos para interactuar con su computadora. Para iniciar el clúster de Minikube, escriba el siguiente comando y presione Enter:

minikube start

Este comando iniciará el proceso de creación y arranque de su clúster de Kubernetes. Minikube descargará los componentes necesarios y configurará su clúster. Verá la salida en su terminal a medida que Minikube se inicia. Aquí hay un ejemplo de cómo podría ser 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 se está ejecutando y que el clúster de Kubernetes está listo. Ejecute los siguientes comandos uno tras otro, presionando Enter después de cada comando:

minikube status
kubectl get nodes

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

Aquí hay un ejemplo de la salida que podría 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 se están ejecutando 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 (control plane) para el clúster de Kubernetes, administrando y orquestando el clúster.

Estos comandos confirman que:

  1. Minikube se está ejecutando en el entorno de máquina virtual.
  2. Se ha creado y configurado un clúster de Kubernetes por Minikube.
  3. El clúster de Kubernetes está en estado Ready y listo para usarse.
  4. Tiene un clúster de Kubernetes de un solo nodo donde el nodo minikube actúa como el plano de control.

Aprender Comandos Básicos de kubectl y su Sintaxis

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

Comencemos explorando los namespaces dentro de su clúster de Kubernetes. Los namespaces son una forma de organizar sus 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, ejecute el siguiente comando:

kubectl get namespaces

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

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

Típicamente verá al menos estos namespaces predeterminados:

  • default: El namespace predeterminado para 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 rastrear el estado de los nodos.
  • kube-public: Destinado a recursos que deben ser públicamente accesibles (aunque rara vez se utiliza para información sensible).
  • kube-system: Contiene recursos a 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, use la bandera -n o --namespace seguida del nombre del namespace. Ejecute 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 en el pod están listos del 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 para los comandos de kubectl es:

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

Desglosemos esto:

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

Veamos algunos ejemplos:

## Obtener todos los recursos en el namespace predeterminado
kubectl get all

## Describir un tipo de recurso específico (el nodo 'minikube')
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. La salida de ejemplo podría verse 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, incluido su estado, capacidad, direcciones y más. Esto es útil para comprender el estado y la configuración de sus nodos.

Estos comandos le ayudan a:

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

Crear un Manifiesto YAML Sencillo

Antes de crear su primer manifiesto YAML, es importante comprender los objetos clave de Kubernetes con los que trabajará. Estos objetos son los bloques de construcción para administrar y orquestar sus aplicaciones dentro de Kubernetes.

Comprendiendo 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. Piense en un pod como una instancia única de su aplicación.
  • Deployment: Los Deployments se utilizan para administrar pods. Aseguran que un número deseado de réplicas de pods se ejecuten en todo momento. Si un pod falla, un Deployment lo reemplazará automáticamente. Los Deployments también manejan las actualizaciones de su aplicación de manera controlada, como las actualizaciones graduales (rolling updates).
  • Service: Los Services proporcionan una forma estable de acceder a su aplicación que se ejecuta en pods. Dado que los pods pueden crearse y destruirse, sus direcciones IP pueden cambiar. Un Service proporciona una dirección IP y un nombre DNS fijos que siempre apuntan al conjunto de pods que administra. Esto permite que otras partes de su aplicación, o clientes externos, accedan de manera confiable a su aplicación sin necesidad de rastrear las IPs de pods individuales.

Aquí hay 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á su estado y configuración deseados utilizando manifiestos YAML.

Descripción General de los Manifiestos YAML

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

  1. Gestión Declarativa: Usted describe el estado deseado de sus recursos en el archivo YAML (por ejemplo, "Quiero que se ejecuten 3 réplicas de mi aplicación"). Kubernetes luego trabaja para que el estado real coincida con su estado deseado. Esto se llama gestión declarativa.
  2. Control de Versiones: Los archivos YAML están basados en texto y se pueden almacenar fácilmente en sistemas de control de versiones como Git. Esto le permite rastrear los cambios en sus configuraciones de Kubernetes a lo largo del tiempo, revertir a configuraciones anteriores y colaborar con otros.
  3. Reutilización y Portabilidad: Puede reutilizar manifiestos YAML en diferentes entornos (desarrollo, pruebas, producción) con cambios mínimos. Esto hace que sus despliegues sean más consistentes y reproducibles.

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

Creación de un Manifiesto YAML

Primero, navegue hasta el directorio de su proyecto. Se asume que tiene un directorio project en su directorio de inicio (~). Si no lo tiene, créelo ahora usando mkdir project. Luego, cambie su directorio actual a project usando cd project:

cd ~/project

A continuación, cree un nuevo directorio para almacenar sus manifiestos de Kubernetes. Llamémoslo k8s-manifests. Use el comando mkdir para crear el directorio y luego cd para moverse dentro de él:

mkdir -p k8s-manifests
cd k8s-manifests

Ahora, creará su primer archivo de manifiesto YAML. Comencemos con un manifiesto simple para un pod de NGINX. NGINX es un servidor web popular. Crearemos un pod que ejecute un solo contenedor NGINX. Use 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 su terminal. Una vez que nano se abra, pegue 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

Entendamos 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, services y namespaces.
  • kind: Pod: Indica que está definiendo un recurso de tipo Pod.
  • metadata:: Contiene datos sobre el Pod, como su nombre y etiquetas (labels).
    • name: nginx-pod: Establece el nombre del Pod a nginx-pod. Así es como se referirá 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 a 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, guarde el archivo y salga de nano. Para hacer esto, presione Ctrl+X (salir), luego escriba Y (sí para guardar) y finalmente presione Enter para confirmar el nombre del archivo y guardar.

Ahora que ha creado su archivo nginx-pod.yaml, necesita aplicarlo a su clúster de Kubernetes para crear el pod. Use 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 su clúster de Kubernetes, y Kubernetes creará el pod según lo definido. Debería ver una salida similar a esta:

pod/nginx-pod created

Para verificar que el pod se ha creado y se está ejecutando, use el comando kubectl get pods. Esto listará todos los pods en el namespace predeterminado. También puede usar kubectl describe pod nginx-pod para obtener información detallada sobre el nginx-pod. Ejecute 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 su pod NGINX se ha creado y está ejecutándose correctamente.

Ahora, creemos un manifiesto para un recurso más complejo: un Deployment. Un Deployment administrará un conjunto de pods, asegurando que se ejecute el número deseado de réplicas. Cree un nuevo archivo llamado nginx-deployment.yaml usando nano:

nano nginx-deployment.yaml

Pegue 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

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

  • apiVersion: apps/v1: Para Deployments, utiliza la versión de API apps/v1, que forma parte del grupo de API apps y maneja recursos de gestión de aplicaciones de nivel superior.
  • kind: Deployment: Indica que está definiendo un recurso de tipo Deployment.
  • spec:: La sección spec para un Deployment es más compleja porque define cómo el Deployment administrará los pods.
    • replicas: 3: Esto es nuevo. Especifica que desea que se ejecuten 3 réplicas (copias) de su pod. El Deployment se asegurará de que siempre haya 3 pods que coincidan con los criterios definidos en la template.
    • selector:: Un selector es utilizado por el Deployment para identificar qué pods debe administrar.
      • matchLabels:: Define las etiquetas que los pods deben tener para ser seleccionados por este Deployment. Aquí, selecciona pods con la etiqueta app: nginx.
    • template:: La template define la especificación del pod que el Deployment 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 las selector.matchLabels para que el Deployment pueda administrar estos pods.

Guarde y salga de nano (Ctrl+X, Y, Enter).

Ahora, aplique este manifiesto de Deployment a su clúster:

kubectl apply -f nginx-deployment.yaml

Debería ver una salida como:

deployment.apps/nginx-deployment created

Verifique el Deployment y los pods que creó. Use kubectl get deployments para verificar el estado del Deployment 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 Deployment ha creado y está administrando exitosamente 3 pods, 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 administrados por su nginx-deployment.

Aplicar el Manifiesto YAML

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

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

cd ~/project/k8s-manifests

Creemos un nuevo subdirectorio para organizar aún más nuestros manifiestos. Cree un directorio llamado manifests y navegue dentro de él:

mkdir -p manifests
cd manifests

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

nano web-app.yaml

Agregue 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 que es nuevo:

  • Múltiples Recursos en un Solo Archivo: El archivo web-app.yaml ahora contiene dos definiciones de recursos de Kubernetes separadas: un Deployment y un Service. El separador --- se utiliza para distinguirlos.
  • kind: Service: Esto define un recurso de tipo Service.
    • spec.selector.app: web: Este Service se dirigirá a los pods que tengan la etiqueta app: web. Esto coincide con las etiquetas que establecimos para los pods creados por el Deployment 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 los puertos a los pods de destino.
      • port: 80: El puerto en el propio Service al que accederá.
      • 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. Use kubectl apply -f seguido del nombre del archivo:

kubectl apply -f web-app.yaml

Este comando creará tanto el Deployment como el Service definidos en web-app.yaml. Debería ver una salida como:

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

Método 2: Aplicar desde un directorio

Puede aplicar todos los manifiestos de un directorio a la vez. Si tiene varios archivos de manifiesto en el directorio manifests, puede 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 aplicará todos ellos. Esto es útil cuando ha organizado sus manifiestos en varios 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 o configuraciones de ejemplo alojadas en línea. Por ejemplo, puede desplegar el despliegue maestro de Redis del repositorio de ejemplos de Kubernetes:

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

Esto descargará el manifiesto de la URL y lo aplicará a su clúster. Nota: Tenga cuidado al aplicar manifiestos de URLs no confiables, ya que pueden modificar su clúster.

Exploremos algunas opciones adicionales para kubectl apply.

Dry Run (Simulación)

Puede 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 verificar si su 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 en realidad no aplicará los cambios a su clúster.

Salida Detallada (Verbose Output)

Para obtener una salida más detallada de kubectl apply, puede usar la bandera -v seguida de un nivel de verbosidad (por ejemplo, -v=7). Los niveles de verbosidad más altos proporcionan información más detallada, 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.

Verifique los recursos creados al aplicar web-app.yaml. Use kubectl get deployments y kubectl get services para listar los Deployments y Services en su clúster:

## Listar despliegues
kubectl get deployments

## Listar servicios
kubectl get services

## Describir el despliegue para ver más detalles
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

Observe que ahora tiene un Deployment web-app con 2/2 réplicas READY y un web-service de tipo ClusterIP.

Discutamos brevemente 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. Usted define el estado deseado en sus archivos de manifiesto, y kubectl apply intenta lograr ese estado. Si ejecuta 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 es generalmente recomendado para administrar recursos de Kubernetes porque es más robusto y fácil de administrar cambios a lo largo del tiempo. Rastrea la configuración de sus recursos y permite actualizaciones incrementales.
  • kubectl create: Utiliza un enfoque imperativo. Usted instruye directamente a Kubernetes para que cree un recurso. Si intenta ejecutar kubectl create para un recurso que ya existe, generalmente resultará en un error. kubectl create es menos flexible para administrar actualizaciones y cambios en comparación con kubectl apply.

En la mayoría de los casos, especialmente para administrar 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 Deployment

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

Primero, asegúrese de estar en el directorio manifests dentro de su proyecto:

cd ~/project/k8s-manifests/manifests

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

kubectl get deployments

Este comando proporciona una visión general concisa de sus 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

Aquí se explica qué significa cada columna:

  • NAME: El nombre del despliegue.
  • READY: Muestra el número de réplicas listas frente al 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 servir tráfico.
  • AGE: Cuánto tiempo ha estado ejecutándose el despliegue.

Para obtener información más detallada en un formato más amplio, puede 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 de -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, puede usar etiquetas. Recuerde que en nuestro manifiesto web-app Deployment, establecimos la etiqueta app: web para los pods. Puede usar esta etiqueta para filtrar pods usando kubectl get pods -l <label_selector>. Para ver los pods asociados con el despliegue web-app, ejecute:

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 administrados por el Deployment web-app.

Para obtener información detallada sobre un despliegue específico, use 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 administrados por este despliegue.
  • Replicas: Recuentos de réplicas deseados, actualizados, 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 pueden ser útiles para la resolución de problemas.

Observe las secciones Conditions y Events en la salida de describe. Estas secciones a menudo brindan pistas si hay problemas con su despliegue. Por ejemplo, si un despliegue no se vuelve Available, los Events podrían mostrar errores relacionados con la extracción de imágenes, fallos en la creación de pods, etc.

Para verificar el estado del Service, puede usar comandos similares. Primero, liste todos los services:

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 service, use 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 los puertos de los pods que actualmente respaldan este servicio. Esto es muy importante. Si no ve ningún endpoint, significa que el servicio no está conectado correctamente a ningún pod, probablemente debido a una falta de coincidencia en el 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 Deployment: Asegúrese de que muestre el número deseado de réplicas (por ejemplo, 2/2 para web-app).
  • STATUS del Pod: Todos los pods deben estar en estado Running.
  • Endpoints del Service: Verifique que el service tenga endpoints y que correspondan a las direcciones IP de sus pods en ejecución. Si no hay endpoints, solucione el selector del service y las etiquetas de los pods.
  • Busque advertencias o errores: Examine la salida de kubectl describe deployment <deployment_name> y kubectl describe service <service_name> en busca de condiciones o errores inusuales en las secciones Events.

Al utilizar estos comandos kubectl, puede monitorear y verificar eficazmente el estado de sus despliegues y services en Kubernetes, asegurando que sus aplicaciones se ejecuten según lo esperado.

Acceder a la Aplicación usando kubectl proxy

En este paso, aprenderá a acceder a sus aplicaciones de Kubernetes utilizando kubectl proxy. kubectl proxy crea una conexión proxy segura al servidor de la API de Kubernetes, lo que le permite acceder a los servicios y pods del clúster desde su entorno actual. Esto es muy útil para el desarrollo y la depuración, especialmente cuando desea acceder a servicios que no están expuestos externamente.

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

cd ~/project/k8s-manifests/manifests

Inicie kubectl proxy en segundo plano. Este comando ejecutará el proxy en un proceso separado, lo que le permitirá continuar usando su terminal.

kubectl proxy --port=8080 &

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

Starting to serve on 127.0.0.1:8080

Si su terminal parece colgarse después de ejecutar este comando, es posible que deba presionar Ctrl+C una vez para volver a su prompt. El proxy aún debería estar ejecutándose en segundo plano.

Ahora, encontremos los nombres de los pods que forman parte de su despliegue web-app. Puede usar kubectl get pods -l app=web nuevamente:

## 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

Tome nota de uno de los nombres de los pods, por ejemplo, web-app-xxx-yyy. Usará 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, necesita 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 en su entorno actual.
  • /api/v1: Especifica la versión de la API de Kubernetes (v1).
  • /namespaces/<namespace>: El namespace donde se está ejecutando su pod. En nuestro caso, es default.
  • /pods/<pod_name>: El nombre del pod al que desea acceder. Reemplace <pod_name> con el nombre real de su pod (por ejemplo, web-app-xxx-yyy).
  • /proxy/: Indica que desea reenviar una conexión al pod.

Para que sea más fácil usar el nombre del pod en la URL, almacenemos el nombre del primer pod en una variable de shell. Ejecute 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, puede usar la variable $POD_NAME en su comando curl para acceder a la página predeterminada de NGINX servida por su pod. Use curl para enviar una solicitud HTTP a la URL del proxy. Reemplace ${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 comienza con:

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

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

Exploremos algunas cosas más que puede hacer con kubectl proxy.

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

Puede acceder a la API de Kubernetes directamente a través del proxy. Por ejemplo, para listar todos los pods en el namespace default, puede 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), puede acceder directamente al endpoint 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 haya terminado de usar kubectl proxy, debe detenerlo. Dado que lo iniciamos en segundo plano, necesita encontrar su ID de proceso (PID) y terminarlo. Puede usar el comando jobs para listar los procesos en segundo plano:

jobs

Esto le mostrará los procesos en segundo plano que se ejecutan desde su sesión de terminal actual. Debería ver kubectl proxy listado. Para detenerlo, puede usar el comando kill seguido del ID del proceso. Por ejemplo, si jobs muestra [1] Running kubectl proxy --port=8080 &, entonces el ID del proceso es 1. Usaría:

kill %1

Reemplace %1 con el ID del trabajo que muestra el comando jobs. Alternativamente, puede encontrar el ID del proceso usando 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.
  • Le permite acceder a los recursos del clúster (pods, services, etc.) desde su entorno actual como si estuviera dentro de la red del clúster.
  • Es muy útil para depuración, desarrollo y 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 usarse para exponer servicios públicamente.

Resumen

En este laboratorio, ha aprendido con éxito a desplegar aplicaciones en un clúster de Kubernetes utilizando Minikube. Comenzó configurando un clúster de Kubernetes con Minikube y verificando su estado. Luego exploró comandos esenciales de kubectl para interactuar con su clúster y administrar recursos. Aprendió a listar namespaces, obtener detalles sobre nodos y pods, y comprender la estructura básica de comandos de kubectl. Estos pasos le proporcionaron una base sólida para trabajar con Kubernetes.

Continuó creando manifiestos YAML sencillos para un Pod y un Deployment, los aplicó a su clúster usando kubectl apply y verificó el estado del despliegue utilizando varios comandos kubectl como get y describe. Esta experiencia práctica le permitió comprender el enfoque declarativo para desplegar aplicaciones en Kubernetes y cómo interactuar eficazmente con el clúster.

Finalmente, aprendió a acceder a su aplicación desplegada utilizando kubectl proxy, que proporciona una forma segura de interactuar con la API de su clúster y acceder a servicios y pods desde su entorno actual. Esta es una técnica valiosa para el desarrollo, la depuración y la exploración de su entorno de Kubernetes.

Al completar este laboratorio, ha adquirido experiencia práctica con conceptos y herramientas esenciales de Kubernetes, encaminándolo hacia el despliegue y la gestión de aplicaciones más complejas en Kubernetes.