Implementa una aplicación web en contenedor

En este instructivo, se muestra cómo empaquetar una aplicación web en una imagen de contenedor de Docker y ejecutar esa imagen en un clúster de Google Kubernetes Engine (GKE). Luego, deberás implementar la aplicación web como un conjunto de réplicas con balanceo de cargas que puede escalar según las necesidades de los usuarios.

Objetivos

  • Empaquetar una aplicación web de muestra en una imagen de Docker
  • Subir la imagen de Docker a Container Registry
  • Crear un clúster de GKE
  • Implementar la app de muestra en el clúster
  • Administrar el ajuste de escala automático para la implementación
  • Exponer la app de muestra a la Internet
  • Implementar una versión nueva de la app de muestra

Antes de comenzar

Sigue los pasos que se indican a continuación para habilitar la API de Kubernetes Engine:
  1. Consulta la página de Kubernetes Engine en Google Cloud Console.
  2. Crea o selecciona un proyecto.
  3. Espera a que la API y los servicios relacionados se habiliten. Esto puede tomar varios minutos.
  4. Comprueba que la facturación esté habilitada en tu proyecto.

    Descubre cómo puedes habilitar la facturación

Opción A: Usa Cloud Shell

Puedes seguir este instructivo mediante Cloud Shell, que viene preinstalado con las herramientas de línea de comandos de gcloud, docker y kubectl que se usan en este instructivo. Si usas Cloud Shell, no necesitas instalar estas herramientas de línea de comandos en tu estación de trabajo.

Para usar Cloud Shell, sigue estos pasos:

  1. Ve a Google Cloud Console.
  2. Haz clic en el botón Activar Cloud Shell Botón de activar Shell que se encuentra en la parte superior de la ventana de Cloud Console.

    Se abrirá una sesión de Cloud Shell en un marco nuevo en la parte inferior de Cloud Console, que mostrará una ventana de la línea de comandos.

    Sesión de Cloud Shell

Opción B: Usa las herramientas de línea de comandos de manera local

Si prefieres seguir este instructivo en tu estación de trabajo, sigue estos pasos para instalar las herramientas necesarias.

  1. Instala el SDK de Cloud, que incluye la herramienta de línea de comandos de gcloud.

  2. Con la herramienta de línea de comandos de gcloud, instala la herramienta de línea de comandos deKubernetes. kubectl se usa para comunicarse con Kubernetes, que es el sistema de organización de clústeres de los clústeres de GKE:

    gcloud components install kubectl
    
  3. Instala la edición de la comunidad de Docker (CE) en tu estación de trabajo. Usarás esto a fin de compilar una imagen de contenedor para la aplicación.

  4. Instala la herramienta de control de fuente Git para obtener la aplicación de muestra de GitHub.

Compila la imagen de contenedor

En este instructivo, implementarás una aplicación web de muestra llamada hello-app, un servidor web escrito en Go que responde a todas las solicitudes con el mensaje Hello, World! en el puerto 8080.

GKE acepta imágenes de Docker como el formato de implementación de la aplicación. Antes de implementar hello-app en GKE, debes empaquetar el código fuente de hello-app como una imagen de Docker.

Para compilar una imagen de Docker, necesitas un código fuente y un Dockerfile. Un Dockerfile contiene instrucciones para compilar la imagen.

  1. Descarga el código fuente de hello-app y el Dockerfile mediante la ejecución de los siguientes comandos:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    cd kubernetes-engine-samples/hello-app
    
  2. Configura la variable de entorno PROJECT_ID como el ID de tu proyecto de Google Cloud (PROJECT_ID). La variable PROJECT_ID asocia la imagen de contenedor con el Container Registry de tu proyecto.

    export PROJECT_ID=PROJECT_ID
    
  3. Confirma que la variable de entorno PROJECT_ID tenga el valor correcto:

    echo $PROJECT_ID
    
  4. Compila y etiqueta la imagen de Docker para hello-app:

    docker build -t gcr.io/${PROJECT_ID}/hello-app:v1 .
    

    Con este comando, se le indica a Docker que compile la imagen mediante el Dockerfile en el directorio actual y que la etiquete con un nombre, como gcr.io/my-project/hello-app:v1. El prefijo gcr.io se refiere a Container Registry, donde se aloja la imagen. Cuando ejecutas este comando, se compila la imagen y se guarda en tu entorno local. La imagen se enviará a Container Registry en la siguiente sección.

  5. Ejecuta el comando docker images a fin de verificar que la compilación se realizó de forma correcta:

    docker images
    

    Resultado:

    REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
    gcr.io/my-project/hello-app    v1                  25cfadb1bf28        10 seconds ago      54 MB
    

