1. What is Ingress
인그레스는 무엇일까요?
인그레스는 쿠버네티스에서 클러스터 외부에서 내부 서비스로의 HTTP와 HTTPS 경로를 노출시키는 API 오브젝트입니다.
주요 기능
1.
외부 접근 관리
클러스터 외부에서 내부 서비스에 접근할 수 있도록 합니다. NodePort나 LoadBalancer 타입의 서비스를 사용하지 않고도 외부 접근이 가능합니다.
2.
트래픽 라우팅
URL 경로나 호스트 기반으로 트래픽을 여러 서비스로 라우팅할 수 있습니다.
•
/shop -> 쇼핑 애플리케이션
•
/blog -> 블로그 애플리케이션
3.
SSL/TLS 종료
인그레스에서 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: /
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 설정과 일치하도록 합니다.
◦
유연성: 외부 요청 경로와 내부 서비스 경로를 다르게 설정할 수 있어 유연한 라우팅이 가능합니다.
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 풀이법
문제
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
복사