SKS (Smileserv Kubernetes System) Ingress 배포 메뉴얼 ver. 2025.03.28
Ingress
ingress 란
로드밸런서 서비스를 직접 사용하는 대신 Path-base routing 등 더 다양한 기능을 사용 할 수 있는 Ingress를 통해 트래픽을 제어 할 수 있습니다.
인그레스를 사용하기 위해서는 클러스터에 인그레스 컨트롤러를 배포해야 합니다.
k8s에서는 본 메뉴얼에서 다룰 Nginx ingress controller 외에도 다양한 서드파티 인그레스 컨트롤러를 사용 할 수 있습니다.
본 메뉴얼에서는 Nginx ingress controller 와 Cert Manager 를 사용하여 서비스에 인증서를 발급, 운영하는 방법을 설명하고 있습니다.
Deployment 에서 생성한 whoami 포드에 ingress 로 연결하는 방법을 샘플로 진행 합니다.
Nginx Ingress Controller
인그레스 컨트롤러중 하나인 Nginx ingress controller 를 배포 합니다.
본과정을 그대로 진행시 로드밸런서, IP 가 생성되어 요금이 청구 되므로 확인 후 테스트 진행 부탁 드립니다.
-
배포 전 현재 운영중인 K8s server 버젼과 호환 되는 버젼을 체크 해야 합니다.
-
현재 메뉴얼 업데이트 시점 (2025.03.28) 기준 SKS의 K8s server 버젼은 v1.28.9 으로 Nginx Ingress Controller v1.12.1 버젼 으로 배포 진행 했습니다.
Nginx Ingress Controller v1.11.0 이하, v1.11.0 ~ v1.11.4 , v1.12.0 은 CVE-2025-1974 CVSS 9.8 등급의 취약점이 확인된 버젼 입니다.
위 버젼을 사용중인 경우 v.1.11.5 혹은 v1.12.1 이후 버젼으로 즉시 업그레이드 해야 합니다.
📌 사용중인 Nginx Ingress Controller 버젼 확인 방법
kubectl describe deployment ingress-nginx-controller -n ingress-nginx | grep Image
관련 사항 확인: https://kubernetes.io/blog/2025/03/24/ingress-nginx-cve-2025-1974/
- nginx ingress controller 공식 github 의 yaml 파일로 바로 배포 가 가능합니다.
Nginx Ingress Controller 가 배포 되면 Controller에서 관리하는 로드밸런서가 같이 배포 됩니다.
로드밸런서 서비스를 직접 배포 했을때와 같이 IP 가 연결 되며 비용이 발생 합니다.
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.12.1/deploy/static/provider/cloud/deploy.yaml
- Nginx Ingress controller 의 Load balancer External-IP 를 확인 합니다.
kubectl get svc -A
Nginx Ingress controller 관련 pod 확인
kubectl get pod -A
- 연결할 도메인의 A 레코드에 위에서 확인한 LB External IP 를 입력합니다.
*이용중인 네임서버에 따라 DNS입력 인터페이스에 차이가 있을 수 있습니다.
이용중인 로드밸런서를 삭제하실 경우 기존에 사용하시던 IP를 다시 사용할 수 없으니 신중히 삭제 하여 주시기 바랍니다.
- Ingress 배포를 위한 yaml 파일을 작성 합니다.
아래 ingress 는 tls 발급,적용이 포함되어있어 클러스터에 cert-manager 배포, 인증서 발급이 준비되어있어야 합니다. Cert-manager 가이드
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: whoami-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- secretName: whoami-tls
hosts:
- My-domain
rules:
- host: My-domain
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: whoami-service
port:
number: 80
- annotations 의 issuer를 상황에 맞게 수정 합니다. (테스트 = letsencrypt-staging 실제 발급 = letsencrypt-prod)
- rules 부분 호스트에 도메인을 입력하고 아래에 라우팅 방식을 설정 합니다.
yaml 파일을 저장하고 Apply 합니다.
kubectl apply -f ingress.yaml
- 생성된 Ingress 의 정보를 확인 합니다.
kubectl get ingress
배포한 ingress 와 함께 cm-acme-http-solver 가 let's encrypt 인증서 발급을 위해 임시로 생성 되어있는 것을 확인 할 수 있습니다.
잠시 후 인증서 발급이 완료되면 자동으로 삭제 됩니다.
kubectl describe ingress whoami-ingress
Event 부분에서 인증서가 자동으로 생성 된 것을 확인 할 수 있습니다.
- 인증서는 secret 오브젝트 에 저장 됩니다.
kubectl get secret
- kubectl describe 로 조회하면 인증서와 키 를 포함하고 있는 것을 확인 할수 있습니다.
kubectl describe secret whoami-tls
- 웹브라우져에서 도메인으로 HTTPS 접속, 인증서를 확인 할 수 있습니다.
- 예제를 따라 생성한 인그레스 에 적용된 도메인으로 접속시 대략적인 트래픽 흐름 입니다.
도메인 접속 > Loadbalancer > Nginx Ingress Controller [Ingress route Rule 에 따라 Service 로 연결 ] > Service [ selector 로 포드에 연결 ] > Pod
Nginsx Ingress Controller 추가 기능
Ingress 에서는 컨트롤러에 따라 다양한 기능들을 활용 할 수 있습니다.
Sticky Session
비회원 장바구니 기능과 같이 서비스중 세션 유지가 필요한 경우가 있습니다.
스티키 세션을 사용하면 세션 유지에 도움이 됩니다.
- 위에서 배포한 Ingress 의 yaml 파일을 수정 합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: whoami-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "sticky"
nginx.ingress.kubernetes.io/session-cookie-max-age: "86400"
nginx.ingress.kubernetes.io/session-cookie-expires: "86400"
spec:
ingressClassName: nginx
tls:
- secretName: whoami-tls
hosts:
- My-domain
rules:
- host: My-domain
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: whoami-service
port:
number: 80
session-cookie-max-age, session-cookie-expires 는 초 단위로 입력 합니다. (86400 = 24시간)
- 수정한 yaml 파일을 Apply 합니다.
kubectl apply -f
- ingress 정보를 확인 합니다.
kubectl describe ingress whoami-ingress
- 웹 브라우져로 접속하여 세션 유지를 확인 합니다.
hostname 의 포드 정보와 쿠키 부분에 sticky session 을 확인 할 수 있습니다.
- curl 로 쿠키 헤더를 확인 할 수 있습니다.
curl -I https://My.Domain
Proxy Protocol
프록시 프토로콜을 사용하면 로드밸런서, 프록시 등을 통과 할때 실제 IP 와 같은 접속자의 정보를 유지 할 수 있습니다.
- Nginx Ingress Controller yaml 파일 다운로드.
Nginx Ingress Controller 의 수정 배포를 위해 yaml 파일을 다운로드 합니다.
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.3/deploy/static/provider/cloud/deploy.yaml
- ConfigMap 부분을 수정 합니다.
kind: ConfigMap 으로 검색하면 빠르게 찾을 수 있습니다.
apiVersion: v1
data:
allow-snippet-annotations: "true"
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.11.3
name: ingress-nginx-controller
namespace: ingress-nginx
data:
use-proxy-protocol: 'true'
use-forwarded-headers: 'true'
compute-full-forwarded-for: 'true'
ssl-redirect: 'false'
- type: LoadBalancer 로 검색 LoadBalancer 설정 부분에 annotations 를 추가 합니다.
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.11.3
name: ingress-nginx-controller
namespace: ingress-nginx
annotations:
loadbalancer.openstack.org/proxy-protocol: "true"
spec:
externalTrafficPolicy: Local
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- appProtocol: http
name: http
port: 80
protocol: TCP
targetPort: http
- appProtocol: https
name: https
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
type: LoadBalancer
- 수정한 yaml 파일을 배포 합니다.
kubectl apply -f deploy.yaml
- 다시 연결한 도메인으로 접속 하면 X-Real-IP 부분에 실제 접속 IP 가 기록 되는 것을 확인 할 수 있습니다.
Path-base routing
ingress 에서는 path 를 기반으로 트래픽을 제어 할 수 있습니다.
- ingress yaml 파일을 열어 path 부분을 설정 합니다.
pathType 에는 ImplementationSpecific, Exact, Prefix 가 있습니다.
ImplementationSpecific: 기본값, Ingress Controller 의 기본 동작에 따라 매칭 규칙을 결정 합니다.
⚠️ 인그레스 컨트롤러마다 동작이 다를 수 있어 주의가 필요 합니다.
Exact : 지정한 경로와 정확히 일치해야 합니다.
ex) path: /app -> /app 경로만 일치 /app/ , /app/version2 는 일치하지 않음
Prefix : 지정한 경로로 시작하는 모든 서브경로와 매치.
ex) path: /app -> /app, /app/ , /app/main/user 모두 매칭
- 설정한 경로로 요청하여 서비스로 정상 연결 되는지 확인 합니다.
path: / |
---|
path: /adm |
---|
ip-whitelist
ip 기반 접근 제어 설정
Nginx Ingress 에 ip 화이트리스트 설정을 추가하여 허용된 ip 에서만 접근 가능하도록 제어 할 수 있습니다.
whitelist-source-range 추가시 허용 ip 외 모두 차단 설정 됩니다.
- ingress yaml 파일을 열 어 annotation 을 추가 합니다.
ip는 CIDR 형식으로 입력하며 ',' 로 구분하여 여러개의 ip를 입력 할 수 있습니다.
nginx.ingress.kubernetes.io/whitelist-source-range: 1.2.3.4,255.255.255.0/24
- 수정된 yaml 파일을 적용 합니다.
kubectl apply -f MY-ingress.yaml
- 허용되지 않은 IP 에서 접근시 403 Forbidden 이 반환 됩니다.