
Totul este corect, după lansare la începutul lunii mai 2019, în Consul este posibil să se facă autorizarea aplicațiilor și serviciilor care rulează în Kubernetes, nativ.
În acest ghid, vom crea pas cu pas (Proba de concept (Proof of concept, PoC) — dovada [viabilității] conceptului — n.red.), demonstrând această nouă funcționalitate. Se așteaptă de la dumneavoastră cunoștințe de bază despre Kubernetes și Hashicorp’s Consul. Și, deși puteți utiliza orice platformă cloud sau un mediu local, în acest ghid ne vom folosi de Google’s Cloud Platform.
Prezentare generală
Dacă ne îndreptăm spre , vom obține o prezentare generală a scopului și cazului de utilizare, precum și câteva detalii tehnice și o imagine de ansamblu asupra logicii. Vă recomand cu tărie să o citiți cel puțin o dată înainte de a continua, deoarece acum voi explica și detalia toate acestea.

Schema 1: Prezentarea oficială a metodei de autorizare Consul
Să ne uităm în .
Desigur, există informații utile acolo, dar nu există un ghid despre cum să folosiți efectiv toate acestea. Așa că, ca orice persoană cu bun simț, căutați pe internet un ghid. Și apoi... suferiți o înfrângere. Se mai întâmplă. Haideți să corectăm asta.
Înainte de a începe crearea POC-ului nostru, să ne întoarcem la prezentarea generală a metodelor de autorizare Consul (Schema 1) și să o detaliem în contextul Kubernetes.
Arhitectură
În acest ghid, vom crea un server Consul pe o mașină separată, care va interacționa cu clusterul Kubernetes cu clientul Consul instalat. Apoi, vom crea aplicația noastră fictivă în pod și vom folosi metoda noastră de autorizare configurată pentru a citi din stocarea Consul key/value.
Schema de mai jos ilustrează detaliile arhitecturii pe care o construim în acest ghid, precum și logica metodei de autorizare, care va fi explicată ulterior.

Schema 2: Prezentarea metodei de autorizare în Kubernetes
O mică observație: serverul Consul nu trebuie să fie situat în afara clusterului Kubernetes pentru a funcționa. Dar da, poate fi și așa.
Așadar, luând schema de bază Consul (Schema 1) și aplicând-o la Kubernetes, obținem diagramă de mai sus (Schema 2), iar logica va fi următoarea:
- Fiecărei pod îi va fi atașat un cont de serviciu, care conține un token JWT, generat și cunoscut de Kubernetes. Acest token este, de asemenea, inserat în podul implicit.
- Aplicația sau serviciul nostru din interiorul podului inițiază un comutator de autentificare către clientul nostru Consul. În cererea de autentificare va fi inclus și tokenul nostru și va fi specificat numele creat special metodei de autorizare (tip Kubernetes). Acest pas nr. 2 corespunde pasului 1 din schema Consul (Schema 1).
- Clientul nostru Consul va direcționa apoi această cerere către serverul nostru Consul.
- MAGIE! Aici serverul Consul verifică autenticitatea cererii, adună informațiile despre identitatea cererii și le compară cu eventuale reguli predefinite asociate. Mai jos va fi o altă schemă pentru a ilustra acest lucru. Acest pas corespunde pașilor 3, 4 și 5 din schema de revizuire Consul (Schema 1).
- Serverul nostru Consul generează un token Consul cu permisiuni conforme cu regulile specificate de noi pentru metoda de autorizare (pe care le-am definit) în raport cu identitatea solicitantului. Apoi, acesta va trimite înapoi acest token. Acesta corespunde pasului 6 din schema Consul (Schema 1).
- Clientul nostru Consul redirecționează tokenul aplicației sau serviciului solicitant.
Aplicația sau serviciul nostru pot acum utiliza acest token Consul pentru a comunica cu datele noastre Consul, așa cum a fost definit în privilegiile tokenului.
Magia dezvăluită!
Pentru cei dintre voi care nu sunt mulțumiți doar cu un iepure din pălărie și vor să știe cum funcționează… permiteți-mi să vă „arăt cât de adâncă vopseaua de iepure».
După cum am menționat anterior, „magicul” nostru pas (Schema 2: Pasul 4) constă în faptul că serverul Consul verifică autenticitatea cererii, adună detalii despre cerere și le compară cu orice reguli predefinite asociate. Acest pas corespunde pașilor 3, 4 și 5 din schema de revizuire Consul (Schema 1). Mai jos este o schemă (Schema 3), al cărei scop este să arate vizibil ceea ce se întâmplă de fapt sub capotă metodei specifice de autorizare Kubernetes.

