Cloudflare와 Cert-Manager를 이용한 Wildcard SSL 인증서 발급 가이드

Gabia와 같이 DNS API를 제공하지 않는 도메인 등록업체에서 도메인을 구입한 경우, Cloudflare로 DNS 관리를 이관하여 API Token을 발급받고, Kubernetes에서 Wildcard SSL 인증서를 자동으로 발급받을 수 있습니다.

이 방법의 주요 장점은 다음과 같습니다.

  1. DNS-01 Challenge 방식: Let’s Encrypt 서버가 인증서 발급 시 실제 웹 서버에 직접 접근할 필요 없이 DNS 레코드만으로 도메인 소유권을 확인합니다. 따라서 방화벽 뒤에 있거나 외부에서 접근할 수 없는 내부 클러스터에서도 인증서 발급이 가능합니다.

  2. Wildcard 인증서 지원: *.example.com 형태의 Wildcard 인증서를 발급받아 모든 서브도메인에서 동일한 인증서를 사용할 수 있습니다.

  3. Cloudflare의 추가 기능 활용:

    • DDoS 방어 및 웹 방화벽(WAF)
    • CDN을 통한 콘텐츠 캐싱 및 성능 향상
    • SSL/TLS 암호화 강화
    • 트래픽 분석 및 모니터링

본 가이드에서는 Cloudflare에 도메인을 추가하고, API Token을 발급받은 후, Kubernetes 클러스터의 cert-manager를 통해 Let’s Encrypt Wildcard 인증서를 자동으로 발급받는 전체 과정을 안내합니다.


1. Cloudflare에 도메인 추가하기

1.1 도메인 온보딩 시작

  • 좌측 메뉴에서 Domains 선택
  • 상단의 "+Onboard a domain" 버튼 클릭
  • 도메인 입력 (예: cnapcloud.com)
  • Continue 클릭

1.2 플랜 선택

  • Free 플랜 선택

1.3 DNS 레코드 확인

  • Quick Scan이 자동으로 기존 DNS 레코드를 스캔하여 추가
  • Manual entry에서 스캔된 레코드 확인
  • 하단의 Continue activation 클릭

1.4 네임서버 변경

도메인 등록업체(registrar)에 로그인하여 네임서버를 변경해야 합니다.

변경 방법

  1. 도메인 등록업체 확인

    • ICANN Lookup에서 등록업체 확인 가능
    • 리셀러(예: Squarespace)를 통해 구매했다면 해당 계정에 로그인
  2. 네임서버 설정

    • 기존 네임서버 삭제
    • Cloudflare 네임서버로 교체:
      • naya.ns.cloudflare.com
      • vick.ns.cloudflare.com

참고: 네임서버 변경은 일반적으로 다운타임을 발생시키지 않지만, 변경 전 DNS 레코드를 미리 확인할 수 있습니다.


2. Cloudflare API Token 발급받기

API를 통해 Cloudflare를 관리하려면 API Token이 필요합니다.

2.1 발급 방법

  1. 프로필 설정 접근

    • 우측 상단 프로필 아이콘 클릭
    • My Profile 선택
  2. API Token 생성

    • 좌측 메뉴에서 API Tokens 선택
    • Create Token 버튼 클릭
  3. 템플릿 선택 또는 커스텀 설정

    • 사용 목적에 맞는 템플릿 선택 (예: Edit zone DNS)
    • 또는 Create Custom Token으로 직접 권한 설정
  4. 권한 설정 (Permissions)

    • Zone - Zone - Read
    • Zone - DNS - Edit
  5. Zone Resources 설정

    • Include - Specific zone 선택
    • 도메인 선택 (예: cnapcloud.com)
  6. Token 생성 완료

    • Continue to summary 클릭
    • Create Token 클릭
    • 생성된 Token을 안전한 곳에 복사 및 저장

중요: Token은 생성 시 한 번만 표시되므로 반드시 안전하게 보관하세요.


3. Cert-Manager 설치 및 Wildcard 인증서 발급

