,

[OKE 인프라 학습 시리즈] 무료 클러스터에 https:// 붙이기 — Traefik LoadBalancer + 도메인 + cert-manager

이 글의 위치: 기술 블로그 → Infra · OKE 인프라 학습 시리즈 실습 2편. 무료 OKE 클러스터 구축 편에서 노드 2개가 Ready가 됐다. 하지만 지금은 클러스터 안에서만 통한다. 이번 편에서 바깥 인터넷 → 클러스터 → 서비스로 가는 https:// 진입점을 만든다.

이 계층의 좋은 점은 클라우드 provider와 무관하다는 것이다. GKE에서 쓰던 Traefik·cert-manager 설정을 OKE에서 거의 그대로 재사용했다. Provider 계층(gke-init ↔ oke-init)만 갈아끼우고 그 위는 손대지 않는다는 원칙은 시리즈 마지막 스킬 설계 편에서 자세히 다룬다.

1. Traefik를 LoadBalancer로 — 여기서 무료 LB가 나온다

Ingress 컨트롤러로 Traefik(v3.x)을 helm으로 설치한다. 핵심은 Traefik Service의 타입을 LoadBalancer 로 두는 것.

# traefik-values.yaml (요지)
service:
  type: LoadBalancer      # → OCI가 flexible LB를 자동 프로비저닝
ports:
  web:
    port: 80
  websecure:
    port: 443
helm install traefik traefik/traefik -n traefik --create-namespace -f traefik-values.yaml
kubectl -n traefik get svc traefik -w   # EXTERNAL-IP 가 붙을 때까지 대기

type: LoadBalancer를 보면 OCI가 flexible LoadBalancer를 만들어 공인 IP를 할당한다. 최소 대역 10Mbps는 Always Free 범위라, 여기서도 비용이 0이다. 잠시 뒤 EXTERNAL-IP에 공인 IP(예: 134.185.107.236)가 붙는다.

⚠️ 함정 — LB 공인 IP의 수명(lifetime). 이 IP는 기본적으로 RESERVED라 일반 운영 중엔 바뀌지 않는다. 하지만 LB를 삭제·재생성하면 바뀐다. 도메인 A 레코드가 물려 있으면 곤란하니, 정말 고정하고 싶다면 OCI reserved-ip를 미리 확보해 Service 어노테이션으로 핀(pin)해 두는 게 안전하다.

2. 도메인 연결 — 네임서버 변경 없이 A 레코드로

여기서 두 갈래가 있다.

(a) 진짜 도메인을 붙이는 경우 — 가비아 같은 등록처의 DNS 관리툴에서 A 레코드만 추가하면 된다. 네임서버 자체를 바꿀 필요가 없다.

호스트 타입
@ (루트) A 134.185.107.236
* (와일드카드) A 134.185.107.236

와일드카드 *www·docs·grafana 같은 서브도메인을 한 번에 커버한다. 전파는 dig <도메인>으로 확인한다.

(b) 도메인 없이 바로 테스트하려면sslip.io를 쓴다. 134-185-107-236.sslip.io처럼 IP를 하이픈으로 박은 호스트명이 그대로 그 IP로 해석된다. DNS 등록 0초에 TLS까지 받을 수 있어, 실제로 채팅 백엔드의 첫 라이브 URL을 https://134-185-107-236.sslip.io로 띄웠다. Bibleana 클라이언트도 이 sslip.io 오리진에 붙었다.

3. cert-manager + Let’s Encrypt로 인증서 자동 발급

TLS 인증서는 cert-manager가 자동으로 발급·갱신한다. helm으로 설치한 뒤 ClusterIssuer를 만든다. 검증 방식은 HTTP-01(80포트로 챌린지 응답).

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            ingressClassName: traefik

Ingress에 cert-manager.io/cluster-issuer: letsencrypt-prod 어노테이션과 tls 블록을 달면, cert-manager가 챌린지를 통과시키고 시크릿에 인증서를 채운다. 발급이 되면 SAN에 도메인과 www가 들어간 90일 인증서가 만들어지고, 만료 전에 자동 갱신된다.

💡 처음엔 letsencrypt-staging issuer로 파이프라인이 통과하는지 확인한 뒤 letsencrypt-prod로 바꾸는 걸 권한다. 프로덕션 엔드포인트는 실패 rate limit이 빡빡하다.

4. HTTP-01의 한계 — 와일드카드 인증서는 못 준다

⚠️ 함정 — HTTP-01은 *.도메인 와일드카드 인증서를 발급하지 못한다. HTTP-01은 각 호스트의 80포트로 챌린지를 하기 때문에, 구체적인 호스트명(docs.도메인, chat.도메인)에 대해서만 발급된다. 그래서 서브도메인은 서비스를 붙일 때마다 그 호스트로 개별 발급해야 한다.

진짜 *.도메인 와일드카드 인증서가 필요하면 DNS-01 방식(DNS TXT 레코드로 검증)을 써야 하는데, 이건 등록처의 DNS API를 cert-manager webhook으로 연동해야 한다(가비아라면 별도 webhook 구현 필요 — 아직 미구현으로 남겨둔 부채다).

정리

  • Traefik type: LoadBalancer → OCI 무료 10Mbps LB 공인 IP
  • A 레코드(루트 @ + 와일드카드 *) 또는 sslip.io로 도메인 연결
  • cert-manager + Let’s Encrypt(HTTP-01)로 인증서 자동 발급/갱신
  • 와일드카드가 필요하면 HTTP-01이 아니라 DNS-01

이제 https:// 진입점이 생겼다. 다음 편 arm64 OKE에 채팅 백엔드 배포에서 실제 서비스(Go 채팅 백엔드) 이미지를 OCIR에 올리고 이 인그레스 뒤에 붙인다. 관련해서 상시 가동 노드를 고른 이유는 커넥션 풀 운영 시리즈처럼 "상태를 유지하는 워크로드"를 다룰 때 더 분명해진다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다