Introduzione all'autorizzazione Kubernetes di Hashicorp Consul

Introduzione all'autorizzazione Kubernetes di Hashicorp Consul

Esatto, dopo il rilascio Console Hashicorp 1.5.0 all'inizio di maggio 2019, in Consul puoi autorizzare applicazioni e servizi in esecuzione in Kubernetes in modo nativo.

In questo tutorial creeremo passo dopo passo POC (Proof of concept, PoC) che dimostra questa nuova funzionalità. È prevista una conoscenza di base di Kubernetes e di Hashicorp Consul. Sebbene sia possibile utilizzare qualsiasi piattaforma cloud o ambiente locale, in questo tutorial utilizzeremo la piattaforma cloud di Google.

panoramica

Se andiamo a Documentazione consolare sulla sua modalità di autorizzazione, avremo una rapida panoramica del suo scopo e del caso d'uso, oltre ad alcuni dettagli tecnici e una panoramica generale della logica. Consiglio vivamente di leggerlo almeno una volta prima di procedere, poiché ora lo spiegherò e lo studierò tutto.

Introduzione all'autorizzazione Kubernetes di Hashicorp Consul

Grafico 1: Panoramica ufficiale del metodo di autorizzazione del Console

Diamo un'occhiata documentazione per uno specifico metodo di autorizzazione Kubernetes.

Certo, ci sono informazioni utili lì, ma non c'è una guida su come utilizzarle effettivamente. Quindi, come ogni persona sana di mente, esplori Internet in cerca di indicazioni. E poi... fallisci. Succede. Risolviamo questo problema.

Prima di passare alla creazione del nostro POC, torniamo alla panoramica dei metodi di autorizzazione di Consul (Diagramma 1) e perfezioniamolo nel contesto di Kubernetes.

Architettura

In questo tutorial creeremo un server Consul su una macchina separata che comunicherà con un cluster Kubernetes con il client Consul installato. Creeremo quindi la nostra applicazione fittizia nel pod e utilizzeremo il nostro metodo di autorizzazione configurato per leggere dal nostro archivio chiave/valore Consul.

Il diagramma seguente descrive in dettaglio l'architettura che stiamo creando in questo tutorial, nonché la logica alla base del metodo di autorizzazione, che verrà spiegata in seguito.

Introduzione all'autorizzazione Kubernetes di Hashicorp Consul

Diagramma 2: panoramica del metodo di autorizzazione Kubernetes

Una breve nota: non è necessario che il server Consul risieda al di fuori del cluster Kubernetes affinché funzioni. Ma sì, può farlo in questo e quello.

Quindi, prendendo il diagramma della panoramica di Console (Diagramma 1) e applicandovi Kubernetes, otteniamo il diagramma sopra (Diagramma 2) e la logica qui è la seguente:

  1. A ogni pod sarà collegato un account di servizio contenente un token JWT generato e conosciuto da Kubernetes. Anche questo token viene inserito nel pod per impostazione predefinita.
  2. La nostra applicazione o servizio all'interno del pod avvia un comando di accesso al nostro client Consul. La richiesta di accesso includerà anche il nostro token e il nostro nome appositamente creato metodo di autorizzazione (tipo Kubernetes). Questo passaggio n. 2 corrisponde al passaggio 1 del diagramma Console (Schema 1).
  3. Il nostro cliente Console inoltrerà quindi questa richiesta al nostro server Console.
  4. MAGIA! È qui che il server Consul verifica l'autenticità della richiesta, raccoglie informazioni sull'identità della richiesta e la confronta con eventuali regole predefinite associate. Di seguito è riportato un altro diagramma per illustrarlo. Questo passaggio corrisponde ai passaggi 3, 4 e 5 del diagramma della panoramica di Console (diagramma 1).
  5. Il nostro server Consul genera un token Consul con autorizzazioni in base alle regole del nostro metodo di autorizzazione specificate (che abbiamo definito) relative all'identità del richiedente. Quindi rimanderà indietro quel token. Ciò corrisponde al passo 6 del diagramma Console (Diagramma 1).
  6. Il nostro cliente Consul inoltra il token all'applicazione o al servizio richiedente.

