Questo tutorial mostra come personalizzare i nodi di un cluster Google Kubernetes Engine (GKE) utilizzando DaemonSets. Un DaemonSet garantisce che tutti i nodi (o quelli selezionati) eseguano una copia di un pod. Questo approccio ti consente di utilizzare gli stessi strumenti per orchestrare i carichi di lavoro che utilizzi per modificare i nodi GKE.
Se gli strumenti e i sistemi che utilizzi per inizializzare i cluster sono diversi da quelli che utilizzi per eseguire i workload, aumenti l'impegno necessario per gestire l'ambiente. Ad esempio, se utilizzi uno strumento di gestione della configurazione per inizializzare i nodi del cluster, ti affidi a una procedura esterna all'ambiente di runtime in cui vengono eseguiti gli altri workload.
Lo scopo di questo tutorial è aiutare gli amministratori di sistema, gli ingegneri di sistema o gli operatori dell'infrastruttura a semplificare l'inizializzazione dei cluster Kubernetes.
Prima di leggere questa pagina, assicurati di avere familiarità con:
In questo tutorial imparerai a utilizzare
etichette e selettori Kubernetes
per scegliere la procedura di inizializzazione da eseguire in base alle etichette applicate a un nodo. In questi passaggi, implementi un DaemonSet da eseguire solo sui nodi
a cui è stata applicata l'etichetta default-init
. Tuttavia, per dimostrare la
flessibilità di questo meccanismo, potresti creare un altropool di nodil e applicare l'etichetta
alternative-init
ai nodi di questo nuovo pool. Nel cluster, puoi quindi eseguire il deployment di un altro DaemonSet configurato per essere eseguito solo sui nodi con l'etichetta alternative-init
.
Inoltre, puoi eseguire più procedure di inizializzazione su ogni nodo, non solo una. Puoi sfruttare questo meccanismo per strutturare meglio le procedure di inizializzazione, separando chiaramente le preoccupazioni di ciascuna.
In questo tutorial, a titolo di esempio, la procedura di inizializzazione esegue le
seguenti azioni su ogni nodo etichettato con l'etichetta default-init
:
- Collega un disco aggiuntivo al nodo.
- Installa un insieme di pacchetti e librerie utilizzando il gestore di pacchetti del sistema operativo del nodo.
- Carica un insieme di moduli kernel Linux.
Esegui il bootstrap dell'ambiente
In questa sezione, imparerai a:
- Abilita le API Cloud necessarie.
- Esegui il provisioning di un service account con privilegi limitati per i nodi nel cluster GKE.
- Prepara il cluster GKE.
- Concedi all'utente i privilegi di amministrazione del cluster.
Abilita Cloud APIs
Apri Cloud Shell.
Seleziona il progetto Google Cloud :
gcloud config set project project-id
Sostituisci
project-id
con l'ID del progettoGoogle Cloud che hai creato o selezionato per questo tutorial.Attiva l'API Google Kubernetes Engine:
gcloud services enable container.googleapis.com
Provisiona un account di servizio per gestire i cluster GKE
In questa sezione crei un service account associato ai nodi del cluster. In questo tutorial, i nodi GKE utilizzano questo account di servizio anziché quello predefinito. Come best practice, concedi al account di servizio solo i ruoli e le autorizzazioni di accesso necessari per eseguire l'applicazione.
I ruoli richiesti per il account di servizio sono i seguenti:
- Ruolo Visualizzatore Monitoring (
roles/monitoring.viewer
). Questo ruolo concede accesso di sola lettura alla console e all'API Cloud Monitoring. - Ruolo Monitoring Metric Writer (
roles/monitoring.metricWriter
). Questo ruolo consente di scrivere dati di monitoraggio. - Ruolo Writer log (
roles/logging.logWriter
). Questo ruolo concede autorizzazioni sufficienti per scrivere i log. - Ruolo Utente service account (
roles/iam.serviceAccountUser
). Questo ruolo consente di accedere ai service account in un progetto. In questo tutorial, la procedura di inizializzazione simula l'identità delaccount di serviziot per eseguire operazioni con privilegi. - Ruolo Amministratore Compute (
roles/compute.admin
). Questo ruolo fornisce il controllo completo di tutte le risorse Compute Engine. In questo tutorial, il service account ha bisogno di questo ruolo per collegare dischi aggiuntivi ai nodi del cluster.
Per eseguire il provisioning di un account di servizio:
In Cloud Shell, inizializza una variabile di ambiente che memorizza il nome delaccount di serviziot:
GKE_SERVICE_ACCOUNT_NAME=ds-init-tutorial-gke
Crea un account di servizio:
gcloud iam service-accounts create "$GKE_SERVICE_ACCOUNT_NAME" \ --display-name="$GKE_SERVICE_ACCOUNT_NAME"
Inizializza una variabile di ambiente che memorizza il nome dell'account email del account di servizio:
GKE_SERVICE_ACCOUNT_EMAIL="$(gcloud iam service-accounts list \ --format='value(email)' \ --filter=displayName:"$GKE_SERVICE_ACCOUNT_NAME")"
Associa i ruoli Identity and Access Management (IAM) al account di servizio:
gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/compute.admin gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/monitoring.viewer gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/monitoring.metricWriter gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/logging.logWriter gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/iam.serviceAccountUser
Prepara il cluster GKE
In questa sezione avvii il cluster GKE, concedi le autorizzazioni e completi la configurazione del cluster.
Per questo tutorial, un cluster con un numero relativamente basso di nodi piccoli
di uso generale
è sufficiente per dimostrare il concetto. Crea un cluster con un node pool (quello predefinito). Poi etichetti tutti i nodi nel pool di nodi predefinito con l'etichetta default-init
.
In Cloud Shell, crea e avvia un cluster GKE regionale:
gcloud container clusters create ds-init-tutorial \ --enable-ip-alias \ --image-type=ubuntu_containerd \ --machine-type=n1-standard-2 \ --metadata disable-legacy-endpoints=true \ --node-labels=app=default-init \ --node-locations us-central1-a,us-central1-b,us-central1-c \ --no-enable-basic-auth \ --no-issue-client-certificate \ --num-nodes=1 \ --location us-central1 \ --service-account="$GKE_SERVICE_ACCOUNT_EMAIL"
Esegui il deployment del DaemonSet
In questa sezione, imparerai a:
- Crea il ConfigMap che memorizza la procedura di inizializzazione.
- Esegui il deployment del DaemonSet che pianifica ed esegue la procedura di inizializzazione.
DaemonSet esegue le seguenti operazioni:
- Configura un volume che rende disponibile il contenuto di ConfigMap ai container gestiti da DaemonSet.
- Configura i volumi per le aree del file system privilegiate del nodo del cluster sottostante. Queste aree consentono ai contenitori pianificati da DaemonSet di interagire direttamente con il nodo che li esegue.
- Pianifica ed esegue un init container che esegue la procedura di inizializzazione e poi viene terminato al termine.
- Pianifica ed esegue un container che rimane inattivo e non consuma risorse.
Il container inattivo garantisce che un nodo venga inizializzato una sola volta. I DaemonSet sono progettati in modo che tutti i nodi idonei eseguano una copia di un pod. Se utilizzi un container normale, questo esegue la procedura di inizializzazione e viene terminato al termine. Per progettazione, DaemonSet riprogramma il pod. Per evitare la "ripianificazione continua", DaemonSet esegue prima la procedura di inizializzazione in un contenitore init, quindi lascia un contenitore in esecuzione.
La seguente procedura di inizializzazione contiene operazioni privilegiate e non privilegiate. Utilizzando chroot
, puoi eseguire i comandi come se li stessi eseguendo
direttamente sul nodo, non solo all'interno di un container.
Ti consigliamo di esaminare attentamente ogni procedura di inizializzazione, perché potrebbe alterare lo stato dei nodi del cluster. Solo un piccolo gruppo di persone dovrebbe avere il diritto di modificare queste procedure, perché possono influire notevolmente sulla disponibilità e sulla sicurezza dei tuoi cluster.
Per eseguire il deployment di ConfigMap e DaemonSet:
In Cloud Shell, cambia la directory di lavoro in
$HOME
:cd "$HOME"
Clona il repository Git che contiene gli script e i file manifest per eseguire il deployment e configurare la procedura di inizializzazione:
git clone https://github.com/GoogleCloudPlatform/solutions-gke-init-daemonsets-tutorial
Cambia la directory di lavoro impostandola sulla directory del repository appena clonato:
cd "$HOME"/solutions-gke-init-daemonsets-tutorial
Crea un ConfigMap per contenere lo script di inizializzazione del nodo:
kubectl apply -f cm-entrypoint.yaml
Esegui il deployment di DaemonSet:
kubectl apply -f daemon-set.yaml
Verifica che l'inizializzazione del nodo sia completata:
kubectl get ds --watch
Attendi che DaemonSet venga segnalato come pronto e aggiornato, come indicato da un output simile al seguente:
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE node-initializer 3 3 3 3 3 <none> 2h
Convalida e verifica la procedura di inizializzazione
Dopo che ogni nodo del cluster contrassegnato con l'etichetta default-init
esegue
la procedura di inizializzazione, puoi verificare i risultati.
Per ogni nodo, la procedura di verifica controlla quanto segue:
- Un disco aggiuntivo è collegato e pronto per essere utilizzato.
- I pacchetti e le librerie installati del gestore dei pacchetti del sistema operativo del nodo.
- I moduli kernel vengono caricati.
Esegui la procedura di verifica:
In Cloud Shell, esegui lo script di verifica:
kubectl get nodes -o=jsonpath='{range .items[?(@.metadata.labels.app=="default-init")]}{.metadata.name}{" "}{.metadata.labels.failure-domain\.beta\.kubernetes\.io/zone}{"\n"}{end}' | while IFS= read -r line ; do ./verify-init.sh $line < /dev/null; done
Attendi l'esecuzione dello script e verifica che ogni nodo sia stato inizializzato correttamente, come indicato da un output simile al seguente:
Verifying gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c) configuration Disk configured successfully on gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c) Packages installed successfully in gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c) Kernel modules loaded successfully on gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c) Verifying gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a) configuration Disk configured successfully on gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a) Packages installed successfully in gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a) Kernel modules loaded successfully on gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a) Verifying gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b) configuration Disk configured successfully on gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b) Packages installed successfully in gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b) Kernel modules loaded successfully on gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b)