Въведение в Hashicorp Consul за авторизация в Kubernetes

Въведение в Hashicorp Consul за авторизация в Kubernetes

Всичко е вярно, след излизането Hashicorp Consul 1.5.0 в началото на май 2019 година в Consul бе добавена възможността за авторизация на приложения и услуги, стартирани в Kubernetes, нативно.

В това ръководство стъпка по стъпка ще създадем POC (Проверка на концепцията (Proof of concept, PoC — доказателство [осуществимости] концепции — бел. прев.), демонстрирайки тази нова функция. Очаква се да имате основни познания за Kubernetes и Hashicorp Consul. И докато можете да използвате всяка облачна платформа или локална среда, в това ръководство ще използваме Google Cloud Platform.

Преглед

Ако преминем към документацията на Consul за неговия метод на авторизация, ще получим кратък преглед на предназначението и приложението му, както и някои технически детайли и общ преглед на логиката. Настоятелно препоръчвам да я прочетете поне веднъж, преди да продължите, тъй като сега ще обясня всичко това.

Въведение в Hashicorp Consul за авторизация в Kubernetes

Схема 1: Официален преглед на метода за авторизация на Consul

Нека погледнем в документацията за конкретния метод на авторизация в Kubernetes.

Разбира се, там има полезна информация, но няма ръководство как всъщност да се използва всичко това. Така че, както всеки разумен човек, търсите в Интернет ръководство. И след това… претърпявате неуспех. Случва се. Нека го поправим.

Преди да преминем към създаването на нашия POC, нека се върнем към прегледа на методите за авторизация на Consul (Схема 1) и да го уточним в контекста на Kubernetes.

Архитектура

В това ръководство ще създадем Consul сървър на отделна машина, която ще комуникира с кластера на Kubernetes, на който е инсталиран клиентът на Consul. След това ще създадем нашето демонстрационно приложение в пода и ще използваме нашия конфигуриран метод на авторизация, за да четем от нашето хранилище за ключ/стойност на Consul.

Схемата по-долу подробно показва архитектурата, която изграждаме в това ръководство, както и логиката на метода за авторизация, която ще бъде обяснена по-късно.

Въведение в Hashicorp Consul за авторизация в Kubernetes

Схема 2: Преглед на метода за авторизация в Kubernetes

Няколко забележки: на Consul сървъра не му е необходимо да се намира извън кластерa на Kubernetes, за да работи. Но да, той може да бъде и там и тук.

И така, взимайки обзорната схема на Consul (Схема 1) и прилагайки я към Kubernetes, получаваме схемата по-горе (Схема 2), и логиката ще бъде следната:

  1. На всеки под ще бъде прикачен служебен акаунт, който съдържа JWT токен, генериран и познат на Kubernetes. Този токен също така се внедрява в пода по подразбиране.
  2. Нашето приложение или услуга вътре в пода инициира команда за вход в нашия Consul клиент. В заявката за вход също ще бъде указан нашият токен и името специфично създадено метод за удостоверяване (тип Kubernetes). Тази стъпка № 2 съответства на стъпка 1 от схемата на Consul (Схема 1).
  3. Нашият Consul клиент след това ще насочи този заявка към нашия Consul сървър.
  4. МАГИЯ! Тук Consul сървърът проверява автентичността на заявката, събира информация за идентичността на запитването и я сравнява с предварително зададени правила. По-долу ще представим друга схема, за да илюстрираме това. Тази стъпка съответства на стъпки 3, 4 и 5 от обзорната схема на Consul (Схема 1).
  5. Нашият Consul сървър генерира Consul токен с разрешения, в съответствие с указаните от нас правила на метода за удостоверяване (които сме определили) по отношение на личността на запитващия. След това той ще изпрати този токен обратно. Това съответства на стъпка 6 от схемата на Consul (Схема 1).
  6. Нашият Consul клиент пренасочва токена на запитващото приложение или услуга.

Нашето приложение или услуга сега могат да използват този Consul токен, за да взаимодействат с нашите данни в Consul, както е определено от привилегиите на токена.

Магията е разкрита!

За онези от вас, които не са доволни само от заек от шапка и искат да знаят как работи… нека ви „покажа колко дълбока е заешката дупка».

Както бе споменато по-рано, нашата „магическа“ стъпка (Схема 2: Стъпка 4) е, че Consul сървърът проверява автентичността на заявката, събира информация за заявката и я сравнява с всякакви свързани предварително зададени правила. Тази стъпка съответства на стъпки 3, 4 и 5 от обзорната схема на Consul (Схема 1). По-долу имате схема (Схема 3), целта на която е да илюстрира какво всъщност се случва под капака конкретния метод за удостоверяване на Kubernetes.

Въведение в Hashicorp Consul за авторизация в Kubernetes

Схема 3: Магията е разкрита!

  1. Като отправна точка, нашият Consul клиент пренасочва заявката за вход към нашия Consul сървър с токен на акаунта на Kubernetes и конкретното име на инстанцията на метода за удостоверяване, който беше създаден по-рано. Тази стъпка съответства на стъпка 3 в предишното обяснение на схемата.
  2. Сега на Consul-сервера (или лидера) му е необходимо да провери автентичността на получения токен. Затова той ще се консултира с Kubernetes клъстера (чрез Consul-клиент) и ако има подходящи разрешения, ние ще разберем дали токенът е автентичен и на кого принадлежи.
  3. След това провереното искане се връща на Consul-лидера и на Consul-сервера се извършва търсене на инстанс на метода за удостоверяване с указаното име от искането за вход в системата (и тип Kubernetes).
  4. Consul-лидерът определя указания инстанс на метода за удостоверяване (ако бъде намерен) и прочита набора от правила за свързване, които са прикрепени към него. След това той прочита тези правила и ги сравнява с проверените атрибути на идентичността.
  5. Ура! Преминаваме към стъпка 5 в предишното обяснение на схемата.

Стартирайте Consul-сервер на обикновена виртуална машина

От този момент нататък основно ще давам инструкции за създаване на този POC, често в точки, без обяснителни изречения. Както беше отбелязано по-рано, ще използвам GCP за изграждането на цялата инфраструктура, но можете да създадете същата инфраструктура на всяко друго място.

  • Стартирайте виртуалната машина (инстанс / сървър).

Въведение в Hashicorp Consul за авторизация в Kubernetes

  • Създайте правило за защитната стена (група за сигурност в AWS):
  • Обичам да присвоявам същото име на машината на правилото и мрежовия таг, в този случай това е "skywiz-consul-server-poc".
  • Намерете IP адреса на локалния си компютър и го добавете в списъка на изходящите IP адреси, за да можем да имаме достъп до потребителския интерфейс (UI).
  • Отворете порт 8500 за UI. Щракнете върху Create (Създаване). Скоро отново ще променим тази защитна стена [линк].
  • Добавете правило за защитната стена към инстанса. Върнете се на таблото за мониторинг на VM на Consul-сервера и добавете "skywiz-consul-server-poc" в полето за мрежови тагове. Щракнете върху Save (Запази).

Въведение в Hashicorp Consul за авторизация в Kubernetes

  • Инсталирайте Consul на виртуалната машина, проверете тук. Не забравяйте, че ви трябва версия на Consul ≥ 1.5 [линк]
  • Нека създадем single node Consul – конфигурацията е следната.

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

  • По-подробно ръководство за инсталиране на Consul и настройка на клъстер от 3 нода можете да намерите тук. тук.
  • Създайте файл /etc/consul.d/agent.json по следния начин [линк]:

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

  • Стартирайте нашия Consul-сървър:

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

  • Трябва да видите куп изходни данни и в крайна сметка „... update blocked by ACLs“.
  • Намерете външния IP адрес на Consul сървъра и отворете браузър с този IP адрес на порт 8500. Уверете се, че интерфейсът на потребителя се отваря.
  • Опитайте да добавите двойка ключ/стойност. Трябва да получите грешка. Това е така, защото сме заредили Consul сървъра с ACL и сме забранили всички правила.
  • Върнете се в терминала на Consul сървъра и стартирайте процеса във фонов режим или по друг начин, за да работи, и въведете следното:

consul acl bootstrap

  • Намерете стойността „SecretID“ и се върнете в интерфейса. На таба „ACL“ въведете секретния идентификатор на токена, който току-що копирахте. Копирайте SecretID на друго място, той ще ни е нужен по-късно.
  • Сега добавете двойка ключ/стойност. За този POC ще добавим следното: ключ: „custom-ns/test_key“, стойност: „Аз съм в папката custom-ns!“

Стартиране на Kubernetes клъстер за нашето приложение с Consul клиент като Daemonset

  • Създайте K8s (Kubernetes) клъстер. Ще го създадем в същата зона като сървера, за по-бърз достъп, и затова можем да използваме същата подсет за лесно свързване с вътрешни IP адреси. Ще го наречем „skywiz-app-with-consul-client-poc“.

Въведение в Hashicorp Consul за авторизация в Kubernetes

  • Като забележка, ето едно добро ръководство, на което се натъкнах при настройката на POC Consul клъстер с Consul Connect.
  • Също така ще използваме Helm chart на Hashicorp с разширен файл с настройки.
  • Инсталирайте и конфигурирайте Helm. Стъпки за конфигурация:

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

  • Приложете helm chart:

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

  • При опит за стартиране му ще са нужни разрешения за Consul сървъра, така че нека да ги добавим.
  • Обърнете внимание на „диапазона на адресите на Pod“, разположен на таблото на клъстера, и се върнете към нашето правило за защитна стена „skywiz-consul-server-poc“.
  • Добавете диапазона на адресите за пода в списъка с IP адреси и отворете портовете 8301 и 8300.

Въведение в Hashicorp Consul за авторизация в Kubernetes

  • Отидете в интерфейса на Consul и след няколко минути ще видите, че нашият клъстер ще се появи на таба с възли.

Въведение в Hashicorp Consul за авторизация в Kubernetes

Настройка на метода за удостоверяване чрез интеграция на Consul с Kubernetes.

  • Върнете се в терминала на Consul сървера и експортирайте токена, който запазихте по-рано:

export CONSUL_HTTP_TOKEN=

  • Нужна ни е информация от нашия Kubernetes клъстер, за да създадем инстанция на метода auth:
  • kubernetes-хост

kubectl get endpoints | grep kubernetes

  • kubernetes-сервисен-акаунт-jwt

kubectl get sa -consul-client -o yaml | grep "- name:"\nkubectl get secret  -o yaml | grep token:

  • Токенът е кодирано в base64, така че декодирайте го с помощта на вашия любим инструмент [линк]
  • kubernetes-ca-cert

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

  • Вземете сертификата “ca.crt” (след декодиране от base64) и го запишете в файл “ca.crt”.
  • Сега създайте инстанция на метода auth, заменяйки placeholders с стойностите, които току-що получихте.

consul acl auth-method create \n-type "kubernetes" \n-name "auth-method-skywiz-consul-poc" \n-description "Това е метод за автентикация, който използва kubernetes за клъстера skywiz-app-with-consul-client-poc" \n-kubernetes-host "" \n-kubernetes-ca-cert=@ca.crt \n-kubernetes-service-account-\njwt=""

  • След това трябва да създадем правило и да го свържем с новата роля. За тази част можете да използвате Consul UI, но ние ще използваме командния ред.
  • Напишете правило

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

  • Приложете правилото

consul acl policy create \n-name kv-custom-ns-policy \n-description "Това е пример на политика за kv в custom-ns/" \n-rules @kv-custom-ns-policy.hcl

  • Намерете идентификатора на правилото, което току-що създадохте, от изхода.
  • Създайте роля с новото правило.

consul acl role create \n-name "custom-ns-role" \n-description "Това е примерна роля за пространство custom-ns" \n-policy-id

  • Сега ще свържем новата роля с инстанцията на метода auth. Обърнете внимание, че флагът „селектор“ определя дали нашето входящо заявка ще получи тази роля. Проверете тук за други опции на селектора: https://www.consul.io/docs/acl/auth-methods/kubernetes.html#trusted-identity-attributes

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

Конфигурации за финал

Права за достъп

  • Създайте права за достъп. Трябва да дадем разрешение на Consul да проверява и идентифицира удостоверението на токена на K8s сервисния акаунт.
  • Запишете следното в файл [линк]:

###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

  • Нека създадем права за достъп

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

Свързване с Consul Client

  • Както вече отбелязахме тук, има няколко опции за свързване с daemonset, но ще преминем към следващото просто решение:
  • Прилагайте следния файл [линк].

### 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

  • След това приложете следващата вградена команда за създаване на configmap [линк]. Обърнете внимание, че се позоваваме на името на нашата услуга, сменете го при необходимост.

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

Тест на метода за идентификация

Сега нека видим магията в действие!

  • Създайте още няколко ключови папки с един и същ основен ключ (т.е. /sample_key) и стойността по ваш избор. Създайте съответстващи политики и роли за новите ключови пътища. Ние ще направим привързвания по-късно.

Въведение в Hashicorp Consul за авторизация в Kubernetes

Потребителски тест на пространството от имена:

  • Да създадем собствено пространство от имена:

kubectl create namespace custom-ns

  • Създайте под в нашето ново пространство от имена. Напишете конфигурация за пода.

###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

  • Създайте под:

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

  • След като контейнерът стартира, влезте в него и инсталирайте curl.

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

  • Сега ще изпратим заявка за влизане в Consul, използвайки метода за автентикация, който създадохме по-рано [линк].
  • За да видите въведения токен от вашата служебна сметка:

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

  • Напишете следното във файл в контейнера:

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

  • Вход!

curl 
--request POST 
--data @payload.json 
consul-ds-client.default.svc.cluster.local/v1/acl/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

  • Работи! Поне така трябва. Сега вземете SecretID и опитайте да получите достъп до ключа/стойността, до която трябва да имаме достъп.

curl 
consul-ds-client.default.svc.cluster.local/v1/kv/custom-ns/test_key --header "X-Consul-Token: "

  • Можете да декодирате "Value" base64 и да видите, че то съответства на стойността в custom-ns/test_key в UI. Ако сте използвали същата стойност, посочена по-горе в това ръководство, вашето кодирано значение ще бъде IkknbSBpbiB0aGUgY3VzdG9tLW5zIGZvbGRlciEi.

Тест на служебната сметка на потребителя:

  • Създайте потребителска служебна сметка с помощта на следната команда [линк].

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

  • Създайте нов файл за конфигурация за пода. Обърнете внимание, че включих инсталацията на curl за да спестя работа 🙂

###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

  • След това стартирайте черупка в контейнера.

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

  • Вход!

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

  • Достъпът е отказан. О, забравихме да добавим нова привързване на правила с съответните разрешения, нека направим това сега.

Повторете предишните стъпки:
а) Създайте идентична Политика за префикса "custom-sa/".
б) Създайте Роля, наречете я "custom-sa-role".
в) Прикрепете Политиката към Ролята.

  • Създайте Правило-привързване (възможно само от cli / api). Обърнете внимание на различното значение на флага на селектора.

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

  • Повторете влизането в контейнера "poc-ubuntu-custom-sa". Успех!
  • Проверете нашия достъп до ключовия път custom-sa/.

