Si no tienes experiencia con las cargas de trabajo en contenedores, este tutorial es para ti. Te presenta los contenedores y la orquestación de contenedores explicándote cómo configurar una aplicación sencilla desde el código fuente hasta un contenedor que se ejecuta en GKE.
Para seguir este tutorial no es necesario tener experiencia previa con contenedores ni con Kubernetes. Sin embargo, si quieres leer una descripción general de la terminología básica de Kubernetes antes de empezar este tutorial, consulta Empezar a aprender sobre Kubernetes (o, si prefieres aprender sobre Kubernetes en formato cómic, consulta nuestro cómic de Kubernetes). Encontrarás recursos más detallados en la sección Próximos pasos, al final del tutorial.
Si ya conoces los contenedores y Kubernetes, puedes saltarte este tutorial y empezar a aprender sobre GKE.
Objetivos
- Descubre una aplicación sencilla de "Hola, mundo" con varios servicios.
- Ejecuta la aplicación desde la fuente.
- Conteneriza la aplicación.
- Crea un clúster de Kubernetes.
- Despliega los contenedores en el clúster.
Antes de empezar
Sigue estos pasos para habilitar la API de Kubernetes Engine:- Ve a la página de Kubernetes Engine en la Google Cloud consola.
- Crea o selecciona un proyecto.
- Espera a que la API y los servicios relacionados se habiliten. Este proceso puede tardar varios minutos.
-
Verify that billing is enabled for your Google Cloud project.
Preparar Cloud Shell
En este tutorial se usa Cloud Shell, que aprovisiona una máquina virtual g1-small de Compute Engine que ejecuta un sistema operativo Linux basado en Debian.
Usar Cloud Shell tiene las siguientes ventajas:
- Un entorno de desarrollo de Python 3 (incluido
virtualenv
) está totalmente configurado. - Las herramientas de línea de comandos
gcloud
,docker
,git
ykubectl
que se usan en este tutorial ya están instaladas. Puedes elegir entre los editores de texto integrados:
Editor de Cloud Shell, al que puedes acceder haciendo clic en Abrir editor en la parte superior de la ventana de Cloud Shell.
Emacs, Vim o Nano, a los que puedes acceder desde la línea de comandos de Cloud Shell.
In the Google Cloud console, activate Cloud Shell.
Descargar el código de ejemplo
Descarga el código fuente de
helloserver
:git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples
Cambia al directorio del código de ejemplo:
cd anthos-service-mesh-samples/docs/helloserver
Explorar la aplicación multiservicio
La aplicación de ejemplo está escrita en Python. Tiene los siguientes componentes, que se comunican mediante REST:
server
: un servidor básico con un endpointGET
,/
, que imprime "hello world" en la ventana de la terminal.loadgen
: una secuencia de comandos que envía tráfico aserver
, con un número configurable de solicitudes por segundo (RPS).
Ejecutar la aplicación desde la fuente
Para familiarizarte con la aplicación de ejemplo, ejecútala en Cloud Shell:
En el directorio
sample-apps/helloserver
, ejecutaserver
:python3 server/server.py
Al iniciarse,
server
muestra lo siguiente:INFO:root:Starting server...
Abre otra ventana de terminal para poder enviar solicitudes al
server
. Para hacerlo en Cloud Shell, haz clic en Abrir una pestaña nueva para abrir otra sesión.En la nueva ventana de terminal, envía una solicitud a
server
:curl http://localhost:8080
El resultado de
server
es el siguiente:Hello World!
En la misma pestaña, ve al directorio que contiene la secuencia de comandos
loadgen
:cd anthos-service-mesh-samples/docs/helloserver/loadgen
Crea las siguientes variables de entorno:
export SERVER_ADDR=http://localhost:8080 export REQUESTS_PER_SECOND=5
Inicio
virtualenv
:virtualenv --python python3 env
Activa el entorno virtual:
source env/bin/activate
Instala los requisitos de
loadgen
:pip3 install -r requirements.txt
Ejecuta la aplicación
loadgen
para generar tráfico enserver
:python3 loadgen.py
Al iniciarse, la salida de
loadgen
es similar a la siguiente:Starting loadgen: 2024-10-11 09:49:51.798028 5 request(s) complete to http://localhost:8080
Ahora, abre la ventana de terminal en la que se está ejecutando
server
. Deberías ver mensajes similares a los siguientes:127.0.0.1 - - [11/Oct/2024 09:51:28] "GET / HTTP/1.1" 200 - INFO:root:GET request, Path: / Headers: Host: localhost:8080 User-Agent: python-requests/2.32.3 Accept-Encoding: gzip, deflate Accept: */* Connection: keep-alive
Desde el punto de vista de la red, toda la aplicación se ejecuta ahora en el mismo host, lo que te permite usar
localhost
para enviar solicitudes alserver
.Para detener
loadgen
yserver
, pulsaCtrl-c
en cada ventana de terminal.En la ventana de terminal
loadgen
, desactiva el entorno virtual:deactivate
Contenerizar la aplicación
Para ejecutar la aplicación en GKE, debes empaquetar los dos componentes de la aplicación de ejemplo en contenedores. Un contenedor es un paquete que contiene todos los elementos necesarios para que tu aplicación se ejecute en cualquier entorno. En este tutorial se usa Docker para crear un contenedor de la aplicación.
Para crear un contenedor de la aplicación con Docker, necesitas un Dockerfile
. Un Dockerfile
es un archivo de texto que define los comandos necesarios para ensamblar el código fuente de la aplicación y sus dependencias en una imagen de contenedor. Después de crear la imagen, súbela a un registro de contenedores, como Artifact Registry.
El código fuente de este tutorial incluye un Dockerfile
tanto para server
como para loadgen
con todos los comandos necesarios para crear las imágenes. A continuación, se muestra el Dockerfile
de server
:
En este archivo, puede ver lo siguiente:
- La instrucción
FROM python:3-slim as base
indica a Docker que use la imagen de Python 3 más reciente como imagen base. - La instrucción
COPY . .
copia los archivos de origen del directorio de trabajo actual (en este caso,server.py
) en el sistema de archivos del contenedor. ENTRYPOINT
define la instrucción que se usa para ejecutar el contenedor. En este ejemplo, la instrucción es similar a la que has usado para ejecutarserver.py
desde el código fuente.- La instrucción
EXPOSE
especifica queserver
escucha en el puerto8080
. Esta instrucción no expone ningún puerto, sino que sirve como documentación para indicar que debes abrir el puerto8080
cuando ejecutes el contenedor.
Preparar la contenedorización de la aplicación
Antes de contenerizar la aplicación, debes configurar las herramientas y los servicios que vas a usar:
Define el proyecto Google Cloud predeterminado de Google Cloud CLI.
gcloud config set project PROJECT_ID
Define la región predeterminada de Google Cloud CLI.
gcloud config set compute/region us-central1
Crear el repositorio
Para crear un repositorio de imágenes de contenedor Docker en Artifact Registry, sigue estos pasos:
Asegúrate de que el servicio Artifact Registry esté habilitado en tuGoogle Cloud proyecto.
gcloud services enable artifactregistry.googleapis.com
Crea el repositorio de Artifact Registry:
gcloud artifacts repositories create container-intro --repository-format=docker \ --location=us-central1 \ --description="My new Docker repository"
Configura la autenticación de Docker en Artifact Registry mediante la CLI de Google Cloud:
gcloud auth configure-docker us-central1-docker.pkg.dev
Contenedorizar el server
Ahora es el momento de crear un contenedor para tu aplicación. Primero, crea un contenedor para el archivo "hello
world" server
y envía la imagen a Artifact Registry:
Cambia al directorio donde se encuentra el ejemplo
server
:cd ~/anthos-service-mesh-samples/docs/helloserver/server/
Crea la imagen con
Dockerfile
:docker build -t us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1 .
- Sustituye
PROJECT_ID
por el ID de tu Google Cloud proyecto.
La bandera
-t
representa la etiqueta de Docker. Es el nombre de la imagen que usas al implementar el contenedor.- Sustituye
Envía la imagen a Artifact Registry:
docker push us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1
Contenedorizar el loadgen
A continuación, crea un contenedor para el servicio de generador de carga de la misma forma:
Cambia al directorio donde se encuentra el ejemplo
loadgen
:cd ../loadgen
Crea la imagen:
docker build -t us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen:v0.0.1 .
Envía la imagen a Artifact Registry:
docker push us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen:v0.0.1
Enumera las imágenes
Obtén una lista de las imágenes del repositorio para confirmar que se han enviado:
gcloud container images list --repository us-central1-docker.pkg.dev/PROJECT_ID/container-intro
En la salida se deben mostrar los nombres de las imágenes que has enviado, de forma similar a lo siguiente:
NAME us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen
Crear un clúster de GKE
En este punto, podrías ejecutar los contenedores en la VM de Cloud Shell con el comando docker run
. Sin embargo, para ejecutar cargas de trabajo de producción fiables, debes gestionar los contenedores de una forma más unificada. Por ejemplo, debes asegurarte de que los contenedores se reinicien si fallan y necesitas una forma de ampliar y poner en marcha instancias adicionales de un contenedor para gestionar los aumentos de tráfico.
GKE puede ayudarte a satisfacer estas necesidades. GKE es una plataforma de orquestación de contenedores que funciona conectando máquinas virtuales en un clúster. Cada máquina virtual se denomina nodo. Los clústeres de GKE se basan en el sistema de gestión de clústeres de código abierto de Kubernetes. Kubernetes proporciona los mecanismos a través de los cuales interactúas con tu clúster.
Para ejecutar los contenedores en GKE, primero debes crear un clúster y, a continuación, conectarte a él:
Crea el clúster:
gcloud container clusters create-auto container-intro
El comando
gcloud
crea un clúster en el proyecto Google Cloud y la región predeterminados que hayas definido anteriormente.El comando para crear el clúster tarda unos minutos en completarse. Cuando el clúster esté listo, el resultado será similar al siguiente:
NAME: container-intro LOCATION: us-central1 MASTER_VERSION: 1.30.4-gke.1348000 MASTER_IP: 34.44.14.166 MACHINE_TYPE: e2-small NODE_VERSION: 1.30.4-gke.1348000 NUM_NODES: 3 STATUS: RUNNING
Proporciona credenciales a la herramienta de línea de comandos
kubectl
para que puedas usarla para gestionar el clúster:gcloud container clusters get-credentials container-intro
Examinar manifiestos de Kubernetes
Cuando ejecutaste la aplicación desde el código fuente, usaste un comando imperativo: python3 server.py
Imperativo significa que se basa en verbos: "haz esto".
Por el contrario, Kubernetes funciona con un modelo declarativo. Esto significa que, en lugar de decirle a Kubernetes exactamente qué debe hacer, le proporcionas el estado deseado. Por ejemplo, Kubernetes inicia y finaliza pods según sea necesario para que el estado real del sistema coincida con el estado deseado.
Especificas el estado deseado en un archivo llamado manifiesto. Los manifiestos se escriben en lenguajes como YAML o JSON y contienen la especificación de uno o varios objetos de Kubernetes.
El ejemplo contiene un manifiesto para server
y otro para loadgen
. Cada manifiesto especifica el estado deseado del objeto de implementación de Kubernetes (que gestiona la ejecución del contenedor, empaquetado para la gestión como un pod de Kubernetes) y del servicio (que proporciona una dirección IP al pod). Un pod es la unidad de computación desplegable más pequeña que puedes crear y gestionar en Kubernetes, y contiene uno o varios contenedores.
En el siguiente diagrama se muestra la aplicación que se ejecuta en GKE:
Puedes consultar más información sobre pods, implementaciones y servicios en la sección Empezar a aprender sobre Kubernetes o en los recursos que aparecen al final de esta página.
Servidor
Primero, consulta el manifiesto de la aplicación "hello world" server
:
Este manifiesto contiene los siguientes campos:
kind
indica el tipo de objeto.metadata.name
especifica el nombre de la implementación.- El primer campo
spec
contiene una descripción del estado deseado. spec.replicas
especifica el número de pods que se quieren.- La sección
spec.template
define una plantilla de pod. En la especificación de los pods se incluye el campoimage
, que es el nombre de la imagen que se va a extraer de Artifact Registry. En el siguiente paso, actualizarás este valor con la nueva imagen que acabas de crear.
El Servicio hellosvc
se define de la siguiente manera:
LoadBalancer
: los clientes envían solicitudes a la dirección IP de un balanceador de carga de red, que tiene una dirección IP estable y se puede acceder a él desde fuera del clúster.targetPort
: Recuerda que el comandoEXPOSE 8080
deDockerfile
no expone ningún puerto. Expón el puerto8080
para poder acceder al contenedorserver
fuera del clúster. En este caso,hellosvc.default.cluster.local:80
(nombre abreviado:hellosvc
) se asigna al puerto8080
de la IP del podhelloserver
.port
: es el número de puerto que usan otros servicios del clúster al enviar solicitudes.
Generador de carga
El objeto Deployment de loadgen.yaml
es similar a server.yaml
. Una diferencia notable es que la especificación de Pod de loadgen
Deployment tiene un campo llamado env
. En esta sección se definen las variables de entorno que requiere loadgen
, que ya has definido al ejecutar la aplicación desde la fuente.
Como loadgen
no acepta solicitudes entrantes, el campo type
se ha definido como ClusterIP
. Este tipo de servicio proporciona una dirección IP estable que pueden usar las entidades del clúster, pero la dirección IP no se expone a los clientes externos.
Desplegar los contenedores en GKE
Para implementar los contenedores, aplica los manifiestos que especifican el estado que quieres mediante kubectl
.
Desplegar el server
Cambia al directorio donde se encuentra el ejemplo
server
:cd ~/anthos-service-mesh-samples/docs/helloserver/server/
Abre
server.yaml
en el editor de Cloud Shell (o en el editor de texto que prefieras).Sustituye el nombre del campo
image
por el nombre de tu imagen de Docker.image: us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1
Sustituye PROJECT_ID por el ID de tu proyecto. Google Cloud
- Si usas el editor de Cloud Shell, el archivo se guarda automáticamente. Vuelve a la ventana de la terminal haciendo clic en Abrir terminal.
- Si estás usando un editor de texto en Cloud Shell, guarda y cierra
server.yaml
.
Despliega el manifiesto en Kubernetes:
kubectl apply -f server.yaml
El resultado debería ser similar al siguiente:
deployment.apps/helloserver created service/hellosvc created
Desplegar el loadgen
Cambia al directorio en el que se encuentra
loadgen
.cd ../loadgen
Abre
loadgen.yaml
en un editor de texto, como antes.De nuevo, sustituye el nombre del campo
image
por el nombre de tu imagen Docker.image: us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen:v0.0.1
Sustituye PROJECT_ID por el ID de tu proyecto. Google Cloud
- Si usas el editor de Cloud Shell, el archivo se guarda automáticamente. Vuelve a la ventana de la terminal haciendo clic en Abrir terminal.
- Si estás usando un editor de texto en Cloud Shell, guarda y cierra
loadgen.yaml
.
Despliega el manifiesto en tu clúster:
kubectl apply -f loadgen.yaml
Si la acción se realiza correctamente, el comando mostrará lo siguiente:
deployment.apps/loadgenerator created service/loadgensvc created
Verificar la implementación
Después de implementar los manifiestos en el clúster, comprueba que los contenedores se han implementado correctamente:
Comprueba el estado de los pods de tu clúster:
kubectl get pods
El comando responde con un estado similar al siguiente:
NAME READY STATUS RESTARTS AGE helloserver-69b9576d96-mwtcj 1/1 Running 0 58s loadgenerator-774dbc46fb-gpbrz 1/1 Running 0 57s
Obtén los registros de la aplicación del pod
loadgen
. Sustituye POD_ID por el identificador del pod del generador de carga de la salida anterior.kubectl logs POD_ID
Obtén las direcciones IP externas de
hellosvc
:kubectl get service hellosvc
El resultado debería ser similar al siguiente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hellosvc LoadBalancer 10.81.15.158 192.0.2.1 80:31127/TCP 33m
Envía una solicitud al
hellosvc
. Sustituye EXTERNAL_IP por la dirección IP externa de tuhellosvc
.curl http://EXTERNAL_IP
Debería aparecer el mensaje "Hello World!" del servidor.
Limpieza
Para evitar que los recursos utilizados en este tutorial se cobren en tu cuenta de Google Cloud, elimina el proyecto que contiene los recursos o conserva el proyecto y elimina los recursos.
Si no quieres eliminar todo el proyecto, sigue estos pasos:
Elimina el clúster de GKE. Al eliminar el clúster, se eliminan todos los recursos que lo componen, como las instancias de Compute Engine, los discos y los recursos de red.
gcloud container clusters delete container-intro
Elimina el repositorio de Artifact Registry:
gcloud artifacts repositories delete container-intro --location=us-central1
Siguientes pasos
Consulta más información sobre las tecnologías que se usan en este tutorial:
Consulta más información sobre las herramientas:
Consulta más información sobre los conceptos de Kubernetes: