Kubernetes 환경 ACME 구성

Prev Next

cert-manager를 사용하여 Kubernetes 클러스터에서 Ncloud ACME 서버로 인증서를 발급받는 방법을 안내합니다.

참고

본 가이드는 cert-manager v1.x 기준입니다. RFC 8555를 준수하는 다른 ACME 클라이언트도 사용 가능하나, 공식 기술 지원은 cert-manager 기준으로만 제공됩니다.

시작하기 전에

ACME 사용 준비의 모든 단계를 완료한 뒤, 다음 항목이 준비되어야 합니다.

  • 발급된 EAB Key IDEAB HMAC Key
  • kubectl 사용 권한 및 클러스터 관리자(cluster-admin) 권한
  • cert-manager가 지원하는 DNS 제공자 계정 및 API 권한 (지원 목록 확인)
  • OV 인증서 사용 시, Certificate Manager > Organization에서 조직 검증 완료
주의

Ncloud ACME 서버는 DNS-01 검증만 지원합니다. cert-manager가 네이티브로 지원하는 DNS 제공자(AWS Route53, Cloudflare, Google Cloud DNS, Azure DNS 등) 또는 webhook 기반 solver가 필요합니다.

동작 구조

cert-manager를 통한 인증서 자동화 흐름은 다음과 같습니다.

  사용자 브라우저
       │ HTTPS
       ▼
  Ingress
       │ tls.secretName 참조
       ▼
  K8s Secret (인증서 저장)
       ▲ 자동 발급 / 갱신
       │
  cert-manager
       │ ACME DNS-01 챌린지
       ▼
  Ncloud ACME 서버  ←→  DNS 제공자 (TXT 레코드 자동 처리)

cert-manager는 인증서 lifetime의 2/3 시점에 자동 갱신을 시도합니다. 갱신 시점을 명시적으로 지정하려면 Certificate.spec.renewBefore 필드를 사용해 주십시오.

1단계: cert-manager 설치

다음 명령어를 실행하여 cert-manager를 클러스터에 설치해 주십시오.

kubectl apply -f \
  https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml

설치 후 모든 Pod가 Running 상태가 될 때까지 대기해 주십시오.

kubectl get pods -n cert-manager

출력 예시:

NAME                                       READY   STATUS    RESTARTS
cert-manager-xxxx                          1/1     Running   0
cert-manager-cainjector-xxxx               1/1     Running   0
cert-manager-webhook-xxxx                  1/1     Running   0

2단계: EAB Secret 생성

ACME 계정 등록에 사용할 EAB HMAC Key를 Kubernetes Secret으로 저장합니다. [EAB_HMAC_KEY]를 발급받은 실제 값으로 교체하여 실행해 주십시오.

kubectl create secret generic ncp-acme-eab \
  --from-literal secret="[EAB_HMAC_KEY]" \
  -n cert-manager
주의

EAB 키는 1회용입니다. 계정 등록에 사용하면 소진되며 재사용할 수 없습니다.
3단계에서 생성되는 ncp-acme-account-key Secret은 ACME 계정 식별 키이므로 반드시 백업해 주십시오. 분실 시 새 EAB 키를 다시 발급받아 계정을 재등록해야 합니다.

3단계: ClusterIssuer 생성

cert-manager는 두 가지 발급자 리소스를 제공합니다.

리소스 적용 범위 사용 시나리오
ClusterIssuer 클러스터 전체 여러 네임스페이스에서 공통으로 인증서를 발급할 때 (권장)
Issuer 특정 네임스페이스 네임스페이스별로 발급자를 분리해야 할 때

본 가이드는 일반적으로 권장되는 ClusterIssuer를 사용합니다. 다음 내용으로 clusterissuer.yaml 파일을 작성해 주십시오. [EAB_KEY_ID], admin@example.com, solvers 섹션을 사용 환경에 맞게 교체해 주십시오.

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: ncp-acme
spec:
  acme:
    server: https://acme.navercloudtrust.com/acme/directory
    email: admin@example.com
    privateKeySecretRef:
      name: ncp-acme-account-key
    externalAccountBinding:
      keyID: "[EAB_KEY_ID]"
      keySecretRef:
        name: ncp-acme-eab
        key: secret
    solvers:
    - dns01:
        # 사용 중인 DNS 제공자에 따라 설정
        # 상세 설정은 cert-manager 공식 문서 참조
        # https://cert-manager.io/docs/configuration/acme/dns01/

파일 작성 후 다음 명령어를 실행하여 ClusterIssuer를 생성해 주십시오.

kubectl apply -f clusterissuer.yaml

생성 후 등록 상태를 확인해 주십시오. Ready 상태가 True이면 정상입니다.

kubectl get clusterissuer ncp-acme
kubectl describe clusterissuer ncp-acme

4단계: 인증서 요청

Certificate 리소스를 생성하여 인증서를 요청합니다. 다음 내용으로 certificate.yaml 파일을 작성해 주십시오.

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: company-tls
  namespace: default
spec:
  secretName: company-tls-secret
  issuerRef:
    name: ncp-acme
    kind: ClusterIssuer
  dnsNames:
  - www.example.com
  - api.example.com
kubectl apply -f certificate.yaml

발급 상태를 확인하려면 다음 명령어를 실행해 주십시오. Ready 상태가 True가 될 때까지 대기합니다. DNS-01 챌린지 완료까지 수분이 소요될 수 있습니다.

# 인증서 발급 상태 확인
kubectl get certificate company-tls -n default

# 상세 이벤트 확인 (오류 발생 시 원인 파악)
kubectl describe certificate company-tls -n default
kubectl describe certificaterequest -n default

# 발급 완료 후 Secret 확인
kubectl get secret company-tls-secret -n default

인증서를 재발급하려면 Certificate 리소스를 삭제 후 재생성해 주십시오.

kubectl delete -f certificate.yaml
kubectl apply -f certificate.yaml

5단계: Ingress 적용

발급된 인증서를 Ingress에 적용합니다. 다음 내용으로 ingress.yaml 파일을 작성해 주십시오.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: company-ingress
  annotations:
    cert-manager.io/cluster-issuer: "ncp-acme"
spec:
  tls:
  - hosts:
    - www.example.com
    secretName: company-tls-secret
  rules:
  - host: www.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: company-service
            port:
              number: 80
kubectl apply -f ingress.yaml
참고

Ingress에 cert-manager.io/cluster-issuer 어노테이션을 추가하면 Certificate 리소스를 별도로 생성하지 않아도 cert-manager가 자동으로 인증서를 요청하고 관리합니다. 이 경우 4단계의 certificate.yaml 생성은 생략할 수 있습니다.

문제 해결

확인 항목 명령어
ClusterIssuer 상태 확인 kubectl describe clusterissuer ncp-acme
Certificate 상태 확인 kubectl describe certificate <name> -n <namespace>
CertificateRequest 상세 kubectl describe certificaterequest -n <namespace>
Challenge 상세 (DNS-01 검증 단계) kubectl describe challenge -A
cert-manager 로그 확인 kubectl logs -n cert-manager -l app.kubernetes.io/name=cert-manager --tail=200

보안 권고

  • EAB HMAC Key가 저장된 ncp-acme-eab Secret 및 ACME 계정 키 ncp-acme-account-key Secret은 cert-manager 네임스페이스에서만 접근 가능하도록 RBAC를 설정해 주십시오.
  • DNS 제공자 API 키가 저장된 Secret의 접근 권한을 최소화해 주십시오.
  • DNS 제공자 API 키에는 해당 DNS 서비스에 필요한 최소 권한만 부여하는 것을 권장합니다.
  • Secret 리소스를 Git 저장소에 직접 커밋하지 마십시오. Sealed Secrets 또는 외부 Secret 관리 도구 사용을 권장합니다.

참고 문서