본문 바로가기
Security/Vault

Vault Secrets Operator(VSO)를 활용한 Kubernetes secrets 관리 (정적 시크릿)

by wlsdn3004 2024. 2. 26.
728x90
반응형

 

Vault Secrets Operator(VSO)란?

Vault Secrets Operator(이하 "VSO"라 한다)를 사용하면 Pod가 Kubernetes Secrets으로 Vault Secrets을 사용할 수 있다.

Vault Secrets Operator는 지원되는 CRD(Custom Resource Definitions)의 변경 사항을 감시하여 작동한다.

Vault Secrets Operator는 Vault에서 가져온 Secret 정보를 Kubernetes의 Secret로 생성하며, Vault에서 발생하는 모든 변경사항이 Kubernetes의 Secret에도 실시간으로 반영되도록 한다. 이러한 방식으로 애플리케이션은 Secret 정보를 사용하기 위해 Kubernetes의 Secret에만 접근하면 되므로, Secret 정보의 관리가 훨씬 간편해진다.

 

아래 그림을 구조 및 동작을 이해할 수 있다.

 

VSO에서 지원하는 기능은 다음과 같다.

  • 모든 Vault 비밀 엔진 지원.
  • Vault와의 TLS/mTLS 통신.
  • Kubernetes Auth Method를 통해 요청하는 Pod의 ServiceAccount를 사용한 인증.
  • Vault Secrets을 Kubernetes Secrets에 동기화.
  • Deployment, ReplicaSet, StatefulSet Kubernetes 리소스 유형에 대한 Secret 로테이션.
  • Operator 모니터링을 위한 Prometheus의 계측 도구
  • 지원되는 설치 방법: Helm, Kustomize

 

현재 지원되는 Kubernetes 버전은 아래와 같다.

  • 1.28
  • 1.27
  • 1.26
  • 1.25
  • 1.24

(참고: Vault Secrets Operator 지원 버전)

 

이번 글에서는 Vault Secrets Operator를 설치하고 Vault에 저장된 Secret(정적 시크릿)을 Kubernetes Secret으로 생성하여 동기화하는 실습을 진행한다.

 

실습 환경

  • Amazon EKS 1.27.7
  • Helm Cli v3.8.2
  • Vault 1.15.2 (Vault 설치 참고: [Vault 설치])
  • Vault-Secrets-Operator 0.4.3

 

1. Vault Secrets Operator 설치


Helm repo 등록한다.

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

 

VSO의 value 파일을 작성한다.

# vso-values.yaml
defaultVaultConnection:
  enabled: true
  address: http://vault:8200
  skipTLSVerify: false
  spec:
  template:
    spec:
      containers:
      - name: manager
        args:
        - "--client-cache-persistence-model=direct-encrypted"

 

위에서 작성한 value 파일로 설치한다.

$ helm install vault-secrets-operator \ 
    hashicorp/vault-secrets-operator \
    -n vault --create-namespace \
    -f vso-values.yaml

 

정상 설치되었는지 확인한다.

$ kubectl get po -n vault 
NAME                                                         READY   STATUS    RESTARTS   AGE
#...생략
vault-secrets-operator-controller-manager-5c4b7f6b45-ph2qk   2/2     Running   0          2d17h

 

설치 후 "VaultConnection" 커스텀 리소스가 생성되었는지 확인한다.

VaultConnection는 "Vault Secrets Operator"가 Vault 서버에 연결하는 데 필요한 커스텀 리소스이다.

$ kubectl get vaultconnections.secrets.hashicorp.com  -n vault default  -oyaml
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultConnection
metadata:
  annotations:
    meta.helm.sh/release-name: vault-secrets-operator
    meta.helm.sh/release-namespace: vault
  finalizers:
  - vaultconnection.secrets.hashicorp.com/finalizer
  labels:
    app.kubernetes.io/component: controller-manager
    app.kubernetes.io/instance: vault-secrets-operator
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: vault-secrets-operator
    app.kubernetes.io/version: 0.4.3
    component: controller-manager
    control-plane: controller-manager
    helm.sh/chart: vault-secrets-operator-0.4.3
  name: default
  namespace: vault
spec:
  address: http://vault:8200
  skipTLSVerify: false
status:
  valid: true

 

 

2. Vault Secrets Operator 정적 시크릿 정의


정적 시크릿을 사용하기 위해 Vault 서버에서 kv 시크릿 엔진을 활성화한다.

# Vault Pod 접근
$ kubectl exec -it vault-0 -- /bin/sh

# Vault root token으로 로그인
$ vault login {vault_root_token}

# kv 시크릿 엔진 활성화
$ vault secrets enable -path vso-test -version=2 kv

 

