Ingress란?
일반적으로 Ingress는 네트워크 트레픽을 구분하는 말로써 요즘은 GCP와 같은 클라우드에서 VM의 방화벽 규칙을 만들 때 쉽게 접할 수 있습니다. 구체적으로 Ingress는 외부에서 들어오는 트래픽이며 반대로 밖으로 나가는 트래픽은 Egress라고 합니다. 이는 전통적인 데이터센터를 기준으로는 Inbound와 Outbound의 개념에 상응합니다.
쿠버네티스에도 Ingress라는 리소스 오브젝트가 존재하는데 쿠버네티스 클러스터 외부로 부터 들어오는 트래픽을 어떻게 처리할 지를 정의할 수 있습니다. 앞서 공부했던 Deployment나 Service에 접근하기 위한 일종의 Gateway 역할을 담당합니다.
만약 Ingress를 사용하지 않는다면 외부 트래픽을 처리할 수 있는 선택지에는 대표적으로 NodePort가 있습니다. 여러개의 Service가 운영되고 있는 쿠버네티스 클러스터에서 NodePort로 외부 트래픽을 처리한더면 Service 개수만큼 포트를 열고 사용자에게 어떤 포트가 어떤 Service에 대해 열려있는지를 알려줘야합니다. 운영하고 있는 Service가 손가락에 꼽을 정도라면 이 일이 대단하게 느껴지지 않을 수 있지만, 수십개로 늘어나는 경우를 생각해본다면 절대 쉬운일이 아닐겁니다.
쿠버네티스에서는 이처럼 관리하는 Service 개수가 늘어남에 따라 외부 트래픽을 용이하게 처리하기 위해 존재하는 리소스 오브젝트가 바로 Ingress입니다. Ingress를 사용하면 위의 그림처럼 도메인을 통해 각각의 Service에 접근하도록 할 수 있으며, 80(http) 또는 443(https) 포트로 여러 개의 Servcie를 연결하는데 사용할 수도 있습니다.
Ingress 만들어보기
Ingress를 사용하기 위해서는 두 가지가 필요합니다, 첫 째로는 Ingress 오브젝트이고 두번째는 Ingress 규칙을 적용할 Ingress Controller입니다. Ingress 오브젝트는 yaml파일에 kind에서 정의할 수 있지만 Ingress Controller는 별도로 설치가 필요합니다.
Ingress Controller에는 Nginx, Haproxy, Traefik, alb 등이 존재하며, 본 포스팅에서는 이들 중 대표격인 Nginx Ingress Controller를 사용합니다.
minikube에 Ingress 활성화
minikube addons enable ingress
커맨드를 통해 minkube에서 ingress를 활성화 할 수 있습니다. 그리고 kubectl -n ingress-nginx get pod
커맨드를 통해 ingress가 활성화 됐는지 확인 할 수 있습니다.
마지막으로는 curl -I [http://192.168.49.2/healthz](http://192.168.49.2/healthz)
커맨드를 통해 연결이 정상적으로 되고 있는지를 확인합니다. 접속 주소로는 minikube의 ip를 사용합니다.
앱 배포
이젠 이전에 사용했던 echo 웹 어플리케이션을 v1, v2 2버전으로 배포할겁니다. Ingress의 spec.rules.host
에 자신의 minikube ip를 넣어주면 됩니다.
- echo-v1.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-v1
spec:
rules:
- host: v1.echo.192.168.49.5.sslip.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: echo-v1
port:
number: 3000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-v1
spec:
replicas: 3
selector:
matchLabels:
app: echo
tier: app
version: v1
template:
metadata:
labels:
app: echo
tier: app
version: v1
spec:
containers:
- name: echo
image: ghcr.io/subicura/echo:v1
livenessProbe:
httpGet:
path: /
port: 3000
---
apiVersion: v1
kind: Service
metadata:
name: echo-v1
spec:
ports:
- port: 3000
protocol: TCP
selector:
app: echo
tier: app
version: v1
- echo-v1.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-v2
spec:
rules:
- host: v2.echo.192.168.49.5.sslip.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: echo-v2
port:
number: 3000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-v2
spec:
replicas: 3
selector:
matchLabels:
app: echo
tier: app
version: v2
template:
metadata:
labels:
app: echo
tier: app
version: v2
spec:
containers:
- name: echo
image: ghcr.io/subicura/echo:v2
livenessProbe:
httpGet:
path: /
port: 3000
---
apiVersion: v1
kind: Service
metadata:
name: echo-v2
spec:
ports:
- port: 3000
protocol: TCP
selector:
app: echo
tier: app
version: v2
이제 해당 yaml파일을 apply하여 Deplyment, Service, Ingress를 생성해줍니다. 그리고 나서 kubectl get ingress
커맨드를 통해 ingress가 생성된 것을 확인할 수 있습니다.
Ingress 생성 흐름
Ingress Controller
는Ingress
변화를 체크Ingress Controller
는 변경된 내용을Nginx
에 설정하고 프로세스 재시작
동작방식을 보면 YAML로 만든 Ingress 설정을 단순히 nginx 설정으로 바꾸는 걸 알 수 있습니다. 이러한 과정을 수동으로 하지 않고 Ingress Controller가 하는 것 뿐입니다.
마무리
Ingress라는 개념은 네트워크 트래픽의 방향을 의미합니다. 이는 쿠버네티스에서의 Ingress에서도 같은 의미를 갖지만 동시에 미묘하게 다릅니다. 이는 컨테이너 환경이 성숙해 감에 따라 좀더 구체적이고 어플리케이션 중심적인 정의로 규정되었기 때문이겠죠. 안타깝게도 현재 저는 이 미묘한 차이에 대해서 완전히 감을 잡지 못했기 때문에 차후 기회가 된다면 좀 더 공부한 후에 포스팅을 올리도록 하겠습니다.