CI/CD

ArgoCD Manage Secrets

uuuhhh 2022. 12. 15. 17:14

👀 Epilogue


  • DB Pod 매니페스트 파일 정의 다하고..
  • MySQL 시크릿도 다 정의해주고..
  • namespace 안에 apply로 적용을 다 한 상태에서..
  • argoCD로 배포만 하면 되는데..
  • 왜 Sync failed로 인해서 에러가 발생하는 것일까..😢

 

  • 에러 로그 탐색 !

 

  • 유효하지 않는 데이터 에러
    • Deployment.spec.template.spec.containers[1]..
  • 위 변수는 다음과 같은 secret을 참조하는 데이터다.
...
- name: MYSQL_USER
        valueFrom:
          secretKeyRef:
            name: mysql-secret
            key: username
...

 

  • 여기서 시크릿에 대한 문제인 것을 확인하였다.
  • 결론은 시크릿과 매니페스트 데이터 매칭을 제대로 설정하지 않아서 생긴 오류였다.

 

  • 이슈 해결 후 secret 리소스만 따로 관리하는 것이 마음에 안 들기 시작했다..
  • github repo에 secret 파일을 같이 올려서 argoCD를 통해 배포 후 관리하면 편하지 않을까?

 

말도 안 되는 소리..❗️

  • github와 같은 public한 공간에는 절대 절대 절대로 secret 파일을 올리는 건 안된다.

 

왜냐하면..

  • 공개가 되어선 매우 치명적인 데이터를 숨기고자 생성하고 사용하는 secret 파일을 모두가 볼 수 있는 공간에 업로드한다는 것은 secret의 의미가 퇴색되도록 만드는 것이기 때문이다.

 

그럼 무슨 방법이..

  • ArgoCD 자체에서 secret을 관리할 수 있는 방법은 없다.
  • 외부 Tools을 사용하는 등.. 다른 솔루션으로 해결해야 한다.
  • ArgoCD 공식 Doc에서 소개하는 방법 중 제일 간편하고 따라 하기 쉬운 것을 소개하고자 한다.

 

 

▪︎ ArgoCD로 Secret 관리하기


  • 그건 바로 바로..
  • Beatnami의 sealed-secrets 오픈소스를 사용해서 secret을 한 번 더 암호화하는 방법을 소개해본다.

 

 

GitHub - bitnami-labs/sealed-secrets: A Kubernetes controller and tool for one-way encrypted Secrets

A Kubernetes controller and tool for one-way encrypted Secrets - GitHub - bitnami-labs/sealed-secrets: A Kubernetes controller and tool for one-way encrypted Secrets

github.com

 

  • sealed-secrets은 두 가지 구조로 동작한다.
    • cluster-side의 controller / operator
      • seal-secrets-controller
    • client-side의 tool
      • kubeseal
  • 동작 프로세스

출처 : https://coffeewhale.com/sealedsecret

 

  1. client-side의 tool인 kubeseal은 public key를 보유 중이며 k8s secret암호화한다.
    • 암호화 : Secret → SealedSecret
  2. git repository에 업로드를 하더라도 그 누구도 복호화할 수 없다.
  3. GitOps Operator(e.g. ArgoCD)로 인해 k8s 클러스터로 배포한다.
  4. cluster-side의 controller / operator는 private key를 보유중이며 암호화한 k8s secret을 복호화한다.
    • 복호화 : SealedSecret → Secret

 

 

▪︎ kubeseal 설치


  • $ brew install kubeseal

 

  • $ helm install sealed-secrets -n kube-system sealed-secrets/sealed-secrets
    • 🚨 namespace는 kube-system에 지정하여 설치해줘야 한다.

 

⚠️ 주의사항


  • 헬름 차트는 기본적으로 컨트롤러 이름을 sealed-secrets로 설치한다.
  • kubeseal CLI는 기본적으로 sealed-secrets-controller의 이름을 가진 컨트롤러에 접근한다.

 

  • kubeseal에 controller 이름을 명시하지 않았을 경우
    • 다음과 같은 에러 발생

 

  • kubeseal에서 --controller-name옵션을 통해 CLI에 명시적으로 컨트롤러의 이름을 전달할 수 있다.
    • e.g.) $ kubeseal --controller-name sealed-secrets <args>
  • kubeseal에 controller 이름을 명시해줬을 경우
    • 정상적으로 kubeseal 명령 수행

 

  • 만약 CLI를 통해 kubeseal을 사용할 때 매번 위와 같은 옵션을 사용하지 않으려면?
  • helm chart를 설치할 때 fullnameOverride=**.. 옵션으로 controller의 이름을 명시하여 설치할 수 있다.
    • e.g.) $ helm install sealed-secrets -n kube-system --set-string fullnameOverride=sealed-secrets-controller sealed-secrets/sealed-secrets

 

 

▪︎ kubeseal로 암호화


  • kubeseal을 사용해서 여러 가지 방법으로 암호화가 가능하다.
    • 여러 파일 형식 지원 (json, yaml)
    • echo를 통해 데이터 하나씩 암호화
    • cat을 통해 Secret 오브젝트를 SealedSecret으로 변환
    • 등..

 

  • ‘1234’를 암호화 해보자 !
  • 꼭 지정한 namespace에 해당 secret을 넣어주어야만 복호화가 가능하다.
    • data : 1234
    • namespace : test-namespace
    • secret name : test-secret
$ echo -n 1234 | kubeseal --controller-name sealed-secrets --raw --namespace test-namespace --name test-secret

AgBa27gCAJDNYXYy+0PRHhmm8hBocVbq5tGiojJhehv/eHA....

 

  • ‘db-secret.yaml’를 ‘db-sealed-secret.yaml’로 암호화 해보자 !
    • object : Secret → SealedSecret
    • data file : db-secret.yaml → db-sealed-secret.yaml
    • namespace : cucumovie-main
    • secret name : mysql-secret
$ cat db-secret.yaml | kubeseal --controller-name sealed-secrets --namespace cucumovie-main -oyaml > db-sealed-secret.yaml

$ cat db-sealed-secret.yaml
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  creationTimestamp: null
  name: mysql-secret
  namespace: cucumovie-main
spec:
  encryptedData:
    host: AgAOGqdmS5HUPkLD9+s6A...
    password: AgBpRqR6scdjQvAs4n...
    root-password: AgCmj/tE2nVK1...
    username: AgBZqHpSItYBRJwXjtM...
  template:
    metadata:
      creationTimestamp: null
      name: mysql-secret
      namespace: cucumovie-main
    type: Opaque

 

 

▪︎ SealedSecret Controller로 복호화


  • Github에 업로드 !
$ git add .
$ git commit -m "add sealed-secret"
$ git push

 

  • GitOps Operator(e.g. ArgoCD)로 배포 !
    • controller로 sealedsecret을 복호화한 secret을 확인할 수 있다.

 

  • 해당 파드도 정상적으로 controller로 복호화한 secret을 통해 환경변수를 설정하는 것 확인 !

 

 

ref.


Secret Management - Argo CD - Declarative GitOps CD for Kubernetes

How to Use Secrets with GitOps and ArgoCD | Dev House 2021 | Kostis Kapelonis