Kubernetes 환경에서 L7 트래픽 라우팅을 구현하는 몇 가지 솔루션이 있습니다. 본 문서에서는 ingress-nginx를 활용한 L7 로드밸런싱 구현 방법을 중점적으로 다룹니다.
Ingress Controller 설치
ingress-nginx는 Kubernetes 클러스터 내에서 Ingress 리소스를 관리하고 트래픽을 해당 백엔드 서비스로 라우팅하는 컨트롤러입니다. 설치는 다음과 같은 단계를 따릅니다.
Ingress Controller 배포
먼저 Ingress Controller를 위한 네임스페이스를 생성하고 필요한 YAML 파일을 다운로드하여 적용합니다.
mkdir nginx-ingress
cd nginx-ingress
# mandatory.yaml 파일 다운로드 (Ingress Controller 핵심 컴포넌트 포함)
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.1/deploy/static/mandatory.yaml
# YAML 파일 적용
kubectl apply -f mandatory.yaml
# 설치 확인
kubectl get ns
kubectl get pod -n ingress-nginx
Ingress Service 배포 (NodePort 방식)
Ingress Controller로 외부 트래픽을 전달하기 위한 Service를 NodePort 타입으로 배포합니다. 이를 통해 각 노드의 특정 포트로 접근하여 Ingress Controller에 도달할 수 있습니다.
# service-nodeport.yaml 파일 다운로드
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml
# 파일 내용 확인 (NodePort 설정 확인)
cat service-nodeport.yaml
# Service 적용
kubectl apply -f service-nodeport.yaml
# 배포 확인
kubectl get pod -n ingress-nginx
kubectl get svc -n ingress-nginx
service-nodeport.yaml 파일의 주요 설정 내용은 다음과 같습니다. NodePort 타입으로 설정되어 있으며, HTTP/HTTPS 트래픽을 위한 포트가 지정됩니다. 특정 nodePort 값을 직접 지정하여 기억하기 쉽게 할 수 있지만, 포트 충돌 가능성에 유의해야 합니다.
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30080 # HTTP 접근을 위한 NodePort
protocol: TCP
- name: https
port: 443
targetPort: 443
nodePort: 30443 # HTTPS 접근을 위한 NodePort
protocol: TCP
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
Ingress 리소스 설정 및 테스트
Ingress Controller 설치 후, 실제 애플리케이션으로 트래픽을 라우팅하기 위한 Ingress 리소스를 생성합니다. 각 애플리케이션별로 Deployment, Service, 그리고 Ingress 규칙을 정의합니다.
1. Myapp 서비스
먼저 myapp 애플리케이션의 Deployment와 Service를 정의합니다.
apiVersion: v1
kind: Service
metadata:
name: myapp-service
namespace: default
spec:
selector:
app: myapp
release: canary
ports:
- name: http
targetPort: 80
port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: myapp
release: canary
template:
metadata:
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp-container
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
이어서 myapp 서비스로 트래픽을 전달하는 Ingress 리소스를 생성합니다. host 필드에 도메인을 지정하고, kubernetes.io/ingress.class: "nginx" 어노테이션을 통해 해당 Ingress를 nginx-ingress 컨트롤러가 처리하도록 명시합니다.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myapp-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: myapp.example.com # 접근할 호스트 이름
http:
paths:
- path: / # 경로
backend:
serviceName: myapp-service # 백엔드 서비스 이름
servicePort: 80 # 백엔드 서비스 포트
2. Tomcat 서비스
Tomcat 이미지를 사용하여 Deployment와 Service를 구성합니다. Tomcat은 기본적으로 8080 포트에서 HTTP 요청을 처리하고 8009 포트에서 AJP 요청을 처리합니다.
apiVersion: v1
kind: Service
metadata:
name: tomcat-service
namespace: default
spec:
selector:
app: tomcat
release: canary
ports:
- name: http
targetPort: 8080
port: 8080
- name: ajp
targetPort: 8009
port: 8009
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deployment
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: tomcat
release: canary
template:
metadata:
labels:
app: tomcat
release: canary
spec:
containers:
- name: tomcat-container
image: tomcat:8.5.32-jre8-alpine
ports:
- name: http
containerPort: 8080
- name: ajp
containerPort: 8009
Tomcat 서비스에 대한 Ingress 규칙을 정의합니다. host는 tomcat.example.com으로 설정하고, HTTP 트래픽을 tomcat-service의 8080 포트로 전달하도록 설정합니다.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: tomcat-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: tomcat.example.com # 접근할 호스트 이름
http:
paths:
- path: /
backend:
serviceName: tomcat-service # 백엔드 서비스 이름
servicePort: 8080 # 백엔드 서비스 포트
위 설정들을 적용한 후, 각 호스트 이름(myapp.example.com, tomcat.example.com)으로 외부에서 접근하면 해당 Ingress Controller를 통해 올바른 백엔드 서비스로 트래픽이 라우팅되는 것을 확인할 수 있습니다. 외부 접근은 NodePort로 설정된 포트(예: 30080)를 통해 이루어집니다.