본문 바로가기

CI CD/argocd

[ArgoCD] argocd v.2.8이상 사이드카로 Vault Plugin 적용하기

개요

argo CD Vault Plugin은 민감한 secret들을 custom resource 또는 operator에 의존하지 않고 볼트에 저장하여 사용하는 방법이다. k8s의 secret뿐만 아니라 configmap, deployment또는 다른 쿠버네티스 리소스에서 사용할 수 있다.

사용법은 배포할 쿠버네티스 매니페스트 파일에 <path/to/secret/password-vault-key>  이런식으로 vault secret path와 key값을 넣어서 사용한다. 사용법보다는 설치방법이 조금 복잡하다.

ArgoCD는 아래 두가지 방법의 설치를 제안한다.

1. argocd-cm configmap을 이용한 설치방법

2. 사이드카 컨테이너에서 설치를 진행하는 방법

 

나는 v.2.4.0이후에 설치하는 사이드카를 이용한 방식으로 설치를 진행했다. 그리고 글을 작성하는 시점 기준 아르고시디 최신버전의 헬름(argocd App version v.2.8.4)에서는 1번 방법은 아예 deprecated 되어 사용할 수 없다. (참고)

볼트 플러그인을 사용하는 블로그가 많이 있지만 최신 아르고 헬름차트를 이용한 내용은 보이지 않아 글을 쓰게 되었다.

 

 

설치

일단 vault plugin을 사용하는 만큼 볼트는 이미 설치되어있다고 가정한다.

vault 설정

1. secret을 저장할 vault secret path에 값을 저장한다.

UI를 통해 볼트에 접근하든 로컬에서 VAULT_ADDR변수에 볼트 엔드포인트를 넣어서 로그인한 후 secret을 활성화 시킨다.

# 로컬에서 접근가능하기 위해 포트 포워딩
kubectl port-forward -n vault vault-0 8200

# root token을 이용하여 볼트 로그인
export VAULT_ADDR=http://127.0.0.1:8200
vault login

로그인 후 key-value secret을 활성화 해주고 값을 저장한다.

그리고 해당 볼트 시크릿에 대한 읽을 수 있는 권한을 생성한다. (policy)

# key value secret 활성화
vault secrets enable kv-v2

# demo위치에 시크릿 넣기
vault kv put kv-v2/demo user="user1" password="password1"

# demo 위치에 있는 시크릿들을 읽을 수 있는 policy 생성
vault policy write demo - <<EOF
path "kv-v2/data/demp" {
capabilities = ["read"]
}
EOF

2. argocd 에서 vault에 접근할 수 있도록 backend 설정 및 k8s secret 생성

vault 인증 방법으로 approle, vault token, github, kubernetes 등등 다양한 인증 방법이 존재하는데, 나는 Kubernetes Authentication 을 이용하였다. 

다른 인증 방법 보러가기 👉🏻 https://argocd-vault-plugin.readthedocs.io/en/stable/backends/

 

Backends - Argo CD Vault Plugin

Backends HashiCorp Vault We support AppRole, Token, Github, Kubernetes and Userpass Auth Method for getting secrets from Vault. We currently support retrieving secrets from KV-V1 and KV-V2 backends. Note: For KV-V2 backends, the path needs to be specified

argocd-vault-plugin.readthedocs.io

vault에서 kubernetes 인증을 활성화 시킨 후 위에서 생성한 demo policy를 argocd에서 사용할 수 있도록 argocd repo-server의 service account와 연결시켜준다. 

# 아래 명령들은 vault-0 pod에 접근한 후 vault login한 후에 수행한다.
# kubernetes 인증 활성화
vault auth enable kubernetes

# kubernetes 인증에 config 설정
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

# kubernetes auth후 사용할 role인 argocd를 생성하고 위에서 만든 secret에 접근할 수 있도록 demo policy attach
# serviceaccount는 argocd repo-server에서 이용하기 때문에 repo server의 service account를 연결
vault write auth/kubernetes/role/argocd \
  bound_service_account_names=argocd-repo-server \
  bound_service_account_namespaces=argocd \
  policies=demo \
  ttl=48h

vault plugin에서 사용할 수 있는 k8s secret을 생성한다.

kind: Secret
apiVersion: v1
metadata:
  name: argocd-vault-plugin-credentials
  namespace: argocd