Kubernetes 클러스터에서 Let’s Encrypt Wildcard 인증서를 자동으로 발급받기 위해 cert-manager를 설치합니다.

3.1 Helm으로 Cert-Manager 설치

# Helm 저장소 추가
helm repo add jetstack https://charts.jetstack.io
helm repo update

# cert-manager 네임스페이스 생성
kubectl create namespace cert-manager

# cert-manager 설치
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --version v1.14.0 \
  --set installCRDs=true

3.2 설치 확인

kubectl get pods -n cert-manager

모든 Pod가 Running 상태인지 확인합니다.

3.3 Cloudflare API Token Secret 생성

kubectl create secret generic cloudflare-api-token-secret \
  --from-literal=api-token=<YOUR_CLOUDFLARE_API_TOKEN> \
  -n cert-manager

3.4 ClusterIssuer 생성

clusterissuer.yaml 파일을 생성합니다.

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: your-email@example.com  # 본인 이메일로 변경
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - dns01:
        cloudflare:
          apiTokenSecretRef:
            name: cloudflare-api-token-secret
            key: api-token

ClusterIssuer 적용합니다.

kubectl apply -f clusterissuer.yaml

3.5 Wildcard 인증서 생성

wildcard-certificate.yaml 파일을 생성합니다.

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: wildcard-cnapcloud-com
  namespace: default  # 사용할 네임스페이스로 변경
spec:
  secretName: wildcard-cnapcloud-com-tls
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
  - "*.cnapcloud.com"
  - "cnapcloud.com"

cert-manager에 인증서 발급을 요청합니다.

kubectl apply -f wildcard-certificate.yaml

3.6 인증서 발급 확인

# Certificate 상태 확인
kubectl get certificate -n default

# Certificate 상세 정보 확인
kubectl describe certificate wildcard-cnapcloud-com -n default

# Secret 생성 확인
kubectl get secret wildcard-cnapcloud-com-tls -n default

인증서가 성공적으로 발급되면 READY 상태가 True로 표시됩니다.

3.7 Ingress에서 인증서 사용

Ingress 리소스에서 발급받은 인증서를 사용할 수 있습니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: default
spec:
  tls:
  - hosts:
    - "*.cnapcloud.com"
    - "cnapcloud.com"
    secretName: wildcard-cnapcloud-com-tls
  rules:
  - host: app.cnapcloud.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-service
            port:
              number: 80

3.8 Kubernetes DNS Server 설정

Kind와 같은 Kubernetes 클러스터가 사용하는 Docker DNS(172.18.0.1)는 일반 재귀 해석은 수행하지만 SOA 조회와 같은 권한 있는 쿼리를 올바르게 처리하지 않습니다. 따라서 Cert-Manager의 DNS-01 챌린지가 요구하는 SOA 검사를 위해 CoreDNS ConfigMap을 수정하여 DNS 쿼리를 공용 리졸버로 전달해야 합니다.

이를 위해 CoreDNS ConfigMap에 다음과 같이 Forward DNS Server를 구성합니다.

kubectl -n kube-system edit cm coredns

forward . 1.1.1.1 1.0.0.1 {
    max_concurrent 1000 
}

ConfigMap을 저장하면 CoreDNS가 자동으로 reload 되지만, 반영이 바로 되지 않을 경우 아래 명령어로 수동 재시작할 수 있습니다.

kubectl -n kube-system rollout restart deployment coredns

참고: 인증서 발급은 DNS01 챌린지를 통해 진행되므로 몇 분 정도 소요될 수 있습니다. Let’s Encrypt는 90일마다 갱신이 필요하며, cert-manager가 자동으로 갱신을 처리합니다.


4. Wildcard 인증서를 다른 네임스페이스에 자동 복사하기

Wildcard 인증서를 여러 네임스페이스에서 사용하려면 인증서 Secret을 각 네임스페이스로 복사해야 합니다. Reflector를 사용하면 Secret을 자동으로 복사하고 동기화할 수 있습니다.

