1. Introducción
No es fácil administrar sitios web y aplicaciones.
Las cosas pueden salir mal cuando no deberían, los servidores fallan, el aumento en la demanda hace que se utilicen más recursos y realizar cambios sin tiempo de inactividad es complicado y estresante.
Imagina una herramienta que pueda ayudarte a hacer todo eso e incluso permitirte automatizarlo. Con GKE, todo eso es no solo posible, ¡sino también fácil! En este codelab, asumirás el rol de un desarrollador que ejecuta un sitio web de comercio electrónico para una empresa ficticia: Fancy Store. Debido a problemas de interrupción y escalamiento, se te asigna la tarea de implementar tu aplicación en GKE.
Los ejercicios están ordenados para reflejar una experiencia común de desarrollador de la nube:
- Crear un clúster de GKE
- Crear un contenedor de Docker
- Implementar el contenedor en GKE
- Exponer el contenedor a través de un servicio
- Escalar el contenedor a varias réplicas
- Modifica el sitio web.
- Lanzar una versión nueva sin tiempo de inactividad
Diagrama de arquitectura
Qué aprenderás
- Cómo crear un clúster de GKE
- Cómo crear una imagen de Docker
- Cómo implementar imágenes de Docker en Kubernetes
- Cómo escalar una aplicación en Kubernetes
- Cómo realizar una actualización progresiva en Kubernetes
Requisitos previos
- Una Cuenta de Google con acceso de administrador para crear proyectos o un proyecto con un rol de propietario del proyecto
- Conocimientos básicos sobre Docker y Kubernetes (si no tienes los conocimientos básicos, consulta Docker y Kubernetes ahora)
2. Configuración del entorno
Configuración del entorno de autoaprendizaje
Si aún no tienes una Cuenta de Google, debes crear una. Accede a la consola de Google Cloud y crea un proyecto nuevo.
Recuerda que el ID del proyecto es un nombre único en todos los proyectos de Google Cloud (el nombre anterior ya está en uso y no funcionará para ti). Más adelante, se denominará PROJECT_ID
.
A continuación, deberás habilitar la facturación en la consola de Cloud para usar los recursos de Google Cloud. Los usuarios nuevos de Google Cloud son aptos para una prueba gratuita de$300. Si no eres un usuario nuevo, no te preocupes, ya que el codelab no debería costarte más de unos pocos dólares. Sin embargo, el codelab podría costarte más dinero si usas más recursos o los dejas ejecutándose (consulta la sección "Limpieza" al final). Para obtener más información, consulta Precios.
Cloud Shell
Si bien puedes operar Google Cloud y GKE de forma remota con tu laptop, para el codelab usarás Cloud Shell, un entorno de línea de comandos que se ejecuta en la nube.
Esta máquina virtual basada en Debian está cargada con todas las herramientas de desarrollo que necesitarás. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Esto significa que todo lo que necesitarás para este Codelab es un navegador (sí, funciona en una Chromebook).
- Para activar Cloud Shell desde la consola de Cloud, solo haz clic en Activar Cloud Shell (el aprovisionamiento y la conexión al entorno debería llevar solo unos minutos).
Una vez conectado a Cloud Shell, debería ver que ya se autenticó y que el proyecto ya se configuró con tu PROJECT_ID
:
gcloud auth list
Resultado del comando
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
gcloud config list project
Resultado del comando
[core] project = <PROJECT_ID>
Si, por algún motivo, el proyecto no está configurado, solo emite el siguiente comando:
gcloud config set project <PROJECT_ID>
Si no conoce su PROJECT_ID
, Observa el ID que usaste en los pasos de configuración o búscalo en el panel de la consola de Cloud:
Cloud Shell también configura algunas variables de entorno de forma predeterminada, lo que puede resultar útil cuando ejecutas comandos futuros.
echo $GOOGLE_CLOUD_PROJECT
Resultado del comando
<PROJECT_ID>
- Establece la zona predeterminada y la configuración del proyecto.
gcloud config set compute/zone us-central1-f
Puedes elegir una variedad de zonas diferentes. Para obtener más información, consulta Regiones y Zonas
3. Crea un clúster de GKE
Ahora que tienes tu entorno de desarrollador activo, necesitas un clúster de GKE en el que implementar tu sitio web. Antes de crear un clúster, debes asegurarte de que estén habilitadas las APIs correspondientes. Ejecuta el siguiente comando para habilitar la API de los contenedores:
gcloud services enable container.googleapis.com
Ahora puedes crear tu clúster. Sigue los pasos a continuación para crear un clúster llamado fancy-cluster con 3 nodos:
gcloud container clusters create fancy-cluster --num-nodes 3
La creación del clúster puede demorar varios minutos. Luego, ejecuta el siguiente comando para ver las tres instancias de máquina virtual (VM) de trabajador del clúster:
gcloud compute instances list
Resultado:
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS gke-fancy-cluster-default-pool-ad92506d-1ng3 us-east4-a n1-standard-1 10.150.0.7 XX.XX.XX.XX RUNNING gke-fancy-cluster-default-pool-ad92506d-4fvq us-east4-a n1-standard-1 10.150.0.5 XX.XX.XX.XX RUNNING gke-fancy-cluster-default-pool-ad92506d-4zs3 us-east4-a n1-standard-1 10.150.0.6 XX.XX.XX.XX RUNNING
También puedes ver tu clúster y la información relacionada en la consola de Cloud. Haz clic en el botón de menú de la esquina superior izquierda, desplázate hacia abajo hasta Kubernetes Engine y haz clic en Clústeres. Deberías ver tu clúster llamado fancy-cluster.
¡Felicitaciones! Creaste tu primer clúster.
4. Clona el repositorio de código fuente
Dado que este es un sitio web existente, solo tienes que clonar la fuente del repositorio para enfocarte en crear imágenes de Docker e implementarlas en GKE.
Ejecuta los siguientes comandos para clonar el repositorio de código fuente en tu instancia de Cloud Shell y cambiarlo al directorio correspondiente. También instalarás las dependencias de Node.js para poder probar tu aplicación antes de implementarla.
cd ~ git clone https://github.com/googlecodelabs/monolith-to-microservices.git cd ~/monolith-to-microservices ./setup.sh
Con esta acción, se clona el repositorio, se cambia el directorio y se instalan las dependencias necesarias para ejecutar tu aplicación de manera local. Es posible que la secuencia de comandos demore unos minutos en ejecutarse.
Realiza tu diligencia debida y prueba tu aplicación. Ejecuta el siguiente comando para iniciar tu servidor web:
cd ~/monolith-to-microservices/monolith npm start
Resultado:
Monolith listening on port 8080!
Para obtener una vista previa de tu aplicación, haz clic en el ícono de vista previa en la Web, en el menú de Cloud Shell, y selecciona Vista previa en el puerto 8080.
Se debería abrir una ventana nueva en la que podrás ver tu Fancy Store en acción.
Puedes cerrar esa ventana después de ver el sitio web. Presiona Control+C
(Windows o Mac) en la ventana de terminal para detener el proceso del servidor web.
5. Crea el contenedor de Docker con Cloud Build
Ahora que los archivos fuente están listos, es momento de crear los contenedores de Docker para tu aplicación.
Normalmente, tendrías que adoptar un enfoque de dos pasos que implica compilar un contenedor de Docker y enviarlo a un registro para almacenar la imagen de la que extrae GKE. Sin embargo, puedes simplificar el proceso si usas Cloud Build para crear el contenedor de Docker y colocar la imagen en Container Registry con un único comando. (Para ver el proceso manual de creación y envío de un archivo Docker, consulta la Guía de inicio rápido para Container Registry).
Cloud Build comprime los archivos del directorio y los mueve a un bucket de Cloud Storage. Luego, el proceso de compilación toma los archivos del bucket y usa el Dockerfile para ejecutar el proceso de compilación de Docker. Debido a que especificaste la marca --tag
con el host como gcr.io
para la imagen de Docker, la imagen de Docker resultante se envía a Container Registry.
Primero, debes habilitar la API de Cloud Build con el siguiente comando:
gcloud services enable cloudbuild.googleapis.com
Después de habilitar la API, ejecuta el siguiente comando en Cloud Shell para iniciar el proceso de compilación:
cd ~/monolith-to-microservices/monolith gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0 .
Ese proceso tardará unos minutos, pero cuando se complete, verás el siguiente resultado en la terminal:
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ID CREATE_TIME DURATION SOURCE IMAGES STATUS 1ae295d9-63cb-482c-959b-bc52e9644d53 2019-08-29T01:56:35+00:00 33S gs://<PROJECT_ID>_cloudbuild/source/1567043793.94-abfd382011724422bf49af1558b894aa.tgz gcr.io/<PROJECT_ID>/monolith:1.0.0 SUCCESS
Para ver tu historial de compilaciones o el proceso en tiempo real, dirígete a la consola de Cloud. Haz clic en el botón de menú en la esquina superior izquierda, desplázate hacia abajo hasta Ci/CD, haz clic en Cloud Build y, por último, haz clic en Historial. Allí podrás ver una lista de tus compilaciones anteriores, pero solo debería aparecer la que creaste.
Si haces clic en el ID de compilación, podrás ver todos sus detalles, incluida la salida del registro.
Para ver la imagen del contenedor que se creó, en la página de detalles de compilación, haz clic en el nombre de la imagen en la sección de información de la compilación.
6. Implementa el contenedor en GKE
Ahora que creaste un contenedor para tu sitio web y lo enviaste a Container Registry, puedes implementarlo en Kubernetes.
Para implementar y administrar aplicaciones en un clúster de GKE, debes comunicarte con el sistema de administración de clústeres de Kubernetes. Normalmente, esto se hace con la herramienta de línea de comandos kubectl.
Kubernetes representa aplicaciones como Pods, que son unidades que representan un contenedor (o grupo de contenedores con acoplamiento alto). Un Pod es la unidad más pequeña que se puede implementar en Kubernetes. Aquí, cada Pod solo contiene tu contenedor monolith.
Para implementar tu aplicación, tienes que crear un objeto Deployment. Un Deployment administra varias copias de tu aplicación, llamadas réplicas, y las programa para que se ejecuten en los nodos individuales de tu clúster. En este caso, Deployment ejecutará solo un Pod de tu aplicación. Los objetos Deployment crean un ReplicaSet para garantizar esto. El ReplicaSet debe asegurarse de que la cantidad especificada de réplicas siempre esté en ejecución.
El comando kubectl create deployment
hace que Kubernetes cree un Deployment llamado monolith en tu clúster con 1 réplica.
Ejecuta el siguiente comando para implementar tu aplicación:
kubectl create deployment monolith --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0
Verifica la implementación
Para verificar que el objeto Deployment se haya creado correctamente, ejecuta el siguiente comando (el estado del Pod puede tardar unos minutos en cambiar a “Running”):
kubectl get all
Resultado:
NAME READY STATUS RESTARTS AGE pod/monolith-7d8bc7bf68-htm7z 1/1 Running 0 6m21s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.27.240.1 <none> 443/TCP 24h NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment.apps/monolith 1 1 1 1 20m NAME DESIRED CURRENT READY AGE replicaset.apps/monolith-7d8bc7bf68 1 1 1 20m
Ese resultado te muestra varias cosas. Puedes ver tu objeto Deployment, que es actual. tu ReplicaSet, con un recuento de Pods deseado de uno; y tu Pod, que se está ejecutando. Parece que creaste todo correctamente.
Para ver tus recursos de forma individual, puedes ejecutar los siguientes comandos:
# Show pods kubectl get pods # Show deployments kubectl get deployments # Show replica sets kubectl get rs #You can also combine them kubectl get pods,deployments
Para conocer el beneficio completo de Kubernetes, puedes simular una falla del servidor, borrar el Pod y ver qué sucede.
Copia el nombre de tu Pod del comando anterior y ejecuta el siguiente comando para borrarlo:
kubectl delete pod/<POD_NAME>
Si eres lo suficientemente rápido, puedes ejecutar el comando anterior para ver todo de nuevo y deberías ver dos Pods, uno con el estado finalizado y el otro en proceso de creación o ejecución:
kubectl get all
Resultado:
NAME READY STATUS RESTARTS AGE pod/monolith-7d8bc7bf68-2bxts 1/1 Running 0 4s pod/monolith-7d8bc7bf68-htm7z 1/1 Terminating 0 9m35s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.27.240.1 <none> 443/TCP 24h NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment.apps/monolith 1 1 1 1 24m NAME DESIRED CURRENT READY AGE replicaset.apps/monolith-7d8bc7bf68 1 1 1 24m
¿Por qué motivo? El ReplicaSet vio que el Pod tenía el estado Terminating y activó un Pod nuevo para mantener el recuento deseado de réplicas. Más adelante, aprenderás a escalar para asegurarte de que tienes varias instancias en ejecución, de modo que tus usuarios no experimenten tiempo de inactividad si alguna de ellas falla.
7. Expón el Deployment de GKE
Ya implementaste tu aplicación en GKE, pero no tienes manera de acceder a ella desde fuera del clúster. Según la configuración predeterminada, los contenedores que ejecutas en GKE no son accesibles desde Internet, ya que no tienen direcciones IP externas. Debes exponer tu aplicación al tráfico de Internet de forma explícita mediante un recurso Service, Este recurso proporciona herramientas de redes y compatibilidad con IP para los Pods de tu app. GKE crea una IP externa y un balanceador de cargas (sujeto a facturación) para tu app.
Ejecuta el siguiente comando para exponer tu sitio web a Internet:
kubectl expose deployment monolith --type=LoadBalancer --port 80 --target-port 8080
Resultado:
service/monolith exposed
Accede al servicio
GKE asigna la dirección IP externa al recurso Service, no a Deployment. Si quieres encontrar la IP externa que GKE aprovisionó para tu aplicación, puedes inspeccionar el objeto Service con el comando kubectl get service:
kubectl get service
Resultado:
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE monolith 10.3.251.122 203.0.113.0 80:30877/TCP 3d
Después de determinar la dirección IP externa para tu app, cópiala. y escribe esa URL (como http://203.0.113.0) en tu navegador para verificar si se puede acceder a ella.
Deberías ver el mismo sitio web que probaste antes. ¡Felicitaciones! Tu sitio web se ejecuta por completo en Kubernetes.
8. Escala el recurso Deployment de GKE
Ahora que tienes una instancia en ejecución de tu app en GKE y la expusiste a Internet, tu sitio web se ha vuelto extremadamente popular. Necesitas una forma de escalar tu app a varias instancias para poder controlar el tráfico. Aprende a escalar tu aplicación hasta tres réplicas.
Ejecuta el siguiente comando para escalar tu Deployment a un máximo de tres réplicas:
kubectl scale deployment monolith --replicas=3
Resultado:
deployment.apps/monolith scaled
Verifica la implementación escalada
Para verificar que el recurso Deployment haya escalado correctamente, ejecuta el siguiente comando:
kubectl get all
Resultado:
NAME READY STATUS RESTARTS AGE pod/monolith-7d8bc7bf68-2bxts 1/1 Running 0 36m pod/monolith-7d8bc7bf68-7ds7q 1/1 Running 0 45s pod/monolith-7d8bc7bf68-c5kxk 1/1 Running 0 45s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.27.240.1 <none> 443/TCP 25h service/monolith LoadBalancer 10.27.253.64 XX.XX.XX.XX 80:32050/TCP 6m7s NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment.apps/monolith 3 3 3 3 61m NAME DESIRED CURRENT READY AGE replicaset.apps/monolith-7d8bc7bf68 3 3 3 61m
Deberías ver tres instancias de tu Pod en ejecución. Además, ten en cuenta que tu objeto Deployment y ReplicaSet ahora tienen un recuento deseado de tres.
9. Realiza cambios en el sitio web
Tu equipo de marketing te solicitó que cambies la página principal de tu sitio web. Creen que debería ser más informativo si explica qué es su empresa y qué vende en realidad. En esta sección, agregarás texto a la página principal para satisfacer al equipo de marketing. Parece que uno de los desarrolladores ya creó los cambios con el archivo llamado index.js.new
. Puedes copiar el archivo en index.js
, y deberías ver reflejados los cambios. Sigue las instrucciones que se incluyen a continuación para realizar los cambios apropiados.
Ejecuta los siguientes comandos, copia el archivo actualizado en el nombre de archivo correcto y, luego, imprime el contenido para verificar los cambios:
cd ~/monolith-to-microservices/react-app/src/pages/Home mv index.js.new index.js cat ~/monolith-to-microservices/react-app/src/pages/Home/index.js
El código resultante debería verse así:
/* Copyright 2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ import React from "react"; import { makeStyles } from "@material-ui/core/styles"; import Paper from "@material-ui/core/Paper"; import Typography from "@material-ui/core/Typography"; const useStyles = makeStyles(theme => ({ root: { flexGrow: 1 }, paper: { width: "800px", margin: "0 auto", padding: theme.spacing(3, 2) } })); export default function Home() { const classes = useStyles(); return ( <div className={classes.root}> <Paper className={classes.paper}> <Typography variant="h5"> Fancy Fashion & Style Online </Typography> <br /> <Typography variant="body1"> Tired of mainstream fashion ideas, popular trends and societal norms? This line of lifestyle products will help you catch up with the Fancy trend and express your personal style. Start shopping Fancy items now! </Typography> </Paper> </div> ); }
Ya actualizaste los componentes de React, pero debes compilar la app de React para generar archivos estáticos. Ejecuta el siguiente comando para compilar la app y copiarla en el directorio público de monolith:
cd ~/monolith-to-microservices/react-app npm run build:monolith
Ahora que se actualizó el código, debes volver a compilar el contenedor de Docker y publicarlo en Container Registry. Puedes utilizar el mismo comando que antes, pero esta vez actualizarás la etiqueta de la versión.
Ejecuta el siguiente comando para activar un Cloud Build nuevo con una versión de imagen actualizada de 2.0.0:
cd ~/monolith-to-microservices/monolith #Feel free to test your application npm start gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0 .
Presiona Control+C
(Windows o Mac) en la ventana de terminal para detener el proceso del servidor web.
En la siguiente sección, usarás esa imagen para actualizar tu aplicación sin tiempo de inactividad.
10. Actualiza el sitio web sin tiempo de inactividad
Los cambios están completos, y el equipo de marketing está feliz con las actualizaciones que realizaste. Es momento de actualizar el sitio web sin que los usuarios tengan interrupciones. Para actualizar tu sitio web, sigue las instrucciones que se indican a continuación.
Las actualizaciones progresivas de GKE garantizan que tu aplicación se mantenga activa y disponible incluso cuando el sistema reemplace las instancias de la imagen de contenedor anterior por la nueva en todas las réplicas en ejecución.
Desde la línea de comandos, puedes decirle a Kubernetes que deseas actualizar la imagen de tu Deployment a una nueva versión con el siguiente comando:
kubectl set image deployment/monolith monolith=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0
Resultado:
deployment.apps/monolith image updated
Verifique el recurso Deployment
Puedes validar la actualización del objeto Deployment ejecutando el siguiente comando:
kubectl get pods
Resultado:
NAME READY STATUS RESTARTS AGE monolith-584fbc994b-4hj68 1/1 Terminating 0 60m monolith-584fbc994b-fpwdw 1/1 Running 0 60m monolith-584fbc994b-xsk8s 1/1 Terminating 0 60m monolith-75f4cf58d5-24cq8 1/1 Running 0 3s monolith-75f4cf58d5-rfj8r 1/1 Running 0 5s monolith-75f4cf58d5-xm44v 0/1 ContainerCreating 0 1s
Verás que se crean tres Pods nuevos y se cierran los antiguos. Se puede saber por las edades cuáles son nuevas y cuáles son antiguas. Al final, nuevamente verás solo tres Pods, que serán tus tres Pods actualizados.
Para verificar los cambios, navega a la IP externa del balanceador de cargas nuevamente y observa que se actualizó tu app.
Ejecuta el siguiente comando para generar una lista de los servicios y ver la dirección IP si la olvidaste:
kubectl get svc
Tu sitio web debe mostrar el texto que agregaste al componente de la página principal.
11. Limpia
Borra el repositorio de Git
cd ~ rm -rf monolith-to-microservices
Borrar imágenes de Container Registry
NOTA: Si creaste otras versiones, también puedes usar la misma sintaxis para borrar esas imágenes. En este codelab, se supone que solo tienes dos etiquetas.
# Delete the container image for version 1.0.0 of our monolith gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0 --quiet # Delete the container image for version 2.0.0 of our monolith gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0 --quiet
Borra los artefactos de Cloud Build de Cloud Storage
NOTA: Si usaste Cloud Build para otros artefactos que no sean este codelab, deberás borrar manualmente tu fuente del bucket gs://<PROJECT_ID>_cloudbuild/source
de Cloud Storage.
# The following command will take all source archives from all builds and delete them from cloud storage # Run this command to print all sources: # gcloud builds list | awk 'NR > 1 {print $4}' gcloud builds list | awk 'NR > 1 {print $4}' | while read line; do gsutil rm $line; done
Borrar el servicio de GKE
kubectl delete service monolith kubectl delete deployment monolith
Borrar clúster de GKE
gcloud container clusters delete fancy-cluster
NOTA: Este comando puede tardar un poco.
12. ¡Felicitaciones!
Implementaste, escalaste y actualizaste tu sitio web en GKE. Ahora tienes experiencia con Docker y Kubernetes.