test="password"라는 kv 시크릿을 작성한다.

$ vault kv put vso-test/secret test="password"

 

작성된 시크릿 데이터를 확인한다.

$ vault kv get vso-test/secret
==== Secret Path ====
vso-test/data/secret

======= Metadata =======
Key                Value
---                -----
created_time       2024-02-26T05:32:52.734330359Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

==== Data ====
Key     Value
---     -----
test    password

 

 

3. Kuberenetes Auth Method 구성


Vault 인증을 위한 Kubernetes auth method를 구성한다.
 
먼저 kubernetes auth method 활성화한다.
# vault Pod 접근
$ kubectl exec -it vault-0 -- /bin/sh

# root token으로 vault 로그인
$ vault login {vault_root_token}

# kubernetes auth method 활성화
$ vault auth enable kubernetes

 

아래와 같이 Kubernetes auth method를 설정한다.

$ vault write auth/kubernetes/config \
    kubernetes_host="https://{kubernetes API 서버 엔드포인트}"

 

VSO에서 사용할 정책을 생성한다.

$ vault policy write vso-policy - <<EOF
path "vso-test/data/secret" {
  capabilities = ["read"]
}
EOF
Success! Uploaded policy: vso-policy

 

인증에 사용할 Kubernetes serviceaccount를 생성한다.

# vault pod에서 빠져나온다.
$ exit

$ kubectl create sa vso-sa
serviceaccount/vso-sa created

 

Kubernetes 인증에 사용할 role을 생성한다.

  • 위에서 생성한 vso-policy 정책을 vso-sa라는 default/serviceaccount에 할당한다.
  • 인증 후 유효기간은 5분이다.
# vault Pod 접근
$ kubectl exec -it vault-0 -- /bin/sh

$ vault write auth/kubernetes/role/vso \
    bound_service_account_names=vso-sa \
    bound_service_account_namespaces=default \
    policies=vso-policy \
    ttl=5m
Success! Data written to: auth/kubernetes/role/vso

 

 

4. Vault CRD 설정(VaultAuth, VaultStaticSecret)


Kubernetes에 Vault 서버 인증을 위한 VaultAuth CRD를 작성하여 적용한다.

$ kubectl apply -f - <<EOF
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
  name: static-auth
  namespace: default
spec:
  kubernetes:
    audiences:
    - vault
    role: vso
    serviceAccount: vso-sa
    tokenExpirationSeconds: 600
  method: kubernetes
  mount: kubernetes
EOF

 

 

Vault 정적 시크릿을 Kubernetes 시크릿으로 생성 및 동기화를 위해 VaultStaticSecret CRD를 작성하여 적용한다.

$ kubectl apply -f -<<EOF
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
  name: vault-kv
  namespace: default
spec:
  type: kv-v2
  mount: vso-test
  path: secret
  destination:
    name: vsosecret
    create: true
  refreshAfter: 30s
  vaultAuthRef: static-auth
EOF

 

Kubernetes에 생성된 Secret을 확인한다.

$ kubectl get secrets
NAME        TYPE                             DATA   AGE
#...생략
vsosecret   Opaque                           2      3s

 

생성된 Secret의 데이터가 실제 Vault의 kv 데이터와 같은지 확인한다.

$ kubectl get secret vsosecret -o jsonpath='{.data.test}' | base64 -d
password

 

데이터 변경 후 실제 데이터가 Sync 되는지 확인한다.

# vault pod 접근
$ kubectl exec -it vault-0 -- /bin/sh

# kv secret 내용 변경
$ vault kv put vso-test/secret test="password2"
==== Secret Path ====
vso-test/data/secret

======= Metadata =======
Key                Value
---                -----
created_time       2024-02-26T06:07:17.839365479Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            2

# vault pod 접근 종료
$ exit

# secret data 내용 확인
$ kubectl get secret vsosecret -o jsonpath='{.data.test}' | base64 -d
password2

test="password"에서 test="password2"로 데이터가 실시간 Sync 된 것을 확인할 수 있다.

 

실제 Operator 로그를 확인해 보면 아래와 같이 로그 내용을 확인할 수 있다.

$ kubectl logs -n vault deploy/vault-secrets-operator-controller-manager
#...생략
2024-02-26T06:07:25Z    DEBUG   events  Secret synced   {"type": "Normal", "object": {"kind":"VaultStaticSecret","namespace":"default","name":"vault-kv","uid":"62ad46c2-21d7-4645-a42c-0bd18798297c","apiVersion":"secrets.hashicorp.com/v1beta1","resourceVersion":"26792398"}, "reason": "SecretRotated"}
#...생략

 

반응형

댓글