1. What is Ingress
인그레스는 무엇일까요?
인그레스는 쿠버네티스에서 클러스터 외부에서 내부 서비스로의 HTTP와 HTTPS 경로를 노출시키는 API 오브젝트입니다. L7 스위치의 역활을 논리적으로 수행하며 클로스터로 접근하는 url 별로 다른 서비스에 트래픽을 분산해줍니다.
주요 기능
1.
외부 접근 관리 (Service에 외부 url을 제공)
클러스터 외부에서 내부 서비스에 접근할 수 있도록 합니다. NodePort나 LoadBalancer 타입의 서비스를 사용하지 않고도 외부 접근이 가능합니다.
2.
트래픽 라우팅
URL 경로나 호스트 기반으로 트래픽을 여러 서비스로 라우팅할 수 있습니다.
•
/shop -> 쇼핑 애플리케이션
•
/blog -> 블로그 애플리케이션
3.
SSL/TLS 종료 (ssl 인증서 처리)
인그레스에서 SSL/TLS 인증서를 관리하고 HTTPS 연결을 종료할 수 있습니다.
4.
네임 기반 가상 호스팅
동일한 IP 주소에서 여러 도메인을 호스팅할 수 있습니다.
5.
로드 밸런싱
L7(애플리케이션 계층) 수준에서 로드 밸런싱을 수행합니다.
여기까지만 보면 떠오르는 것이 있을지도 모릅니다.
Nginx랑 같은 것 아니야..?
•
인그레스: 쿠버네티스 환경에 특화된 개념입니다.
•
Nginx: 쿠버네티스 외부에서도 널리 사용되는 범용 웹 서버/프록시 서버입니다.
•
Nginx는 인그레스 컨트롤러로도 자주 사용되고 있습니다. 또한 Nginx는 캐싱, 접근제어와 같이 더 광범위한 기능을 제공하고 있습니다. 둘은 유사하지만 다른 개념이며, 상호 호환적으로 작동하게 할 수 있습니다.
인그레스 컨트롤러
인그레스 규칙을 실제로 구현하는 것은 인그레스 컨트롤러입니다.
다양한 인그레스 컨트롤러가 있으며, 대표적으로 Nginx, HAProxy, Traefik 등이 있습니다.
클라우드 제공업체 별로 자체 인그레스 컨트롤러를 제공하기도 합니다(예: GKE Ingress).
인그레스 컨트롤러는 하단에서 더 다뤄보겠습니다.
마이크로서비스 아키텍처에서의 활용
1.
API 게이트웨이와 인그레스의 협력
•
인그레스: 외부 트래픽을 클러스터 내 적절한 서비스로 라우팅
•
API 게이트웨이 (예: Spring Cloud Gateway): 세밀한 라우팅, 인증, 속도 제한 등 추가 기능 제공
2.
실제 애플리케이션 구성
•
Deployment: 애플리케이션 구성
•
Service (NodePort): 외부 접근 가능한 엔드포인트 제공
3.
4.
인그레스의 라우팅 역할
•
여러 서비스에 대한 단일 진입점 제공
•
경로 기반 라우팅 예시
◦
/apparel → GCP Load Balancer 1
◦
/video → GCP Load Balancer 2
5.
인그레스의 장점
•
복잡한 라우팅 규칙을 단순화
•
여러 마이크로서비스를 하나의 도메인에서 제공 가능
•
로드 밸런싱, SSL 종료 등 추가 기능 제공
인그레스를 통해 마이크로서비스 아키텍처에서 외부 요청을 효율적으로 관리하고, 각 서비스로 적절히 라우팅할 수 있습니다
2. Ingress
Ingress의 본질을 다시 살펴봅시다.
Ingress는 여러 솔루션(예: HAProxy, NGINX)을 하나의 추상화된 개체로 표현한 것.
⇒ 이를 통해 쿠버네티스에서 외부 트래픽을 내부 서비스로 라우팅하는 규칙을 정의 가능
이전 vs 현재 버젼의 Ingress
인그레스 실행법
Format
kubectl create ingress <ingress-name> --rule="host/path=service:port"
Example
kubectl create ingress ingress-test --rule="wear.my-online-store.com/wear*=wear-service:80"
Shell
복사
Ingress Resource
1.
정의: Ingress Resource는 Ingress를 정의하는 YAML 파일입니다.
2.
구조: 간단하지만 강력한 구조를 가지고 있어, 다양한 라우팅 규칙을 정의할 수 있습니다.
3.
기능: 특정 경로(예: /api)로 들어오는 모든 요청을 지정된 서비스로 전달하는 등의 작업이 가능합니다.
예시
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-wildcard-host
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: "foo.bar.com"
http:
paths:
- pathType: Prefix
path: "/bar"
backend:
service:
name: bar-service
port:
number: 80
- host: "*.foo.com"
http:
paths:
- pathType: Prefix
path: "/foo"
backend:
service:
name: service2
port:
number: 80
YAML
복사
이 설정은 /bar로 들어오는 요청을 bar-service의 80포트로 전달합니다.
️ 중요 포인트 - rewrite-target:
•
annotations.nginx.ingress.kubernetes.io/rewrite-target: / 설정의 의미:
◦
이 설정이 있으면: foo.bar.com/bar 요청 → foo.bar.com/로 bar-service에 전달
◦
이 설정이 없으면: foo.bar.com/bar 요청 → foo.bar.com/bar로 bar-service에 전달
•
rewrite-target의 중요성:
◦
API 경로 일치: 내부 서비스의 API 설정과 일치하도록 합니다.
◦
유연성: 외부 요청 경로와 내부 서비스 경로를 다르게 설정할 수 있어 유연한 라우팅이 가능합니다.
•
nginx.ingress.kubernetes.io/ssl-redirect
◦
SSL 리다이렉션을 비활성화합니다.
◦
HTTP 요청을 HTTPS로 자동 리다이렉트하지 않도록 설정합니다.
Ingress Controller
Ingress 설정 시 주의사항
1.
Ingress Resource의 한계
•
많은 초보자들이 Ingress Resource를 설정하면 자동으로 SSL, 로드 밸런싱, NGINX 설정이 완료된다고 오해하곤 합니다
•
하지만, 실제로 Ingress Resource만으로는 아무 동작도 하지 않습니다.
2.
Ingress Controller의 필요성:
•
Ingress가 실제로 작동하려면 Ingress Controller가 반드시 필요합니다.
•
개발자는 최소한 하나 이상의 Ingress Controller 솔루션을 사용해야 합니다.
•
쿠버네티스 프로젝트에서 지속적으로 사용되는 NGINX, GCE 등의 Controller를 추천합니다.
Ingress Controller 설정
1.
필요한 컴포넌트:
•
Deployment: NGINX Controller를 배포하기 위한 설정
•
ConfigMap: NGINX 설정을 저장하고 런타임에 수정 가능
•
Service: 외부와의 통신을 위한 설정
•
ServiceAccount: 인가 처리를 위한 설정 (RBAC)
2.
Deployment 설정:
•
NGINX Controller 배포를 위한 상세 설정 포함
•
args를 통해 ConfigMap에서 NGINX 설정을 불러옴
•
이를 통해 Deployment를 재배포하지 않고도 ConfigMap 수정으로 XFF, SSL 등의 설정 변경 가능
3.
ConfigMap의 활용:
•
런타임에 수정 가능하여 유연한 설정 관리 가능
•
SSL, XFF(X-Forwarded-For) 등의 설정을 동적으로 변경 가능
4.
ServiceAccount와 RBAC:
•
권한 관리를 위해 사용
•
예: 특정 ID에 개발자 권한을 부여하는 등의 역할 기반 접근 제어(RBAC) 구현
인그레스 컨트롤러의 rewrite-target 옵션
•
인그레스 컨트롤러의 커스터마이징:
◦
다양한 인그레스 컨트롤러는 각자의 커스터마이징 옵션을 제공합니다.
◦
NGINX 인그레스 컨트롤러는 많은 옵션을 제공하며, 그 중 하나가 rewrite-target입니다.
•
예시 시나리오:
◦
watch 앱: http://<watch-service>:<port>/에서 비디오 스트리밍 페이지 표시
◦
wear 앱: http://<wear-service>:<port>/에서 의류 페이지 표시
•
목표 설정:
◦
사용자가 /watch나 /wear 경로로 접근할 때, 해당 서비스로 내부적으로 포워딩
◦
백엔드 앱들은 /watch나 /wear 경로를 인식하지 못함
•
rewrite-target 없이 발생하는 문제:
◦
요청이 /watch나 /wear를 포함한 채로 백엔드로 전달됨
◦
백엔드 앱이 이 경로를 인식하지 못해 404 에러 발생
•
rewrite-target의 역할
◦
URL을 재작성하여 백엔드 앱이 이해할 수 있는 형태로 변경
◦
사용자가 입력한 경로를 백엔드 앱에 맞게 수정
•
설정 예시
이 경우, /pay로 들어오는 요청이 /로 재작성됩니다.
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /pay
backend:
serviceName: pay-service
servicePort: 8282
YAML
복사
•
고급 사용 예
이 경우, /something 뒤의 모든 경로가 유지되며 /something만 제거됩니다.
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- path: /something(/|$)(.*)
backend:
serviceName: http-svc
servicePort: 80
YAML
복사
rewrite-target 옵션을 통해 인그레스는 들어오는 요청의 URL을 백엔드 서비스에 맞게 유연하게 조정할 수 있습니다
CKA 풀이법 1
문제
pong 이라는 이름을 가진 ingress 만드시오
namespace 는 ing-internal/hi 로 요청이 들어오면 hi 서비스 5678 포트로 라우팅 해
curl -kL {Internal-ip}/hi 로 테스트 할 수 있습니다
## -h 명령어를 통해서 템플릿 파악
kubectl create ing -h | grep -A 1 Usage
>>
Usage:
kubectl create ingress NAME --rule=host/path=service:port[,tls[=secret]] [options]
## Usage 적용해서 pong ingress 생성하기 네임스페이스 반드시 넣기
kubectl create ing pong --rule=/hi*=hi:5678 -n ing-ingernal --dry-run=client -o yaml
Shell
복사
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp:nullname: pong
namespace: ing-ingernal
spec:
rules:
- http:
paths:
- backend:
service:
name: hi
port:
number: 5678
path: /hi
pathType: Prefix
status:
loadBalancer: {}
YAML
복사
Ingress 설정 및 테스트 과정:
1.
YAML 파일 적용
•
제공된 YAML 파일을 kubectl apply 명령어로 적용하면 Ingress 설정이 완료됩니다.
2.
Ingress 트래픽 흐름
엔드포인트 요청 → 워커 노드 → Ingress Controller 서비스 → Ingress → 서비스 → 파드
3.
테스트 방법 고찰
•
지문에 언급된 {Internal-IP}의 의미가 불분명했습니다.
•
Ingress는 외부에서 클러스터로의 접근 규칙을 정의하므로, 외부 접근을 시뮬레이션하는 테스트가 필요했습니다.
4.
초기 테스트 방법
•
테스트용 파드를 생성하고, 그 파드 내부에서 다음 명령어로 테스트:
curl -kL http://node-external-ip/hi
•
응답이 오는 것을 확인하고 설정이 완료되었다고 판단했습니다.
5.
테스트 방법 재고
•
내부 요청 테스트의 경우, 워커 노드 내부 IP 또는 Ingress Controller 서비스의 ClusterIP를 사용해야 할 것 같습니다.
•
노드 내부 IP 사용은 Ingress의 목적에 부합하지 않습니다.
6.
개선된 테스트 방법
•
Ingress Controller 서비스의 ClusterIP를 {Internal-IP}로 사용하는 것이 더 적절할 것 같습니다.
•
이 방법이 Ingress의 실제 동작을 더 정확하게 테스트할 수 있습니다.
## 아래 명령어로 node internal-ip 를 받을 수 있음
kubectl get nodes -o wide
## 테스트 파드 생성하면서 curl 명령어 날리기
kubectl run test-ing -n ing-internal
##
curl -kL <Ingress 컨트롤러 서비스 클러스터 ip>/hi
Shell
복사
CKA 풀이법 2
1.
작업 환경: Kubernetes 클러스터
2.
Nginx Pod 생성:
•
Namespace: ingress-nginx
•
이미지: nginx
•
레이블: app=nginx
3.
기존 서비스 (변경 불필요):
•
appjs-service
•
nginx 서비스
4.
Ingress 리소스 생성:
•
파일명: app-ingress.yaml
•
이름: app-ingress
•
라우팅 규칙:
◦
NodePort:30080/ → nginx 서비스로 연결
◦
NodePort:30080/app → appjs-service로 연결
•
추가할 annotations:
annotations:
kubernetes.io/ingress.class: nginx
YAML
복사
위 요구사항에 맞춰 app-ingress.yaml 파일을 생성하고 Ingress 리소스를 구성해 주세요.
풀이
•
Kubernetes 컨텍스트 전환:
kubectl config use-context k8s
Plain Text
복사
•
네임스페이스 확인:
kubectl get namespace
Plain Text
복사
•
Nginx Pod 생성:
kubectl run nginx --image=nginx -n ingress-nginx --port 80 --labels=app=nginx
Plain Text
복사
•
Pod 및 서비스 확인:
kubectl get pod -n ingress-nginx
kubectl get svc -n ingress-nginx
Plain Text
복사
•
Ingress 리소스 생성 (app-ingress.yaml):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
namespace: ingress-nginx
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
- path: "/app"
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
YAML
복사
•
Ingress 리소스 적용:
kubectl apply -f app-ingress.yaml
Plain Text
복사
•
Ingress 리소스 확인:
kubectl describe ingress -n ingress-nginx
Plain Text
복사
•
접근 테스트:
curl k8s-worker1:30080
curl k8s-worker1:30080/app
Plain Text
복사