티스토리 뷰

반응형

쿠버네티스 실습: Secret Manager + Vault + OIDC로 보안 중심 DevSecOps 파이프라인 구축하기

앞선 글에서는 Terraform + ArgoCD + Helm을 이용해 완전 자동화된 IaC (Infrastructure as Code) 파이프라인을 구축했습니다.
이번 글에서는 DevOps를 한 단계 더 확장해, 보안(SEC) 이 자동으로 통합된 DevSecOps 환경을 실습합니다.
즉, 쿠버네티스 인프라 전체에서 비밀정보(Secrets), 인증(OIDC), **권한관리(Vault)**를 안전하게 관리하는 구조를 완성합니다.


1) DevSecOps란?

DevSecOps = DevOps + Security
즉, “개발-배포-운영”의 모든 단계에서 보안을 자동화하는 접근 방식입니다.

구분 DevOps DevSecOps

초점 CI/CD 자동화 보안 내재화 + 자동 검증
시점 배포 이후 보안 점검 배포 전·중·후 실시간 점검
방식 수동 인증 관리 OIDC + Vault로 자동 인증/갱신
비밀정보 쿠버네티스 Secret에 직접 저장 암호화된 Secret Manager로 관리

이번 실습 목표는 다음과 같습니다:

“쿠버네티스 클러스터에 노출되는 비밀번호, 키, 인증 토큰을 코드 없이 자동으로 보호하는 것”


2) 실습 목표 아키텍처

개발자 Git Commit
     ↓
[Argo CD] ----> [Vault (HashiCorp)] ←→ [OIDC Provider (e.g. Google, GitHub)]
     ↓
 [Kubernetes Cluster]
     └── Pod가 필요한 Secret을 Vault에서 동적 요청

핵심 원리:

  • 쿠버네티스 Pod는 Vault Agent Injector로부터 필요한 Secret을 런타임에 동적으로 주입받습니다.
  • 비밀번호나 API 키를 코드/Helm values.yaml에 직접 저장하지 않습니다.
  • Vault는 OIDC로 개발자 및 CI/CD 접근을 인증합니다.

3) Vault 설치

3-1. Helm Chart로 설치

helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update

helm install vault hashicorp/vault \
  --namespace vault --create-namespace \
  --set "server.dev.enabled=true"

설치 확인:

kubectl get pods -n vault

출력 예시:

NAME      READY   STATUS    AGE
vault-0   1/1     Running   1m

4) Vault 초기 설정

반응형

Vault Pod에 접속:

kubectl exec -it vault-0 -n vault -- /bin/sh
vault operator init

출력된 Unseal Key와 Root Token은 안전한 곳에 저장.

Vault 로그인:

vault login <Root Token>

5) Kubernetes 인증 설정

Vault는 쿠버네티스와 직접 통신해 Pod의 서비스 계정으로 인증할 수 있습니다.

vault auth enable kubernetes
vault write auth/kubernetes/config \
    kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443"

6) Secret 엔진 활성화

예: PostgreSQL 접속 비밀번호를 Vault에 저장

vault secrets enable -path=postgresql kv-v2
vault kv put postgresql/credentials \
  username="postgres" password="supersecurepassword"

7) Vault Agent Injector 설정

Vault는 Pod에 사이드카 컨테이너를 주입해 Secret을 자동으로 삽입할 수 있습니다.

예시 Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nestjs
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nestjs
  template:
    metadata:
      labels:
        app: nestjs
      annotations:
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/role: "nestjs-role"
        vault.hashicorp.com/agent-inject-secret-db: "postgresql/credentials"
    spec:
      serviceAccountName: vault-auth
      containers:
      - name: nestjs
        image: <YOUR_IMAGE>
        env:
        - name: DB_CREDENTIAL_FILE
          value: "/vault/secrets/db"

이렇게 설정하면, NestJS Pod는 /vault/secrets/db 파일을 통해 Vault에서 직접 가져온 비밀번호를 사용합니다.


8) Vault 정책과 역할(Role) 설정

Vault 내부에서 서비스 계정별 접근 권한을 정의합니다.

vault policy write nestjs-policy - <<EOF
path "postgresql/credentials" {
  capabilities = ["read"]
}
EOF

vault write auth/kubernetes/role/nestjs-role \
    bound_service_account_names=vault-auth \
    bound_service_account_namespaces=team-a \
    policies=nestjs-policy \
    ttl=24h

이제 team-a 네임스페이스의 vault-auth 서비스 계정으로 실행된 Pod만 해당 Secret에 접근할 수 있습니다.


9) OIDC 인증 연동

Vault는 기본적으로 OIDC(OpenID Connect) 인증을 지원합니다.
이를 이용해 GitHub, Google, Okta, AWS Cognito 등 외부 IdP를 연동할 수 있습니다.

