• 가비아 + Cloudflare + Let's Encrypt + Kubernetes 실전 연동.

    2026. 6. 7.

    by. Daramu

    이전 포스팅으로 Cloudflare의 네임서버와 연동하고 API 키를 발급받는 것 까지 진행했다.

    이제 쿠버네티스에서 이걸 어떻게 적용할지에 대한 포스팅을 진행할 것이다.

     

    물론, 그 전에 cert-manager는 설치 되어있어야한다.

    https://daramu.tistory.com/83

     

    설치가 되었다면 이제 저번 포스팅에서 발급받은 API Key를 Secret으로 등록할 것이다.

    본 포스팅에서는 cert-manager가 "cert-manager" 네임스페이스에 설치되어 있기에 secret도 "cert-manager" 네임스페이스에 생성할 것이다. cert-manager와 secret의 네임스페이스를 맞추라는 의미다.

     

    kubectl create secret generic cloudflare-api-token-secret --from-literal=api-token='YOUR_API_TOKEN_!!!!' --namespace=cert-manager

     

     

    다음으로는 ClusterIssuer를 생성하여 실행해 준다.

     

    위의 링크에도 설명되어있지만, 간단하게 말하자면 Let's Encrypt에 "클라우드플레어 DNS-01 방식으로 와일드카드를 발급 받겠다." 하고 선언하는 파일이라고 보면 된다. 

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: letsencrypt-wildcard
    spec:
      acme:
        server: https://acme-v02.api.letsencrypt.org/directory
        email: 실제 이메일 주소 입력
        privateKeySecretRef:
          name: letsencrypt-wildcard-key
        solvers:
        - dns01:
            cloudflare:
              apiTokenSecretRef:
                name: cloudflare-api-token-secret
                key: api-token

     

     

    방식을 지정했으니 다음으로 실제 도메인(본 포스팅에서는 daramu.co.kr)과 서브도메인들(*.daramu.co.kr)을 묶어서 무료 인증서를 요청하는 명세서를 작성하여 실행해준다.

    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: wildcard-cert
      namespace: default
    spec:
      secretName: wildcard-tls
      issuerRef:
        name: letsencrypt-wildcard
        kind: ClusterIssuer
      dnsNames:
      - "daramu.co.kr"
      - "*.daramu.co.kr"

     

    여기서 dnsNames만 바꿔준다.

    참고로 namespace는 실제 웹 서비스가 돌아갈 네임스페이스를 입력한다.

    frontend namespace에 들어갈거면, 네임스페이스를 frontend로 수정하면 된다.

     

    추가로 굳이 daramu.co.kr과 *.daramu.co.kr 두개를 기입한것은,

    SSL 인증서 표준 규격상 *.daramu.co.kr 은 "한 단계 서브도메인`만` 보호"할 수 있기 때문이다.

     

    만약 daramu.co.kr없이 *.daramu.co.kr만 집어 넣는다면 daramu.co.kr 은 대응이 불가능해 진다. 반대로 dev.api.daramu.co.kr같은 두 단계 서브도메인도 안된다. api.daramu.co.kr, dev.daramu.co.kr 같은 한단계만 커버할 수 있으니 주의할 것.

     

    처음 생성하면 한동안 Flase일 것이다.

    kubectl get certificate -n default
    kubectl get certificaterequest -n default

     

    여기서 Events 확인시 별다른 에러가 없다면 일정 시간(약 5분?)이 지난 후 다시 확인해보면 True로 바뀌어 있을 것이다.

     

    그럼 성공이다.

     

    이제 이걸 ingress에 적용하면 tls가 적용된 LB를 생성할 수 있다.

    여기서 다시 고민해야하는것이 ingressclass인데, 여태까지는 ncp의 공식 ingressclass인 alb를 사용했었다.

     

    하지만 NCP의 alb ingress는 cert-manager로 발급한 와일드카드와 TLS연동이 깔끔하지 못하고, rewrite-target도 지원하지 않기 때문에 이번에는 ingressclass로 nginx를 사용하겠다.

     

    kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml
    kubectl get ingressclasses

     

     

    다음으로 테스트용으로 nginx 한개를 띄우고 DNS 등록을 하면 된다.

    yaml 파일이 기니까 가장 밑 <아래> 에 두었다.

    deployment, service, ingress가 한개씩 있는 단순한 yaml 파일이다.

     

    yaml 파일을 apply 했다면 LB가 하나 생성되었을 것이다.

     

    NCP 콘솔에서 LB의 공인IP를 확인 후 클라우드 플레어에서 A레코드 작업을 해줬다.

    좌측 네비게이션 -> DNS -> Record 에서 설정 가능하다.

     

    그럼 https 가 정상적으로 작동하는걸 확인할 수 있다.

     

     

     

    인증서 뷰어도 Let's Encrypt 에서 받을걸 확인할 수있다.

     

     

     

     

    <아래>

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: test-nginx
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: test-nginx
      template:
        metadata:
          labels:
            app: test-nginx
        spec:
          containers:
          - name: nginx
            image: nginx:latest
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: test-service
      namespace: default
    spec:
      type: NodePort
      selector:
        app: test-nginx
      ports:
      - port: 80
        targetPort: 80
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-ingress
      namespace: default
      annotations:
        nginx.ingress.kubernetes.io/ssl-redirect: "true"
    spec:
      ingressClassName: nginx 
      tls:
      - hosts:
        - daramu.co.kr
        - "*.daramu.co.kr"
        secretName: wildcard-tls
      rules:
      - host: daramu.co.kr
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: test-service
                port:
                  number: 80

     

    댓글