Schema 3: Magia dezvăluită!
- Ca punct de plecare, clientul nostru Consul redirecționează cererea de autentificare către serverul nostru Consul cu tokenul contului Kubernetes și numele specific al instanței metodei de autorizare, care a fost creat anterior. Acest pas corespunde pasului 3 din explicația anterioară a schemei.
- Acum, serverul Consul (sau liderul) trebuie să verifice autenticitatea tokenului primit. De aceea, acesta va consulta clusterul Kubernetes (prin intermediul clientului Consul) și, în cazul în care are permisiunile necesare, vom determina dacă tokenul este autentic și cui aparține.
- Apoi, cererea verificată este returnată liderului Consul, iar pe serverul Consul se caută instanța metodei de autorizare cu numele specificat din cererea de autentificare (de tip Kubernetes).
- Liderul Consul identifică instanța specificată a metodei de autorizare (dacă este găsită) și citește setul de reguli de legătură care îi sunt atașate. Apoi, citește aceste reguli și le compară cu atributele identității verificate.
- Tada! Trecem la pasul 5 din explicația anterioară a schemei.
Rulați Consul-server pe o mașină virtuală obișnuită.
De acum înainte, voi oferi în principal instrucțiuni pentru crearea acestui POC, adesea sub formă de puncte, fără propoziții explicative întregi. De asemenea, după cum am menționat anterior, voi folosi GCP pentru a crea întreaga infrastructură, dar puteți crea o infrastructură similară în altă parte.
- Rulați o mașină virtuală (instanță / server).

- Creează o regulă pentru firewall (grup de securitate în AWS):
- Îmi place să atribui același nume mașinii regulii și etichetei de rețea, în acest caz este «skywiz-consul-server-poc».
- Găsiți adresa IP a computerului local și adăugați-o în lista IP-urilor sursă, astfel încât să putem accesa interfața utilizatorului (UI).
- Deschideți portul 8500 pentru UI. Faceți clic pe Create (Creează). Vom modifica din nou acest firewall în curând [].
- Adăugați regula pentru firewall instanței. Întoarceți-vă la tabloul de bord VM de pe serverul Consul și adăugați «skywiz-consul-server-poc» în câmpul etichetelor de rețea. Faceți clic pe Save (Salvează).

- Instalați Consul pe mașina virtuală, verificați aici. Amintiți-vă că aveți nevoie de versiunea Consul ≥ 1.5 [link]
- Să creăm un Consul single node — configurația este următoarea.
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- Un ghid mai detaliat pentru instalarea Consul și configurarea unui cluster de 3 noduri poate fi găsit aici. .
- Creează fișierul /etc/consul.d/agent.json astfel []:
### /etc/consul.d/agent.json
{
"acl" : {
"enabled": true,
"default_policy": "deny",
"enable_token_persistence": true
}
}- Rulați serverul nostru Consul:
consul agent
-server
-ui
-client 0.0.0.0
-data-dir=/var/lib/consul
-bootstrap-expect=1
-config-dir=/etc/consul.d- Ar trebui să vedeți o mulțime de ieșiri și, în final, „… actualizare blocată de ACL-uri”.
- Găsiți adresa IP externă a serverului Consul și deschideți un browser cu această adresă IP pe portul 8500. Asigurați-vă că interfața utilizatorului se deschide.
- Încercați să adăugați o pereche cheie/valoare. Ar trebui să fie o eroare. Acest lucru se datorează faptului că am încărcat serverul Consul cu ACL și am interzis toate regulile.
- Întoarceți-vă la shell-ul de pe serverul Consul și rulați procesul în fundal sau în alt mod pentru a-l face să funcționeze, și introduceți următoarele:
consul acl bootstrap- Găsiți valoarea „SecretID” și întoarceți-vă la interfața utilizatorului. În tab-ul „ACL”, introduceți identificatorul secret al tokenului pe care tocmai l-ați copiat. Salvați SecretID undeva, ne va fi necesar mai târziu.
- Acum adăugați o pereche cheie/valoare. Pentru acest POC, vom adăuga următoarele: cheie: „custom-ns/test_key”, valoare: „Sunt în folderul custom-ns!”
Lansare a clusterului Kubernetes pentru aplicația noastră cu clientul Consul ca Daemonset
- Creați un cluster K8s (Kubernetes). Îl vom crea în aceeași zonă ca serverul, pentru un acces mai rapid, astfel încât putem folosi aceeași subrețea pentru o conexiune ușoară cu adrese IP interne. Îl vom numi „skywiz-app-with-consul-client-poc”.

- Ca o notă, iată un ghid bun cu care m-am întâlnit în timpul configurării POC-ului clusterului Consul cu Consul Connect.
- De asemenea, vom folosi graficul helm Hashicorp cu un fișier de valori extins.
- Instalați și configurați Helm. Etapele de configurare:
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- grafic helm:
- Utilizați următorul fișier de valori (rețineți că majoritatea am dezactivat):
### 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- Aplicați graficul helm:
. /helm install -f poc-helm-consul-values.yaml . /consul-helm - name skywiz-app-with-consul-client-poc- Când încercați să rulați, îi vor fi necesare permisiuni pentru serverul Consul, așa că haideți să le adăugăm.
- Reveniți la „intervalul de adrese Pod” situat pe panoul de control al clusterului și întoarceți-vă la regula noastră pentru firewall-ul „skywiz-consul-server-poc”.
- Adăugați intervalul de adrese pentru pod în lista de adrese IP și deschideți porturile 8301 și 8300.

- Accesați interfața utilizatorului Consul, iar în câteva minute veți vedea că clusterul nostru va apărea pe tab-ul noduri.

Configurarea metodei de autorizare prin integrarea Consul cu Kubernetes
- Întoarceți-vă la shell-ul serverului Consul și exportați tokenul pe care l-ați salvat anterior:
export CONSUL_HTTP_TOKEN=- Vom necesita informații din clusterul nostru Kubernetes pentru a crea o instanță a metodei 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:- Tokenul este codificat în base64, așa că decodificați-l cu instrumentul dumneavoastră preferat []
- kubernetes-ca-cert
kubectl get secret -o yaml | grep ca.crt:- Luați certificatul "ca.crt" (după decodificare cu base64) și introduceți-l în fișierul "ca.crt".
- Acum creați o instanță a metodei auth, înlocuind locurile rezervate cu valorile pe care tocmai le-ați obținut.
consul acl auth-method create -type "kubernetes" -name "auth-method-skywiz-consul-poc" -description "Aceasta este o metodă de autentificare folosind kubernetes pentru clusterul skywiz-app-with-consul-client-poc" -kubernetes-host "" -kubernetes-ca-cert=@ca.crt -kubernetes-service-account-jwt=""- În continuare, trebuie să creăm o regulă și să o atașăm unui nou rol. Pentru această parte, puteți folosi interfața utilizatorului Consul, dar vom folosi linia de comandă.
- Scrieți regula
### kv-custom-ns-policy.hcl
key_prefix "custom-ns/" {
policy = "write"
}- Aplicați regula
consul acl policy create -name kv-custom-ns-policy -description "Aceasta este o politică exemplu pentru kv la custom-ns/" -rules @kv-custom-ns-policy.hcl- Găsiți identificatorul regulii pe care tocmai ați creat-o din ieșirea datelor.
- Creați un rol cu noua regulă.
consul acl role create -name "custom-ns-role" -description "Aceasta este un rol exemplu pentru spațiul de nume custom-ns" -policy-id- Acum vom lega noul nostru rol de instanța metodei auth. Rețineți că flagul „selector” determină dacă cererea noastră de intrare va obține acest rol. Verificați aici alte opțiuni de selector:
consul acl binding-rule create -method=auth-method-skywiz-consul-poc -bind-type=role -bind-name='custom-ns-role' -selector='serviceaccount.namespace=="custom-ns"'Configurările de final
Permisiuni
- Creați permisiunile. Trebuie să dăm Consul permisiunea de a verifica și identifica certificatul tokenului contului de serviciu K8s.
- Scrieți în fișier următorul lucru :
###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- Să creăm permisiunile
kubectl create -f skywiz-poc-consul-server_rbac.yamlConectare la Consul Client
- După cum s-a menționat , există câteva opțiuni pentru a se conecta la daemonset, dar vom trece la următoarea soluție simplă:
- Aplicați următorul fișier [].
### 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- Apoi, aplicați următoarea comandă încorporată pentru a crea configmap []. Rețineți că facem referire la numele serviciului nostru, înlocuiți-l dacă este necesar.
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}')"]}
EOFTestarea metodei de autentificare
Acum să vedem magia în acțiune!
- Creează câteva alte foldere cheie cu aceeași cheie de nivel superior (adică /sample_key) și o valoare la alegerea ta. Creează politicile și rolurile corespunzătoare pentru noile căi de cheie. Vom face legăturile mai târziu.

