미루고미루고 미루고...미뤄왔던 HTTPS를 해결해야 할 시간이 온 것 같다.
쿠버네티스(이하 K8s)가 없을 때는 NGINX를 사용하면 가능하다. 하지만 현재 환경은 K8S의 환경이고, 조금 다른 방식을 사용하여야 한다. 이를 위해선 K8s가 외부에 연결하는 방식 중 하나인 Ingress방식에 대해 알아야 한다.
Ingress 방식이란?
도메인 또는 경로 기반의 규칙을 설정하여, 외부에서 들어오는 HTTP/HTTPS 요청을 K8s 클러스터 내부의 적절한 서비스(Service)로 전달하는 구조이다. Ingress 리소스, Controller, DNS, TLS 인증서로 구성된다. K8s 내부에서는 아래 예시처럼 작동하게 된다.

외부 요청 흐름은 아래와 같다.
[1] 사용자: 브라우저에서 도메인 요청
↓
[2] DNS: 도메인→ Ingress Controller 노드의 공인 IP
↓
[3] Ingress Controller(NGINX 등): Ingress 리소스를 읽고 규칙 확인
↓
[4] Ingress 리소스: 구매한 도메인 → /test 경로는 test 네임스페이스의 특정 Service 라우팅
↓
[5] Service: 내부 파드로 트래픽 전달
↓
[6] Pod: 애플리케이션에서 응답 반환
Ingress Controller(NGINX Ingress Controller)
클러스터 내의 Ingress가 작동하려면, Ingress Controller가 실행되고 있어야 한다.
NGINX Ingress Controller 설치
helm을 활용해서 NGINX Ingress Controller 설치하는 방법이다.
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx --create-namespace
설치 확인 : kubectl get all -n ingress-nginx
cert-manager - K8s에서 SSL/TLS 인증서를 자동으로 관리하고 갱신해주는 컨트롤러
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set installCRDs=true
# 설치 확인
kubectl get pods --namespace cert-manager
clusterissuer - K8s 클러스터 전체에서 사용할 수 있는 인증서 발급자 리소스
파일명 : clusterissuer-prod.yaml
적용 명령어 : kubectl apply -f clusterissuer-prod.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod # ingress의 annotation.cert-mana..issuer 이름이랑 같아야 함
spec:
acme:
email: your@email.com
server: https://acme-v02.api.letsencrypt.org/directory
#[테스트] server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod-account-key
solvers:
- http01:
ingress:
class: nginx
podTemplate: {}
ingressTemplate:
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /.well-known/acme-challenge/
pathType: Prefix
Ingress 리소스(ingress.yaml)
ingress리소스는 네임스페이스별로 생성해야 한다.
1. 여러 도메인 → 각각 다른 서비스
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-domain-ingress
namespace: default
annotations:
cert-manager.io/cluster-issuer: letsencrypt-staging
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- app1.example.com
- app2.example.com
secretName: multi-cert-secret
rules:
- host: app1.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
- host: app2.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80
2. 하나의 도메인 + 경로별 분기 (리버스 프록시 스타일)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path-routing-ingress
namespace: test
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod(테스트:letsencrypt-staging)
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- test.com
secretName: path-cert-secret
rules:
- host: test.com
http:
paths:
- path: /test
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 80
적용 명령어 : kubectl apply -f ingress.yaml
명령어로 적용한 이후, Ingress Controller가 이를 감지하여 동적으로 NGINX 설정을 생성
발급된 인증서 확인 : kubectl get certificate -n <NameSpace>
발급 상태 확인
kubectl describe certificate path-cert-secret -n <Namespace>
kubectl describe order -A
kubectl describe challenge -A'Infra' 카테고리의 다른 글
| [트러블슈팅] Vercel 다중 프로젝트 연결 시 도메인/서브도메인 충돌 해결기 (0) | 2025.08.21 |
|---|---|
| [미니PC] 3. k8s에 환경 변수 적용하기(namespace기준, CI/CD와 별개로 미리 등록) (2) | 2025.05.16 |
| [미니PC] 2. Github Action+ArgoCD+GHCR를 활용한 CI/CD 구축 (0) | 2025.05.14 |
| [미니PC] 1. 우분투 서버에 Kubernetes(마스터+워커 단일 서버)+ArgoCD 설치 관련 (0) | 2025.05.14 |
| [Docker] portainer와 watchtower (0) | 2025.03.26 |