curl 
consul-ds-client.default.svc.cluster.local/v1/kv/custom-sa/test_key --header "X-Consul-Token: "

  • Можете също така да се уверите, че този токен не предоставя достъп до kv в "custom-ns/". Просто повторете горната команда, като смените "custom-sa" с префикса "custom-ns".
    Достъпът е отказан.

Пример за оверлей:

  • Важно е да се отбележи, че всички привързвания на правила ще бъдат добавени към токена с тези права.
  • Нашият контейнер "poc-ubuntu-custom-sa" е в пространство на имена по подразбиране — така че нека го използваме за друга привързване на правила.
  • Повторете предишните стъпки:
    а) Създайте идентична Политика за префикса на ключа "default/".
    б) Създайте Роля, наречете я "default-ns-role".
    в) Прикрепете Политиката към Ролята.
  • Създайте Правило-привързване (възможно само от 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"'

  • Върнете се към нашия контейнер "poc-ubuntu-custom-sa" и опитайте да получите достъп до пътя "default/" kv.
  • Достъпът е отказан.
    Можете да прегледате посочените идентификационные данни за всеки токен в UI в секцията ACL > Tokens. Както виждате, към текущия ни токен е прикрепена само една "custom-sa-role". Токенът, който използваме в момента, е бил генериран, когато влязохме в системата, и по това време е имало само едно привързване на правила, което тогава е съответствало. Нужно е отново да влезем в системата и да използваме нов токен.
  • Уверете се, че можете да четете както от пътищата "custom-sa/", така и от "default/" kv.
    Успех!
    Това е, защото нашият "poc-ubuntu-custom-sa" отговаря на привързванията на правила "custom-sa" и "default-ns".

Заключение

TTL управление на токени?

В момента на написването на тази статия не съществува интегриран начин за определяне на TTL за токени, генерирани по този метод на авторизация. Това би била фантастична възможност — да се осигури безопасна автоматизация на авторизацията на Consul.

Има възможност ръчно да се създаде токен с TTL:

Надявам се скоро да можем да контролираме как се генерират токените (за всяко правило или метод на авторизация) и да добавяме TTL.

До тогава се предлага да използвате крайна точка за изход от системата в логиката си.

Също така прочетете други статии в нашия блог:

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster