Si no estás familiarizado con las cargas de trabajo en contenedores, este instructivo es para ti. Te presenta los contenedores y la organización de contenedores guiándote para configurar una aplicación simple desde el código fuente a un contenedor que se ejecuta en GKE.
No se requiere experiencia previa con contenedores ni Kubernetes para realizar este instructivo. Sin embargo, si quieres leer una descripción general de la terminología básica de Kubernetes antes de comenzar este instructivo, consulta Comienza a aprender sobre Kubernetes (o si prefieres aprender sobre Kubernetes en forma de cómic, consulta nuestro cómic de Kubernetes). Encontrarás recursos más detallados en la sección Qué sigue al final del instructivo.
Si ya conoces los contenedores y Kubernetes, puedes omitir este instructivo y comenzar a aprender sobre GKE.
Objetivos
- Explorarás una aplicación “Hello World” simple de varios servicios.
- Ejecuta la aplicación desde la fuente.
- Organizarás la aplicación en contenedores.
- Crearás un clúster de Kubernetes.
- Implementarás los contenedores en el clúster.
Antes de comenzar
Sigue los pasos que se indican a continuación para habilitar la API de Kubernetes Engine:- Visita la página de Kubernetes Engine en la consola de Google Cloud .
- Crea o selecciona un proyecto.
- Espera a que la API y los servicios relacionados se habiliten. Esto puede tomar varios minutos.
-
Make sure that billing is enabled for your Google Cloud project.
Prepara Cloud Shell
En este instructivo, se usa Cloud Shell, que aprovisiona una máquina virtual (VM) g1-small de Compute Engine que ejecuta un sistema operativo Linux basado en Debian.
El uso de Cloud Shell tiene las siguientes ventajas:
- Un entorno de desarrollo de Python 3 (incluido
virtualenv
) está completamente configurado. - Las herramientas de línea de comandos de
gcloud
,docker
,git
ykubectl
que se usan en este instructivo 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 en Cloud Shell.
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
Descarga el código de muestra
Descarga el código fuente de
helloserver
:git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples
Cambia al directorio del código de muestra:
cd anthos-service-mesh-samples/docs/helloserver
Explora la aplicación de varios servicios
La aplicación de ejemplo está escrita en Python. Tiene los siguientes componentes que se comunican mediante REST:
server
: Es un servidor básico con un extremoGET
,/
, que imprime “Hello World” en la ventana de la terminal.loadgen
: Es una secuencia de comandos que envía tráfico alserver
, con una cantidad configurable de solicitudes por segundo (RPS).
Ejecuta la aplicación desde la fuente
Para familiarizarte con la aplicación de ejemplo, ejecútala en Cloud Shell:
Desde el directorio
sample-apps/helloserver
, ejecutaserver
:python3 server/server.py
En el inicio, el
server
muestra lo siguiente:INFO:root:Starting server...
Abre otra ventana de la 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 la terminal, envía una solicitud al
server
:curl http://localhost:8080
El resultado de
server
es el siguiente:Hello World!
En la misma pestaña, cambia 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
Inicia
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 para elserver
:python3 loadgen.py
En el inicio, el resultado de
loadgen
es similar al siguiente:Starting loadgen: 2024-10-11 09:49:51.798028 5 request(s) complete to http://localhost:8080
Ahora abre la ventana de terminal que ejecuta
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 las herramientas de redes, toda la aplicación ahora se ejecuta en el mismo host, lo que te permite usar
localhost
para enviar solicitudes aserver
.Para detener
loadgen
y elserver
, presionaCtrl-c
en cada ventana de la terminal.En la ventana de la terminal de
loadgen
, desactiva el entorno virtual:deactivate
Organiza la aplicación en contenedores
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 instructivo, se usa Docker para contener la aplicación.
Para organizar la aplicación en contenedores con Docker, necesitas un Dockerfile
. Un Dockerfile
es un archivo de texto que define los comandos necesarios para juntar el código fuente de la aplicación y sus dependencias en una imagen de contenedor. Después de compilar la imagen, debes subirla a un registro de contenedores, como Artifact Registry.
El código fuente de este instructivo incluye un Dockerfile
para el server
y loadgen
con todos los comandos necesarios para compilar las imágenes. A continuación, se incluye el Dockerfile
para el server
:
En este archivo, puedes ver lo siguiente:
- La instrucción
FROM python:3-slim as base
le indica a Docker que use la imagen de Python 3 más reciente como imagen base. - La instrucción
COPY . .
copia los archivos fuente del directorio de trabajo actual (en este caso,server.py
) al sistema de archivos del contenedor. - El
ENTRYPOINT
define la instrucción que se usa para ejecutar el contenedor. En este ejemplo, la instrucción es similar a la que usaste 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, pero sirve como documentación que necesitas para abrir el puerto8080
cuando ejecutas el contenedor.
Prepárate para organizar la aplicación en contenedores
Antes de contener la aplicación, debes configurar las herramientas y los servicios que usarás:
Establece el proyecto predeterminado Google Cloud para Google Cloud CLI.
gcloud config set project PROJECT_ID
Establece la región predeterminada para Google Cloud CLI.
gcloud config set compute/region us-central1
Crea el repositorio
Para crear un repositorio nuevo para imágenes de contenedores de Docker en Artifact Registry, haz lo siguiente:
Asegúrate de que el servicio de Artifact Registry esté habilitado en tu proyecto deGoogle Cloud .
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 a Artifact Registry con Google Cloud CLI:
gcloud auth configure-docker us-central1-docker.pkg.dev
Crea contenedores para el server
Ahora es momento de alojar tu aplicación en contenedores. Primero, crea un contenedor para el server
de "hello world" y envía la imagen a Artifact Registry:
Cambia al directorio en el que se encuentra el
server
de muestra:cd ~/anthos-service-mesh-samples/docs/helloserver/server/
Compila la imagen con
Dockerfile
:docker build -t us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1 .
- Reemplaza
PROJECT_ID
por el ID de tu proyecto de Google Cloud .
La marca
-t
representa la etiqueta de Docker. Este es el nombre de la imagen que debes usar en la implementación del contenedor.- Reemplaza
Envía la imagen a Artifact Registry:
docker push us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1
Crea contenedores para el loadgen
A continuación, crea un contenedor para el servicio del generador de cargas de la misma manera:
Cambia al directorio en el que se encuentra el
loadgen
de muestra:cd ../loadgen
Compila 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
Obtén una lista de las imágenes
Obtén una lista de las imágenes en el repositorio para confirmar que se enviaron:
gcloud container images list --repository us-central1-docker.pkg.dev/PROJECT_ID/container-intro
El resultado debería mostrar una lista de los nombres de las imágenes que enviaste, similar a la siguiente:
NAME us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen
Cree un clúster de GKE
En este punto, puedes ejecutar los contenedores en la VM de Cloud Shell con el comando docker run
. Sin embargo, para ejecutar cargas de trabajo de producción confiables, debes administrar los contenedores de una manera más unificada. Por ejemplo, debes asegurarte de que los contenedores se reinicien si fallan y necesitas una forma de escalar verticalmente e iniciar instancias adicionales de un contenedor para manejar los aumentos de tráfico.
GKE puede ayudarte a satisfacer estas necesidades. GKE es una plataforma de organización de contenedores que funciona mediante la conexión de VMs a un clúster. Cada VM se conoce como un nodo. Los clústeres de GKE funcionan con el sistema de administración de clústeres de código abierto de Kubernetes. Kubernetes proporciona los mecanismos a través de los cuales interactúas con el clúster.
Para ejecutar los contenedores en GKE, primero debes crear un clúster y, luego, conectarte a él:
Crea el clúster:
gcloud container clusters create-auto container-intro
El comando
gcloud
crea un clúster en el proyecto y la región Google Cloud predeterminados que estableciste antes.El comando para crear el clúster toma unos minutos en completarse. Cuando el clúster está listo, el resultado es 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 de
kubectl
para que puedas usarla a fin de administrar el clúster:gcloud container clusters get-credentials container-intro
Examina los manifiestos de Kubernetes
Cuando ejecutaste la aplicación desde el código fuente, usaste un comando imperativo: python3 server.py
“Imperativo” significa basado en un verbo: “haz esto”.
Por el contrario, Kubernetes opera en función de un modelo declarativo. Esto significa que, en lugar de indicarle a Kubernetes qué hacer con exactitud, le proporcionas a Kubernetes el estado deseado. Por ejemplo, Kubernetes inicia y finaliza los Pods según sea necesario para que el estado real del sistema coincida con el estado deseado.
Debes especificar 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 más objetos de Kubernetes.
La muestra contiene un manifiesto para server
y loadgen
. Cada manifiesto especifica el estado deseado para el objeto Deployment de Kubernetes (que administra la ejecución de tu contenedor, empaquetado para la administración como un Pod de Kubernetes) y Service (que proporciona una dirección IP para el Pod). Un Pod es la unidad de procesamiento más pequeña que se puede implementar en Kubernetes y que contiene uno o más contenedores.
En el siguiente diagrama, se muestra la aplicación que se ejecuta en GKE:
Puedes obtener más información sobre los pods, las implementaciones y los servicios en Comienza a aprender sobre Kubernetes o en los recursos que se encuentran al final de esta página.
Servidor
Primero, observa el manifiesto del server
de "Hello World":
Este manifiesto contiene los siguientes campos:
kind
indica el tipo de objeto.metadata.name
especifica el nombre del objeto Deployment.- El primer campo
spec
contiene una descripción del estado deseado. spec.replicas
especifica la cantidad de Pods deseados.- La sección
spec.template
define una plantilla de Pod. En la especificación para los Pods, se incluye el campoimage
, que es el nombre de la imagen que se extraerá de Artifact Registry. En el siguiente paso, actualizarás esta imagen a la nueva 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 cargas de redes, que tiene una dirección IP estable y a la que se puede acceder desde fuera del clúster.targetPort
: Recuerda que el comandoEXPOSE 8080
en elDockerfile
no expone ningún puerto. Debes exponer el puerto8080
para poder acceder al contenedor deserver
fuera del clúster. En este caso,hellosvc.default.cluster.local:80
(nombre corto:hellosvc
) se asigna al puerto8080
de la IP del Podhelloserver
.port
: Este es el número de puerto que usan otros servicios en el clúster cuando envían solicitudes.
Generador de cargas
El objeto Deployment en loadgen.yaml
es similar a server.yaml
. Una diferencia notable es que la especificación de Pod para la Deployment de loadgen
tiene un campo llamado env
. En esta sección, se definen las variables de entorno que requiere loadgen
, que configuraste antes cuando ejecutaste la aplicación desde la fuente.
Debido a que loadgen
no acepta solicitudes entrantes, el campo type
se establece en ClusterIP
. Este tipo de servicio proporciona una dirección IP estable que las entidades del clúster pueden usar, pero la dirección IP no está expuesta a clientes externos.
Implementa los contenedores en GKE
Para implementar los contenedores, aplicas los manifiestos que especifican el estado deseado con kubectl
.
Implementa el server
Cambia al directorio en el que se encuentra el
server
de muestra:cd ~/anthos-service-mesh-samples/docs/helloserver/server/
Abre
server.yaml
en el Editor de Cloud Shell (o tu editor de texto preferido).Reemplaza el nombre en el campo
image
por el nombre de tu imagen de Docker.image: us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1
Reemplaza PROJECT_ID por el ID de tu proyecto de Google Cloud .
- Si usas el editor de Cloud Shell, el archivo se guardará automáticamente. Para volver a la ventana de la terminal, haz clic en Abrir terminal.
- Si usas un editor de texto en Cloud Shell, guarda y cierra
server.yaml
.
Implementa el manifiesto en Kubernetes:
kubectl apply -f server.yaml
El resultado es similar a este:
deployment.apps/helloserver created service/hellosvc created
Implementa el loadgen
Cambia al directorio en el que se encuentra
loadgen
.cd ../loadgen
Abre
loadgen.yaml
en un editor de texto, como antes.Una vez más, reemplaza el nombre en el campo
image
por el nombre de tu imagen de Docker.image: us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen:v0.0.1
Reemplaza PROJECT_ID por el ID de tu proyecto de Google Cloud .
- Si usas el editor de Cloud Shell, el archivo se guardará automáticamente. Para volver a la ventana de la terminal, haz clic en Abrir terminal.
- Si usas un editor de texto en Cloud Shell, guarda y cierra
loadgen.yaml
.
Implementa el manifiesto en tu clúster:
kubectl apply -f loadgen.yaml
Si se ejecuta de forma correcta, el comando responde con lo siguiente:
deployment.apps/loadgenerator created service/loadgensvc created
Verifica tu implementación
Después de implementar tus manifiestos en el clúster, verifica que los contenedores se hayan implementado correctamente:
Verifica el estado de los Pods en 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 desde el Pod
loadgen
. Reemplaza POD_ID por el identificador del Pod del generador de cargas del resultado anterior.kubectl logs POD_ID
Obtén las direcciones IP externas de
hellosvc
:kubectl get service hellosvc
El resultado es similar a este:
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 a
hellosvc
. Reemplaza EXTERNAL_IP por la dirección IP externa de tuhellosvc
.curl http://EXTERNAL_IP
Deberías ver el mensaje “Hello World!” del servidor.
Limpia
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.
Si no quieres borrar todo el proyecto, haz lo siguiente:
Borra el clúster de GKE. Cuando borras el clúster, se borran todos los recursos que lo conforman, como las instancias, los discos y los recursos de red de Compute Engine.
gcloud container clusters delete container-intro
Borra el repositorio de Artifact Registry:
gcloud artifacts repositories delete container-intro --location=us-central1
¿Qué sigue?
Obtén más información sobre las tecnologías que se usan en este instructivo:
Obtén más información sobre las herramientas:
- CLI de gcloud
- Referencia de
gcloud
kubectl
docker
Obtén más información sobre los conceptos de Kubernetes: