
Tutto corretto, dopo il rilascio all'inizio di maggio 2019, in Consul è possibile effettuare l'autenticazione delle applicazioni e dei servizi eseguiti in Kubernetes in modo nativo.
In questa guida creeremo passo dopo passo (Proof of Concept, PoC - prova di concetto), dimostrando questa nuova funzionalità. Ci si aspetta che tu abbia conoscenze di base su Kubernetes e Hashicorp’s Consul. Anche se puoi utilizzare qualsiasi piattaforma cloud o ambiente locale, in questa guida utilizzeremo Google Cloud Platform.
Panoramica
Se passiamo a , avremo una breve panoramica del suo scopo e dei casi d'uso, insieme ad alcuni dettagli tecnici e una visione generale della logica. Ti consiglio vivamente di leggerla almeno una volta prima di continuare, poiché ora spiegherò tutto ciò e lo analizzerò in dettaglio.

Schema 1: Panoramica ufficiale del metodo di autorizzazione di Consul
Diamo un'occhiata alla .
Certo, ci sono informazioni utili, ma non c'è una guida su come utilizzare effettivamente tutto questo. Quindi, come chiunque di buon senso, inizi a cercare una guida su Internet. E poi… subisci una sconfitta. Può capitare. Correggiamolo.
Prima di passare alla creazione del nostro POC, torniamo alla panoramica dei metodi di autorizzazione di Consul (Schema 1) e chiarifichiamo il contesto di Kubernetes.
Architettura
In questa guida, creeremo un server Consul su una macchina separata che interagirà con il 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 key/value di Consul.
Lo schema sottostante mostra in dettaglio l'architettura che stiamo costruendo 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 nota: il server Consul non deve necessariamente risiedere al di fuori del cluster Kubernetes affinché funzioni. Ma sì, può essere sia dentro che fuori.
Quindi, prendendo la panoramica del Consul (Schema 1) e applicandola a Kubernetes, otteniamo lo schema sopra (Schema 2), e la logica è la seguente:
- A ciascun pod verrà associato un account di servizio contenente un token JWT, generato e noto a Kubernetes. Questo token viene anche inserito nel pod di default.
- La nostra applicazione o servizio all'interno del pod avvia una richiesta di accesso al nostro client Consul. La richiesta di accesso include anche il nostro token e specifica il nome di un metodo di autorizzazione creato appositamente (tipo Kubernetes). Questo passaggio n. 2 corrisponde al passaggio 1 dello schema Consul (Schema 1).
- Il nostro client Consul invierà quindi questa richiesta al nostro server Consul.
- MAGIA! Qui il server Consul verifica l'autenticità della richiesta, raccoglie informazioni sull'identità della richiesta e le confronta con eventuali regole predefinite associate. Di seguito ci sarà un altro schema per illustrare questo. 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 permessi in base alle regole del metodo di autorizzazione che abbiamo definito in relazione all'identità del richiedente. Quindi lo invierà indietro. Questo corrisponde al passaggio 6 dello schema Consul (Schema 1).
- Il nostro client Consul reindirizza il token all'applicazione o al servizio richiedente.
La nostra applicazione o servizio ora può utilizzare questo token Consul per interagire con i nostri dati Consul, come definito dai privilegi del token.
La magia è rivelata!
Per coloro di voi che non si accontentano di un semplice coniglio dal cappello e vogliono sapere come funziona… lasciate che vi «mostri quanto è profonda la tana del coniglio».
Come accennato in precedenza, il nostro passaggio “magico” (Schema 2: Passaggio 4) consiste nel fatto 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) il cui obiettivo è illustrare cosa succede realmente sotto il cofano di un specifico metodo di autorizzazione Kubernetes.

