Notice
Recent Posts
Recent Comments
Link
«   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
Archives
Today
Total
관리 메뉴

근묵자흑

Kubernetes Pattern: Configuration Template 본문

k8s/kubernetes-pattern

Kubernetes Pattern: Configuration Template

Luuuuu 2025. 12. 27. 20:13

 

Configuration Template 패턴은 애플리케이션 시작 시점에 설정 템플릿을 처리하여 완전한 설정 파일을 생성하는 방식입니다. 템플릿에는 환경에 따라 달라지는 값들을 파라미터로 정의하고, 런타임에 실제 값을 주입하여 최종 설정 파일을 만들어냅니다.

 

이 패턴은 Configuration Resource 패턴(ConfigMap, Secret)의 상위 개념으로, 복잡하고 큰 설정 파일을 다룰 때 특히 유용합니다. Kubernetes Patterns 책에서 강조하듯이, 이 패턴의 핵심 목적은 DRY(Don't Repeat Yourself) 원칙을 설정 관리에 적용하는 것입니다. 환경별로 90% 이상 동일한 대규모 설정 파일을 각각 별도의 ConfigMap으로 관리하면 유지보수 부담이 커지고 설정 드리프트(configuration drift)가 발생하기 쉽습니다.

테스트 환경

  • Kubernetes 버전: 1.34.1
  • 플랫폼: minikube 1.37.0

Configuration Patterns의 필요성

설정 외부화 원칙

Twelve-Factor App 방법론에서 강조하듯이, 설정을 코드에서 분리하는 것은 컨테이너 환경에서 필수입니다. 설정을 하드코딩하면 환경별로 다른 이미지를 빌드해야 하지만, 설정을 외부화하면 동일한 이미지로 모든 환경에 배포할 수 있습니다.

graph TB
    subgraph "설정 하드코딩 방식"
        A1[Application Code + Config] --> B1[Dev Image]
        A1 --> B2[Staging Image]
        A1 --> B3[Prod Image]
    end

    subgraph "설정 외부화 방식"
        A2[Application Code] --> C[Single Image]
        D1[Dev ConfigMap] --> E1[Dev Deployment]
        D2[Staging ConfigMap] --> E2[Staging Deployment]
        D3[Prod ConfigMap] --> E3[Prod Deployment]
        C --> E1
        C --> E2
        C --> E3
    end

설정 외부화의 장점은 동일 이미지로 모든 환경에 배포할 수 있고, 민감 정보를 소스 코드에 저장하지 않으며, 재빌드 없이 설정을 변경할 수 있다는 점입니다.

Kubernetes의 설정 관리 계층

Kubernetes는 설정 관리를 위해 여러 수준의 패턴을 제공합니다.

flowchart LR
    A["Environment Variables<br/>기본 수준"]
    B["ConfigMap & Secret<br/>표준 수준"]
    C["Template Processing<br/>고급 수준"]
    D["External Configuration<br/>전문가 수준"]

    A -->|제한적| B
    B -->|대용량 파일| C
    C -->|중앙 관리| D

이 글에서는 주로 ConfigMap/Secret 기반의 표준 수준과 Template Processing을 활용한 고급 패턴을 다룹니다.

ConfigMap의 한계와 Configuration Template의 필요성

ConfigMap을 직접 사용할 때 발생하는 문제들이 있습니다.

  • 첫째, 크기 제한입니다. ConfigMap과 Secret의 모든 값 합계는 1MB를 초과할 수 없습니다. 이는 etcd의 max-request-bytes 설정에 의해 강제됩니다. WildFly의 standalone.xml이나 Elasticsearch의 설정처럼 수백 KB에 달하는 설정 파일을 다룰 때 이 제한이 문제가 됩니다.
  • 둘째, 환경별 중복입니다. 개발, 스테이징, 운영 환경의 설정이 대부분 동일하고 데이터베이스 URL이나 로그 레벨 같은 일부만 다른 경우에도 전체 설정 파일을 각 환경별로 별도의 ConfigMap으로 관리해야 합니다.
  • 셋째, 유지보수 부담입니다. 공통 설정이 변경되면 모든 환경의 ConfigMap을 수정해야 하고, 이 과정에서 설정 드리프트가 발생하기 쉽습니다.

Configuration Template 패턴은 이러한 문제를 해결합니다. 환경에 따라 달라지는 값만 ConfigMap이나 환경 변수로 관리하고, 공통 설정은 템플릿으로 유지합니다. Pod 시작 시 템플릿 프로세서가 파라미터를 템플릿에 주입하여 완전한 설정 파일을 생성합니다.

기본 개념: ConfigMap과 Secret

ConfigMap과 Secret의 차이

graph TB
    subgraph "ConfigMap"
        A1[일반 설정 데이터]
        A2[평문 저장]
        A3[환경별 설정]
    end

    subgraph "Secret"
        B1[민감 정보]
        B2[Base64 인코딩]
        B3[암호, API 키]
    end

    subgraph "공통 사용 방법"
        C1[환경변수로 주입]
        C2[볼륨으로 마운트]
    end

    A1 --> C1
    A1 --> C2
    B1 --> C1
    B1 --> C2

ConfigMap은 일반적인 설정 데이터를 저장하며, Secret은 민감한 데이터를 저장합니다. 단, Secret의 Base64 인코딩은 암호화가 아니므로 프로덕션에서는 etcd 암호화나 External Secrets Operator를 사용해야 합니다.

ConfigMap 사용 방법

ConfigMap을 Pod에서 사용하는 주요 방법은 세 가지입니다.

환경변수로 주입하는 방식은 간단하지만, Pod 생성 후에는 값이 변경되지 않습니다.

env:
- name: APP_CONFIG
  valueFrom:
    configMapKeyRef:
      name: app-config
      key: config.json

전체 ConfigMap을 환경변수로 가져오는 방식은 여러 설정 값을 한 번에 주입할 때 유용합니다.

envFrom:
- configMapRef:
    name: app-config
  prefix: CONFIG_

볼륨으로 마운트하는 방식은 파일 형태의 설정에 적합하며, ConfigMap 업데이트 시 자동으로 반영됩니다.

volumes:
- name: config
  configMap:
    name: app-config
volumeMounts:
- name: config
  mountPath: /etc/config

볼륨 마운트의 내부 메커니즘

Kubernetes는 ConfigMap을 볼륨으로 마운트할 때 심볼릭 링크를 사용합니다.

graph LR
    A["/config"] --> B["..data"]
    B --> C["..2025_12_27_10_00_00"]
    C --> D["config.yaml"]

ConfigMap이 업데이트되면 새로운 타임스탬프 디렉토리를 생성하고 ..data 링크만 변경합니다. 이를 통해 파일 읽기 중 부분적인 업데이트를 방지하는 원자적(atomic) 업데이트를 구현합니다.

주의사항: subPath를 사용하여 마운트한 파일은 자동 업데이트되지 않습니다. 이는 Kubernetes의 알려진 제한사항입니다.

템플릿 프로세서 도구 비교

Configuration Template 패턴을 구현할 때 여러 템플릿 프로세서 중 선택할 수 있습니다. 각 도구의 특성을 이해하고 상황에 맞게 선택하는 것이 중요합니다.

도구별 특성 비교

flowchart TB
    A{템플릿 처리 요구사항}

    A -->|단순 변수 치환| B[envsubst]
    A -->|외부 데이터소스 연동| C[Gomplate]
    A -->|YAML 구조 조작| D[ytt]
    A -->|타입 안전성 필요| E[CUE]

    B --> B1["장점: 설치 불필요<br/>단점: 조건문/반복 없음"]
    C --> C1["장점: 400+ 함수, Vault 연동<br/>단점: 추가 이미지 필요"]
    D --> D1["장점: YAML 구조 인식<br/>단점: Starlark 학습 필요"]
    E --> E1["장점: 스키마 검증<br/>단점: 학습 곡선 높음"]

 

envsubst는 가장 간단한 도구로 대부분의 Linux 배포판에 기본 포함되어 있습니다. ${VAR} 형식의 변수를 치환하며, CI/CD 파이프라인에서 간단한 치환에 적합합니다.

# envsubst 사용 예시
envsubst < config.template > config.yaml

 

Gomplate는 Go 템플릿 기반으로 400개 이상의 내장 함수를 제공합니다. Vault, AWS SSM, Consul 등 외부 데이터소스와 연동이 가능하며, Kubernetes Patterns 책에서 권장하는 도구입니다.

# Gomplate 템플릿 예시
database_url: {{ (datasource "secrets").database_url }}
log_level: {{ .Env.LOG_LEVEL | default "INFO" }}

 

ytt는 Carvel 프로젝트(CNCF Sandbox)의 일부로, YAML 구조를 인식하여 처리합니다. 들여쓰기나 이스케이프 문제가 없으며, Python과 유사한 Starlark 문법을 사용합니다.

#@ load("@ytt:data", "data")
apiVersion: v1
kind: ConfigMap
data:
  log_level: #@ data.values.log_level

도구 선택 가이드

상황 권장 도구 이유
CI/CD 단순 변수 치환 envsubst 추가 설치 불필요
Vault/AWS SSM 연동 Gomplate 외부 데이터소스 지원
복잡한 YAML 오버레이 ytt 구조 인식 처리
대규모 설정 검증 CUE 타입 시스템 지원
레거시 시스템 confd 주의: 2018년 이후 미유지보수

Pattern 1: Configuration Template with Gomplate

개념

Configuration Template 패턴은 Init Container에서 템플릿 엔진을 사용하여 설정 파일을 동적으로 생성하는 방식입니다. 대규모 XML이나 JSON 설정 파일을 환경별로 생성할 때 유용합니다.

sequenceDiagram
    participant CM as ConfigMap
    participant Init as Init Container<br/>(gomplate)
    participant Vol as Shared Volume
    participant Main as Main Container

    CM->>Init: 1. 템플릿 및 변수 제공
    Init->>Init: 2. 템플릿 처리
    Init->>Vol: 3. 생성된 파일 저장
    Init->>Main: 4. 완료 신호
    Main->>Vol: 5. 설정 파일 읽기
    Main->>Main: 6. 애플리케이션 시작

책의 WildFly 예제 분석

Kubernetes Patterns 책에서는 WildFly 설정을 예로 들어 설명합니다. standalone.xml 파일의 로그 포맷 부분을 템플릿화하는 예제입니다.

<!-- standalone.xml 템플릿 (Go 템플릿 문법) -->
<formatter name="COLOR-PATTERN">
    <pattern-formatter pattern="{{(datasource "config").logFormat}}"/>
</formatter>

이 접근 방식의 핵심은 환경별로 다른 부분만 파라미터화하고, 나머지 수백 줄의 설정은 단일 템플릿으로 유지한다는 점입니다.

테스트 구성

테스트에서는 NGINX 설정을 예로 사용했습니다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: webapp-config
data:
  environment: "DEVELOPMENT"
  logLevel: "DEBUG"

  # 템플릿 파일
  nginx.conf.tmpl: |
    http {
      error_log /var/log/nginx/error.log {{ (datasource "config").logLevel | strings.ToLower }};

      log_format main '{{ (datasource "config").environment }} - $remote_addr...';
    }

Deployment에서 Init Container 구성은 다음과 같습니다.

spec:
  initContainers:
  - name: template-processor
    image: hairyhenderson/gomplate:v4.3.0-alpine
    command:
      - /bin/sh
      - -c
      - |
        # ConfigMap 데이터를 JSON으로 변환
        cat > /tmp/config.json <<EOF
        {
          "environment": "$ENVIRONMENT",
          "logLevel": "$LOG_LEVEL"
        }
        EOF

        # 템플릿 처리
        gomplate -d config=/tmp/config.json \
          -f /templates/nginx.conf.tmpl \
          -o /config/nginx.conf
    env:
    - name: ENVIRONMENT
      valueFrom:
        configMapKeyRef:
          name: webapp-config
          key: environment
    volumeMounts:
    - name: templates
      mountPath: /templates
    - name: config
      mountPath: /config

  containers:
  - name: webapp
    image: nginx:1.27-alpine
    volumeMounts:
    - name: config
      mountPath: /etc/nginx/nginx.conf
      subPath: nginx.conf

테스트 결과

소요 시간: 약 30초

검증된 사항:

  • Init container가 main container 전에 실행
  • Gomplate를 통한 템플릿 변수 치환
  • 환경별(dev/prod) 설정 분리
  • NGINX 로그에 환경별 prefix 적용
# NGINX access log 결과
DEVELOPMENT - 10.244.18.114 - - [27/Dec/2025:10:07:34 +0000] "GET / HTTP/1.1" 200

환경 전환 테스트

ConfigMap만 교체하고 Deployment를 재시작하면 새로운 설정이 적용됩니다.

# Dev ConfigMap 제거
kubectl delete configmap webapp-config

# Prod ConfigMap 적용
kubectl apply -f prod/configmap-prod.yaml

# Deployment 재시작
kubectl rollout restart deployment/webapp

재시작 후 로그 확인 결과 환경이 PRODUCTION으로 변경되었습니다.

PRODUCTION - 10.244.18.114 - - [27/Dec/2025:10:15:22 +0000] "GET / HTTP/1.1" 200

적용 사례

Configuration Template 패턴이 적합한 경우는 대규모 XML 설정 파일(WildFly, Tomcat 등), 복잡한 JSON 구조(Elasticsearch, Logstash), 다중 환경에서 유사한 설정 구조를 다룰 때입니다.

적합하지 않은 경우는 간단한 key-value 설정, 자주 변경되는 설정, 실시간 업데이트가 필요한 경우입니다.

Pattern 2: Native Sidecar Containers

Kubernetes 1.33 GA 기능

2025년 4월, Kubernetes 1.33에서 Native Sidecar Containers가 정식(GA) 기능으로 승격되었습니다. 이는 KEP-753으로 추진되어 왔으며, 1.28에서 알파, 1.29에서 베타를 거쳐 안정화되었습니다.

Init container에 restartPolicy: Always를 설정하면 sidecar로 동작합니다. 이 sidecar는 main container보다 먼저 시작하고, main container가 종료된 후에 종료됩니다.

sequenceDiagram
    participant K8s as Kubernetes
    participant Sidecar as Sidecar Container<br/>(restartPolicy: Always)
    participant Main as Main Container

    K8s->>Sidecar: 1. Sidecar 시작
    Sidecar->>Sidecar: 2. 초기화 완료 (startupProbe 통과)
    K8s->>Main: 3. Main container 시작
    Main->>Main: 4. 애플리케이션 실행
    Main->>K8s: 5. 작업 완료
    K8s->>Sidecar: 6. Sidecar 종료 (SIGTERM)

버전별 상태

Kubernetes 버전 SidecarContainers 상태 기본 활성화
1.28 Alpha 비활성화
1.29 Beta 활성화
1.33+ GA (Stable) 활성화

테스트 구성

spec:
  initContainers:
  - name: config-sidecar
    image: busybox:1.36
    restartPolicy: Always  # Sidecar로 동작
    command:
      - /bin/sh
      - -c
      - |
        while true; do
          echo "$(date): Config refresh cycle"
          cp /config-source/config.json /config-dest/config.json
          sleep 10
        done
    volumeMounts:
    - name: config-source
      mountPath: /config-source
    - name: config-dest
      mountPath: /config-dest
    startupProbe:
      exec:
        command: ["test", "-f", "/config-dest/config.json"]
      periodSeconds: 1

  containers:
  - name: webapp
    image: busybox:1.36
    command: ["sh", "-c", "cat /app-config/config.json && sleep 30"]
    volumeMounts:
    - name: config-dest
      mountPath: /app-config

테스트 결과

소요 시간: 약 35초

검증된 사항:

Sidecar가 main container보다 먼저 시작하는 것을 확인했습니다.

Sat Dec 27 10:44:06 UTC 2025: Sidecar starting
Sat Dec 27 10:44:08 UTC 2025: Main container starting

Sidecar는 main container 종료 후에도 계속 실행되며, Job에서 sidecar가 completion을 차단하지 않습니다.

# Job 완료 확인
job.batch/data-processor condition met

주요 특징

Native Sidecar의 장점은 공식 지원으로 안정적인 동작이 보장되고, startupProbe와 livenessProbe를 모두 지원하며, Job에서 completion을 차단하지 않는다는 점입니다. 이전에 사용하던 preStop hook이나 shareProcessNamespace 같은 workaround가 더 이상 필요하지 않습니다.

적용 사례로는 설정 파일 동적 갱신, 로그 수집 및 전송, 서비스 메시 프록시(Istio, Linkerd), 모니터링 에이전트가 있습니다.

Pattern 3: Projected Volumes

개념

Projected Volumes는 ConfigMap, Secret, DownwardAPI, ServiceAccountToken 등 여러 소스를 하나의 볼륨으로 통합하는 기능입니다.

graph TB
    subgraph "여러 소스"
        A[ConfigMap]
        B[Secret]
        C[DownwardAPI]
        D[ServiceAccountToken]
    end

    subgraph "Projected Volume"
        E["config 디렉토리"]
        E --> F[app.conf]
        E --> G[db-password]
        E --> H[pod-name]
        E --> I[token]
    end

    A --> E
    B --> E
    C --> E
    D --> E

테스트 구성

spec:
  containers:
  - name: app
    volumeMounts:
    - name: all-in-one
      mountPath: /config

  volumes:
  - name: all-in-one
    projected:
      sources:
      - configMap:
          name: app-settings
      - secret:
          name: app-secrets
      - downwardAPI:
          items:
          - path: "pod-name"
            fieldRef:
              fieldPath: metadata.name
      - serviceAccountToken:
          path: token
          expirationSeconds: 3600

테스트 결과

소요 시간: 약 20초

마운트된 파일 구조:

/config:
├── app.conf (ConfigMap)
├── db-password (Secret)
├── api-key (Secret)
├── pod-name (DownwardAPI)
├── namespace (DownwardAPI)
└── token (ServiceAccountToken)

모든 소스가 단일 디렉토리로 통합되어 애플리케이션에서 쉽게 접근할 수 있습니다.

적용 사례

Projected Volumes가 유용한 경우는 Service Account token과 Secret, ConfigMap을 조합해야 할 때, 여러 설정 소스를 단일 경로에서 읽어야 할 때, Pod 메타데이터와 설정을 함께 사용할 때입니다.

Pattern 4: Kustomize ConfigMapGenerator

개념

Kustomize의 ConfigMapGenerator는 설정 파일 내용이 변경되면 자동으로 hash suffix를 추가하여 새로운 ConfigMap을 생성합니다. 이를 통해 rolling update가 자동으로 트리거됩니다.

sequenceDiagram
    participant Dev as Developer
    participant File as config.yaml
    participant Kustomize as Kustomize
    participant K8s as Kubernetes
    participant Pod as Pods

    Dev->>File: 1. config.yaml 수정<br/>(version: 1.0 → 2.0)
    Dev->>Kustomize: 2. kubectl apply -k
    Kustomize->>Kustomize: 3. 파일 내용 hash 계산
    Kustomize->>K8s: 4. app-config-m86f649764 생성
    K8s->>Pod: 5. Rolling update 시작
    Pod->>Pod: 6. 새 ConfigMap 사용

테스트 구성

# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

configMapGenerator:
- name: app-config
  files:
  - app.properties

resources:
- deployment.yaml

테스트 결과

초기 배포:

configmap/app-config-m5gt5c88dt created

설정 변경 후:

# app.properties 내용 수정
configmap/app-config-m86f649764 created

hash가 변경되면서 자동으로 새로운 ConfigMap이 생성되고, Deployment가 새 ConfigMap을 참조하도록 업데이트됩니다.

장점

Git에서 설정 변경 이력을 추적할 수 있고, 수동 restart 명령이 불필요하며, 여러 버전의 ConfigMap이 동시에 존재할 수 있어 Blue-Green 배포에 유용합니다. GitOps 워크플로우와 완벽하게 통합됩니다.

Helm과의 비교

Helm에서도 유사한 패턴을 checksum annotation으로 구현할 수 있습니다.

spec:
  template:
    metadata:
      annotations:
        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}