type: Opaque
stringData:
  AVP_AUTH_TYPE: "k8s"
  AVP_K8S_ROLE: "argocd"
  AVP_TYPE: "vault"
  VAULT_ADDR: "http://10.1.4.160:8200"

😐 삽질 기록

처음에 VAULT_ADDR를 http://localhost:8200 으로 설정해놓고 argocd application까지 다 배포했는데 자꾸 이런 에러가 떴다.

이 실습도 시작한지 사실 좀 오래됐는데 이 에러를 해결하느라 며칠 사용한것 같다.. argocd pod에 접근해보아도 curl이나 telnet등 다양하게 호출을 시도해보았으나 명령어가 설치되어있지도 않고 설치할 수 있는 권한조차 없어 확인하기도 어려웠다.

그러다가 repo server의 localhost는 host에서 바라보는 localhost가 아니라 repo server자기 자신이라는 것을 깨달았고

그래서 처음에는 host 의 IP주소로 설정해봤는데 (mac IP) 로컬에서 그 주소로 접근되지도 않고 아르고에서도 접근하지 못해 metalb를 설치하여 vault의 service를 LoadBalancer type으로 오픈했다. 그때 나오는 external-IP가 저 주소(10.1.4.160)이다.

만약 실습용으로 테스트하는 경우가 아니거나 클라우드 환경을 이용해서 외부에서 접근할 수 있는 로드밸런서를 생성하여 도메인을 연결한 상태라면 이런 오류는 만나지 않았을듯하다. 근데 집에서 실습으로 해보려는 사람들은 이부분이 걸릴 것 같다. 😐

 

vault plugin 설정

cmp 작성

먼저 plugin 구성파일을 configmap으로 작성한다. 해당 configmap은 extraContainers에서 마운트하여 플러그인 이용할때 사용된다.

v.2.8버전 부터는 configmap section이 아닌 cmp section이 별도로 존재한다. 이때 생성되는 configmap이름은 argocd-cmp-cm이다.(기존은 cmp-plugin인것 같음)

plugin은 helm, kustomize, 그냥 kubernetes manifest에 직접 넣는 경우가 있을 수 있는데 나의 경우 helm을 통해 넣는 플러그인만 사용했다. 다른 플러그인들을 추가하고싶다면 여기 깃헙에서 참조하면 좋을 것 같다.

👉🏻 https://github.com/argoproj-labs/argocd-vault-plugin/blob/main/manifests/cmp-sidecar/cmp-plugin.yaml

여기서 generate command에서는 위에서 생성해주었던 argocd-vault-plugin-credentials을 이용한다. 해당 시크릿을 이용하여 볼트정보를 가져와 시크릿을 주입시킨다. <namespace>:<secret-name> 형태로 사용하면 된다.

Volume설정

위의 configmap을 마운트할 볼륨(argocd-cmp-cm), plugin을 다운받을 볼륨(custom-tools)생성

plugin tool 다운받는 initContainer생성

initcontainers에서 다운받은 볼트 플러그인은 별도의 containers에서 사용한다.

  initContainers: 
    - name: download-tools
      image: alpine/curl
      env:
        - name: AVP_VERSION
          value: 1.14.0
      command: [sh, -c]
      args:
        - >-
          curl -L https://github.com/argoproj-labs/argocd-vault-plugin/releases/download/v$(AVP_VERSION)/argocd-vault-plugin_$(AVP_VERSION)_linux_amd64 -o argocd-vault-plugin &&
          chmod +x argocd-vault-plugin &&
          mv argocd-vault-plugin /custom-tools/
      volumeMounts:
        - mountPath: /custom-tools
          name: custom-tools

plugin 이용할 sidecar container생성

cmp에서 정의한 플러그인 갯수만큼 컨테이너를 생성해주면 된다.

initContainer에서 다운받은 플러그인을 실행가능한 위치로 옮겨주고 cmp configmap에서 작성했던 플러그인을 마운트한다.

argocd는 플러그인 구성파일이 /home/argocd/cmp-server/config/plugin.yaml 안에 위치한다고 예상하기때문에 이 위치에 넣어주저야 정상적으로 작동한다. 만약 사이드카 컨테이너에 볼륨 마운트하는게 아니라 직접 이미지 만들어서 이용하는 경우 이런 부분 고려해주어야 한다.