Schema 3: Magia rivelata!
- 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. Pertanto, consulterà il cluster Kubernetes (attraverso il client Consul) e, se ci sono le autorizzazioni appropriate, scopriremo se il token è autentico e a chi appartiene.
- Successivamente, la richiesta verificata viene restituita al leader di Consul, e sul server Consul viene cercato l'istanza del metodo di autorizzazione con il nome specificato nella richiesta di accesso (e tipo Kubernetes).
- Il leader di Consul identifica l'istanza del metodo di autorizzazione specificato (se trovata) e legge il set di regole di vincolo ad essa associate. Poi legge queste regole e le confronta con gli attributi di identità verificati.
- Ecco! Passiamo al passo 5 nella spiegazione precedente dello schema.
Esegui il server Consul su una normale macchina virtuale
A partire da questo momento, fornirò principalmente istruzioni per creare questo POC, spesso in punti, senza frasi esplicative complete. Come già accennato, utilizzerò GCP per creare l'intera infrastruttura, ma puoi costruire la stessa infrastruttura altrove.
- 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 alla regola e al tag di rete, in questo caso si tratta di "skywiz-consul-server-poc".
- Trova l'indirizzo IP del tuo computer locale e aggiungilo all'elenco degli IP sorgente, in modo da poter 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 alla dashboard della 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 ti serve la 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 all'installazione di Consul e alla configurazione di un cluster di 3 nodi qui. .
- Crea il file /etc/consul.d/agent.json in questo 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 IP sulla porta 8500. Assicurati che si apra l'UI.
- Prova ad aggiungere un paio di chiave/valore. Dovresti ricevere un errore. Questo perché abbiamo caricato il server Consul con ACL e bloccato tutte le regole.
- Torna al tuo terminale sul server Consul e esegui il processo in background o in altro modo affinché funzioni, e digita quanto segue:
consul acl bootstrap- Trova il valore «SecretID» e torna all'UI. Nella scheda «ACL» inserisci l'identificatore segreto del token che hai appena copiato. Copia il SecretID da qualche altra parte, ne avremo bisogno più tardi.
- Ora aggiungi un paio di chiave/valore. Per questo POC aggiungeremo quanto segue: chiave: «custom-ns/test_key», valore: «Sono nella cartella custom-ns!»
Avvia il 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, quindi possiamo utilizzare la stessa subnet per una semplice connessione con indirizzi IP interni. Lo chiameremo «skywiz-app-with-consul-client-poc».

- A proposito, ecco una buona guida che ho trovato mentre impostavo il POC del cluster Consul con Consul Connect.
- Utilizzeremo anche il chart di Helm di 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- helm chart:
- Usa il seguente file di valori (nota che ho disabilitato la maggior parte):
### 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 chart di helm:
./helm install -f poc-helm-consul-values.yaml ./consul-helm --name skywiz-app-with-consul-client-poc- Quando lo avvii, avrà bisogno di autorizzazioni per il server Consul, quindi aggiungiamole.
- Controlla l'«intervallo degli indirizzi Pod» situato nel pannello del cluster e torna alla nostra regola per il firewall «skywiz-consul-server-poc».
- Aggiungi l'intervallo degli indirizzi per il pod all'elenco degli IP e apri le porte 8301 e 8300.

- Vai all'UI di Consul e dopo alcuni minuti vedrai che il nostro cluster apparirà nella scheda nodi.

Configurazione del metodo di autorizzazione mediante integrazione di Consul con Kubernetes
- Torna al terminale del server Consul ed esporta il token che hai salvato in precedenza:
export CONSUL_HTTP_TOKEN=- Avremo bisogno delle 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 -consul-client -o yaml | grep "- name:"
kubectl get secret -o yaml | grep token:- Il token è codificato in base64, quindi decodificalo con 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 inseriscilo nel file “ca.crt”.
- Ora crea un'istanza del metodo 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 autenticazione che utilizza kubernetes per il cluster skywiz-app-with-consul-client-poc"
-kubernetes-host ""
-kubernetes-ca-cert=@ca.crt
-kubernetes-service-account-
jwt=""- Poi dobbiamo creare una regola e associarla al nuovo ruolo. Per questa parte puoi usare l'interfaccia utente di Consul, ma 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 "Questo è un esempio di policy per kv a custom-ns/"
-rules @kv-custom-ns-policy.hcl- Trova l'identificativo della regola che hai appena creato, dai risultati.
- 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 auth. Nota che il flag «selector» determina se la nostra richiesta di accesso riceverà questo ruolo. Controlla qui altre opzioni per il selettore:
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 per finire
Diritti di accesso
- Crea i permessi. Dobbiamo consentire a Consul di verificare e identificare l'identità del token dell'account di 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 i permessi
kubectl create -f skywiz-poc-consul-server_rbac.yamlCollegamento a Consul Client
- Come notato , ci sono diverse opzioni per collegarsi a daemonset, ma passeremo alla prossima 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- Poi applica il seguente comando incorporato per creare configmap []. Nota 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}')"]}
EOFTestare il metodo auth
Ora vediamo la magia in azione!
- Crea alcune chiavi di esempio con la stessa chiave di primo livello (cioè /sample_key) e valori a tua scelta. Crea le politiche e i ruoli corrispondenti per i nuovi percorsi delle chiavi. Faremo le associazioni più tardi.