La nostra applicazione o servizio può ora utilizzare questo token Console per comunicare con i dati del nostro Console, come determinato dai privilegi del token.

La magia è rivelata!

Per quelli di voi che non si accontentano di un semplice coniglio tirato fuori dal cappello e vogliono sapere come funziona... lasciate che vi mostri quanto è profondo tana del coniglio'.

Come accennato in precedenza, il nostro passaggio "magico" (Figura 2: Passaggio 4) è quello in cui il server Consul autentica la richiesta, raccoglie informazioni sulla richiesta e la confronta con eventuali regole predefinite associate. Questo passaggio corrisponde ai passaggi 3, 4 e 5 del diagramma della panoramica del Console (diagramma 1). Di seguito è riportato un diagramma (Diagramma 3), il cui scopo è mostrare chiaramente cosa sta realmente accadendo sotto il cappuccio metodo di autorizzazione Kubernetes specifico.

Introduzione all'autorizzazione Kubernetes di Hashicorp Consul

Diagramma 3: La magia è rivelata!

  1. Come punto di partenza, il nostro client Consul inoltra la richiesta di accesso al nostro server Consul con il token dell'account Kubernetes e il nome di istanza specifico del metodo di autorizzazione creato in precedenza. Questo passaggio corrisponde al passaggio 3 nella spiegazione del circuito precedente.
  2. Ora il server del Console (o leader) deve verificare l'autenticità del token ricevuto. Consulterà quindi il cluster Kubernetes (tramite il client Consul) e, con gli opportuni permessi, scopriremo se il token è autentico e a chi appartiene.
  3. La richiesta convalidata viene quindi restituita al leader della Console e il server della Console cerca l'istanza del metodo di autorizzazione con il nome specificato dalla richiesta di accesso (e il tipo Kubernetes).
  4. Il leader della console identifica l'istanza del metodo di autorizzazione specificata (se trovata) e legge l'insieme di regole vincolanti ad essa allegate. Quindi legge queste regole e le confronta con gli attributi di identità verificati.
  5. TA-dah! Passiamo al passaggio 5 della spiegazione del circuito precedente.

Esegui Consul-server su una normale macchina virtuale

D'ora in poi, fornirò principalmente istruzioni su come creare questo POC, spesso in elenchi puntati, senza spiegazioni complete delle frasi. Inoltre, come notato in precedenza, utilizzerò GCP per creare tutta l'infrastruttura, ma puoi creare la stessa infrastruttura ovunque.

  • Avviare la macchina virtuale (istanza/server).

Introduzione all'autorizzazione Kubernetes di Hashicorp Consul

  • Crea una regola per il firewall (gruppo di sicurezza in AWS):
  • Mi piace assegnare lo stesso nome macchina sia alla regola che al tag di rete, in questo caso "skywiz-consul-server-poc".
  • Trova l'indirizzo IP del tuo computer locale e aggiungilo all'elenco degli indirizzi IP di origine in modo che possiamo accedere all'interfaccia utente (UI).
  • Apri la porta 8500 per l'interfaccia utente. Fare clic su Crea. Presto modificheremo di nuovo questo firewall [collegamento].
  • Aggiungi una regola firewall all'istanza. Torna alla dashboard della VM su Consul Server e aggiungi "skywiz-consul-server-poc" al campo dei tag di rete. Fare clic su Salva.

Introduzione all'autorizzazione Kubernetes di Hashicorp Consul

  • Installa Consul su una macchina virtuale, controlla qui. Ricorda che è necessaria la versione di Console ≥ 1.5 [link]
  • Creiamo un singolo nodo Console: la configurazione è la seguente.

groupadd --system consul
useradd -s /sbin/nologin --system -g consul consul
mkdir -p /var/lib/consul
chown -R consul:consul /var/lib/consul
chmod -R 775 /var/lib/consul
mkdir /etc/consul.d
chown -R consul:consul /etc/consul.d

  • Per una guida più dettagliata sull'installazione di Consul e sulla configurazione di un cluster di 3 nodi, vedere qui.
  • Crea un file /etc/consul.d/agent.json come segue [collegamento]:

