En este instructivo se muestra la práctica recomendada para cambiar la visibilidad de costos de Google Kubernetes Engine (GKE) a tu equipo de desarrollo mediante GitLab. Crear conocimiento de los costos al comienzo del proceso de desarrollo te ayuda a evitar sorpresas en tu factura de Google Cloud. Trasladar una tarea o información a una parte anterior de un proceso se conoce como desplazamiento a la izquierda.
Este instructivo está dirigido a desarrolladores, operadores y profesionales de FinOps que deseen optimizar los costos de los clústeres de GKE y que usen GitLab en producción. En cambio, si usas GitHub, consulta Calcula tus costos de GKE al principio del ciclo de desarrollo mediante GitHub.
En este instructivo, suponemos que estás familiarizado con las siguientes tecnologías:
- Docker
- GitLab
- Kubernetes
- GKE
- Cloud Build
- Linux
Descripción general
Muchos equipos que adoptan la nube pública no están acostumbrados al estilo de facturación prepago. Por lo general, no comprenden por completo el entorno en el que se ejecutan las apps, en este caso, GKE. El modelo operativo de FinOps fomenta la cultura de responsabilidad financiera. Una práctica recomendada de FinOps es proporcionar a los equipos información en tiempo real sobre sus gastos para que los problemas de costos se puedan abordar cuando se presenten.
En este documento, se muestra cómo ir un paso más allá mediante la estimación de costos antes de que se convierta en un gasto en tu factura. Como se destaca en el sitio web de GitLab, “La revisión de código es una práctica esencial en todos los proyectos exitosos, y darle la aprobación cuando una solicitud de combinación esté en buen estado es una parte importante del “proceso de revisión”. El mejor momento para estimar los costos es al comienzo del proceso durante el desarrollo y en el momento de la revisión de código. De esta manera, los profesionales pueden comprender y analizar alternativas para el costo de las nuevas funciones y correcciones de errores antes de que se conviertan en un problema. En el siguiente diagrama, se resume esta práctica.
Como se muestra en el diagrama, los desarrolladores pueden estimar los costos de GKE en su entorno local, lo ideal sería en el tiempo de compilación. Esta estimación les brinda una buena comprensión del costo de la carga de trabajo de producción mensual. Cuando la función o la corrección de errores está completa, se puede proponer una solicitud de combinación que activa una canalización de CI/CD de GitLab. para comprobar la diferencia entre el costo anterior y el nuevo. Si hay aumentos superiores a un límite predefinido, la canalización solicita de forma automática una revisión de código nueva. Esta práctica ayuda a los desarrolladores a conocer más su capacidad de carga de trabajo y solucionar de forma proactiva los problemas de la aplicación en lugar de agregar más recursos cada vez que se encuentra una inestabilidad en producción.
Objetivos
- Compilar y enviar la imagen del estimador de costos de Kubernetes
- Crear un proyecto nuevo de GitLab
- Configurar el ejecutor de GitLab para que se ejecute en un clúster de GKE
- Enviar el código de ejemplo a tu repositorio de GitHub.
- Cambiar el código y propón una solicitud de extracción para ver la estimación de costos en acción.
Costos
En este documento, usarás los siguientes componentes facturables de Google Cloud:
Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.
Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.
Antes de comenzar
-
En la consola de Google Cloud, ve a la página del selector de proyectos.
-
Selecciona o crea un proyecto de Google Cloud.
-
Comprueba que la facturación esté habilitada en tu proyecto.
-
En la consola de Google Cloud, activa Cloud Shell.
En la parte inferior de la consola de Google Cloud, se inicia una sesión de Cloud Shell en la que se muestra una ventana de línea de comandos. Cloud Shell es un entorno de shell con Google Cloud CLI ya instalada y con valores ya establecidos para el proyecto actual. La sesión puede tardar unos segundos en inicializarse.
Prepara tu entorno
En Cloud Shell, clona el repositorio
gke-shift-left-cost
de GitHub.git clone https://github.com/GoogleCloudPlatform/gke-shift-left-cost cd gke-shift-left-cost
El código de este repositorio se organiza en las siguientes carpetas:
- Raíz: contiene un archivo Dockerfile que se usa para compilar la imagen del estimador de costos y el archivo
main.go
que implementa la lógica de la línea de comandos del estimador de costos. api/
: contiene la API de Go para manipular los objetos de Kubernetes y realizar la estimación de costos.samples/
: contiene ejemplos de manifiestos de Kubernetes para que puedas experimentar con el proceso antes de implementarlo en tu organización.
- Raíz: contiene un archivo Dockerfile que se usa para compilar la imagen del estimador de costos y el archivo
Configura el ID del proyecto de Cloud, la cuenta de usuario de GitLab y la dirección de correo electrónico:
export GCP_PROJECT_ID=YOUR_PROJECT_ID export GITLAB_USER=YOUR_GITLAB_USER export GITLAB_EMAIL=YOUR_GITLAB_EMAIL_ADDRESS gcloud config set project $GCP_PROJECT_ID gcloud services enable cloudbilling.googleapis.com \ compute.googleapis.com \ container.googleapis.com \ iamcredentials.googleapis.com \ artifactregistry.googleapis.com gcloud config set compute/region us-central1 gcloud config set compute/zone us-central1-f
Reemplaza lo siguiente:
YOUR_PROJECT_ID
: Es el ID del proyecto de Cloud para el proyecto que usas en este instructivo.YOUR_GITLAB_USER
: Es la cuenta de usuario que usas para acceder a tu cuenta de GitLab.YOUR_GITLAB_EMAIL_ADDRESS
: Es el correo electrónico que usas en tu cuenta de GitHub.
De forma opcional, puedes usar una región y una zona diferentes para este instructivo.
Compila y envía la imagen del estimador de costos de Kubernetes
La herramienta de estimación de costos de Kubernetes que se incluye en este instructivo es solo un ejemplo de lo que se puede hacer. Ofrece la capacidad de estimar el costo de los objetos de Kubernetes de DaemonSet, Deployment, StatefulSet, ReplicaSet, HorizontalPodAutoScaler y PersistentVolumeClaim. También puedes implementar tu propia herramienta de estimación de costos o proponer solicitudes de extracción con las mejoras que desees.
En Cloud Shell, permite que
application-default
use tus credenciales:gcloud auth application-default login
Compila el objeto binario del estimador de costos de Kubernetes:
mkdir ./bin go test ./api go build -v -o ./bin/k8s-cost-estimator .
Prueba el objeto binario mediante la ejecución de la estimación de costos en una carpeta de muestra:
./bin/k8s-cost-estimator \ --k8s ./samples/k8s-cost-estimator-local/app-v1 \ --config ./samples/k8s-cost-estimator-local/example-conf.yaml \ --v trace
En el resultado, verás una tabla de Markdown que detalla los costos mensuales estimados de la carpeta
./samples/k8s-cost-estimator-local/app-v1/
. Para comprender mejor el costo de producción mensual de sus aplicaciones, los desarrolladores pueden ejecutar este paso antes de enviar el código al repositorio remoto.INFO[0000] Starting cost estimation (version v0.0.1)... ... | KIND | MIN REQUESTED (USD) | MIN REQ + HPA CPU BUFFER (USD) | MAX REQUESTED (USD) | MIN LIMITED (USD) | MAX LIMITED (USD) | |-----------------------|---------------------|--------------------------------|---------------------|-------------------|-------------------| | Deployment | $133.31 | $198.71 | $266.54 | $312.83 | $579.29 | | StatefulSet | $36.33 | $36.33 | $36.33 | $72.67 | $72.67 | | DaemonSet | $29.68 | $29.68 | $29.68 | $53.19 | $53.19 | | PersistentVolumeClaim | $28.88 | $28.88 | $28.88 | $33.68 | $33.68 | | **TOTAL** | **$228.20** | **$293.60** | **$361.43** | **$472.38** | **$738.83** | INFO[0002] Finished cost estimation!
Compila la imagen de contenedor del estimador de costos de Kubernetes:
docker build . -t \ us-central1-docker.pkg.dev/$GCP_PROJECT_ID/docker-repo/k8s-cost-estimator:v0.0.1
Crea el repositorio de Docker de Artifact Registry para almacenar la imagen:
gcloud artifacts repositories create docker-repo \ --repository-format=docker \ --location=us-central1 \ --description="Docker repository"
Registra
gcloud
como auxiliar de credenciales para el archivo de configuración de Docker.gcloud auth configure-docker us-central1-docker.pkg.dev
Si se te solicita, confirma la actualización del archivo.
Envía la imagen a Artifact Registry:
docker push us-central1-docker.pkg.dev/$GCP_PROJECT_ID/docker-repo/k8s-cost-estimator:v0.0.1
Crea un proyecto de GitLab nuevo
En Cloud Shell, cambia el directorio al ejemplo de GitLab:
cd samples/k8s-cost-estimator-gitlab
En la página Tokens de acceso personal de GitLab, crea un token de acceso:
Navega a la página Personal access tokens de GitHub.
- En el campo Nombre, ingresa el nombre del token que crearás.
- En el campo Alcance, selecciona API y, luego, haz clic en Crear token de acceso personal.
- Copia el valor de Tu nuevo token de acceso personal.
En Cloud Shell, guarda el token de acceso personal en una variable:
GITLAB_API_TOKEN=YOUR_NEW_PERSONAL_ACCESS_TOKEN
Reemplaza lo siguiente:
YOUR_NEW_PERSONAL_ACCESS_TOKEN
: Es el token de acceso personal de GitHub que creaste.
Crea un proyecto de GitLab nuevo:
GITLAB_PROJECT_OUTPUT=$(curl -X POST -H "content-type:application/json" -H "PRIVATE-TOKEN:$GITLAB_API_TOKEN" -d '{"name":"k8s-cost-estimator-gitlab","visibility":"public"}' https://gitlab.com/api/v4/projects) GITLAB_PROJECT_ID=$(echo $GITLAB_PROJECT_OUTPUT | jq ".id") GITLAB_FINOPS_REVIEWER_ID=$(echo $GITLAB_PROJECT_OUTPUT | jq ".owner.id")
Configura las variables que se usarán en la herramienta de estimador de costos cuando se cree una solicitud de combinación:
curl -X POST -H "content-type:application/json" -H "PRIVATE-TOKEN:$GITLAB_API_TOKEN" -d "{\"key\": \"GITLAB_API_TOKEN\",\"value\": \"$GITLAB_API_TOKEN\", \"masked\":\"true\"}" https://gitlab.com/api/v4/projects/$GITLAB_PROJECT_ID/variables curl -X POST -H "content-type:application/json" -H "PRIVATE-TOKEN:$GITLAB_API_TOKEN" -d "{\"key\": \"GITLAB_FINOPS_REVIEWER_ID\",\"value\": \"$GITLAB_FINOPS_REVIEWER_ID\"}" https://gitlab.com/api/v4/projects/$GITLAB_PROJECT_ID/variables curl -X POST -H "content-type:application/json" -H "PRIVATE-TOKEN:$GITLAB_API_TOKEN" -d "{\"key\": \"GITLAB_FINOPS_COST_USD_THRESHOLD\",\"value\": \"10\"}" https://gitlab.com/api/v4/projects/$GITLAB_PROJECT_ID/variables
Verifica que se hayan creado el proyecto y las variables:
curl -s --header "PRIVATE-TOKEN:$GITLAB_API_TOKEN" \ https://gitlab.com/api/v4/projects/$GITLAB_PROJECT_ID/variables | jq
El resultado se parece al siguiente:
[ { "variable_type": "env_var", "key": "GITLAB_API_TOKEN", "value": "Ex...n1", "protected": false, "masked": true, "environment_scope": "*" }, { "variable_type": "env_var", "key": "GITLAB_FINOPS_REVIEWER_ID", "value": "88..87", "protected": false, "masked": false, "environment_scope": "*" }, { "variable_type": "env_var", "key": "GITLAB_FINOPS_COST_USD_THRESHOLD", "value": "10", "protected": false, "masked": false, "environment_scope": "*" } ]
El archivo
./samples/k8s-cost-estimator-gitlab/templates/.gitlab-ci.yml.tpl
usa las variables configuradas en el proyecto de GitLab para actualizar las solicitudes de combinación y son las siguientes:GITLAB_API_TOKEN
: Tu token de acceso personal de GitLab.GITLAB_FINOPS_REVIEWER_ID
: El revisor de código requerido cada vez que el costo aumenta por encima de un límite determinado. Para simplificar, en este instructivo se establece tu propio ID de usuario como revisor. Sin embargo, en un entorno de producción, recomendamos que configures un equipo en lugar de una persona individual.GITLAB_FINOPS_COST_USD_THRESHOLD
: el límite en USD, en este caso, $10. Cuando la diferencia entre los costos antiguos y los nuevos supera este umbral, se aplica una aprobación extraordinaria. También puedes establecer umbrales para otros valores. Para explorar esta función, puedes agregar el parámetro--output
cuando ejecutes el comando./bin/k8s-cost-estimator
en Compila y envía la imagen del estimador de costos de Kubernetes. Este parámetro genera un archivo con una extensión.diff
que te permite ver las opciones disponibles.
Configura el ejecutor de GitLab para que se ejecute en un clúster de GKE
En esta sección, instalarás el ejecutor de GitLab en tu propio clúster de GKE con Workload Identity para permitir que la herramienta de estimador de Kubernetes consulte el catálogo de precios de Google Cloud. El estimador usa precios brutos y no tiene en cuenta las VM interrumpibles ni los descuentos.
En Cloud Shell, crea un clúster de GKE:
gcloud beta container clusters create gitlab-runners \ --enable-ip-alias \ --release-channel=stable \ --workload-pool=$GCP_PROJECT_ID.svc.id.goog \ --enable-autoprovisioning --min-cpu 1 --min-memory 1 --max-cpu 4 --max-memory 16 \ --autoscaling-profile=optimize-utilization \ --preemptible
Obtén el token de registro del ejecutor de GitLab del proyecto que creaste:
export GITLAB_RUNNER_TOKEN=$(curl -s --header "PRIVATE-TOKEN:$GITLAB_API_TOKEN" https://gitlab.com/api/v4/projects/$GITLAB_PROJECT_ID | jq -r '.runners_token') [ -z "$GITLAB_RUNNER_TOKEN" ] && echo "GITLAB_RUNNER_TOKEN is not exported" || echo "GITLAB_RUNNER_TOKEN is $GITLAB_RUNNER_TOKEN"
Instala el ejecutor de GitLab en tu clúster de GKE:
kubectl create namespace gitlab helm repo add gitlab https://charts.gitlab.io sed "s/GCP_PROJECT_ID/$GCP_PROJECT_ID/g; s/GITLAB_RUNNER_TOKEN/$GITLAB_RUNNER_TOKEN/g" templates/gitlab-runner-values.yaml.tpl > gitlab-runner-values.yaml helm install --namespace gitlab --version 0.24.0 gitlab-runner -f gitlab-runner-values.yaml gitlab/gitlab-runner kubectl -n gitlab wait --for=condition=available deployment gitlab-runner --timeout=5m gcloud iam service-accounts create gitlab-runner --display-name=gitlab-runner gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:$GCP_PROJECT_ID.svc.id.goog[gitlab/gitlab-runner]" \ gitlab-runner@$GCP_PROJECT_ID.iam.gserviceaccount.com
Inhabilita los ejecutores compartidos en tu proyecto de GitLab:
curl -s --header "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" -X PUT "https://gitlab.com/api/v4/projects/$GITLAB_PROJECT_ID" --form "shared_runners_enabled=false"
Verifica que el ejecutor que implementaste esté habilitado en tu proyecto de GitLab:
curl -s --header "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" "https://gitlab.com/api/v4/projects/$GITLAB_PROJECT_ID/runners?status=active" | jq '.[] | select(.is_shared==false)'
El resultado se parece al siguiente:
{ "id": 49345561, "description": "gitlab-runner-gitlab-runner-788459d488-jlscn", "ip_address": "35.178.223.199", "active": true, "is_shared": false, "name": "gitlab-runner", "online": true, "status": "online" }
Envía el código de ejemplo a tu repositorio de GitHub
Crea un par de claves SSH para enviar el código de muestra a tu repositorio de GitLab:
mkdir -p ssh && cd ssh ssh-keygen -t rsa -b 4096 -N '' -f gitlab-key eval `ssh-agent` && ssh-add $(pwd)/gitlab-key curl -s --request POST --header "PRIVATE-TOKEN:$GITLAB_API_TOKEN" https://gitlab.com/api/v4/user/keys --form "title=k8s-cost-estimator-key" --form "key=$(cat gitlab-key.pub)" cd ..
Envía el contenido a tu repositorio de GitLab nuevo.
sed "s/GCP_PROJECT_ID/$GCP_PROJECT_ID/g; s/GITLAB_USER/$GITLAB_USER/g; s/GITLAB_EMAIL/$GITLAB_EMAIL/g;" templates/.gitlab-ci.yml.tpl > .gitlab-ci.yml GITLAB_SSH_URL_REPO=$(curl -s --header "PRIVATE-TOKEN:$GITLAB_API_TOKEN" https://gitlab.com/api/v4/users/$GITLAB_FINOPS_REVIEWER_ID/projects | jq '.[] | select(.name=="k8s-cost-estimator-gitlab")' | jq -r '.ssh_url_to_repo') [ -z "$GITLAB_SSH_URL_REPO" ] && echo "GITLAB_PROJECT_SSH_URL is not exported" || echo "GITLAB_PROJECT_SSH_URL is $GITLAB_SSH_URL_REPO" git init git remote add origin $GITLAB_SSH_URL_REPO git add -A . git commit -m "Initial commit" git checkout -b main git push -u origin main
Cambia el código y propone una solicitud de combinación para ver la estimación de costos en acción
En Cloud Shell, obtén la URL del entorno de desarrollo integrado (IDE) de GitLab:
echo "https://gitlab.com/-/ide/project/$GITLAB_USER/k8s-cost-estimator-gitlab/tree/main/-/wordpress/wordpress_hpa.yaml"
Ctrl + clic (Cmd + clic en macOS) en la URL de salida para navegar al IDE web de GitLab.
En el IDE web de GitLab, edita el archivo
./wordpress/wordpress_hpa.yaml
de la siguiente manera:- Cambia el valor
minReplicas
de2
a5
. - Haz clic en Confirmar.
- Cambia el valor
Como se muestra en la siguiente captura de pantalla, selecciona Create a new branch y Start a new merge request. Luego, haz clic en Commit.
En la pantalla Nueva solicitud de combinación, haz clic en Crear solicitud de combinación en la parte inferior de la página.
Además de crear una nueva solicitud de combinación, este paso activa una canalización de estimación de costos en función del archivo
.gitlab-ci.yml
. Esta canalización usa la imagen de contenedor que creaste en una sección anterior. Esta canalización también determina cuándo se requiere una aprobación de FinOps. Para simplificar,.gitlab-ci.yml
agrega aprobaciones para cada base de solicitud de combinación, pero puedes definir y reutilizar reglas de aprobación definidas a nivel de proyecto de GitLab.Espera un minuto para que finalice la canalización. Cuando termine, se agregará un comentario con los detalles de los costos a la solicitud de combinación. Debido a que el aumento del costo del código que propones supera el límite de $10, también se solicita un revisor de FinOps.
El resultado se parece al siguiente:
En este instructivo, se usa la configuración predeterminada para las aprobaciones de solicitudes de combinación. Es posible seleccionar diferentes parámetros de configuración para tus solicitudes de combinación en Gitlab. Por ejemplo, para evitar que el autor apruebe solicitudes de combinación, ve a Configuración > General > Aprobaciones de solicitud de combinación (MR) > Configuración de aprobación.
Limpia
Puedes borrar tu proyecto para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo.
Borra el proyecto
- En la consola de Google Cloud, ve a la página Administrar recursos.
- En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
- En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.
Borra el proyecto de GitLab
Si no deseas conservar tu proyecto de GitLab, haz lo siguiente:
En Cloud Shell, borra tu proyecto de GitLab:
curl -X DELETE -H "content-type:application/json" -H "PRIVATE-TOKEN:$GITLAB_API_TOKEN" https://gitlab.com/api/v4/projects/$GITLAB_PROJECT_ID
El resultado se parece al siguiente:
{"message":"202 Accepted"}
Si pierdes la conexión con Cloud Shell, debes volver a configurar las siguientes variables:
GITLAB_API_TOKEN
GITLAB_PROJECT_ID
¿Qué sigue?
- Obtén más información sobre la optimización de costos en GKE en Prácticas recomendadas para la ejecución de aplicaciones de Kubernetes con optimización de costos en GKE.
- Obtén información a fin de supervisar tu clúster de GKE y tus aplicaciones en Supervisa tus clústeres de GKE para optimizar costos mediante Cloud Monitoring.
- Lee sobre cómo estimar los costos de GKE al principio del ciclo de desarrollo con GitHub.
- Encuentra más sugerencias y prácticas recomendadas a fin de optimizar costos de GKE en Optimización de costos en Google Cloud para desarrolladores y operadores.
- Explora arquitecturas de referencia, diagramas, instructivos y prácticas recomendadas sobre Google Cloud. Consulta nuestro Cloud Architecture Center.