Test namespace personalizzato:
- Creiamo il nostro namespace:
kubectl create namespace custom-ns- Creiamo un pod nel nostro nuovo namespace. 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 il pod:
kubectl create -f poc-ubuntu-custom-ns.yaml- Una volta avviato il contenitore, accedici 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 in un file all'interno del contenitore:
### payload.json
{
"AuthMethod": "auth-method-test",
"BearerToken": "<jwt_token>"
}- Accedi!
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é eseguiamo 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, almeno. Ora prendi il SecretID e cerca di accedere al valore/chiave 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'UI. Se hai usato lo stesso valore fornito sopra in questa guida, il tuo valore codificato sarà IkknbSBpbiB0aGUgY3VzdG9tLW5zIGZvbGRlciEi.
Test account di servizio personalizzato:
- Crea un ServiceAccount personalizzato con 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 lavoro 🙂
###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 di che, avvia una shell all'interno del contenitore.
kubectl exec -it poc-ubuntu-custom-sa /bin/bash- Accedi!
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- Permission denied. Oh, ci siamo dimenticati di aggiungere la nuova associazione di regole con i permessi corrispondenti, facciamo ora.
Ripeti i passaggi precedenti:
a) Crea una Politica identica per il prefisso «custom-sa/».
b) Crea un Ruolo, chiamalo «custom-sa-role»
c) Collega la Politica al Ruolo.
- Crea un Rule-Binding (possibile solo tramite cli / api). Fai attenzione al diverso 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"'- Ripeti il login dal container «poc-ubuntu-custom-sa». Successo!
- Verifica 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 a kv in «custom-ns/». Basta ripetere il comando sopra sostituendo «custom-sa» con il prefisso «custom-ns».
Permesso negato.
Esempio di overlay:
- È importante notare che tutte le associazioni di rule-binding saranno aggiunte al token con questi diritti.
- Il nostro container «poc-ubuntu-custom-sa» si trova nello spazio dei nomi predefinito — quindi utilizziamolo per un'altra rule-binding.
- Ripeti i passaggi precedenti:
a) Crea una Politica identica per il prefisso chiave «default/».
b) Crea un Ruolo, chiamalo “default-ns-role”
c) Collega la Politica al Ruolo. - Crea un Rule-Binding (possibile solo tramite 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 container «poc-ubuntu-custom-sa» e prova ad accedere al percorso «default/» kv.
- Permesso negato.
Puoi visualizzare le credenziali specificate per ogni token nell'UI nella sezione ACL > Tokens. Come puoi vedere, al nostro attuale token è associata solo una «custom-sa-role». Il token che stiamo attualmente usando è stato generato quando abbiamo effettuato il login, e allora c'era solo una rule-binding 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 del 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 l'automazione sicura dell'autenticazione Consul.
Esiste la possibilità di 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
Speriamo che a breve saremo in grado di controllare come vengono generati i token (per ogni regola o metodo di autorizzazione) e di aggiungere TTL.
Fino ad allora, si consiglia di utilizzare nella propria logica il punto finale di logout.
Leggi anche altri articoli nel nostro blog:
Fonte: habr.com