### /etc/consul.d/agent.json
{
 "acl" : {
 "enabled": true,
 "default_policy": "deny",
 "enable_token_persistence": true
 }
}

  • Avvia il nostro server Consul:

consul agent 
-server 
-ui 
-client 0.0.0.0 
-data-dir=/var/lib/consul 
-bootstrap-expect=1 
-config-dir=/etc/consul.d

  • Dovresti vedere una serie di output e finire con "... aggiornamento bloccato dagli ACL".
  • Trova l'indirizzo IP esterno del server Consul e apri un browser con questo indirizzo IP sulla porta 8500. Assicurati che l'interfaccia utente si apra.
  • Prova ad aggiungere una coppia chiave/valore. Ci deve essere un errore. Questo perché abbiamo caricato il server Consul con un ACL e disabilitato tutte le regole.
  • Torna alla tua shell sul server Consul e avvia il processo in background o in qualche altro modo per farlo funzionare e inserisci quanto segue:

consul acl bootstrap

  • Trova il valore "SecretID" e torna all'interfaccia utente. Nella scheda ACL, inserisci l'ID segreto del token che hai appena copiato. Copia SecretID da qualche altra parte, ne avremo bisogno in seguito.
  • Ora aggiungi una coppia chiave/valore. Per questo POC, aggiungi quanto segue: chiave: "custom-ns/test_key", valore: "Sono nella cartella custom-ns!"

Avvio di un cluster Kubernetes per la nostra applicazione con il client Consul come Daemonset

  • Crea un cluster K8s (Kubernetes). Lo creeremo nella stessa zona del server per un accesso più rapido e così potremo utilizzare la stessa sottorete per connetterci facilmente con gli indirizzi IP interni. La chiameremo "skywiz-app-with-consul-client-poc".

Introduzione all'autorizzazione Kubernetes di Hashicorp Consul

  • Come nota a margine, ecco un buon tutorial in cui mi sono imbattuto durante la configurazione di un cluster POC Consul con Consul Connect.
  • Utilizzeremo anche il grafico timone Hashicorp con un file di valori estesi.
  • Installa e configura Helm. Passaggi di configurazione:

kubectl create serviceaccount tiller --namespace kube-system
kubectl create clusterrolebinding tiller-admin-binding 
   --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
./helm init --service-account=tiller
./helm update

### poc-helm-consul-values.yaml
global:
 enabled: false
 image: "consul:latest"
# Expose the Consul UI through this LoadBalancer
ui:
 enabled: false
# Allow Consul to inject the Connect proxy into Kubernetes containers
connectInject:
 enabled: false
# Configure a Consul client on Kubernetes nodes. GRPC listener is required for Connect.
client:
 enabled: true
 join: ["<PRIVATE_IP_CONSUL_SERVER>"]
 extraConfig: |
{
  "acl" : {
 "enabled": true,   
 "default_policy": "deny",   
 "enable_token_persistence": true 
  }
}
# Minimal Consul configuration. Not suitable for production.
server:
 enabled: false
# Sync Kubernetes and Consul services
syncCatalog:
 enabled: false

  • Applicare la tabella del timone:

./helm install -f poc-helm-consul-values.yaml ./consul-helm - name skywiz-app-with-consul-client-poc

  • Quando tenta di essere eseguito, avrà bisogno delle autorizzazioni per il server Consul, quindi aggiungiamole.
  • Prendi nota dell'"Intervallo di indirizzi del pod" situato nel dashboard del cluster e fai riferimento alla nostra regola firewall "skywiz-consul-server-poc".
  • Aggiungi l'intervallo di indirizzi per il pod all'elenco degli indirizzi IP e apri le porte 8301 e 8300.

Introduzione all'autorizzazione Kubernetes di Hashicorp Consul

  • Vai alla Console UI e dopo pochi minuti vedrai apparire il nostro cluster nella scheda dei nodi.

Introduzione all'autorizzazione Kubernetes di Hashicorp Consul