Ejecuta tu contenedor de manera local (opcional)

  1. Prueba tu imagen de contenedor mediante el motor de Docker local:

    docker run --rm -p 8080:8080 gcr.io/${PROJECT_ID}/hello-app:v1
    
  2. Si usas Cloud Shell, haz clic en el botón Vista previa en la Web Botón Vista previa en la Web y selecciona el número de puerto 8080. GKE abre la URL de vista previa en su servicio de proxy en una nueva ventana del navegador.

  3. De lo contrario, abre una ventana de la terminal nueva (o una pestaña de Cloud Shell) y ejecuta el siguiente comando para verificar que el contenedor funcione y responda a las solicitudes con “Hello, World!”:

    curl http://localhost:8080
    

    Luego de obtener una respuesta exitosa, puedes cerrar el contenedor si presionas Ctrl+C en la pestaña en la que se ejecuta el comando docker run.

Envía la imagen de Docker a Container Registry

Debes subir la imagen de contenedor a un registro para que tu clúster de GKE pueda descargarla y ejecutarla. En Google Cloud, Container Registry está disponible de forma predeterminada.

  1. Habilita la API de Container Registry para el proyecto de Google Cloud en el que trabajas:

    gcloud services enable containerregistry.googleapis.com
    
  2. Configura la herramienta de línea de comandos de Docker para que se autentique en Container Registry:

    gcloud auth configure-docker
    
  3. Envía la imagen de Docker que acabas de compilar a Container Registry:

    docker push gcr.io/${PROJECT_ID}/hello-app:v1
    

Crea un clúster de GKE

Ahora que la imagen de Docker está almacenada en Container Registry, crea un clúster de GKE para ejecutar hello-app. Un clúster de GKE consiste en un grupo de instancias de VM de Compute Engine que ejecutan Kubernetes, el sistema de organización de clústeres de código abierto que se usa en GKE.

Cloud Shell

  1. Establece la opción de tu ID del proyecto para la herramienta de gcloud:

    gcloud config set project $PROJECT_ID
    

    Resultado:

    Updated property [core/project].
    
  2. Configura tu zona o región. Según el modo de operación que elijas usar en GKE, especifica una zona o región predeterminada. Si usas el modo estándar, tu clúster es zonal (para este instructivo), por lo que debes establecer tu zona de procesamiento predeterminada. Si usas el modo Autopilot, tu clúster es regional, así que configura la región de procesamiento predeterminada. Selecciona la zona o región más cercana a ti.

    • Clúster estándar, como us-west1-a:

      gcloud config set compute/zone COMPUTE_ZONE
      
    • Clúster de Autopilot, como us-west1:

      gcloud config set compute/region COMPUTE_REGION
      
  3. Crea un clúster llamado hello-cluster:

    • Clúster estándar:

      gcloud container clusters create hello-cluster
      
    • Clúster de Autopilot:

      gcloud container clusters create-auto hello-cluster
      

    La creación de tu clúster de GKE y la verificación de su estado toma unos minutos.

  4. Una vez que se complete el comando, ejecuta el siguiente comando para ver los tres nodos del clúster:

    kubectl get nodes
    

    Resultado:

    NAME                                           STATUS   ROLES    AGE   VERSION
    gke-hello-cluster-default-pool-229c0700-cbtd   Ready    <none>   92s   v1.18.12-gke.1210
    gke-hello-cluster-default-pool-229c0700-fc5j   Ready    <none>   91s   v1.18.12-gke.1210
    gke-hello-cluster-default-pool-229c0700-n9l7   Ready    <none>   92s   v1.18.12-gke.1210
    

