Управление секретами в ArgoCD при помощи argocd-vault-plugin с Kubernetes auth

в 14:53, , рубрики: argocd, gitops, kubernetes, Vault

Теоретическая часть

Для начала стоит отметить, что в ArgoCD по умолчанию нет возможности скрытно управлять credentials (логинами, паролями, токенами, etc). В документации по ArgoCD приведён список возможных решений по управлению credentials. По моему мнению, наиболее близок к нативному — вариант работы с секретами посредством argocd-vault-plugin (AVP) с использованием Kubernetes auth в Vault. Схема получается следующей: argocd-repo-server авторизуется в Vault при помощи Service Account token, в манифесте Secret в < ... > подставляет небходимое значение, и создаёт секрет.

Управление секретами в ArgoCD при помощи argocd-vault-plugin с Kubernetes auth - 1

Практическая часть

Настройка ArgoCD

Ниже будут преведены примеры необходимых дополнительных настроек для инсталяции ArgoCD при помощи официального helm chart.

Настройка argocd-server

Настройка конфига приложения argocd-server, для подключения плагина:

  # -- [General Argo CD configuration]
  # @default -- See [values.yaml]
  config:
    configManagementPlugins: |
      - name: argocd-vault-plugin
        generate:
          command: ["argocd-vault-plugin"]
          args: ["generate", "./"]

Создание приложение main, которое будет являться app of app, и будет создавать остальные Application:

  # -- Deploy ArgoCD Applications within this helm release
  # @default -- `[]` (See [values.yaml])
  ## Ref: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/
  additionalApplications:
    - name: main
      namespace: argocd
      additionalLabels: {}
      additionalAnnotations: {}
      project: default
      source:
        repoURL: https://github.com/dmitrii-dmnk/argocd-vault-plugin-demo.git
        targetRevision: master
        path: apps
        helm:
          valueFiles:
            - values.yaml
      destination:
        server: https://kubernetes.default.svc
        namespace: argocd
      syncPolicy:
        automated:
          prune: true
          selfHeal: true

Настройка argocd-repo-server

Существует возможность подключать AVP несколькими способами, но самый простой и менее затратный по времени вариант — при помощи initContainer. Схема получается следующей: на старте приложения argocd-repo-server, initContainer скачивает требуемый плагин. При помощи volume типа emptyDir, монтируем скаченный плагин в argocd-repo-server.

Настройка volume и volumeMounts в argocd-repo-server:

  # -- Additional volumeMounts to the repo server main container
  volumeMounts:
    - name: custom-tools
      mountPath: /usr/local/bin/argocd-vault-plugin
      subPath: argocd-vault-plugin

  # -- Additional volumes to the repo server pod
  volumes:
    - name: custom-tools
      emptyDir: {}

Ранее уже упоминалось, что запросы на получение секретов из Vault будет делать приложение argocd-repo-server, поэтому ему необходимо настроить serviceAccount:

  ## Repo server service account
  ## If create is set to true, make sure to uncomment the name and update the rbac section below
  serviceAccount:
    # -- Create repo server service account
    create: true
    # -- Repo server service account name
    name: argocd-repo-server

Настройка initContainer для скачивания плагина:

  # -- Init containers to add to the repo server pods
  initContainers:
    - name: download-tools
      image: alpine:3.8
      command: [ sh, -c ]
      args:
        - wget -O argocd-vault-plugin
          https://github.com/argoproj-labs/argocd-vault-plugin/releases/download/v1.6.0/argocd-vault-plugin_1.6.0_linux_amd64 &&
          chmod +x argocd-vault-plugin && mv argocd-vault-plugin /custom-tools
      volumeMounts:
        - mountPath: /custom-tools
          name: custom-tools

Вышеописанные настройки собраны в одном файле argrocd-values.yaml, и доступны на github.

Применение вышеописанных настроек в ArgoCD