4.1 Reflector 설치

# Helm으로 Reflector 설치
helm repo add emberstack https://emberstack.github.io/helm-charts
helm repo update

helm install reflector emberstack/reflector \
  --namespace kube-system \
  --set rbac.enabled=true

4.2 설치 확인

kubectl get pods -n kube-system | grep reflector

4.3 인증서 Secret에 Annotation 추가

기존 Certificate 리소스를 수정하여 Reflector가 Secret을 자동으로 복사하도록 설정합니다.

wildcard-certificate.yaml 파일을 다음과 같이 수정합니다.

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: wildcard-cnapcloud-com
  namespace: default
spec:
  secretName: wildcard-cnapcloud-com-tls
  secretTemplate:
    annotations:
      reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
      reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
      reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "dev,staging,production"
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
  - "*.cnapcloud.com"
  - "cnapcloud.com"

Reflector Annnotation이 추가된 Certificate 적용합니다.

kubectl apply -f wildcard-certificate.yaml

4.4 주요 Annotation 설명

  • reflector.v1.k8s.emberstack.com/reflection-allowed: Secret 복사 허용
  • reflector.v1.k8s.emberstack.com/reflection-auto-enabled: 자동 복사 활성화
  • reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: 복사할 대상 네임스페이스 목록 (쉼표로 구분)

4.5 대상 네임스페이스 생성

복사할 네임스페이스가 없다면 먼저 생성합니다.

kubectl create namespace dev
kubectl create namespace staging
kubectl create namespace production

4.6 Secret 복사 확인

각 네임스페이스에 Secret이 자동으로 복사되었는지 확인합니다.

kubectl get secret wildcard-cnapcloud-com-tls -n dev
kubectl get secret wildcard-cnapcloud-com-tls -n staging
kubectl get secret wildcard-cnapcloud-com-tls -n production

4.7 다른 네임스페이스의 Ingress에서 사용

이제 각 네임스페이스에서 복사된 인증서를 사용할 수 있습니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: dev-ingress
  namespace: dev
spec:
  tls:
  - hosts:
    - "dev.cnapcloud.com"
    secretName: wildcard-cnapcloud-com-tls
  rules:
  - host: dev.cnapcloud.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: dev-service
            port:
              number: 80

4.8 모든 네임스페이스로 복사 (선택사항)

특정 네임스페이스 대신 모든 네임스페이스로 복사하려면 다음과 같이 Annotation을 설정합니다.

secretTemplate:
  annotations:
    reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
    reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
    # reflection-auto-namespaces를 제거하거나 빈 값으로 설정

참고: Reflector는 원본 Secret이 갱신되면 자동으로 모든 복사본도 업데이트합니다. 따라서 Let’s Encrypt 인증서가 자동 갱신될 때 모든 네임스페이스의 인증서도 함께 갱신됩니다.


5. 마무리

이로써 Kubernetes 클러스터에서 Cloudflare와 cert-manager를 활용하여 Wildcard SSL 인증서를 자동으로 발급하고 관리할 수 있게 되었습니다. 이번 과정에서는 Cloudflare를 통한 도메인 DNS 관리 이관, API Token 발급, cert-manager 설치, Let’s Encrypt 기반 Wildcard 인증서 발급, 그리고 Reflector를 이용한 다중 네임스페이스 인증서 배포까지 순차적으로 진행했습니다. 이 구성을 통해 외부에서 접근할 수 없는 내부 클러스터 환경에서도 안전하게 SSL/TLS 인증서를 발급받을 수 있으며, 인증서 갱신과 배포가 완전히 자동화되어 운영 부담을 크게 줄일 수 있습니다. 또한 Cloudflare의 DDoS 방어, WAF, CDN 등의 보안 및 성능 최적화 기능을 함께 활용할 수 있어, 향후 GitOps 기반 배포 파이프라인이나 Ingress Controller의 고급 라우팅 기능을 추가하여 더욱 확장된 형태로 발전시킬 수도 있습니다.

💬 무료 컨설팅 신청