근묵자흑
Kubernetes Pattern: Configuration Template 본문
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 워크플로우를 유지할 수 있습니다.
참고 자료
- Kubernetes Patterns Book - Chapter 22: Configuration Template
- Kubernetes Documentation - ConfigMap
- Kubernetes Documentation - Secrets
- KEP-753: Sidecar Containers
- Kubernetes v1.33 Release Notes - Sidecar GA
- External Secrets Operator
- Stakater Reloader
- Gomplate Documentation
- AWS EKS Best Practices - Data Encryption
- Twelve-Factor App
'k8s > kubernetes-pattern' 카테고리의 다른 글
| Kubernetes Pattern: Network Segmentation (0) | 2026.01.10 |
|---|---|
| Kubernetes Pattern: Process Containment (0) | 2026.01.03 |
| Kubernetes Pattern: Immutable Configuration & Kubernetes Churn (0) | 2025.12.27 |
| Kubernetes Pattern: EnvVar Configuration && Configuration Resource (0) | 2025.12.20 |
| Kubernetes Pattern: Ambassador (0) | 2025.12.13 |