Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
devops:hashicorp_vault_workflow [2020/08/12 23:01] – [Автоматическое обновление сертификатов с помощью consul-template] admindevops:hashicorp_vault_workflow [2020/08/13 19:48] (current) – [Автоматическое обновление сертификатов с помощью consul-template] admin
Line 292: Line 292:
 https://learn.hashicorp.com/tutorials/nomad/vault-pki-nomad \\ https://learn.hashicorp.com/tutorials/nomad/vault-pki-nomad \\
 Как все работает. Как все работает.
-  * в деплойменте прикладного пода (nginx) прописываются два дополнительных контейнера. Первый - init-контейнер vault-agent, который берет конфигурацию из конфигмапа и получает токен. Этот токен в дальнейшем использует второй контейнер - consul-template, который занимается тем, что обновляет данные в соответствии с темплейтом записаным в конфигмап. Обновленные данные он кладет в папку, которая смонтирована в него и в прикладной под с nginx. +  * в деплойменте пода помимио прикладного контейнера (**nginx**) прописываются два дополнительных контейнера. Первый - **init**-контейнер **vault-agent**, который берет конфигурацию из конфигмапа и получает токен. Этот токен в дальнейшем использует второй контейнер - **consul-template**, который занимается тем, что обновляет данные в соответствии с темплейтом записаным в конфигмап. Обновленные данные он кладет в папку, которая смонтирована в него и в прикладной под с **nginx**
-  * Для того, чтобы все работало в Vault должна быть заведена политика, которая бы разрешала доступ для заданной роли в путь, где выпускаются сертификаты. +  * Для того, чтобы все работало в **Vault** должна быть заведена политика, которая бы разрешала доступ для заданной роли в путь, где выпускаются сертификаты. 
-Создадим файл политики, которая разрешить выпуск сертификатов с помощью промежуточного CA:+Создадим файл политики, которая разрешить выпуск сертификатов с помощью промежуточного **CA**:
 <code>tee cert_issue_policy.hcl <<EOF <code>tee cert_issue_policy.hcl <<EOF
 path "pki_int/issue/*" { path "pki_int/issue/*" {
Line 306: Line 306:
 а также - создадим роль в **vault**, которую привяжем к ServiceAccount (с правами которого будет работать pod) и назначим этой роли созданную ранее политику, разрешающую выпуск сертов: а также - создадим роль в **vault**, которую привяжем к ServiceAccount (с правами которого будет работать pod) и назначим этой роли созданную ранее политику, разрешающую выпуск сертов:
   kubectl -n vault exec -it vault-0 -- vault write auth/kubernetes/role/cert-issue-role bound_service_account_names=vault-auth bound_service_account_namespaces=vault policies=cert-issue-policy ttl=24h   kubectl -n vault exec -it vault-0 -- vault write auth/kubernetes/role/cert-issue-role bound_service_account_names=vault-auth bound_service_account_namespaces=vault policies=cert-issue-policy ttl=24h
 +А теперь создадим объекты в K8S.
 +===== configmap =====
 +Конфигмап содержит три конфига:
 +  * для **init**-контейнера **vault-agent**, который аутентифицируется с помощью **ServiceAccount** и получит токен для контейнера **consul-template**
 +  * для **consul-template**в котором описано где взять токен, поученный **vault-agent**, что именно забрать из **vault** (сертификат и ключ), куда это потом положить (в файлы) и что сделать после этого (послать сигнал nginx для обновления конфига).
 +  * конфиг **nginx**, в котором настроен HTTPS-сервер, использующий файлы сертификата и ключа, полученные из **Vault**.
 +<code>apiVersion: v1
 +kind: ConfigMap
 +metadata:
 +  name: nginx-cert-renew-config
 +  namespace: vault
 +data:
 +  vault-agent-config.hcl: |
 +    # Comment this out if running as sidecar instead of initContainer
 +    exit_after_auth = true
 +
 +    pid_file = "/home/vault/pidfile"
 +
 +    auto_auth {
 +        method "kubernetes" {
 +            mount_path = "auth/kubernetes"
 +            config = {
 +                role = "cert-issue-role"
 +            }
 +        }
 +
 +        sink "file" {
 +            config = {
 +                path = "/home/vault/.vault-token"
 +            }
 +        }
 +    }
 +
 +  consul-template-config.hcl: |
 +    vault {
 +      renew_token = false
 +      vault_agent_token_file = "/home/vault/.vault-token"
 +      retry {
 +        backoff = "1s"
 +      }
 +    }
 +
 +    template {
 +        contents = "{{ with secret \"pki_int/issue/example-dot-ru\" \"common_name=test.example.ru\" \"ttl=2m\"}}{{ .Data.certificate }}{{ end }}"
 +        destination="/etc/secrets/tls.crt"
 +        command="sh -c 'killall -s HUP nginx || true'"
 +    }
 +    template {
 +        contents = "{{ with secret \"pki_int/issue/example-dot-ru\" \"common_name=test.example.ru\" \"ttl=2m\"}}{{ .Data.private_key }}{{ end }}"
 +        destination="/etc/secrets/tls.key"
 +    }
 +    template {
 +        contents = "{{ with secret \"pki_int/issue/example-dot-ru\" \"common_name=test.example.ru\" \"ttl=2m\"}}{{ .Data.issuing_ca }}{{ end }}"
 +        destination="/etc/secrets/int_ca.crt"
 +    }
 +
 +  nginx_ssl.conf: |
 +    server {
 +      listen              443 ssl;
 +      server_name         test.example.ru;
 +      ssl_certificate     /etc/nginx/ssl/tls.crt;
 +      ssl_certificate_key /etc/nginx/ssl/tls.key;
 +      ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
 +      ssl_ciphers         HIGH:!aNULL:!MD5;
 +
 +      location / {
 +        root   /usr/share/nginx/html;
 +        index  index.html index.htm;
 +      }
 +    }
 +</code>
 +===== Pod =====
 +Манифест Pod'а с тремя контейнерами:
 +<code>apiVersion: v1
 +kind: Pod
 +metadata:
 +  name: nginx-cert-renew-example
 +  namespace: vault
 +  labels:
 +    app: nginx
 +spec:
 +  shareProcessNamespace: true
 +  serviceAccountName: vault-auth
 +  volumes:
 +  - configMap:
 +      items:
 +      - key: vault-agent-config.hcl
 +        path: vault-agent-config.hcl
 +      - key: consul-template-config.hcl
 +        path: consul-template-config.hcl
 +      name: nginx-cert-renew-config
 +    name: config
 +  - configMap:
 +      items:
 +      - key: nginx_ssl.conf
 +        path: nginx_ssl.conf
 +      name: nginx-cert-renew-config
 +    name: nginx-config
 +  - emptyDir: {}
 +    name: shared-data
 +  - emptyDir: {}
 +    name: vault-token    
 +
 +  initContainers:
 +  - args:
 +    - agent
 +    - -config=/etc/vault/vault-agent-config.hcl
 +    - -log-level=debug
 +    env:
 +    - name: VAULT_ADDR
 +      value: http://vault:8200
 +    image: vault
 +    imagePullPolicy: IfNotPresent
 +    name: vault-agent
 +    volumeMounts:
 +    - mountPath: /etc/vault
 +      name: config
 +    - name: vault-token
 +      mountPath: /home/vault
 +
 +  containers:
 +  - image: nginx
 +    imagePullPolicy: IfNotPresent
 +    name: nginx-container
 +    ports:
 +    - containerPort: 80
 +    volumeMounts:
 +    - mountPath: /etc/nginx/ssl/
 +      name: shared-data
 +    - mountPath: /etc/nginx/conf.d/
 +      name: nginx-config
 +  - name: consul-template
 +    image: hashicorp/consul-template:alpine
 +    imagePullPolicy: IfNotPresent
 +    securityContext:
 +      runAsUser: 0
 +      capabilities:
 +        add:
 +        - SYS_PTRACE
 +    volumeMounts:
 +      - name: vault-token
 +        mountPath: /home/vault
 +      - name: config
 +        mountPath: /etc/consul-template
 +      - name: shared-data
 +        mountPath: /etc/secrets
 +    env:
 +      - name: HOME
 +        value: /home/vault
 +      - name: VAULT_ADDR
 +        value: http://vault:8200
 +    args: ["-config=/etc/consul-template/consul-template-config.hcl"]
 +</code>
 +Тут стоит обратить внимание на:
 +  shareProcessNamespace: true
 +Эта конструкция позволяет иметь процессам всех контейнеров общий **namespace**, чтобы можно было управлять процессом **nginx** из контейнера **consul-template**. \\
 +Также важно, чтобы у контейнера consul-template был такой **securityContext**:
 +    securityContext:
 +      runAsUser: 0
 +      capabilities:
 +        add:
 +        - SYS_PTRACE
 +Это значит, что процессы этого контейнера будут исполняться с **id=0** (то есть иметь права **root** с точки зрения всех процессов pod'а) и у процессов этого контейнера будут права посылать сигналы в другеи контейнеры (**SYS_PTRACE**). Подробнее тут - https://kubernetes.io/docs/tasks/configure-pod-container/share-process-namespace/ \\
  • devops/hashicorp_vault_workflow.txt
  • Last modified: 2020/08/13 19:48
  • by admin