Come utilizzo Terraform e Helm per distribuire la dashboard Kubernetes
Terraform può distribuire le carte Helm. È giusto per te?
Quando lavoro su progetti che richiedono il provisioning dell'infrastruttura cloud, il mio flusso di lavoro ha due componenti disparati: uno è l'orchestrazione dell'infrastruttura, che include Terraform per attivare l'infrastruttura (ad esempio, nuovi cluster EKS), e il secondo è il componente di provisioning, che include script Ansible o Bash per creare un'istanza e inizializzare l'infrastruttura per accettare nuove distribuzioni (ad esempio, l'installazione di Cluster Autoscaler, kube-state-metrics e così via).
La ragione di ciò è semplice: pochissimi strumenti possono eseguire il passaggio e gestire sia il lato dell'orchestrazione che quello del provisioning. Quando mi sono imbattuto nel provider Helm per Terraform, volevo esplorare la possibilità di utilizzare uno strumento per gestire entrambi i lati: utilizzare Terraform per visualizzare un nuovo cluster EKS ed eseguirne il provisioning con Prometheus, Loki, Grafana, Cluster Autoscaler e altri, tutto in una distribuzione ordinata e pulita. Ma ciò non accadrà finché non avrò capito come utilizzare questa cosa, quindi di seguito è riportata la mia esperienza nell'utilizzo di Terraform e Helm per qualcosa di semplice: distribuire la dashboard Kubernetes.
Il fornitore del timone
Il provider Helm funziona come gli altri provider cloud. Puoi specificare il percorso di KUBECONFIG
o altre credenziali, eseguire terraform init
e il provider Helm verrà inizializzato.
Distribuzione della dashboard Kubernetes
Utilizzerò Minikube per questo test.
Il mio file main.tf
contiene quanto segue:
provider "helm" {
kubernetes {
config_path = "~/.kube/config"
}
}
resource "helm_release" "my-kubernetes-dashboard" {
name = "my-kubernetes-dashboard"
repository = "https://kubernetes.github.io/dashboard/"
chart = "kubernetes-dashboard"
namespace = "default"
set {
name = "service.type"
value = "LoadBalancer"
}
set {
name = "protocolHttp"
value = "true"
}
set {
name = "service.externalPort"
value = 80
}
set {
name = "replicaCount"
value = 2
}
set {
name = "rbac.clusterReadOnlyRole"
value = "true"
}
}
Nel precedente Terraform, sto distribuendo il grafico kubernetes-dashboard
da https://kubernetes.github.io/dashboard/
nello spazio dei nomi default. Sto anche utilizzando la variabile set
per sovrascrivere le impostazioni predefinite del grafico:
service.type
: lo sto modificando inLoadBalancer
per rivedere le mie modifiche localmente. Ricordati di eseguireminikube tunnel
in una finestra separata, altrimenti non funzionerà.protocolHttp
: sto distribuendo la versione non sicura per eliminare gli avvisi HTTPS sulocalhost
.service.externalPort
: deve essere 80 per non sicuro.replicaCount
: lo cambio in 2 per vedere se queste modifiche funzionano :)rbac.clusterReadOnlyRole
: questo dovrebbe esseretrue
affinché il Dashboard disponga delle autorizzazioni corrette.
Eseguendo la nostra Terraform
Iniziamo inizializzando Terraform con terraform init
:
Initializing the backend...
Initializing provider plugins...
- Finding latest version of hashicorp/helm...
- Installing hashicorp/helm v2.2.0...
- Installed hashicorp/helm v2.2.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
Fin qui tutto bene. Terraform ha inizializzato correttamente il provider Helm. E ora per terraform apply
:
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# helm_release.my-kubernetes-dashboard will be created
+ resource "helm_release" "my-kubernetes-dashboard" {
+ atomic = false
+ chart = "kubernetes-dashboard"
+ cleanup_on_fail = false
[...]
+ set {
+ name = "service.type"
+ value = "LoadBalancer"
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
helm_release.my-kubernetes-dashboard: Creating...
helm_release.my-kubernetes-dashboard: Still creating... [10s elapsed]
helm_release.my-kubernetes-dashboard: Creation complete after 14s [id=my-kubernetes-dashboard]
(Ricordati di eseguire minikube tunnel
in un'altra finestra di terminale, altrimenti apply
non funzionerà).
Verificare le nostre modifiche
Controlliamo se i nostri pod sono attivi utilizzando kubectl get po
e kubectl get svc
:
~ kubectl get po
NAME READY STATUS RESTARTS AGE
my-kubernetes-dashboard-7bc7ccfbd9-56w56 1/1 Running 0 18m
my-kubernetes-dashboard-7bc7ccfbd9-f6jc4 1/1 Running 0 18m
~ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20m
my-kubernetes-dashboard LoadBalancer 10.104.144.125 10.104.144.125 80:32066/TCP 19m
I nostri pod sono distribuiti e il sistema di bilanciamento del carico funziona. Ora controlla l'interfaccia utente:
Figura 2: dashboard dei carichi di lavoro Kubernetes
Conclusione
Puoi trovare gli esempi di questo articolo nel mio repository Gitlab.
Con il provisioning di Helm ora parte di Terraform, la mia vita lavorativa è molto più semplice. Mi rendo conto che la separazione tra infrastruttura e provisioning aveva uno scopo diverso: i cambiamenti dell'infrastruttura erano solitamente una tantum o non richiedevano aggiornamenti frequenti, forse alcune volte quando cambiavano le regole di governance o di sicurezza per la mia organizzazione. Le modifiche al provisioning, d'altro canto, si verificavano frequentemente, a volte con ogni versione. Quindi aveva senso avere Terraform (Infrastruttura) e Helm Charts (Provisioning) in due repository diversi con due strumenti diversi e due flussi di lavoro di revisione diversi. Non sono sicuro che unirli utilizzando un unico strumento sia l'idea migliore, ma uno strumento in meno nella toolchain è sempre una grande vittoria. Penso che i pro e i contro di questo varieranno da un progetto all’altro e da una squadra all’altra.