Vault を argocd-vault-plugin と連携できるように構築する

Argocd で Gitops を行う場合 secret をべた書きで git に push する必要がありますが、セキュアに secret を管理するには argocd-vault-plugin などのツールを利用して vault と 連携することで解決できます。

ArgoCD が argocd-vault-plugin を介して Vault にアクセスする方法として Initial Root Token や Kubernetes 認証 Role を利用する方法などがあります。
今回は kubernetes 認証 Role を利用した内容を記載しています。

Vault を argocd-vault-plugin と連携させるための備忘録として記事にしました。
argocd に argocd-vault-plugin を sidecar で構築する方法については以下の記事に記載しています。
https://www.aimhighergg.com/argocd-vault-plugin-sidecar/

Vault Helm values.yaml

chart version: 0.27.0
app version: 1.15.2

server:
  dataStorage:
    enabled: true
    size: 10Gi
    mountPath: "/vault/data"
    storageClass: "longhorn"
    accessMode: ReadWriteOnce
    annotations: {}
    labels: {}
  ha:
    enabled: true
    replicas: 3
    raft:
      enabled: true
      setNodeId: false
      config: |
        ui = true
        listener "tcp" {
          tls_disable = 1
          address = "[::]:8200"
          cluster_address = "[::]:8201"
          telemetry {
            unauthenticated_metrics_access = "true"
          }
        }
        storage "raft" {
          path = "/vault/data"
          retry_join {
            leader_api_addr = "http://vault-0.vault-internal:8200"
          }
          retry_join {
            leader_api_addr = "http://vault-1.vault-internal:8200"
          }
          retry_join {
            leader_api_addr = "http://vault-2.vault-internal:8200"
          }
        }
        service_registration "kubernetes" {}
ui:
  enabled: true
  serviceType: "ClusterIP"
  serviceNodePort: null
  externalPort: 8200
  targetPort: 8200

Setup vault

初期化

出力された Unseal Key と Initial Root Token をメモする。

$ kubectl exec -it -n vault pod/vault-0 -- vault operator init

Unseal

全ての pod で seal を解除する。
デフォルトだと 3回 異なる unseal_key で実施する。

 $ for i in 0 1 2 ;do kubectl exec -it -n vault pod/vault-${i} -- vault operator unseal ${VAULT_UNSEAL_KEY} ;done

Raft 構成

leader の IP を確認する。

$ kubectl exec -n vault pod/vault-0 -- printenv POD_IP

各 member で raft join を行う

$ kubectl exec -it -n vault pod/vault-1 -- vault operator raft join http://${VAULT_LEADER_IP}:8200
$ kubectl exec -it -n vault pod/vault-2 -- vault operator raft join http://${VAULT_LEADER_IP}:8200

vault login

各 pod で cli が利用できるように vault login を行う。

$ for i in 0 1 2 ; do kubectl exec -it -n vault pod/vault-${i} -- vault login ${VAULT_ROOT_TOKEN} ;done

vault kv 有効化

$ kubectl exec -it -n vault pod/vault-0 -- vault secrets enable -path=secret kv-v2

kubernetes 認証有効化

$ kubectl exec -it -n vault pod/vault-0 -- vault auth enable kubernetes

kubernetes 認証情報設定

pod にログイン

$ kubectl exec -it -n vault pod/vault-0 -- sh

kubernetes 認証情報を設定する。
argocd の argocd-repo-server を構築する際に automountServiceAccountToken: true にして argocd-repo-server のサービスアカウントの token を設定する必要があります。

$ vault write auth/kubernetes/config \
    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

ArgoCD が Vault にアクセスできるように kubernetes 認証に Role を設定する

Initial Root Token を利用して Argocd が Vault にアクセスできるようにする方法もありますが今回は Kubernetes 認証を利用します。

argo-repo-server の serviceAccount/argocd-repo-server の token を利用して認証を行う role を作成します。
argocd-vault-plugin と連携する policy をカンマ区切りで複数紐づけます。

$ kubectl exec -it -n vault pod/vault-0 -- \
vault write auth/kubernetes/role/argocd \
  bound_service_account_names=argocd-repo-server \
  bound_service_account_namespaces=argocd \
  policies="www-aimhighergg-com,monitoring-k8s"

KV と policy 作成

kv を作成する。

$ kubectl exec -it -n vault pod/vault-0 -- \
vault kv put secret/www-aimhighergg-com/db \
password="任意のパスワード"

kv の policy を作成する
「www-aimhighergg-com」という policy は 上記のパスにアクセスできる。

$ kubectl exec -it -n vault pod/vault-0 -- \
vault policy write www-aimhighergg-com - <<EOF
path "secret/data/www-aimhighergg-com/db" {
  capabilities = ["read"]
}
EOF

argocd-vault-plugin が実行される secret 作成

cmp で avp.kubernetes.io/path の文字列が見つかれば、argocd-vault-plugin が repo-server で実行されるようになっているため、 annotations に記載するフォーマットで secret を定義する。
そのため、 Application には plugin の指定をする必要はありません。

apiVersion: v1
kind: Secret
metadata:
  name: kustomize-password
  annotations:
    avp.kubernetes.io/path: "secret/data/www-aimhighergg-com/db"
stringData:
  password: <password>
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: www-aimhighergg-com
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: https://github.com/AbeYuki/aimhighergg-com.git
    targetRevision: HEAD
    path: overlay/prod/
  destination:
    server: https://kubernetes.default.svc
    namespace: www-aimhighergg-com
  syncPolicy:
    automated:
      prune: true
      selfHeal: false
    syncOptions:
    - CreateNamespace=true

以上、Argocd が argocd-vault-plugin を介して vault にアクセスし kubernetes secret を展開するためのvault設定についての説明でした。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です