
Tutto corretto, dopo il rilascio all'inizio di maggio 2019, in Consul è possibile effettuare l'autenticazione delle applicazioni e dei servizi eseguiti su Kubernetes in modo nativo.
In questa guida costruiremo passo dopo passo (Proof of concept, PoC — prova di [fattibilità] della concezione — N.d.T.), dimostrando questa nuova funzione. Ci si aspetta che tu abbia conoscenze di base su Kubernetes e Hashicorp’s Consul. E sebbene tu possa utilizzare qualsiasi piattaforma cloud o ambiente locale, in questa guida utilizzeremo Google Cloud Platform.
Panoramica
Se passiamo a , otterremo una panoramica concisa della sua finalità e casi d'uso, così come alcuni dettagli tecnici e una panoramica della logica. Ti consiglio vivamente di leggerla almeno una volta prima di continuare, poiché ora spiegherò tutto questo.

Schema 1: Panoramica ufficiale del metodo di autorizzazione di Consul
Diamo un'occhiata alla .
Certo, lì troverai informazioni utili, ma non ci sono indicazioni su come utilizzare effettivamente tutto questo. Quindi, come qualsiasi persona di buon senso, cerchi in Internet una guida. E poi... subisci una sconfitta. Può succedere. Ripariamo questa situazione.
Prima di passare alla creazione del nostro POC, torniamo a rivedere i metodi di autorizzazione di Consul (Schema 1) e chiarifichiamoli nel contesto di Kubernetes.
Architettura
In questa guida creeremo un server Consul su una macchina separata, che interagirà con un cluster Kubernetes con un client Consul installato. Poi creeremo la nostra applicazione fittizia in un pod e utilizzeremo il nostro metodo di autorizzazione configurato per leggere dal nostro archivio di chiavi/valori di Consul.
Lo schema qui sotto mostra in dettaglio l'architettura che stiamo creando in questa guida, così come la logica del metodo di autorizzazione che sarà spiegata in seguito.

Schema 2: Panoramica del metodo di autorizzazione in Kubernetes
Una piccola nota: il server Consul non deve vivere al di fuori del cluster Kubernetes affinché questo funzioni. Ma sì, può fare anche così.
Quindi, prendendo la panoramica del metodo di autorizzazione di Consul (Schema 1) e applicandola a Kubernetes, otteniamo lo schema sopra (Schema 2), e qui la logica sarà la seguente:
- A ciascun pod sarà allegato un account di servizio contenente un token JWT, generato e noto a Kubernetes. Questo token viene anche inserito nel pod per impostazione predefinita.
- La nostra applicazione o servizio all'interno del pod avvia un comando di accesso al nostro client Consul. Nella richiesta di accesso verranno forniti anche il nostro token e il nome specificamente creato metodo di autorizzazione (tipo Kubernetes). Questo passaggio n° 2 corrisponde al passaggio 1 dello schema di Consul (Schema 1).
- Il nostro client Consul quindi inoltra questa richiesta al nostro server Consul.
- MAGIA! È qui che il server Consul verifica l'autenticità della richiesta, raccoglie informazioni sull'identità della richiesta e le confronta con eventuali regole predefinite associate. Di seguito verrà fornito un altro schema per illustrare questo punto. Questo passaggio corrisponde ai passaggi 3, 4 e 5 dello schema di panoramica di Consul (Schema 1).
- Il nostro server Consul genera un token Consul con autorizzazioni in base alle regole del metodo di autorizzazione da noi specificate (che abbiamo definito) riguardo all'identità del richiedente. Quindi invierà indietro questo token. Questo corrisponde al passaggio 6 dello schema di Consul (Schema 1).
- Il nostro client Consul reindirizza il token all'applicazione o servizio richiedente.
La nostra applicazione o servizio può ora utilizzare questo token Consul per interagire con i nostri dati Consul, come definito dai privilegi del token.
La magia svelata!
Per coloro di voi che non si accontentano di un semplice coniglio dal cappello e vogliono sapere come funziona… permettetemi di "mostrarvi quanto è profonda la tana del coniglio».
Come accennato in precedenza, il nostro passaggio "magico" (Schema 2: Passaggio 4) è che il server Consul verifica l'autenticità della richiesta, raccoglie informazioni sulla richiesta e le confronta con eventuali regole predefinite associate. Questo passaggio corrisponde ai passaggi 3, 4 e 5 dello schema di panoramica di Consul (Schema 1). Di seguito è riportato uno schema (Schema 3) la cui finalità è mostrare chiaramente cosa sta realmente accadendo sotto il cofano. del specifico metodo di autorizzazione Kubernetes.