Configurazione di un metodo di autorizzazione integrando Consul con Kubernetes

  • Ritorna alla shell del server Consul ed esporta il token salvato in precedenza:

export CONSUL_HTTP_TOKEN=<SecretID>

  • Avremo bisogno di informazioni dal nostro cluster Kubernetes per creare un'istanza del metodo auth:
  • Kubernetes-host

kubectl get endpoints | grep kubernetes

  • kubernetes-service-account-jwt

kubectl get sa <helm_deployment_name>-consul-client -o yaml | grep "- name:"
kubectl get secret <secret_name_from_prev_command> -o yaml | grep token:

  • Il token è codificato base64, quindi decrittografalo utilizzando il tuo strumento preferito [collegamento]
  • kubernetes-ca-cert

kubectl get secret <secret_name_from_prev_command> -o yaml | grep ca.crt:

  • Prendi il certificato “ca.crt” (dopo la decodifica base64) e scrivilo nel file “ca.crt”.
  • Adesso istanziamo il metodo auth, sostituendo i segnaposto con i valori appena ricevuti.

consul acl auth-method create 
-type "kubernetes" 
-name "auth-method-skywiz-consul-poc" 
-description "This is an auth method using kubernetes for the cluster skywiz-app-with-consul-client-poc" 
-kubernetes-host "<k8s_endpoint_retrieved earlier>" 
[email protected] 
-kubernetes-service-account-
jwt="<decoded_token_retrieved_earlier>"

  • Successivamente dobbiamo creare una regola e allegarla al nuovo ruolo. Per questa parte puoi utilizzare Consul UI, ma useremo la riga di comando.
  • Scrivi una regola

### kv-custom-ns-policy.hcl
key_prefix "custom-ns/" {
 policy = "write"
}

  • Applicare la regola

consul acl policy create 
-name kv-custom-ns-policy 
-description "This is an example policy for kv at custom-ns/" 
-rules @kv-custom-ns-policy.hcl

  • Trova l'ID della regola appena creata dall'output.
  • Crea un ruolo con una nuova regola.

consul acl role create 
-name "custom-ns-role" 
-description "This is an example role for custom-ns namespace" 
-policy-id <policy_id>

consul acl binding-rule create 
-method=auth-method-skywiz-consul-poc 
-bind-type=role 
-bind-name='custom-ns-role' 
-selector='serviceaccount.namespace=="custom-ns"'

Infine le configurazioni

Diritti di accesso

  • Creare diritti di accesso. Dobbiamo autorizzare Console a verificare e identificare l'identità del token dell'account di servizio K8.
  • Scrivere quanto segue nel file [collegamento]:

###skywiz-poc-consul-server_rbac.yaml
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: review-tokens
 namespace: default
subjects:
- kind: ServiceAccount
 name: skywiz-app-with-consul-client-poc-consul-client
 namespace: default
roleRef:
 kind: ClusterRole
 name: system:auth-delegator
 apiGroup: rbac.authorization.k8s.io
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: service-account-getter
 namespace: default
rules:
- apiGroups: [""]
 resources: ["serviceaccounts"]
 verbs: ["get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: get-service-accounts
 namespace: default
subjects:
- kind: ServiceAccount
 name: skywiz-app-with-consul-client-poc-consul-client
 namespace: default
roleRef:
 kind: ClusterRole
 name: service-account-getter
 apiGroup: rbac.authorization.k8s.io

  • Creiamo i diritti di accesso

kubectl create -f skywiz-poc-consul-server_rbac.yaml

Connessione a Consul Client

  • Come notato quiEsistono diverse opzioni per connettersi a daemonset, ma passeremo alla seguente semplice soluzione:
  • Applicare il seguente file [collegamento].

### poc-consul-client-ds-svc.yaml
apiVersion: v1
kind: Service
metadata:
 name: consul-ds-client
spec:
 selector:
   app: consul
   chart: consul-helm
   component: client
   hasDNS: "true"
   release: skywiz-app-with-consul-client-poc
 ports:
 - protocol: TCP
   port: 80
   targetPort: 8500

  • Quindi utilizzare il seguente comando integrato per creare una mappa di configurazione [collegamento]. Tieni presente che ci riferiamo al nome del nostro servizio, sostituiscilo se necessario.

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
 labels:
   addonmanager.kubernetes.io/mode: EnsureExists
 name: kube-dns
 namespace: kube-system
data:
 stubDomains: |
   {"consul": ["$(kubectl get svc consul-ds-client -o jsonpath='{.spec.clusterIP}')"]}
EOF

Testare il metodo di autenticazione

Ora vediamo la magia in azione!

  • Crea diverse altre cartelle di chiavi con la stessa chiave di livello superiore (ad es. /sample_key) e un valore a tua scelta. Creare politiche e ruoli appropriati per i nuovi percorsi chiave. Faremo le legature più tardi.

Introduzione all'autorizzazione Kubernetes di Hashicorp Consul

Test dello spazio dei nomi personalizzato:

  • Creiamo il nostro spazio dei nomi:

kubectl create namespace custom-ns

  • Creiamo un pod nel nostro nuovo spazio dei nomi. Scrivi la configurazione per il pod.

###poc-ubuntu-custom-ns.yaml
apiVersion: v1
kind: Pod
metadata:
 name: poc-ubuntu-custom-ns
 namespace: custom-ns
spec:
 containers:
 - name: poc-ubuntu-custom-ns
   image: ubuntu
   command: ["/bin/bash", "-ec", "sleep infinity"]
 restartPolicy: Never

  • Crea sotto:

kubectl create -f poc-ubuntu-custom-ns.yaml

  • Una volta che il contenitore è in esecuzione, vai lì e installa curl.

kubectl exec poc-ubuntu-custom-ns -n custom-ns -it /bin/bash
apt-get update && apt-get install curl -y

  • Ora invieremo una richiesta di accesso a Console utilizzando il metodo di autorizzazione creato in precedenza [collegamento].
  • Per visualizzare il token inserito dal tuo account di servizio:

cat /run/secrets/kubernetes.io/serviceaccount/token

  • Scrivi quanto segue in un file all'interno del contenitore:

### payload.json
{
 "AuthMethod": "auth-method-test",
 "BearerToken": "<jwt_token>"
}

  • Accesso!

curl 
--request POST 
--data @payload.json 
consul-ds-client.default.svc.cluster.local/v1/acl/login

  • Per completare i passaggi precedenti in una riga (poiché eseguiremo più test), puoi procedere come segue:

echo "{ 
"AuthMethod": "auth-method-skywiz-consul-poc", 
"BearerToken": "$(cat /run/secrets/kubernetes.io/serviceaccount/token)" 
}" 
| curl 
--request POST 
--data @- 
consul-ds-client.default.svc.cluster.local/v1/acl/login

  • Lavori! Almeno dovrebbe. Ora prendi il SecretID e prova ad accedere alla chiave/valore a cui dovremmo avere accesso.

curl 
consul-ds-client.default.svc.cluster.local/v1/kv/custom-ns/test_key --header “X-Consul-Token: <SecretID_from_prev_response>”

  • Puoi decodificare base64 "Valore" e vedere che corrisponde al valore in custom-ns/test_key nell'interfaccia utente. Se utilizzassi lo stesso valore sopra in questo tutorial, il valore codificato sarebbe IkknbSBpbiB0aGUgY3VzdG9tLW5zIGZvbGRlciEi.

Test dell'account del servizio utente:

  • Crea un ServiceAccount personalizzato utilizzando il comando seguente [collegamento].

kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
 name: custom-sa
EOF

  • Crea un nuovo file di configurazione per il pod. Tieni presente che ho incluso l'installazione dell'arricciatura per risparmiare manodopera :)

###poc-ubuntu-custom-sa.yaml
apiVersion: v1
kind: Pod
metadata:
 name: poc-ubuntu-custom-sa
 namespace: default
spec:
 serviceAccountName: custom-sa
 containers:
 - name: poc-ubuntu-custom-sa
   image: ubuntu
   command: ["/bin/bash","-ec"]
   args: ["apt-get update && apt-get install curl -y; sleep infinity"]
 restartPolicy: Never

  • Successivamente, esegui una shell all'interno del contenitore.

