Ricerca nel sito web

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:

  1. service.type: lo sto modificando in LoadBalancer per rivedere le mie modifiche localmente. Ricordati di eseguire minikube tunnel in una finestra separata, altrimenti non funzionerà.
  2. protocolHttp: sto distribuendo la versione non sicura per eliminare gli avvisi HTTPS su localhost.
  3. service.externalPort: deve essere 80 per non sicuro.
  4. replicaCount: lo cambio in 2 per vedere se queste modifiche funzionano :)
  5. rbac.clusterReadOnlyRole: questo dovrebbe essere true 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.

Articoli correlati: