๐น Argo CD ํ๊ฒฝ์์ ๋ณด์ ๊ฐํ๋ฅผ ์ํ ์ํฌ๋ฆฟ ๊ด๋ฆฌ์ ํ์์ฑ
GitOps ๊ธฐ๋ฐ ๋ฐฐํฌ ๋ฐฉ์์์๋ Kubernetes ๋ฆฌ์์ค์ ํจ๊ป ์ํฌ๋ฆฟ(Secrets) ์ ๋ณด๋ ๊ด๋ฆฌํด์ผ ํฉ๋๋ค.
๊ทธ๋ฌ๋ Git ์ ์ฅ์์ ํ๋ฌธ(Plain Text)์ผ๋ก ์ํฌ๋ฆฟ์ ์ ์ฅํ๋ฉด ๋ณด์ ์ํ์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด Vault ๋ฑ์ ์ธ๋ถ ์ํฌ๋ฆฟ ๊ด๋ฆฌ ์์คํ
์ ํ์ฉํ์ฌ ๋ณด์์ฑ์ ๊ฐํํ ์ ์์ต๋๋ค.
โ Vault๋ฅผ ํ์ฉํ ์ํฌ๋ฆฟ ๊ด๋ฆฌ๊ฐ ํ์ํ ์ด์
โ Git ์ ์ฅ์์ ๋ฏผ๊ฐํ ์ ๋ณด(๋น๋ฐ๋ฒํธ, API ํค)๋ฅผ ์ง์ ์ ์ฅํ์ง ์๋๋ก ๋ณดํธ
โ ๋์ ์ํฌ๋ฆฟ ์์ฑ ๋ฐ ์๋ ๊ฐฑ์ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ๋ณด์์ฑ์ ๊ฐํ
โ RBAC(Role-Based Access Control) ๊ธฐ๋ฐ์ผ๋ก ์ ๊ทผ ์ ์ด ๊ฐ๋ฅ
โ Kubernetes ๋ค์ดํฐ๋ธ ๋ฐฉ์์ผ๋ก Argo CD์ ์ฐ๋ ๊ฐ๋ฅ
๐น 1. HashiCorp Vault๋ฅผ ํ์ฉํ ์ํฌ๋ฆฟ ๊ด๋ฆฌ
Vault๋ ๋์ ์ํฌ๋ฆฟ(Dynamic Secrets) ๋ฐ Kubernetes์์ ์ฐ๋์ ์ง์ํ๋ ๊ฐ๋ ฅํ ์ํฌ๋ฆฟ ๊ด๋ฆฌ ๋๊ตฌ์
๋๋ค.
Kubernetes ํ๊ฒฝ์์ Argo CD์ Vault๋ฅผ ์ฐ๋ํ๋ฉด ์ํฌ๋ฆฟ์ ์์ ํ๊ฒ ๊ด๋ฆฌํ๊ณ ์ ํ๋ฆฌ์ผ์ด์
์ ์๋์ผ๋ก ์ฃผ์
ํ ์ ์์ต๋๋ค.
โ 1.1 Vault ์ค์น ๋ฐ ์ด๊ธฐ ์ค์
Vault๋ฅผ Kubernetes ํ๊ฒฝ์ ๋ฐฐํฌํ๊ธฐ ์ํด Helm Chart๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
helm repo add hashicorp https://helm.releases.hashicorp.com
helm install vault hashicorp/vault --namespace vault --create-namespace
โ
์ค๋ช
:
โ helm install vault hashicorp/vault → Vault Helm ์ฐจํธ ์ค์น
โ --namespace vault --create-namespace → Vault๋ฅผ ๋ณ๋์ ๋ค์์คํ์ด์ค์ ๋ฐฐํฌ
โ Vault Pod ์ํ ํ์ธ
kubectl get pods -n vault
โ ์ถ๋ ฅ ์์:
NAME READY STATUS RESTARTS AGE
vault-0 1/1 Running 0 2m
โ 1.2 Vault ์ด๊ธฐํ ๋ฐ ์ธ์ฆ ์ค์
Vault๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๋จผ์ ์ด๊ธฐํ(Initialize) ๋ฐ ์ธ์ฆ(Authentication) ์ค์ ์ด ํ์ํฉ๋๋ค.
โ Vault ์ด๊ธฐํ ์คํ
kubectl exec -it vault-0 -n vault -- vault operator init
โ ์ถ๋ ฅ ์์:
Unseal Key 1: xxxxx-xxxxx-xxxxx
Unseal Key 2: xxxxx-xxxxx-xxxxx
Root Token: hvs.xxxx-xxxx-xxxx
โ Vault Unlock (Unseal) ์คํ
kubectl exec -it vault-0 -n vault -- vault operator unseal <UNSEAL_KEY_1>
kubectl exec -it vault-0 -n vault -- vault operator unseal <UNSEAL_KEY_2>
โ Vault Root Token ๋ก๊ทธ์ธ
kubectl exec -it vault-0 -n vault -- vault login <ROOT_TOKEN>
โ
์ค๋ช
:
โ vault operator init → Vault ์ด๊ธฐํ ๋ฐ Unseal ํค ์์ฑ
โ vault login <ROOT_TOKEN> → Vault Root Token์ ์ฌ์ฉํ์ฌ ๋ก๊ทธ์ธ
๐น 2. Vault์ Kubernetes ์ฐ๋
Vault๋ฅผ Kubernetes ํ๊ฒฝ์์ ์ฌ์ฉํ๋ ค๋ฉด Kubernetes ์ธ์ฆ(Kubernetes Auth)์ ํ์ฑํํด์ผ ํฉ๋๋ค.
โ 2.1 Vault Kubernetes ์ธ์ฆ ํ์ฑํ
vault auth enable kubernetes
โ
์ค๋ช
:
โ vault auth enable kubernetes → Vault์์ Kubernetes ์ธ์ฆ ํ์ฑํ
โ Kubernetes ์ธ์ฆ ์ค์ ์ถ๊ฐ
vault write auth/kubernetes/config \
token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
kubernetes_host="https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT"
โ
์ค๋ช
:
โ token_reviewer_jwt → Kubernetes์ ServiceAccount ํ ํฐ์ ์ฌ์ฉํ์ฌ ์ธ์ฆ
โ kubernetes_host → Kubernetes API ์๋ฒ ์ฃผ์๋ฅผ Vault์ ๋ฑ๋ก
โ 2.2 Vault์์ ์ํฌ๋ฆฟ ์ ์ฅ ๋ฐ ๊ด๋ฆฌ
Vault๋ฅผ ํ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํจ์ค์๋ ๋ฑ์ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค.
vault kv put secret/db-password value="SuperSecret123"
โ ์ ์ฅ๋ ์ํฌ๋ฆฟ ์กฐํ
vault kv get secret/db-password
โ ์ถ๋ ฅ ์์:
====== Metadata ======
Key Value
value SuperSecret123
๐น 3. Argo CD์ Vault ์ฐ๋์ ํตํ ์ํฌ๋ฆฟ ๊ด๋ฆฌ
Argo CD์์ Vault๋ฅผ ํ์ฉํ์ฌ ์ํฌ๋ฆฟ์ ์ง์ ๋ก๋ํ ์ ์๋๋ก External Secrets Operator๋ฅผ ์ฌ์ฉํฉ๋๋ค.
โ 3.1 External Secrets Operator ์ค์น
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets -n external-secrets --create-namespace
โ
์ค๋ช
:
โ helm install external-secrets → Kubernetes์์ ์ธ๋ถ ์ํฌ๋ฆฟ์ ๋ถ๋ฌ์ค๋ ์คํผ๋ ์ดํฐ ์ค์น
โ External Secrets Pod ํ์ธ
kubectl get pods -n external-secrets
โ ์ถ๋ ฅ ์์:
NAME READY STATUS RESTARTS AGE
external-secrets-5f9fd7dd58-vzfsd 1/1 Running 0 2m
โ 3.2 Vault์์ ์ํฌ๋ฆฟ์ Kubernetes ์ํฌ๋ฆฟ์ผ๋ก ๋ณํ
Argo CD์์ Vault ์ํฌ๋ฆฟ์ ํ์ฉํ๋ ค๋ฉด ExternalSecret์ ์ ์ํด์ผ ํฉ๋๋ค.
apiVersion: external-secrets.io/v1alpha1
kind: ExternalSecret
metadata:
name: db-secret
namespace: example
spec:
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
target:
name: db-secret
creationPolicy: Owner
data:
- secretKey: DB_PASSWORD
remoteRef:
key: secret/db-password # Vault์์ ๋ถ๋ฌ์ฌ ์ํฌ๋ฆฟ ํค
โ
์ค๋ช
:
โ secretStoreRef.name: vault-backend → Vault์์ ์ํฌ๋ฆฟ์ ๊ฐ์ ธ์ด
โ remoteRef.key: secret/db-password → Vault์์ ํด๋น ํค์ ๊ฐ์ ๋ถ๋ฌ์ด
โ External Secret ์ ์ฉ
kubectl apply -f external-secret.yaml -n example
โ ์ํฌ๋ฆฟ ํ์ธ
kubectl get secrets -n example
โ ์ถ๋ ฅ ์์:
NAME TYPE DATA AGE
db-secret Opaque 1 2m
โ ์ํฌ๋ฆฟ ๊ฐ ํ์ธ
kubectl get secret db-secret -n example -o yaml
โ ์ถ๋ ฅ ์์:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
namespace: example
type: Opaque
data:
DB_PASSWORD: U3VwZXJTZWNyZXQxMjM=
๐น ๊ฒฐ๋ก : ์ด๋ฒ ๊ธ์์ ๋ฐฐ์ด ํต์ฌ ๋ด์ฉ ์ ๋ฆฌ
๐ข Vault๋ฅผ ํ์ฉํ์ฌ Git ์ ์ฅ์์์ ์ํฌ๋ฆฟ์ ์์ ํ๊ฒ ๋ณดํธ ๊ฐ๋ฅ
๐ข Argo CD์ External Secrets Operator๋ฅผ ์ฐ๋ํ์ฌ ๋์ ์ผ๋ก ์ํฌ๋ฆฟ์ ๊ด๋ฆฌ ๊ฐ๋ฅ
๐ข Kubernetes ๋ค์ดํฐ๋ธ ๋ฐฉ์์ ํตํด ์ํฌ๋ฆฟ์ ์์ ํ๊ฒ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฃผ์
๊ฐ๋ฅ
๐ข GitOps ํ๊ฒฝ์์๋ ๋ณด์์ฑ์ด ๊ฐํ๋ ์ํฌ๋ฆฟ ๊ด๋ฆฌ ์ด์ ๊ฐ๋ฅ