Helm은 패키징과 배포에 강점이 있고, Kustomize는 선언적 패치에 강점이 있습니다. 두 도구를 조합하여 사용하는 것도 일반적인 패턴입니다.

# Helm 차트를 Kustomize로 커스터마이징
helmCharts:
- name: nginx
  repo: https://charts.bitnami.com/bitnami
  version: 13.2.0
  valuesFile: values.yaml
patches:
- path: nginx-patch.yaml

Pattern 5: Stakater Reloader

개념

Stakater Reloader는 ConfigMap이나 Secret 변경을 감지하여 자동으로 관련 Deployment, StatefulSet, DaemonSet을 재시작하는 컨트롤러입니다. Kubernetes에는 ConfigMap 변경 시 Pod를 재시작하는 내장 메커니즘이 없기 때문에 이 도구가 필요합니다.

sequenceDiagram
    participant User as User
    participant CM as ConfigMap
    participant Reloader as Reloader Controller
    participant Deploy as Deployment
    participant Pod as Pods

    User->>CM: 1. ConfigMap 업데이트
    Reloader->>CM: 2. 변경 감지 (Watch)
    Reloader->>Deploy: 3. annotation 업데이트
    Deploy->>Pod: 4. Rolling restart
    Pod->>CM: 5. 새 설정 로드