Schema 3: La magia svelata!
- Come punto di partenza, il nostro client Consul reindirizza la richiesta di accesso al nostro server Consul con il token dell'account Kubernetes e il nome specifico dell'istanza del metodo di autorizzazione che è stato creato in precedenza. Questo passaggio corrisponde al passaggio 3 della spiegazione precedente dello schema.
- Ora il server Consul (o il leader) deve verificare l'autenticità del token ricevuto. Per questo, si consulterà con il cluster Kubernetes (attraverso il client Consul) e, con i permessi adeguati, scopriremo se il token è autentico e a chi appartiene.
- Il messaggio verificato viene quindi restituito al leader di Consul, e sul server Consul viene cercato un'istanza del metodo di autorizzazione con il nome specificato nella richiesta di accesso (di tipo Kubernetes).
- Il leader di Consul identifica l'istanza del metodo di autorizzazione specificata (se trovata) e legge il set di regole di binding ad essa associato. Poi legge queste regole e le confronta con gli attributi di identità verificati.
- Ecco! Passiamo al passo 5 nella spiegazione precedente dello schema.
Avvia il server Consul su una normale macchina virtuale.
Da questo momento in poi fornirò principalmente istruzioni per la creazione di questo POC, spesso in punti, senza proposte esplicative complete. Inoltre, come già accennato, userò GCP per creare tutta l'infrastruttura, ma puoi creare la stessa infrastruttura ovunque.
- Avvia la macchina virtuale (istanza / server).

- Crea una regola per il firewall (gruppo di sicurezza in AWS):
- Mi piace assegnare lo stesso nome della 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 IP sorgente, in modo che possiamo accedere all'interfaccia utente (UI).
- Apri la porta 8500 per l'UI. Clicca su Crea. Modificheremo di nuovo questo firewall presto [].
- Aggiungi una regola per il firewall all'istanza. Torna al pannello di monitoraggio VM sul server Consul e aggiungi "skywiz-consul-server-poc" nel campo dei tag di rete. Clicca su Salva.

- Installa Consul sulla macchina virtuale, controlla qui. Ricorda che hai bisogno di una versione di Consul ≥ 1.5 [link]
- Creiamo un Consul a nodo singolo — 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- Guida più dettagliata per installare Consul e configurare un cluster di 3 nodi da. .
- Crea il file /etc/consul.d/agent.json nel seguente modo []:
### /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 un sacco di output e alla fine “… update blocked by ACLs”.
- Trova l'indirizzo IP esterno del server Consul e apri il browser con questo indirizzo IP sulla porta 8500. Assicurati che si apra l'interfaccia utente.
- Prova ad aggiungere un paio di coppie chiave/valore. Dovrebbe esserci un errore. Questo perché abbiamo caricato il server Consul con le ACL e vietato tutte le regole.
- Torna alla tua shell sul server Consul e avvia il processo in background o in qualche altro modo, in modo che funzioni, ed inserisci quanto segue:
consul acl bootstrap- Trova il valore «SecretID» e torna all'interfaccia utente. Nella scheda «ACL», inserisci il segreto identificatore del token che hai appena copiato. Copia il SecretID da qualche altra parte, ne avremo bisogno più tardi.
- Ora aggiungi una coppia chiave/valore. Per questo POC, aggiungeremo 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ù veloce, e quindi possiamo utilizzare la stessa sottorete per una facile connessione con indirizzi IP interni. Lo chiameremo «skywiz-app-with-consul-client-poc».

