[Ep.39] [Argo CD μ΄μ μ΅μ ν #9] Argo CD 보μ κ°ν λ° GitOps μ΄μ λ² μ€νΈ νλν°μ€
πΉ Argo CD 보μ κ°νκ° νμν μ΄μ
Argo CDλ GitOps κΈ°λ°μΌλ‘ Kubernetes μ ν리μΌμ΄μ
μ μλ λ°°ν¬νμ§λ§,
보μ μ€μ μ΄ λ―Έν‘ν κ²½μ° Git μ μ₯μ μ μΆ, ν΄λ¬μ€ν° μ κ·Ό κΆν λ¨μ©, μν¬λ¦Ώ λ
ΈμΆ λ±μ 보μ μνμ΄ λ°μν μ μμ΅λλ€.
β Argo CD 보μ κ°νλ₯Ό κ³ λ €ν΄μΌ νλ μ΄μ
β GitOps νκ²½μμ μν¬λ¦Ώκ³Ό μΈμ¦ μ 보λ₯Ό μμ νκ² λ³΄νΈν΄μΌ ν¨
β RBAC(Role-Based Access Control)μ ν΅ν΄ μ¬μ©μμ μ κ·Όμ μ μ΄ν΄μΌ ν¨
β TLS μνΈνλ₯Ό μ μ©νμ¬ μμ ν API ν΅μ μ 보μ₯ν΄μΌ ν¨
β 보μ λͺ¨λν°λ§μ ν΅ν΄ GitOps νκ²½μμ λ°μνλ μνμ κ°μ§ν΄μΌ ν¨
πΉ 1. Argo CD RBAC(Role-Based Access Control) μ μ©
β 1.1 Argo CD κΈ°λ³Έ RBAC μ μ± μ€μ
Argo CDλ κΈ°λ³Έμ μΌλ‘ RBAC μ μ± μ ν΅ν΄ μ¬μ©μ λ° μλΉμ€μ μ κ·Ό κΆνμ μ μ΄ν μ μμ΅λλ€.
π κΈ°λ³Έ RBAC μ€μ μμ (argocd-rbac-cm.yaml)
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.default: role:readonly # κΈ°λ³Έμ μΌλ‘ λͺ¨λ μ¬μ©μλ Read-Only κΆνλ§ κ°μ§
policy.csv: |
p, admin, applications, *, */*, allow # κ΄λ¦¬μ(Admin) λͺ¨λ μ ν리μΌμ΄μ
μ μ΄ κ°λ₯
p, dev, applications, get, */*, allow # κ°λ°μ(Dev)λ μ ν리μΌμ΄μ
μ‘°νλ§ κ°λ₯
p, dev, applications, sync, dev/*, allow # κ°λ°μλ dev λ€μμ€νμ΄μ€ λ΄ λκΈ°ν κ°λ₯
p, qa, applications, sync, qa/*, allow # QA μ¬μ©μλ qa λ€μμ€νμ΄μ€ λ΄ λκΈ°ν κ°λ₯
β
μ€λͺ
:
β policy.default: role:readonly → κΈ°λ³Έμ μΌλ‘ λͺ¨λ μ¬μ©μλ μ½κΈ° μ μ©(Read-Only) κΆν
β p, admin, applications, *, */*, allow → Admin μν μ¬μ©μλ λͺ¨λ μ ν리μΌμ΄μ
μ μ μ΄ κ°λ₯
β p, dev, applications, sync, dev/*, allow → Dev μν μ¬μ©μλ dev λ€μμ€νμ΄μ€μμλ§ λκΈ°ν κ°λ₯
β RBAC μ μ± μ μ©
kubectl apply -f argocd-rbac-cm.yaml -n argocd
kubectl rollout restart deployment argocd-server -n argocd
β 1.2 Argo CD SSO(Single Sign-On) μ μ©
Argo CDλ SSO(Single Sign-On) λ₯Ό μ§μνμ¬ λ³΄μμ±μ λμΌ μ μμ΅λλ€.
DEX(Identity Provider)λ₯Ό νμ©νμ¬ OIDC(OpenID Connect), GitHub, LDAP μΈμ¦μ μ μ©ν μ μμ΅λλ€.
π Argo CD SSO μ€μ μμ (OIDC κΈ°λ°)
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
oidc.config: |
name: Keycloak
issuer: https://keycloak.example.com/auth/realms/master
clientID: argocd
clientSecret: $oidc.keycloak.clientSecret
requestedScopes:
- openid
- profile
- email
β
μ€λͺ
:
β issuer: https://keycloak.example.com/auth/realms/master → Keycloak OIDC μ 곡μ μ¬μ©
β clientID: argocd → Argo CDμ OIDC ν΄λΌμ΄μΈνΈ ID μ€μ
β clientSecret: $oidc.keycloak.clientSecret → ν΄λΌμ΄μΈνΈ μν¬λ¦Ώμ νκ²½ λ³μλ‘ κ΄λ¦¬
β SSO μ μ© ν λ‘κ·ΈμΈ ν μ€νΈ
argocd login argocd.example.com --sso
β SSO λ‘κ·ΈμΈμ ν΅ν΄ μΈμ¦ μ±κ³΅ ν Argo CD μ κ·Ό κ°λ₯
πΉ 2. Argo CD μν¬λ¦Ώ κ΄λ¦¬ λ° μνΈν
GitOps νκ²½μμλ μν¬λ¦Ώ(Secret)μ μμ νκ² μ μ₯νκ³ λ°°ν¬νλ κ²μ΄ μ€μν©λλ€.
Argo CDλ Sealed Secrets, External Secretsμ νμ©νμ¬ μν¬λ¦Ώμ μνΈννκ³ κ΄λ¦¬ν μ μμ΅λλ€.
β 2.1 Sealed Secretsμ νμ©ν μν¬λ¦Ώ μνΈν
π Sealed Secretsμ νμ©ν μν¬λ¦Ώ μμ± λ° μνΈν
kubectl create secret generic db-secret --from-literal=DB_PASSWORD='supersecret' -n example
kubectl label secret db-secret sealedsecrets.bitnami.com/sealed="true"
kubeseal --format yaml < db-secret.yaml > sealed-secret.yaml
π Gitμ μ μ₯ν μνΈνλ Sealed Secret μμ
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: db-secret
namespace: example
spec:
encryptedData:
DB_PASSWORD: AgAGXt... # μνΈνλ λ°μ΄ν°
β
μ€λͺ
:
β kubesealμ μ¬μ©νμ¬ Git μ μ₯μμ μμ νκ² μ μ₯ν μ μλλ‘ μν¬λ¦Ώμ μνΈν
β μνΈνλ λ°μ΄ν°λ 볡νΈν ν€ μμ΄λ μ κ·Ό λΆκ°
β 2.2 External Secretsμ νμ©ν μν¬λ¦Ώ μΈλΆ μ μ₯
AWS Secrets Manager, HashiCorp Vaultμ κ°μ μΈλΆ μν¬λ¦Ώ κ΄λ¦¬ μμ€ν μ νμ©ν μλ μμ΅λλ€.
π External Secrets μ€μ μμ (AWS Secrets Manager μ°λ)
apiVersion: external-secrets.io/v1alpha1
kind: ExternalSecret
metadata:
name: db-secret
namespace: example
spec:
secretStoreRef:
name: aws-secrets
kind: ClusterSecretStore
target:
name: db-secret
creationPolicy: Owner
data:
- secretKey: DB_PASSWORD
remoteRef:
key: production/db-password # AWS Secrets Managerμμ λΆλ¬μ¬ μν¬λ¦Ώ ν€
β
μ€λͺ
:
β secretStoreRef.name: aws-secrets → AWS Secrets Managerλ₯Ό μ¬μ©νμ¬ μν¬λ¦Ώ κ΄λ¦¬
β remoteRef.key: production/db-password → AWS Secretsμμ νΉμ ν€λ₯Ό λΆλ¬μ Kubernetesμ μ μ©
πΉ 3. Argo CD 보μ λͺ¨λν°λ§ λ° κ°μ¬ λ‘κ·Έ νμ±ν
보μ μ΄λ²€νΈλ₯Ό μ€μκ°μΌλ‘ λͺ¨λν°λ§νκ³ κ°μ¬(Audit) λ‘κ·Έλ₯Ό νμ±ννμ¬
λκ°, μΈμ , μ΄λ€ λ³κ²½μ μννλμ§ μΆμ κ°λ₯ν΄μΌ ν©λλ€.
β 3.1 Argo CD κ°μ¬(Audit) λ‘κ·Έ νμ±ν
π Argo CD λ‘κ·Έ μ€μ (argocd-cm.yaml)
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
application.instanceLabelKey: argocd.argoproj.io/instance
server.enable.audit: "true" # κ°μ¬ λ‘κ·Έ νμ±ν
β
μ€λͺ
:
β server.enable.audit: "true" → Argo CD κ°μ¬ λ‘κ·Έ νμ±ν
β λ‘κ·Έ νμΈ λ°©λ²
kubectl logs -l app.kubernetes.io/name=argocd-server -n argocd
πΉ κ²°λ‘ : μ΄λ² κΈμμ λ°°μ΄ ν΅μ¬ λ΄μ© μ 리
π’ RBAC λ° SSO(Single Sign-On) μ μ©μ ν΅ν΄ 보μ κ°νλ₯Ό μν κ°λ₯
π’ Sealed Secrets, External Secretsμ νμ©νμ¬ μν¬λ¦Ώμ μμ νκ² κ΄λ¦¬ κ°λ₯
π’ κ°μ¬(Audit) λ‘κ·Έ λ° λ³΄μ λͺ¨λν°λ§μ νμ±ννμ¬ GitOps νκ²½μ 보μμ±μ κ°ν κ°λ₯