Console

  1. Ve a la página de Google Kubernetes Engine en Cloud Console:

    Ir a Google Kubernetes Engine

  2. Haz clic en Crear.

  3. Selecciona el modo Estándar o Autopilot y haz clic en Configurar.

  4. En el campo Nombre, ingresa el nombre hello-cluster.

  5. Selecciona una zona o región:

    • Clúster estándar: En Tipo de ubicación, selecciona Zonal y, luego, una Zona de Compute Engine de la lista desplegable Zona, como us-west1-a.

    • Clúster de Autopilot: Selecciona una región de Compute Engine de la lista desplegable Región, como us-west1.

  6. Haga clic en Crear. Esto crea un clúster de GKE.

  7. Espera a que se cree el clúster. Cuando el clúster esté listo, aparecerá una marca de verificación verde junto al nombre del clúster.

Cómo implementar la aplicación de muestra en GKE

Ya estás listo para implementar la imagen de Docker que compilaste en el clúster de GKE.

Kubernetes representa las aplicaciones como Pods, que son unidades escalables que contienen uno o más contenedores. Un Pod es la unidad más pequeña que se puede implementar en Kubernetes. Por lo general, implementas los Pods como un conjunto de réplicas que se pueden escalar y distribuir juntas en el clúster. Una forma de implementar un conjunto de réplicas es mediante una implementación de Kubernetes.

En esta sección, crearás una implementación de Kubernetes para ejecutar hello-app en tu clúster. Esta implementación tiene réplicas (pods). Un pod de implementación contiene solo un contenedor: la imagen de Docker hello-app. También crearás un recurso HorizontalPodAutoscaler que escale la cantidad de pods de 3 a un número entre 1 y 5 según la carga de la CPU.

Cloud Shell

  1. Asegúrate de estar conectado a tu clúster de GKE.

    gcloud container clusters get-credentials hello-cluster --zone COMPUTE_ZONE
    
  2. Crea una implementación de Kubernetes para la imagen de Docker de hello-app.

    kubectl create deployment hello-app --image=gcr.io/${PROJECT_ID}/hello-app:v1
    
  3. Establece en 3 el número del modelo de referencia de las réplicas de la implementación.

    kubectl scale deployment hello-app --replicas=3
    
  4. Crea un recurso HorizontalPodAutoscaler para la implementación.

    kubectl autoscale deployment hello-app --cpu-percent=80 --min=1 --max=5
    
  5. Para ver los Pods creados, ejecuta el siguiente comando:

    kubectl get pods
    

    Resultado:

    NAME                         READY   STATUS    RESTARTS   AGE
    hello-app-784d7569bc-hgmpx   1/1     Running   0          10s
    hello-app-784d7569bc-jfkz5   1/1     Running   0          10s
    hello-app-784d7569bc-mnrrl   1/1     Running   0          15s
    

Console

  1. Visita el menú Cargas de trabajo de GKE en Cloud Console.

    Visitar el menú Cargas de trabajo

  2. Haz clic en Implementar.

  3. En la sección Contenedor, selecciona Imagen de contenedor existente.

  4. En el campo Ruta de acceso a la imagen, haz clic en Seleccionar.

  5. En el panel Seleccionar imagen del contenedor, selecciona la imagen hello-app que enviaste a Container Registry y haz clic en Seleccionar.

  6. En la sección Contenedor, haz clic en Listo y, luego, en Continuar.

  7. En la sección Configuración, en Etiquetas, ingresa app en Clave y hello-app en Valor.

  8. En YAML de configuración, haz clic en Ver YAML. De esta forma, se abrirá un archivo de configuración YAML que representa los dos recursos de la API de Kubernetes que se están por implementar en el clúster: una implementación y un HorizontalPodAutoscaler para la implementación.

  9. Haz clic en Cerrar y, luego, en Implementar.

  10. Cuando los pods de implementación estén listos, se abrirá la página Detalles de la implementación.

  11. En Pods administrados, ten en cuenta los tres pods en ejecución para la implementación hello-app.

