Cert-Manager
cert-manager는 Kubernetes 클러스터에서 TLS 인증서의 발급, 갱신, 관리를 자동화하는 도구입니다. Let's Encrypt ACME 프로토콜을 통해 무료 SSL/TLS 인증서를 자동으로 발급하고 관리합니다.
아키텍처
배포 구성
Helm Values
cert-manager는 공식 Helm 차트를 사용하여 배포됩니다:
# CRD 설치
installCRDs: true
# Controller 설정
replicaCount: 1
resources:
requests:
cpu: 15m
memory: 100Mi
limits:
memory: 100Mi
# Webhook 설정
webhook:
replicaCount: 1
resources:
requests:
cpu: 15m
memory: 100Mi
limits:
memory: 100Mi
# CA Injector 설정
cainjector:
replicaCount: 1
resources:
requests:
cpu: 15m
memory: 138Mi
limits:
memory: 138Mi
고가용성 설정
각 컴포넌트는 Pod Anti-Affinity를 통해 서로 다른 노드에 배포됩니다:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/name: cert-manager
topologyKey: kubernetes.io/hostname
ClusterIssuer 구성
Let's Encrypt Production
프로덕션 환경에서 사용하는 ClusterIssuer 설정 (platform/cert-manager/common-values.yaml 기준):
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: bluemayne0213@icloud.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
# HTTP-01 Challenge (Traefik Ingress)
- http01:
ingress:
class: traefik
# DNS-01 Challenge (Cloudflare) — lumie-infra.com 와일드카드
- dns01:
cloudflare:
apiTokenSecretRef:
name: cloudflare-api-token
key: api-token
selector:
dnsZones:
- lumie-infra.com
Let's Encrypt Staging
개발 및 테스트용 ClusterIssuer:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: bluemayne0213@icloud.com
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- http01:
ingress:
class: traefik
인증서 발급 방식
HTTP-01 Challenge
표준 도메인 인증서 발급에 사용됩니다:
DNS-01 Challenge
와일드카드 인증서 발급에 사용됩니다:
Vault 통합
Cloudflare API 토큰은 Vault에서 안전하게 관리됩니다:
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: cloudflare-api-token-vss
namespace: cert-manager
spec:
vaultAuthRef: vault/vault-auth
mount: secret
type: kv-v2
path: tokens
refreshAfter: 1h
destination:
create: true
name: cloudflare-api-token
transformation:
excludeRaw: true
templates:
api-token:
text: "{{ .Secrets.CLOUDFLARE_API_KEYS }}"