설치 및 구성

# Helm으로 설치
helm repo add stakater https://stakater.github.io/stakater-charts
helm install reloader stakater/reloader -n kube-system

사용 방법

Deployment에 annotation을 추가하면 됩니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  annotations:
    # 모든 ConfigMap/Secret 변경 시 재시작
    reloader.stakater.com/auto: "true"
spec:
  template:
    spec:
      containers:
      - name: app
        envFrom:
        - configMapRef:
            name: app-config

특정 ConfigMap이나 Secret만 감시하려면 다음과 같이 지정합니다.

annotations:
  # 특정 ConfigMap만 감시
  configmap.reloader.stakater.com/reload: "app-config,feature-flags"

  # 특정 Secret만 감시
  secret.reloader.stakater.com/reload: "db-credentials"

주의사항

Reloader는 Deployment의 annotation을 업데이트하여 rolling restart를 트리거합니다. 따라서 Immutable ConfigMap을 사용하는 경우에는 Reloader가 필요하지 않습니다. Immutable ConfigMap은 이름을 변경하여 새로 생성해야 하므로, Deployment 자체를 업데이트해야 합니다.

Pattern 6: External Secrets Operator

개념

External Secrets Operator(ESO)는 외부 시크릿 관리 시스템(AWS Secrets Manager, HashiCorp Vault, Azure Key Vault 등)의 시크릿을 Kubernetes Secret으로 동기화합니다. 현재 CNCF Sandbox 프로젝트이며, 30개 이상의 프로바이더를 지원합니다.