Expón la app de muestra a la Internet

Si bien los Pods tienen direcciones IP asignadas de forma individual, solo se puede acceder a estas desde el interior del clúster. Además, los pods de GKE están diseñados para ser efímeros y para iniciarse o detenerse según las necesidades de escalamiento. Cuando un Pod falla debido a un error, GKE volverá a implementarlo de forma automática y le asignará una dirección IP nueva cada vez que esto suceda.

Esto significa que, en cualquier implementación, el conjunto de direcciones IP correspondiente al conjunto activo de Pods es dinámico. Necesitamos una forma de: 1) agrupar los Pods en un nombre de host estático y 2) exponer un grupo de Pods fuera del clúster a la Internet.

Los Servicios de Kubernetes resuelven estos dos problemas. Los servicios agrupan los Pods en una dirección IP estática, a la que se puede acceder desde cualquier Pod dentro del clúster. GKE también asigna un nombre de host de DNS a esa IP estática. Por ejemplo, hello-app.default.svc.cluster.local.

El tipo de servicio predeterminado en GKE se llama ClusterIP. En este tipo, el servicio obtiene una dirección IP a la que solo se puede acceder desde interior del clúster. Para exponer un servicio de Kubernetes fuera del clúster, debes crear un servicio de tipo LoadBalancer. Este tipo de servicio genera una IP del balanceador de cargas externo para un conjunto de Pods, a la que se puede acceder a través de Internet.

En esta sección, debes exponer la implementación hello-app a Internet mediante un servicio de tipo LoadBalancer.

.

Cloud Shell

  1. Usa el comando kubectl expose a fin de generar un servicio de Kubernetes para la implementación de hello-app.

    kubectl expose deployment hello-app --name=hello-app-service --type=LoadBalancer --port 80 --target-port 8080
    

    Aquí, la marca --port especifica el número de puerto configurado en el balanceador de cargas y la marca --target-port especifica el número de puerto en el que escucha el contenedor de hello-app.

  2. Ejecuta el siguiente comando con el fin de obtener los detalles del servicio para hello-app-service.

    kubectl get service
    

    Resultado:

    NAME                 CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
    hello-app-service    10.3.251.122    203.0.113.0     80:30877/TCP     10s
    
  3. Copia la dirección EXTERNAL_IP en el portapapeles (por ejemplo, 203.0.113.0).

Console

  1. Visita el menú Cargas de trabajo de Google Kubernetes Engine en Cloud Console.

    Visitar el menú Cargas de trabajo

  2. Haz clic en hello-app.

  3. En la página Detalles de la implementación, haz clic en Acciones > Exponer.

  4. En el cuadro de diálogo Exponer, configura el Puerto de destino como 8080. Este es el puerto en el que escucha el contenedor de hello-app.

  5. En la lista desplegable Tipo de servicio, selecciona Balanceador de cargas.

  6. Haz clic en Exponer a fin de crear un servicio de Kubernetes para hello-app.

  7. Cuando el balanceador de cargas esté listo, se abrirá la página Detalles del servicio.

  8. Desplázate hacia abajo hasta el campo Extremos externos y copia la dirección IP.

Ahora que los Pods de hello-app están expuestos a la Internet a través de un servicio de Kubernetes, puedes abrir una pestaña nueva del navegador y navegar a la dirección IP del servicio que copiaste en el portapapeles. Aparecerá un mensaje Hello, World!, junto con un campo Hostname. El Hostname corresponde a uno de los tres Pods de hello-app que entregan la solicitud HTTP al navegador.

Implementa una versión nueva de la app de muestra