kubectl exec -it poc-ubuntu-custom-sa /bin/bash

  • Accesso!

echo "{ 
"AuthMethod": "auth-method-skywiz-consul-poc", 
"BearerToken": "$(cat /run/secrets/kubernetes.io/serviceaccount/token)" 
}" 
| curl 
--request POST 
--data @- 
consul-ds-client.default.svc.cluster.local/v1/acl/login

  • Permesso negato. Oh, abbiamo dimenticato di aggiungere una nuova regola vincolante con le autorizzazioni appropriate, facciamolo ora.

Ripeti i passaggi precedenti sopra:
a) Creare una Policy identica per il prefisso “custom-sa/”.
b) Crea un ruolo, chiamalo “custom-sa-role”
c) Allegare la Policy al Ruolo.

  • Creare un'associazione di regole (possibile solo da cli/api). Notare il diverso significato del flag di selezione.

consul acl binding-rule create 
-method=auth-method-skywiz-consul-poc 
-bind-type=role 
-bind-name='custom-sa-role' 
-selector='serviceaccount.name=="custom-sa"'

  • Accedi nuovamente dal contenitore "poc-ubuntu-custom-sa". Successo!
  • Controlla il nostro accesso al percorso custom-sa/key.

curl 
consul-ds-client.default.svc.cluster.local/v1/kv/custom-sa/test_key --header “X-Consul-Token: <SecretID>”

  • Puoi anche assicurarti che questo token non conceda l'accesso a kv in "custom-ns/". Basta ripetere il comando precedente dopo aver sostituito "custom-sa" con il prefisso "custom-ns".
    Permesso negato.

Esempio di sovrapposizione:

  • Vale la pena notare che tutte le mappature vincolanti le regole verranno aggiunte al token con questi diritti.
  • Il nostro contenitore "poc-ubuntu-custom-sa" si trova nello spazio dei nomi predefinito, quindi utilizziamolo per un'associazione di regole diversa.
  • Ripeti i passaggi precedenti:
    a) Creare una policy identica per il prefisso della chiave "default/".
    b) Crea un ruolo, chiamalo "default-ns-role"
    c) Allegare la Policy al Ruolo.
  • Crea un'associazione di regole (possibile solo da cli/api)

consul acl binding-rule create 
-method=auth-method-skywiz-consul-poc 
-bind-type=role 
-bind-name='default-ns-role' 
-selector='serviceaccount.namespace=="default"'

  • Torna al nostro contenitore "poc-ubuntu-custom-sa" e prova ad accedere al percorso kv "default/".
  • Permesso negato.
    È possibile visualizzare le credenziali specificate per ciascun token nell'interfaccia utente in ACL > Token. Come puoi vedere, il nostro token attuale ha solo un "ruolo-sa-personalizzato" allegato. Il token che stiamo attualmente utilizzando è stato generato quando abbiamo effettuato l'accesso e in quel momento c'era solo una regola vincolante che corrispondeva. Dobbiamo accedere nuovamente e utilizzare il nuovo token.
  • Assicurati di poter leggere sia dal percorso kv "custom-sa/" che da quello "default/".
    Successo!
    Questo perché il nostro "poc-ubuntu-custom-sa" corrisponde ai collegamenti delle regole "custom-sa" e "default-ns".

conclusione

Gestione del token TTL?

Al momento in cui scrivo, non esiste un modo integrato per determinare il TTL per i token generati da questo metodo di autorizzazione. Sarebbe una fantastica opportunità per fornire un'automazione sicura dell'autorizzazione del Console.

C'è un'opzione per creare manualmente un token con TTL:

Se tutto va bene nel prossimo futuro saremo in grado di controllare come vengono generati i token (per regola o metodo di autorizzazione) e aggiungere TTL.

Fino ad allora, ti consigliamo di utilizzare un endpoint di disconnessione nella tua logica.

Leggi anche altri articoli sul nostro blog:

Fonte: habr.com

Aggiungi un commento