var-files나 tmp, plugins들은 공식문서에 기본적으로 추가되어 있는 부분이라 딱히 건들지 않았다. 

  extraContainers: 
    - name: argocd-vault-plugin-helm
      command:
        - "/var/run/argocd/argocd-cmp-server"
      image: quay.io/argoproj/argocd:v2.8.4
      securityContext:
        runAsNonRoot: true
        runAsUser: 999
      volumeMounts:
        - mountPath: /var/run/argocd
          name: var-files
        - mountPath: /tmp
          name: tmp
        - mountPath: /home/argocd/cmp-server/plugins
          name: plugins
        # Remove this volumeMount if you've chosen to bake the config file into the sidecar image.
        - mountPath: /home/argocd/cmp-server/config/plugin.yaml
          subPath: argocd-vault-plugin-helm.yaml
          name: argocd-cmp-cm
        - name: custom-tools
          mountPath: /usr/local/bin/argocd-vault-plugin
          subPath: argocd-vault-plugin

values.yaml파일을 작성하고 argocd를 배포한다.

Application 배포

이제 정상적으로 동작이 잘 되는지 vault secret을 이용하는 application을 배포해서 확인한다.

나는 다른분이 만들어둔 데모 어플리케이션 및 소스를 이용하였고, 아래에 참조에 적어두었다.

https://github.com/jingnee/spring-boot-debug-app

argocd 에서 repo를 추가하고

Application을 생성및 배포한다. (소스는 fork해서 사용)

배포후 파드가 잘 안떠서 Probe부분은 주석처리해놨다.  (어차피 시크릿 주입만 확인하는 용이기 때문에)

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: demo
  namespace: argocd
spec:
  destination:
    namespace: argocd
    server: https://kubernetes.default.svc
  project: default
  source:
    path: infra/helm
    repoURL: https://github.com/jingnee/spring-boot-debug-app
    targetRevision: main
    plugin:
      env:
        - name: HELM_ARGS
          value: '-f override-values.yaml'
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

override-values.yaml 파일을 살펴보면 환경변수로 vault에 저장했던 시크릿을 이용하게끔 되어있다. 

deployment의 환경변수로 값이 주입되어있는 것을 확인할 수 있다.

vault secret

하고 나면 간단한 느낌인데 사실 저 vault address에 접근하지 못하는 부분과 cmp를 작성하는 내용도 잘 없어서 많이 걸렸다.

내가 헤맨 만큼 다른사람들은 좀더 빠르게 해결했으면 좋겠다는 생각으로 글을 작성해 보았다.

 


Reference

https://luafanti.medium.com/injecting-secrets-from-vault-into-helm-charts-with-argocd-43fc1df57e74

 

Injecting secrets from Vault into Helm charts with ArgoCD

Managing secrets in Kubernetes isn’t a trivial topic. As is usual with Kubernetes, there are always many ways to achieve the desired goal…

luafanti.medium.com

https://docmoa.github.io/04-HashiCorp/06-Vault/04-UseCase/argocd-vault-plugin.html#_1-vault-%E1%84%92%E1%85%AA%E1%86%AB%E1%84%80%E1%85%A7%E1%86%BC-%E1%84%8C%E1%85%AE%E1%86%AB%E1%84%87%E1%85%B5

 

ArgoCD Vault Plugin

ArgoCD Vault Plugin 연동방안

docmoa.github.io

 

https://argocd-vault-plugin.readthedocs.io/en/stable/installation/

 

Installation - Argo CD Vault Plugin

Installation Installing in Argo CD In order to use the plugin in Argo CD you have 4 distinct options: Explaining your options First, the Argo CD docs provide valuable information on how to extend the argocd-repo-server with additonal tools or a custom buil

argocd-vault-plugin.readthedocs.io

https://argo-cd.readthedocs.io/en/stable/operator-manual/config-management-plugins/#debugging-a-cmp

 

Config Management Plugins - Argo CD - Declarative GitOps CD for Kubernetes

Config Management Plugins Argo CD's "native" config management tools are Helm, Jsonnet, and Kustomize. If you want to use a different config management tools, or if Argo CD's native tool support does not include a feature you need, you might need to turn t

argo-cd.readthedocs.io