В демонстративных целях можно воспользоваться готовой конфигурацией argocd-values.yaml, и выполнить развертывание ArgoCD, например, в minikube.

Клонируем репозиторий с настройками:

git clone git@github.com:dmitrii-dmnk/argocd-vault-plugin-demo.git;
cd  argocd-vault-plugin-demo/helpers

Применяем параметры при помощи helm:

helm upgrade -i argocd argo/argo-cd 
    --atomic 
    --create-namespace -n argocd 
    -f argocd-values.yaml 
    --version=3.29.5

На этом этапе настройка ArgoCD завершена.

Настройка Vault

Если в Vault ещё не включена Kubernetes auth, её можно включить следующей командой:

vault auth enable kubernetes

В случае, если Kubernetes auth была только что подключена командой выше, необходимо настроить дополнительные параметры следующей командой:

vault write auth/kubernetes/config 
  issuer="https://kubernetes.default.svc.cluster.local" 
  token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" 
  kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443" 
  kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt

Стоит обратить внимание на параметр issuer="https://kubernetes.default.svc.cluster.local", который необходим для Vault 1.9.0 и Kubernetes 1.20 и выше версий. Настоятельно рекомендуется ознакомиться подробнее с официальной документацией Vault с разделом Kubernetes auth method.

Для демонстрации добавим дополнительное KV хранилище 2-й версии, и поместим в него test секрет:

vault secrets enable -path=avp -version=2 kv
vault kv put avp/test sample=secret

Создаём и применяем файл с policy для argocd-repo-server:

cat << EOF > /tmp/policy.hcl 
path "avp/data/test" { capabilities = ["read"] } 
EOF
vault policy write argocd-repo-server /tmp/policy.hcl

В Kubernetes auth создаём роль для argocd-repo-server:

vault write auth/kubernetes/role/argocd-repo-server 
	bound_service_account_names=argocd-repo-server 
  bound_service_account_namespaces=argocd policies=argocd-repo-server

Создание App of secrets

Чтобы придерживаться GitOps подхода, необходимо добавить Application в основном git-репозиторий на который опирается ArgoCD. Добавленный Application должен создать Secret с параметрами из Vault. Ниже привдён пример Application с параметрами env для AVP:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: app-of-secrets
  namespace: argocd
spec:
  destination:
    namespace: argocd
    server: https://kubernetes.default.svc
  project: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
  source:
    path: apps/secrets
    plugin:
      env:
        - name: AVP_TYPE
          value: vault
        - name: AVP_AUTH_TYPE
          value: k8s
        - name: AVP_K8S_ROLE
          value: argocd-repo-server
        - name: VAULT_ADDR
          value: http://vault.vault:8200
      name: argocd-vault-plugin
    repoURL: https://github.com/dmitrii-dmnk/argocd-vault-plugin-demo.git
    targetRevision: master

Secret манифест для Application app-of-secrets. Стоит обратить внимание на AVP аннотацию, указывающую путь к секрету в Vault. Полный список аннотаций для плагина доступен по ссылке argocd-vault-plugin.readthedocs.io

kind: Secret
apiVersion: v1
metadata:
  name: example-secret
  namespace: default
  annotations:
    avp.kubernetes.io/path: "avp/data/test"
type: Opaque
stringData:
  sample-secret: <sample>

На данном этапе секрет в дефолтном неймспейсе должен иметь значение из Vault. Возможно, необходимо будет сделать hard refresh в ArgoCD UI, либо выполнить команду:

argocd app sync --force app-of-secrets

Итог

Настройка ArgoCD сводится к: подкладыванию бинарного файла AVP, создание Application с env параметрами и создание Secret со stringData и аннотацией. В качестве бонуса был написан небольшой скрипт на баше, который автоматизирует развёртывание ArgoCD и Vault в minikube. Приветствуются: критика, пожелания, предложения.

Отдельное хочется выразить благодарность за подготовку изображений melpomane

Автор: Деменко Дмитрий

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js