Vault with k8s: различия между версиями
Sirmax (обсуждение | вклад) (→Vault) |
Sirmax (обсуждение | вклад) (→Vault) |
||
Строка 112: | Строка 112: | ||
Так-как в моем случае все PODы находятся в отдельном namespace то: |
Так-как в моем случае все PODы находятся в отдельном namespace то: |
||
<PRE> |
<PRE> |
||
− | export NAMESPACE=" |
+ | export NAMESPACE="my-namespace-name" |
</PRE> |
</PRE> |
||
Получить имя "секрета" |
Получить имя "секрета" |
||
<PRE> |
<PRE> |
||
− | export SECRET_NAME=$( |
+ | export SECRET_NAME=$( \ |
kubectl \ |
kubectl \ |
||
--namespace ${NAMESPACE} \ |
--namespace ${NAMESPACE} \ |
||
Строка 122: | Строка 122: | ||
serviceaccount \ |
serviceaccount \ |
||
vault-tokenreview-service-account \ |
vault-tokenreview-service-account \ |
||
− | -o jsonpath='{.secrets[0].name}' |
+ | -o jsonpath='{.secrets[0].name}' ) |
+ | </PRE> |
||
− | ) |
||
+ | Зная имя секрета можно получить его токен: |
||
+ | <PRE> |
||
+ | export ACCOUNT_TOKEN=$( \ |
||
+ | kubectl \ |
||
+ | --namespace ${NAMESPACE} \ |
||
+ | get \ |
||
+ | secret ${SECRET_NAME} \ |
||
+ | -o jsonpath='{.data.token}' \ |
||
+ | | base64 --decode ) |
||
</PRE> |
</PRE> |
||
+ | В том же секрете содержится сертификат СА: |
||
− | export TR_ACCOUNT_TOKEN=$(kubectl --namespace ${NAMESPACE} get secret ${SECRET_NAME} -o jsonpath='{.data.token}' | base64 --decode) |
||
+ | <PRE> |
||
− | |||
+ | export SERVICE_ACCOUNT_CA_CRT=$( \ |
||
+ | kubectl \ |
||
+ | --namespace ${NAMESPACE} \ |
||
+ | get \ |
||
+ | secret ${SECRET_NAME} \ |
||
+ | -o jsonpath="{.data['ca\.crt']}" \ |
||
+ | | base64 --decode; echo ) |
||
+ | Настроить vault (адрес API можно взять из конфигурации kubectl) |
||
− | export SA_CA_CRT=$(kubectl --namespace ${NAMESPACE} get secret ${SECRET_NAME} -o jsonpath="{.data['ca\.crt']}" | base64 --decode; echo) |
||
+ | <PRE> |
||
− | echo ${TR_ACCOUNT_TOKEN} |
||
+ | vault \ |
||
− | |||
− | echo $TR_ACCOUNT_TOKEN | base64 -d |
||
− | |||
− | ${VAULT} \ |
||
write \ |
write \ |
||
auth/kubernetes/config \ |
auth/kubernetes/config \ |
||
kubernetes_host="https://192.168.191.2:443" \ |
kubernetes_host="https://192.168.191.2:443" \ |
||
− | kubernetes_ca_cert="${ |
+ | kubernetes_ca_cert="${SERVICE_ACCOUNT_CA_CRT}" \ |
− | token_reviewer_jwt="${ |
+ | token_reviewer_jwt="${ACCOUNT_TOKEN}" |
+ | </PRE> |
||
− | |||
− | |||
+ | <PRE> |
||
+ | export VAULT_K8S_ROLE="" |
||
+ | </PRE> |
||
${VAULT} \ |
${VAULT} \ |
||
write \ |
write \ |
||
Строка 150: | Строка 165: | ||
policies=app-akamai-snbui-list,app-akamai-snbui-read,app-kos-snbsvc-list,app-kos-snbsvc-read,app-kos-snbui-self,app-kos-zookeeper-list,app-kos-zookeeper-read,venafi-ssl,app-venafi-ssl-list,app-venafi-ssl-read,app-venafi-ssl-self,app-venafi-ssl-write,default \ |
policies=app-akamai-snbui-list,app-akamai-snbui-read,app-kos-snbsvc-list,app-kos-snbsvc-read,app-kos-snbui-self,app-kos-zookeeper-list,app-kos-zookeeper-read,venafi-ssl,app-venafi-ssl-list,app-venafi-ssl-read,app-venafi-ssl-self,app-venafi-ssl-write,default \ |
||
ttl=1h |
ttl=1h |
||
+ | </PRE> |
||
==Получение токена== |
==Получение токена== |
Версия 15:15, 30 января 2019
Авторизация контейнеров/PODов в Hashicorp Vault
Задача - использовать сервисные аккаунты кубернетиса для авторизации а Hashicorp Vault
Схема работы
1. Создается сервисный аккаунт
2. Запускается POD с этим сервисным аккаунтом
3. Под получает адрес Vault (в моем случае - вычитывает из Consul но это не принципиально)
4. Авторизуется в Vault под определенной ролью используя JWT
5 Vault возвращает токе с политиками назначенными на роль
5. POD читает из Vault используя полученный токен
+-------------------------------------------------------------------------------------------------------------------------------+ | Google Cloud Engine | | | | | | +-----------------------------------------------------------+ | | | K8S Cluster (in GKE) | | | | | | | | | | | | +---------------------------------------------------+ | | | | | POD | | | | | | spec: | | | | | | serviceAccountName: k8s-test-service-account | | | | | | ... | | | | | | containers: | | | | | | - name: container-name | | | | | | image: ... | | +-------------------+ | | | | imagePullPolicy: Always | | | VM Instance | | | | | env: | | | | | | | | - name: VAULT_K8S_ROLE | | | +------------+ | | | | | value: k8s-test-role | ---|-->---> Token Request for role ->-->-->---| | Vault | | | | | +---------------------------------------------------+ | * POD's SA JWT | | Process | | | | | | * Role Name | | | | | | | | | | | | | | | +--------------------+ | Verify POS's Service Account JWT | | | | | | | | K8S API Endpoint |<--------<--------<----------------|-( auth with Vault's Service Account )-<--| | | | | | | +--------------------+ | | +------------+ | | | | | | | | | +-----------------------------------------------------------+ +-------------------+ | | | +-------------------------------------------------------------------------------------------------------------------------------+
Настройка
k8s
Сервисный аккаунт
Это аккаунт с которым Vault подключается к API k8s для валидации JWT
--- apiVersion: v1 kind: ServiceAccount metadata: name: vault-tokenreview-service-account namespace: test-namespace
Права сервисного аккаунта
Для того что б аккаунт мог проверить JWT у других сервисных аккаунтов ему назначается
ClusterRole system:auth-delegator
Важно: Назначить права нужно в 2 неймспейсах - если назначить только в test-namespace то прав для проверки JWT недостаточно (что совершенно не очевидно из конфигурации)
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: vault-tokenreview-service-account-role-binding namespace: test-namespace roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:auth-delegator subjects: - kind: ServiceAccount name: vault-tokenreview-service-account namespace: test-namespace --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: vault-tokenreview-service-account-role-binding-2 namespace: default roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:auth-delegator subjects: - kind: ServiceAccount name: vault-tokenreview-service-account namespace: test-namespace
Vault
Для настройки Vault потребуется токен с рутовыми правами
export VAULT_TOKEN="<ROOT_TOKEN>" export VAULT_ADDR="http://192.168.1.4:8200"
Включить поддержку k8s
vault auth-enable kubernetes
Так-как в моем случае все PODы находятся в отдельном namespace то:
export NAMESPACE="my-namespace-name"
Получить имя "секрета"
export SECRET_NAME=$( \ kubectl \ --namespace ${NAMESPACE} \ get \ serviceaccount \ vault-tokenreview-service-account \ -o jsonpath='{.secrets[0].name}' )
Зная имя секрета можно получить его токен:
export ACCOUNT_TOKEN=$( \ kubectl \ --namespace ${NAMESPACE} \ get \ secret ${SECRET_NAME} \ -o jsonpath='{.data.token}' \ | base64 --decode )
В том же секрете содержится сертификат СА:
export SERVICE_ACCOUNT_CA_CRT=$( \ kubectl \ --namespace ${NAMESPACE} \ get \ secret ${SECRET_NAME} \ -o jsonpath="{.data['ca\.crt']}" \ | base64 --decode; echo ) Настроить vault (адрес API можно взять из конфигурации kubectl) <PRE> vault \ write \ auth/kubernetes/config \ kubernetes_host="https://192.168.191.2:443" \ kubernetes_ca_cert="${SERVICE_ACCOUNT_CA_CRT}" \ token_reviewer_jwt="${ACCOUNT_TOKEN}"
export VAULT_K8S_ROLE=""
${VAULT} \
write \ auth/kubernetes/role/k8s-snbui-role \ bound_service_account_names=k8s-snbui-service-account \ bound_service_account_namespaces=${NAMESPACE} \ policies=app-akamai-snbui-list,app-akamai-snbui-read,app-kos-snbsvc-list,app-kos-snbsvc-read,app-kos-snbui-self,app-kos-zookeeper-list,app-kos-zookeeper-read,venafi-ssl,app-venafi-ssl-list,app-venafi-ssl-read,app-venafi-ssl-self,app-venafi-ssl-write,default \ ttl=1h