Questo tutorial illustra la best practice per spostare la visibilità dei costi di Google Kubernetes Engine (GKE) al team di sviluppo utilizzando GitHub. Essere consapevoli dei costi nelle prime fasi del processo di sviluppo ti aiuta a evitare sorprese nella fattura di Google Cloud. Lo spostamento di un'attività o di informazioni in una parte precedente di un processo a volte è definito spostamento a sinistra.
Questo tutorial è destinato a sviluppatori, operatori e professionisti FinOps che vogliono ottimizzare i costi nei cluster GKE e che utilizzano GitLab in produzione. Se utilizzi GitHub, consulta l'articolo Stimare i costi di GKE nelle prime fasi del ciclo di sviluppo utilizzando GitHub.
Il tutorial presuppone la conoscenza delle seguenti tecnologie:
- Docker
- GitLab
- Kubernetes
- Cloud Build
- GKE
- Linux
Panoramica
Molti team che adottano il cloud pubblico non sono abituati allo stile di fatturazione con pagamento a consumo. Spesso, non comprendono appieno l'ambiente in cui vengono eseguite le loro app, in questo caso GKE. Il modello operativo FinOps promuove la cultura della responsabilità finanziaria. Una best practice di FinOps è fornire ai team informazioni in tempo reale sulle spese, in modo da risolvere eventuali problemi relativi ai costi.
Questo documento mostra come fare un passo in più facendo una stima dei costi prima che diventino spese in fattura. Il momento migliore per stimare i costi è nelle fasi iniziali del processo, sia in fase di sviluppo che di revisione del codice. In questo modo, i professionisti possono comprendere e discutere le alternative per l'impatto sui costi delle nuove funzionalità e delle correzioni di bug prima che diventi un problema. Il seguente diagramma riassume questa pratica.
Come mostra il diagramma, gli sviluppatori possono stimare i costi di GKE nel loro ambiente locale, idealmente in fase di creazione. Questa stima consente loro di avere un'idea chiara del costo mensile del carico di lavoro di produzione. Quando la funzionalità o la correzione del bug è completa, il cliente può proporre una richiesta di unione che attivi una pipeline CI/CD di GitHub per verificare la differenza tra il costo precedente e quello nuovo. In caso di aumenti superiori a una soglia predefinita, la pipeline richiede automaticamente una nuova revisione del codice. Questa pratica aiuta gli sviluppatori a diventare più consapevoli della capacità dei loro carichi di lavoro e a risolvere in modo proattivo i problemi delle applicazioni anziché aggiungere altre risorse ogni volta che si rileva instabilità in produzione.
Obiettivi
- Crea ed esegui il push di un'immagine dello strumento per la stima dei costi di Kubernetes.
- Creare un nuovo progetto GitLab.
- Configura il runner GitLab in modo che venga eseguito su un cluster GKE.
- Esegui il push del codice di esempio nel tuo repository GitLab.
- Modifica il codice e proponi una richiesta di unione per vedere la stima dei costi in azione.
Costi
In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:
Per generare una stima dei costi in base all'utilizzo previsto,
utilizza il Calcolatore prezzi.
Una volta completate le attività descritte in questo documento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la pagina Pulizia.
Prima di iniziare
-
Nella console Google Cloud, vai alla pagina del selettore progetto.
-
Seleziona o crea un progetto Google Cloud.
-
Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.
-
Nella console Google Cloud, attiva Cloud Shell.
Nella parte inferiore della console Google Cloud viene avviata una sessione di Cloud Shell che mostra un prompt della riga di comando. Cloud Shell è un ambiente shell con Google Cloud CLI già installato e con valori già impostati per il progetto attuale. L'inizializzazione della sessione può richiedere alcuni secondi.
prepara l'ambiente
In Cloud Shell, clona il repository GitHub di
gke-shift-left-cost
:git clone https://github.com/GoogleCloudPlatform/gke-shift-left-cost cd gke-shift-left-cost
Il codice in questo repository è strutturato nelle seguenti cartelle:
- Root: contiene un file Dockerfile utilizzato per creare l'immagine dello strumento per la stima dei costi e il file
main.go
che implementa la logica a riga di comando per lo strumento per la stima dei costi. api/
: contiene l'API Go per manipolare gli oggetti Kubernetes e effettuare una stima dei costi.samples/
: contiene esempi di manifest Kubernetes per consentirti di sperimentare il processo prima di implementarlo nella tua organizzazione.
- Root: contiene un file Dockerfile utilizzato per creare l'immagine dello strumento per la stima dei costi e il file
Imposta l'ID progetto Google Cloud, l'account utente e l'indirizzo email GitLab:
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
Sostituisci quanto segue:
YOUR_PROJECT_ID
: l'ID del progetto Google Cloud che stai utilizzando in questo tutorial.YOUR_GITLAB_USER
: l'account utente che utilizzi per accedere al tuo account GitLab.YOUR_GITLAB_EMAIL_ADDRESS
: l'email che utilizzi nel tuo account GitLab.
Facoltativamente, puoi utilizzare una regione e una zona diverse per questo tutorial.
Crea ed esegui il push dell'immagine dello strumento di stima dei costi di Kubernetes
Lo strumento per la stima dei costi di Kubernetes fornito in questo tutorial è un esempio di cosa si può fare. Offre la possibilità di stimare i costi per gli oggetti DaemonSet, Deployment, StatefulSet, ReplicaSet, HorizontalPodAutoScaler e PersistentVolumeClaim Kubernetes. Puoi anche implementare il tuo strumento di stima dei costi o proporre richieste pull con i miglioramenti che preferisci.
In Cloud Shell, consenti a
application-default
di utilizzare le tue credenziali:gcloud auth application-default login
Crea il programma binario dello strumento per la stima dei costi di Kubernetes:
mkdir ./bin go test ./api go build -v -o ./bin/k8s-cost-estimator .
Testa il programma binario eseguendo una stima dei costi in una cartella di esempio:
./bin/k8s-cost-estimator \ --k8s ./samples/k8s-cost-estimator-local/app-v1 \ --config ./samples/k8s-cost-estimator-local/example-conf.yaml \ --v trace
Nell'output, vedi una tabella Markdown che descrive in dettaglio i costi mensili stimati per la cartella
./samples/k8s-cost-estimator-local/app-v1/
. Per comprendere meglio il costo mensile di produzione delle loro applicazioni, gli sviluppatori possono eseguire questo passaggio prima di eseguire il push del codice nel repository 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!
Crea l'immagine del container dello strumento per la stima dei costi di Kubernetes:
docker build . -t \ us-central1-docker.pkg.dev/$GCP_PROJECT_ID/docker-repo/k8s-cost-estimator:v0.0.1
Crea il repository Docker Artifact Registry per archiviare l'immagine:
gcloud artifacts repositories create docker-repo \ --repository-format=docker \ --location=us-central1 \ --description="Docker repository"
Registra
gcloud
come helper delle credenziali per il file di configurazione Docker.gcloud auth configure-docker us-central1-docker.pkg.dev
Se richiesto, conferma l'aggiornamento del file.
Esegui il push dell'immagine in Artifact Registry:
docker push us-central1-docker.pkg.dev/$GCP_PROJECT_ID/docker-repo/k8s-cost-estimator:v0.0.1
Crea un nuovo progetto GitLab
In Cloud Shell, cambia la directory sull'esempio GitLab:
cd samples/k8s-cost-estimator-gitlab
Nella pagina Token di accesso personale di GitLab, crea un token di accesso:
Vai alla pagina dei token di accesso personale di GitLab
- Nel campo Nome, inserisci il nome del token che stai creando.
- Nel campo Ambito, seleziona api e fai clic su Crea token di accesso personale.
- Copia il valore in Il tuo nuovo token di accesso personale.
In Cloud Shell, salva il token di accesso personale in una variabile:
GITLAB_API_TOKEN=YOUR_NEW_PERSONAL_ACCESS_TOKEN
Sostituisci
YOUR_NEW_PERSONAL_ACCESS_TOKEN
con il token di accesso personale GitHub che hai creato.Crea un nuovo progetto GitLab:
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")
Imposta le variabili da utilizzare per lo strumento per la stima dei costi quando viene creata una richiesta di unione:
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 che il progetto e le variabili siano stati creati:
curl -s --header "PRIVATE-TOKEN:$GITLAB_API_TOKEN" \ https://gitlab.com/api/v4/projects/$GITLAB_PROJECT_ID/variables | jq
L'output è simile al seguente:
[ { "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": "*" } ]
Le variabili configurate nel progetto GitLab vengono utilizzate dal file
./samples/k8s-cost-estimator-gitlab/templates/.gitlab-ci.yml.tpl
per aggiornare le richieste di unione e sono le seguenti:GITLAB_API_TOKEN
: il tuo token di accesso personale GitLab.GITLAB_FINOPS_REVIEWER_ID
: il revisore del codice richiesto ogni volta che il costo supera una determinata soglia. Per semplicità, questo tutorial imposta il tuo ID utente come revisore. Tuttavia, in un ambiente di produzione, ti consigliamo di configurare un team anziché una singola persona.GITLAB_FINOPS_COST_USD_THRESHOLD
: la soglia in USD, in questo caso 10 $. Quando la differenza tra i costi precedenti e quelli nuovi supera questa soglia, viene applicata un'approvazione straordinaria. Puoi anche impostare soglie per altri valori. Per esplorare questa funzionalità, puoi aggiungere il parametro--output
quando esegui il comando./bin/k8s-cost-estimator
in Creazione ed esecuzione dell'immagine dello strumento per la stima dei costi di Kubernetes. Questo parametro genera un file con un'estensione.diff
che consente di visualizzare le opzioni disponibili.
Configura il runner GitLab per l'esecuzione su un cluster GKE
In questa sezione installerai il runner GitLab nel tuo cluster GKE con Workload Identity per consentire allo strumento per la stima di Kubernetes di eseguire query sul Catalogo prezzi di Google Cloud. Lo strumento per la stima utilizza prezzi lordi e non tiene conto delle VM prerilasciabili o di eventuali sconti.
In Cloud Shell, crea un cluster 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
Recupera il token di registrazione del runner GitLab dal progetto che hai creato:
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"
Installa il runner GitLab nel tuo cluster 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
Disabilita i runner condivisi nel tuo progetto 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 che il runner di cui hai eseguito il deployment sia abilitato nel tuo progetto 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)'
L'output è simile al seguente:
{ "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" }
Esegui il push del codice di esempio al tuo repository GitLab
Crea una coppia di chiavi SSH per eseguire il push del codice campione nel tuo repository 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 ..
Esegui il push dei contenuti nel nuovo repository GitLab:
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 config --global user.email $GITLAB_EMAIL git config --global user.name $GITLAB_USER 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
Modifica il codice e proponi una richiesta di unione per vedere la stima dei costi in azione
In Cloud Shell, recupera l'URL dell'ambiente di sviluppo integrato web (IDE) GitHub:
echo "https://gitlab.com/-/ide/project/$GITLAB_USER/k8s-cost-estimator-gitlab/tree/main/-/wordpress/wordpress_hpa.yaml"
Ctrl + fai clic (Cmd + fai clic su macOS) sull'URL di output per accedere all'IDE web GitLab.
Nell'IDE web GitLab, modifica il file
./wordpress/wordpress_hpa.yaml
come segue:- Modifica il valore di
minReplicas
da2
a5
. - Fai clic su Esegui il commit.
- Modifica il valore di
Come mostrato nello screenshot seguente, seleziona Crea un nuovo ramo e Avvia una nuova richiesta di unione, quindi fai clic su Esegui il commit.
Nella schermata Nuova richiesta di unione, fai clic su Crea richiesta di unione nella parte inferiore della pagina.
Oltre a creare una nuova richiesta di unione, questo passaggio attiva una pipeline di stima dei costi basata sul file
.gitlab-ci.yml
. Questa pipeline utilizza l'immagine container che hai creato in una sezione precedente. Questa pipeline determina anche quando è richiesta l'approvazione di FinOps. Per semplicità,.gitlab-ci.yml
aggiunge approvazioni per ogni base di richieste di unione, ma puoi definire e riutilizzare le regole di approvazione definite a livello di progetto GitLab.Attendi circa un minuto per il completamento della pipeline. Al termine, nella richiesta di unione viene aggiunto un commento con i dettagli dei costi. Poiché l'aumento del costo del codice che proponi supera la soglia di $10, viene richiesto anche un revisore di FinOps.
L'output è simile al seguente:
In questo tutorial viene utilizzata la configurazione predefinita per le approvazioni delle richieste di unione. È possibile selezionare configurazioni diverse per le richieste di unione in Gitlab. Ad esempio, per impedire all'autore di approvare le richieste di unione, vai a Impostazioni > Generali > Approvazioni richieste di unione (MR) > Impostazioni di approvazione.
Esegui la pulizia
Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, puoi eliminare il tuo progetto.
Elimina il progetto
- Nella console Google Cloud, vai alla pagina Gestisci risorse.
- Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
- Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.
Elimina il progetto GitLab
Se non vuoi conservare il progetto GitLab, segui questi passaggi:
In Cloud Shell, elimina il tuo progetto GitLab:
curl -X DELETE -H "content-type:application/json" -H "PRIVATE-TOKEN:$GITLAB_API_TOKEN" https://gitlab.com/api/v4/projects/$GITLAB_PROJECT_ID ``` The output is similar to the following: ```none {:.devsite-disable-click-to-copy} {"message":"202 Accepted"}
Se perdi la connessione con Cloud Shell, devi impostare di nuovo le seguenti variabili:
GITLAB_API_TOKEN
GITLAB_PROJECT_ID
Passaggi successivi
- Scopri di più sull'ottimizzazione dei costi di GKE, consulta le best practice per l'esecuzione di applicazioni Kubernetes con ottimizzazione dei costi su GKE.
- Scopri come stimare i costi di GKE nelle prime fasi del ciclo di sviluppo utilizzando GitHub.
- Trova suggerimenti e best practice di progettazione per ottimizzare il costo dei carichi di lavoro Google Cloud in Framework dell'architettura Google Cloud: ottimizzazione dei costi.
- Esplora le architetture di riferimento, i diagrammi e le best practice su Google Cloud. Visita il nostro Cloud Architecture Center.