flowchart LR
    subgraph "External Secret Stores"
        A[AWS Secrets Manager]
        B[HashiCorp Vault]
        C[Azure Key Vault]
        D[GCP Secret Manager]
    end

    subgraph "Kubernetes Cluster"
        E[External Secrets Operator]
        F[ExternalSecret CR]
        G[Kubernetes Secret]
        H[Pod]
    end

    A --> E
    B --> E
    C --> E
    D --> E
    E --> F
    F --> G
    G --> H

설치

# Helm으로 설치
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets \
  -n external-secrets --create-namespace

AWS Secrets Manager 연동 예제

먼저 ClusterSecretStore를 생성합니다.

apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
  name: aws-secretstore
spec:
  provider:
    aws:
      service: SecretsManager
      region: ap-northeast-2
      auth:
        jwt:
          serviceAccountRef:
            name: external-secrets-sa
            namespace: external-secrets

그 다음 ExternalSecret을 생성하여 시크릿을 동기화합니다.

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
spec:
  refreshInterval: 1h  # 동기화 주기
  secretStoreRef:
    name: aws-secretstore
    kind: ClusterSecretStore
  target:
    name: db-secrets
    creationPolicy: Owner
  data:
  - secretKey: username
    remoteRef:
      key: /prod/db/credentials
      property: username
  - secretKey: password
    remoteRef:
      key: /prod/db/credentials
      property: password

장점

시크릿의 단일 진실 소스(Single Source of Truth)를 외부 시스템에서 관리할 수 있습니다. 자동 갱신(refreshInterval)을 통해 시크릿 로테이션을 지원하며, Git에 시크릿을 저장하지 않아도 GitOps 워크플로우를 유지할 수 있습니다.

참고 자료