Testul utilizatorului pentru spațiul de nume:
- Să creăm propriul nostru spațiu de nume:
kubectl create namespace custom-ns- Să creăm un pod în noul nostru spațiu de nume. Scrie configurația pentru 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- Creează un pod:
kubectl create -f poc-ubuntu-custom-ns.yaml- Odată ce containerul pornește, intră în el și instalează curl.
kubectl exec poc-ubuntu-custom-ns -n custom-ns -it /bin/bash
apt-get update && apt-get install curl -y- Acum vom trimite o cerere de autentificare către Consul, folosind metoda de autorizare pe care am creat-o anterior [].
- Pentru a vizualiza tokenul introdus din contul tău de serviciu:
cat /run/secrets/kubernetes.io/serviceaccount/token- Scrie următoarele în fișierul din interiorul containerului:
### 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- Pentru a executa pașii de mai sus într-o singură linie (deoarece vom face mai multe teste), poți face următoarele:
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- Merge! Ar trebui să funcționeze, cel puțin. Acum ia SecretID și încearcă să accesezi cheia/valoarea la care ar trebui să avem acces.
curl
consul-ds-client.default.svc.cluster.local/v1/kv/custom-ns/test_key --header “X-Consul-Token: ”- Poți decoda „Value” base64 și vezi că se potrivește cu valoarea din custom-ns/test_key în UI. Dacă ai folosit aceeași valoare menționată mai sus în acest ghid, valoarea ta codificată va fi IkknbSBpbiB0aGUgY3VzdG9tLW5zIGZvbGRlciEi.
Testul contului de serviciu personalizat:
- Creează un ServiceAccount personalizat folosind următoarea comandă [].
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: custom-sa
EOF- Creează un nou fișier de configurație pentru pod. Observă că am inclus instalarea curl pentru a economisi efort 🙂
###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- După aceea, lansează shell-ul în interiorul containerului.
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- Permisiune refuzată. Oh, am uitat să adăugăm un nou binding de reguli cu permisiunile corespunzătoare, să facem asta acum.
Repetă pașii anteriori de mai sus:
a) Creează o Politică identică pentru prefixul „custom-sa/”.
b) Creează un Rol, numește-l „custom-sa-role”
c) Atașează Politica la Rol.
- Creează un Rule-Binding (posibil doar din cli / api). Acordă atenție unei alte valori a semnului selector.
consul acl binding-rule create
-method=auth-method-skywiz-consul-poc
-bind-type=role
-bind-name='custom-sa-role'
-selector='serviceaccount.name=="custom-sa"'- Reîntrează-te în sistem din containerul „poc-ubuntu-custom-sa”. Succes!
- Verifică accesul nostru la calea cheie custom-sa/.
curl
consul-ds-client.default.svc.cluster.local/v1/kv/custom-sa/test_key --header “X-Consul-Token: ”- De asemenea, poți verifica că acest token nu oferă acces la kv în „custom-ns/”. Pur și simplu repetă comanda de mai sus înlocuind „custom-sa” cu prefixul „custom-ns”.
Permisiune refuzată.
Exemplu de overlay:
- Merită menționat că toate asocierile de rule-binding vor fi adăugate la token cu aceste drepturi.
- Containerul nostru „poc-ubuntu-custom-sa” se află în spațiul de nume implicit — așa că să-l folosim pentru un alt rule-binding.
- Repetă pașii anteriori:
a) Creează o Politică identică pentru prefixul cheii „default/”.
b) Creează un Rol, numește-l „default-ns-role”
c) Atașează Politica la Rol. - Creează un Rule-Binding (posibil doar din 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"'- Întoarce-te la containerul nostru „poc-ubuntu-custom-sa” și încearcă să accesezi calea „default/” kv.
- Permisiune refuzată.
Poți vizualiza acreditivele specificate pentru fiecare token în UI în secțiunea ACL > Tokens. Așa cum vezi, la tokenul nostru curent este atașată doar o „custom-sa-role”. Tokenul pe care îl folosit în prezent a fost generat când ne-am autentificat, și atunci a existat doar un singur rule-binding care corespundea. Trebuie să ne autentificăm din nou și să folosim un nou token. - Asigură-te că poți citi atât din căile „custom-sa/”, cât și din „default/” kv.
Succes!
Aceasta se datorează faptului că „poc-ubuntu-custom-sa” corespunde bindurilor de reguli „custom-sa” și „default-ns”.
Concluzie
Gestionarea token-ului TTL?
La momentul redactării acestui articol, nu există o modalitate integrată de a determina TTL pentru token-urile generate prin această metodă de autorizare. Aceasta ar fi o oportunitate fantastică - pentru a oferi automatizare sigură pentru autorizarea Consul.
Există posibilitatea de a crea manual un token cu TTL:
Expiration Time (Timpul de expirare) — momentul în care acest token va fi revocat. (Opțional; adăugat în Consul 1.5.0)- Există doar pentru crearea / actualizarea manuală
Sper că în curând vom putea controla modul în care sunt generate tokenurile (pentru fiecare regulă sau metodă de autorizare) și adăuga TTL.
Până atunci, se recomandă utilizarea în logica sa a endpoint-ului de deconectare.
Citiți și alte articole de pe blogul nostru:
Sursa: habr.com