vault auth enable oidc

vault write auth/oidc/config \
    oidc_discovery_url="https://accounts.google.com" \
    oidc_client_id="" \
    oidc_client_secret="" \
    default_role="developer"

vault write auth/oidc/role/developer \
    user_claim="email" \
    allowed_redirect_uris="https://vault.example.com/ui/vault/auth/oidc/oidc/callback" \
    policies="default" \
    ttl="1h"

이제 Vault UI에서 Google 계정으로 로그인할 수 있습니다.
→ 개발자 인증이 완전 자동화됩니다.


10) ArgoCD + Vault 연동

ArgoCD가 배포 중 Secret을 직접 참조하지 않고, Vault에서 동적으로 가져오도록 설정합니다.

argocd-cm.yaml
data:
  configManagementPlugins: |
    - name: vault-helm
      generate:
        command: ["helm", "template", "."]
        args: ["--values", "values.yaml"]
      postRender:
        command: ["vault", "kv", "get", "-format=json", "postgresql/credentials"]

→ ArgoCD 배포 시점에 Vault로부터 Secret을 자동 삽입.


11) 전체 파이프라인 요약

Git Commit
   ↓
GitHub Actions → Terraform (Infra Provisioning)
   ↓
ArgoCD → Helm 배포
   ↓
Vault Agent → Secret 자동 주입
   ↓
OIDC 인증으로 사용자 권한 검증

결과적으로:

  • 비밀번호나 토큰은 절대 코드에 노출되지 않음
  • Vault가 Secret을 주기적으로 갱신
  • 쿠버네티스 Pod는 필요한 시점에만 Secret 접근
  • 개발자 로그인은 Google/GitHub OIDC로 자동 인증

12) 정리

  • Vault + OIDC + ArgoCD를 결합해 DevSecOps 파이프라인 완성
  • 모든 Secret은 중앙 Vault에서 동적 관리, 더 이상 코드에 저장하지 않음
  • ArgoCD와 Vault의 통합으로 보안과 배포 자동화의 균형 확보
  • Terraform을 통한 IaC + Helm을 통한 애플리케이션 선언적 배포까지 완전 자동화

다음 글에서는 이 DevSecOps 환경 위에서
**Service Mesh (Istio) 보안 + mTLS + 정책기반 접근 제어(OPA, Kyverno)**를 통합해
운영 레벨의 Zero Trust 클러스터 아키텍처를 구축해보겠습니다.

 

 

쿠버네티스,DevSecOps,HashiCorpVault,OIDC,ArgoCD,Helm,Terraform,보안자동화,Secret관리,K8s실습

 

 

 

✅ 참고할 최신 기술 및 공식 문서


⚠️ 보완/강화 제안

아래 항목들을 글에 반영하면 독자에게 더 많은 실무적 인사이트를 제공할 수 있어요:

  1. Vault Agent Injector 설치/운영 관련 주의사항
    • Injector는 Pod 주입을 위해 Admission Webhook 기반입니다. (HashiCorp Developer)
    • Helm Chart 설치 시 injector.enabled, server.dev.enabled=false 등의 설정이 운영환경에서 달라질 수 있다는 점. (Medium)
  2. Argo CD 및 Vault 연동 시 사용 가능한 방식 비교
    • AVP(Argo CD Vault Plugin)를 사용하면 GitOps 배포 시 Secret을 Vault에서 직접 읽어 올 수 있습니다. (Medium)
    • 또한, Vault Agent Injector 방식과의 차이 — Pod 런타임에서 주입 vs GitOps 배포 타임에서 값 채워 넣기 등 — 에 대해 설명하면 좋습니다.
  3. OIDC 인증 적용 시 실제 고려사항
    • Vault에서 OIDC 인증 구성 시 “redirect URI”, “allowed scopes” 등 설정이 필요하다는 점.
    • 개발자 로그인뿐 아니라 CI/CD(예: GitHub Actions)에서 인증 토큰을 사용해 Vault 접근하는 방식도 고려하면 좋습니다.
  4. 비밀 정보 관리 및 코드 노출 방지 전략 강조
    • Helm values.yaml 또는 Kubernetes Secret에 직접 민감정보를 저장하지 않고, Vault/AVP 등을 이용해 동적 참조하는 방식.
    • 정적 Secret 저장 시 암호화(SOPS, SealedSecret 등) 또는 Vault Transit 엔진 이용 고려.
  5. 운영 환경 팁 추가
    • Vault 고가용성(HA) 구성 및 자동 언실(auto-unseal) 패턴. (shadow-soft.com)
    • Vault 토큰 및 역할(Role) 만료, Secret 로테이션(rotate) 고려사항
    • 서비스 계정(ServiceAccount) 기반 권한 분리 및 최소 권한 원칙 적용.

 

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함
반응형