- Come nota, ecco una buona guida che ho trovato quando ho impostato il POC del cluster Consul con Consul Connect.
- Utilizzeremo anche il grafico di Helm di Hashicorp con un file di valori esteso.
- 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- grafico helm:
- Usa il seguente file di valori (nota che la maggior parte l'ho disattivata):
### 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- Applica il grafico helm:
./helm install -f poc-helm-consul-values.yaml ./consul-helm - name skywiz-app-with-consul-client-poc- Nel tentativo di avvio, avrà bisogno dei permessi per il server Consul, quindi aggiungiamo.
- Fai attenzione al «range degli indirizzi Pod» situato nel pannello di controllo del cluster e torna alla nostra regola del firewall «skywiz-consul-server-poc».
- Aggiungi il range degli indirizzi per il pod alla lista degli indirizzi IP e apri le porte 8301 e 8300.

- Vai all'interfaccia utente di Consul e dopo qualche minuto vedrai che il nostro cluster apparirà nella scheda nodi.

Configurazione del metodo di autorizzazione collegando Consul a Kubernetes
- Torna alla shell del server Consul ed esporta il token che hai salvato in precedenza:
export CONSUL_HTTP_TOKEN=- Avremo bisogno di informazioni dal nostro cluster Kubernetes per creare un'istanza del metodo di auth:
- kubernetes-host
kubectl get endpoints | grep kubernetes- kubernetes-service-account-jwt
kubectl get sa -consul-client -o yaml | grep "- name:"
kubectl get secret -o yaml | grep token:- Il token è codificato in base64, quindi decodificalo usando il tuo strumento preferito []
- kubernetes-ca-cert
kubectl get secret -o yaml | grep ca.crt:- Prendi il certificato “ca.crt” (dopo la decodifica da base64) e salvalo nel file “ca.crt”.
- Ora crea un'istanza del metodo di auth, sostituendo i segnaposto con i valori che hai appena ottenuto.
consul acl auth-method create
-type "kubernetes"
-name "auth-method-skywiz-consul-poc"
-description "Questo è un metodo di auth che utilizza Kubernetes per il cluster skywiz-app-with-consul-client-poc"
-kubernetes-host ""
-kubernetes-ca-cert=@ca.crt
-kubernetes-service-account-
jwt=""- Successivamente, dobbiamo creare una regola e associarla a un nuovo ruolo. Per questa parte puoi utilizzare l'interfaccia utente di Consul, ma noi useremo la riga di comando.
- Scrivi la regola
### kv-custom-ns-policy.hcl
key_prefix "custom-ns/" {
policy = "write"
}- Applica la regola
consul acl policy create
-name kv-custom-ns-policy
-description "Questa è un esempio di policy per kv in custom-ns/"
-rules @kv-custom-ns-policy.hcl- Trova l'identificatore della regola che hai appena creato dall'output.
- Crea un ruolo con la nuova regola.
consul acl role create
-name "custom-ns-role"
-description "Questo è un esempio di ruolo per lo spazio dei nomi custom-ns"
-policy-id- Ora collegheremo il nostro nuovo ruolo all'istanza del metodo di auth. Nota che il flag 'selector' determina se la nostra richiesta di accesso riceverà questo ruolo. Controlla qui altre opzioni di selezione:
consul acl binding-rule create
-method=auth-method-skywiz-consul-poc
-bind-type=role
-bind-name='custom-ns-role'
-selector='serviceaccount.namespace=="custom-ns"'Configurazioni finali
Diritti di accesso
- Crea le autorizzazioni. Dobbiamo consentire a Consul di verificare e identificare l'identità del token del servizio K8s.
- Scrivi nel file quanto segue :
###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 le autorizzazioni
kubectl create -f skywiz-poc-consul-server_rbac.yamlCollegamento al Consul Client
- Come notato , ci sono diverse opzioni per connettersi al daemonset, ma passeremo alla seguente soluzione semplice:
- Applica il seguente file [].
### 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 applica il seguente comando integrato per creare il configmap []. Nota che facciamo riferimento 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}')"]}
EOFTesting del metodo auth
Ora vediamo la magia in azione!
- Crea altre chiavi di cartelle con la stessa chiave di livello superiore (cioè /sample_key) e valori a tua scelta. Crea le politiche e i ruoli corrispondenti per i nuovi percorsi delle chiavi. Faremo i binding più tardi.

Test dell'account utente nello spazio dei nomi:
- 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 un pod:
kubectl create -f poc-ubuntu-custom-ns.yaml- Una volta che il contenitore è in esecuzione, accedi 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 Consul, utilizzando il metodo di autorizzazione che abbiamo creato in precedenza [].
- Per visualizzare il token inserito dal tuo account di servizio:
cat /run/secrets/kubernetes.io/serviceaccount/token- Scrivi quanto segue nel file all'interno del contenitore:
### payload.json
{
"AuthMethod": "auth-method-test",
"BearerToken": "<jwt_token>"
}- Login!
curl
--request POST
--data @payload.json
consul-ds-client.default.svc.cluster.local/v1/acl/login- Per eseguire i passaggi sopra in una sola riga (poiché eseguiremo diversi test), puoi fare quanto 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- Funziona! Dovrebbe, perlomeno. 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: "- Puoi decodificare il "Value" in base64 e vedere che corrisponde al valore in custom-ns/test_key nell'interfaccia utente. Se hai usato lo stesso valore fornito sopra in questa guida, il tuo valore codificato sarà IkknbSBpbiB0aGUgY3VzdG9tLW5zIGZvbGRlciEi.
Test dell'account di servizio personalizzato:
- Crea un ServiceAccount personalizzato utilizzando il seguente comando [].
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: custom-sa
EOF- Crea un nuovo file di configurazione per il pod. Nota che ho incluso l'installazione di curl per risparmiare fatica 🙂
###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- Dopo, avvia una shell all'interno del contenitore.
kubectl exec -it poc-ubuntu-custom-sa /bin/bash- Login!
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- Accesso negato. Oh, abbiamo dimenticato di aggiungere una nuova associazione di regole con le autorizzazioni appropriate, facciamolo ora.
Ripeti i passaggi precedenti:
a) Crea una Politica identica per il prefisso "custom-sa/".
b) Crea un Ruolo, chiamalo "custom-sa-role"
c) Associa la Politica al Ruolo.
- Crea una Regola di Associazione (possibile solo da cli/api). Fai attenzione a un altro valore del flag del selettore.
consul acl binding-rule create
-method=auth-method-skywiz-consul-poc
-bind-type=role
-bind-name='custom-sa-role'
-selector='serviceaccount.name=="custom-sa"'- Riprova il login dal contenitore "poc-ubuntu-custom-sa". Successo!
- Controlla il nostro accesso al percorso chiave custom-sa/.
curl
consul-ds-client.default.svc.cluster.local/v1/kv/custom-sa/test_key --header "X-Consul-Token: "- Puoi anche verificare che questo token non fornisca accesso al kv in "custom-ns/". Basta ripetere il comando sopra sostituendo "custom-sa" con il prefisso "custom-ns".
Accesso negato.
Esempio di overlay:
- Va notato che tutte le associazioni di regole saranno aggiunte al token con questi diritti.
- Il nostro contenitore "poc-ubuntu-custom-sa" si trova nello spazio dei nomi predefinito, quindi utilizziamolo per un'altra associazione di regole.
- Ripeti i passaggi precedenti:
a) Crea una Politica identica per il prefisso della chiave "default/".
b) Crea un Ruolo, chiamalo "default-ns-role"
c) Associa la Politica al Ruolo. - Crea una Regola di Associazione (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 "default/" kv.
- Accesso negato.
Puoi visualizzare le credenziali specificate per ciascun token nell'interfaccia utente nella sezione ACL > Tokens. Come puoi vedere, al nostro token attuale è associato solo un "custom-sa-role". Il token che stiamo utilizzando attualmente è stato generato quando abbiamo effettuato il login, e allora c'era solo una associazione di regole che corrispondeva. Dobbiamo effettuare nuovamente il login e usare un nuovo token. - Assicurati di poter leggere sia dai percorsi "custom-sa/" che "default/" kv.
Successo!
Questo è dovuto al fatto che il nostro "poc-ubuntu-custom-sa" corrisponde alle associazioni di regole "custom-sa" e "default-ns".
Conclusione
Gestione TTL token?
Al momento della scrittura di questo articolo non esiste un modo integrato per determinare il TTL per i token generati con questo metodo di autorizzazione. Sarebbe una fantastica possibilità — garantire un'automazione sicura dell'autorizzazione in Consul.
È possibile creare manualmente un token con TTL:
Expiration Time (Tempo di scadenza) — il momento in cui questo token sarà revocato. (Facoltativo; aggiunto in Consul 1.5.0)- Esiste solo per la creazione/aggiornamento manuale
Spero che a breve potremo controllare come vengono generati i token (per ogni regola o metodo di autorizzazione) e aggiungere TTL.
Fino ad allora, si consiglia di utilizzare il punto di uscita nella propria logica.
Leggi anche altri articoli nel nostro blog:
Fonte: habr.com