En esta sección, deberás actualizar hello-app a una versión nueva mediante la compilación y la implementación de una imagen de Docker nueva en el clúster de GKE.

La función de actualización progresiva de GKE te permite actualizar las implementaciones sin tiempo de inactividad. Durante una actualización progresiva, el clúster de GKE reemplaza de forma incremental los Pods de hello-app existentes por Pods que contengan la imagen de Docker de la versión nueva. Durante la actualización, el servicio del balanceador de cargas enruta el tráfico solo a los Pods disponibles.

  1. Regresa a Cloud Shell, donde clonaste el código fuente de hello-app y el Dockerfile. Actualiza la función hello() en el archivo main.go para informar la versión nueva 2.0.0.

  2. Compila y etiqueta una nueva imagen de Docker de hello-app.

    docker build -t gcr.io/${PROJECT_ID}/hello-app:v2 .
    
  3. Envía la imagen a Container Registry.

    docker push gcr.io/${PROJECT_ID}/hello-app:v2
    

Ya estás listo para actualizar la implementación de Kubernetes de hello-app con el fin de usar una imagen de Docker nueva.

Cloud Shell

  1. Aplica una actualización progresiva a la implementación de hello-app existente con una actualización de imagen mediante el comando kubectl set image:

    kubectl set image deployment/hello-app hello-app=gcr.io/${PROJECT_ID}/hello-app:v2
    
  2. Mira cómo finalizan los Pods en ejecución que ejecutan la imagen v1 y cómo inician los Pods nuevos que ejecutan la imagen v2.

    watch kubectl get pods
    

    Resultado:

    NAME                        READY   STATUS    RESTARTS   AGE
    hello-app-89dc45f48-5bzqp   1/1     Running   0          2m42s
    hello-app-89dc45f48-scm66   1/1     Running   0          2m40s
    
  3. En una pestaña diferente, vuelve a navegar a la IP externa hello-app-service. Ahora deberías ver la Version configurada como 2.0.0..

Console

  1. Visita el menú Cargas de trabajo de Google Kubernetes Engine en Cloud Console.

    Visitar el menú Cargas de trabajo

  2. Haz clic en hello-app.

  3. En la página Detalles de la implementación, haz clic en Acciones > Actualización progresiva.

  4. En el cuadro de diálogo Actualización progresiva, configura el campo Imagen de hello-app en gcr.io/PROJECT_ID/hello-app:v2 y reemplaza PROJECT_ID por el ID del proyecto.

  5. Haz clic en Actualizar.

  6. En la página Detalles de la implementación, inspecciona la sección Revisiones activas. Ahora deberías ver dos revisiones: 1 y 2. La revisión 1 corresponde a la implementación inicial que creaste antes. La revisión 2 es la actualización progresiva que acabas de iniciar.

  7. Después de unos momentos, actualiza la página. En Pods administrados, todas las réplicas de hello-app ahora corresponden a la revisión 2.

  8. En otra pestaña, navega nuevamente a la dirección IP del servicio que copiaste. El Version debe ser 2.0.0..

Realice una limpieza

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

  1. Borra el Service: De este modo, se desasigna el balanceador de cargas de Cloud creado para él:

    kubectl delete service hello-app-service
    
  2. Borra el clúster: De este modo, se borran los recursos que conforman el clúster, como las instancias de procesamiento, los discos y los recursos de red:

    gcloud container clusters delete hello-cluster --zone COMPUTE_ZONE
    
  3. Borra tus imágenes de contenedor: Esto borra las imágenes de Docker que enviaste a Container Registry.

    gcloud container images delete gcr.io/${PROJECT_ID}/hello-app:v1  --force-delete-tags --quiet
    gcloud container images delete gcr.io/${PROJECT_ID}/hello-app:v2  --force-delete-tags --quiet
    

¿Qué sigue?

Pruébalo tú mismo

Si es la primera vez que usas Google Cloud, crea una cuenta para evaluar el rendimiento de GKE en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.

Probar GKE gratis