Vault with k8s: различия между версиями
Sirmax (обсуждение | вклад) (→Ссылки) |
Sirmax (обсуждение | вклад) |
||
Строка 186: | Строка 186: | ||
Обратить внимание - политики <B>policy1,policy2</B> уже существуют (созданы до этого). Если политик нет их необходимо создать. |
Обратить внимание - политики <B>policy1,policy2</B> уже существуют (созданы до этого). Если политик нет их необходимо создать. |
||
+ | ==Деплоймент в K8S== |
||
+ | <PRE> |
||
+ | apiVersion: extensions/v1beta1 |
||
+ | kind: Deployment |
||
+ | metadata: |
||
+ | name: {{ template "mosaicName" . }} |
||
+ | spec: |
||
+ | replicas: 1 |
||
+ | selector: |
||
+ | matchLabels: |
||
+ | app: {{ template "mosaicName" . }}-pod |
||
+ | template: |
||
+ | metadata: |
||
+ | labels: |
||
+ | app: {{ template "mosaicName" . }}-pod |
||
+ | spec: |
||
+ | serviceAccountName: {{ .Values.serviceAccount }} |
||
+ | volumes: |
||
+ | - name: {{ template "mosaicName" . }}-super-ca-volume |
||
+ | secret: |
||
+ | secretName: {{ template "mosaicName" . }}-super-ca-secret |
||
+ | containers: |
||
+ | - name: {{ template "mosaicName" . }}-container-consul |
||
+ | image: gcr.io/kohls-kos-cicd/kos/snb-ui-svc:{{ .Values.artifactVersion }} |
||
+ | imagePullPolicy: Always |
||
+ | args: ["/bin/bash", "/opt/hashicorp/consul/bin/start-consul.sh"] |
||
+ | volumeMounts: |
||
+ | - name: {{ template "mosaicName" . }}-super-ca-volume |
||
+ | mountPath: /tmp/superCA |
||
+ | env: |
||
+ | - name: CONSUL_TOKEN |
||
+ | value: {{ .Values.consulToken | quote }} |
||
+ | - name: CONSUL_KEY |
||
+ | value: {{ .Values.consulKey | quote }} |
||
+ | - name: CONSUL_SCHEME |
||
+ | value: {{ .Values.consulScheme | quote }} |
||
+ | - name: CONSUL_HTTP_ADDR |
||
+ | value: {{ .Values.consulHttpAddr | quote }} |
||
+ | - name: CA_PATH |
||
+ | value: {{ .Values.caPath | quote }} |
||
+ | - name: LOCAL_IP |
||
+ | valueFrom: |
||
+ | fieldRef: |
||
+ | fieldPath: status.podIP |
||
+ | - name: DEPLOYMENT_DATACENTER |
||
+ | value: {{ .Values.deploymentDatacenter | quote }} |
||
+ | - name: DEPLOYMENT_CHANNEL |
||
+ | value: {{ .Values.deploymentChannel | quote }} |
||
+ | - name: DEPLOYMENT_ENV |
||
+ | value: {{ .Values.deploymentEnv | quote }} |
||
+ | - name: SECRETS_BACKEND |
||
+ | value: {{ .Values.secretsBackend | quote }} |
||
+ | - name: PROFILE |
||
+ | value: {{ .Values.profile | quote }} |
||
+ | - name: VAULT_K8S_ROLE |
||
+ | value: {{ .Values.vaultK8sRole | quote }} |
||
+ | </PRE> |
||
==Получение токена== |
==Получение токена== |
||
Версия 16:31, 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 потребуется токен с рутовыми правами адрес Vault дан для примера. В моем случае он вычитывается из Consul.
export VAULT_TOKEN="<ROOT_TOKEN>" export VAULT_ADDR="http://192.168.1.4:8200"
Включить поддержку k8s в Vault
vault auth-enable kubernetes
Получение необходимых секретов из K8S
Так-как в моем случае все 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 в K8S==== Настроить 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}"
Обратить внимание:
- Service Account - это аккаунт с которым будет деплоиться POD. Это аккаунт в k8s а не в Vault.
- Роль существует только в пределах Vault (а не в K8S)
- При авторизации POD запрашивает токен для роли
- На токен будут назначены политики из привязки
Привязка сервисных аккаунтов K8S к ролям Vault
export VAULT_K8S_SERVICE_ACCOUNT="k8s-test-service-account" export VAULT_K8S_ROLE="k8s-test-role"
Создать привязку
${VAULT} \ write \ auth/kubernetes/role/${VAULT_K8S_ROLE} \ bound_service_account_names=${VAULT_K8S_SERVICE_ACCOUNT} \ bound_service_account_namespaces=${NAMESPACE} \ policies=policy1,policy2,default \ ttl=1h
Обратить внимание - политики policy1,policy2 уже существуют (созданы до этого). Если политик нет их необходимо создать.
Деплоймент в K8S
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: {{ template "mosaicName" . }} spec: replicas: 1 selector: matchLabels: app: {{ template "mosaicName" . }}-pod template: metadata: labels: app: {{ template "mosaicName" . }}-pod spec: serviceAccountName: {{ .Values.serviceAccount }} volumes: - name: {{ template "mosaicName" . }}-super-ca-volume secret: secretName: {{ template "mosaicName" . }}-super-ca-secret containers: - name: {{ template "mosaicName" . }}-container-consul image: gcr.io/kohls-kos-cicd/kos/snb-ui-svc:{{ .Values.artifactVersion }} imagePullPolicy: Always args: ["/bin/bash", "/opt/hashicorp/consul/bin/start-consul.sh"] volumeMounts: - name: {{ template "mosaicName" . }}-super-ca-volume mountPath: /tmp/superCA env: - name: CONSUL_TOKEN value: {{ .Values.consulToken | quote }} - name: CONSUL_KEY value: {{ .Values.consulKey | quote }} - name: CONSUL_SCHEME value: {{ .Values.consulScheme | quote }} - name: CONSUL_HTTP_ADDR value: {{ .Values.consulHttpAddr | quote }} - name: CA_PATH value: {{ .Values.caPath | quote }} - name: LOCAL_IP valueFrom: fieldRef: fieldPath: status.podIP - name: DEPLOYMENT_DATACENTER value: {{ .Values.deploymentDatacenter | quote }} - name: DEPLOYMENT_CHANNEL value: {{ .Values.deploymentChannel | quote }} - name: DEPLOYMENT_ENV value: {{ .Values.deploymentEnv | quote }} - name: SECRETS_BACKEND value: {{ .Values.secretsBackend | quote }} - name: PROFILE value: {{ .Values.profile | quote }} - name: VAULT_K8S_ROLE value: {{ .Values.vaultK8sRole | quote }}