인그레스(Ingress)
인그레스(Ingress)는 주로 클러스터 외부에서 안에 있는 파드에 접근할 때 사용하는 방법입니다. 서비스와의 차이점은 주로 L7 영역의 통신을 담당해서 처리한다는 것입니다.
인그레스는 클러스터 외부에서 안으로 접근하는 요청들을 어떻게 처리할지 정의해둔 규칙에 대한 모음입니다. 클러스터 외부에서 접근해야 할 URL을 사용할 수 있도록 하고, 트래픽 로드밸런싱, SSL 인증서 처리, 도메인 기반 가상 호스팅도 제공합니다. 인그레스 자체는 이런 규칙들을 정의해둔 자원이고, 실제로 동작시키는 것은 인그레스 컨트롤러(Ingress Controller)입니다.
클라우드 서비스(AWS EKS 등..)를 사용하면 별다른 설정없이 자체 로드밸런서 서비스와 연동해서 인그레스를 사용할 수 있습니다. 클라우드 서비스를 사용하지 않고 직접 쿠버네티스 클러스터를 구축해서 사용한다면 인그레스 컨트롤러를 직접 인그레스와 연동해야 합니다. 이 때 가장 많이 사용하는 도구는 쿠버네티스에서 제공하는 ingress-nginx 입니다.
(ingress-nginx 외에 HAProxy, Envoy, Kong 등 소프트웨어 프록시를 이용한 인그레스 컨트롤러도 있으며, Citrix, F5 같은 로드밸런서 장비 회사에서 자사의 로드밸런서를 이용할 수 있도록 만든 인그레스 컨트롤러도 있습니다.)
ingress-nginx 컨트롤러는 인그레스에서 설정한 내용을 nginx 환경 설정으로 변경하여 nginx에 적용합니다.
인그레스 설정 예시
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
|
apiVersion: networking.k8s.io/v1
kind: Ingress
# Ingress 설정
metadata:
name: test
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / # Ingress-nginx에서 '/'로 리다이렉트
spec:
rules:
- host: "foo.bar.com" # foo.bar.com 주소에 대한 처리
http:
paths:
- pathType: Prefix # Prefix/Exact/ImplementationsSpecific
path: "/foos1" # foo.bar.com/foos1 주소에 대한 처리
backend:
# foo.bar.com/foos1 주소에 대한 요청을 s1 서비스의 80번 포트로 전송
service:
name: s1
port:
number: 80
- pathType: Prefix
path: "/bars2" # foo.bar.com/bars2 주소에 대한 처리
backend:
# foo.bar.com/bars 주소에 대한 요청을 s2 서비스의 80번 포트로 전송
service:
name: s2
port:
number: 80
- host: "*.foo.com"
http:
paths:
# *.foo.com의 모든 요청을 s2 서비스의 80번 포트로 전송
- pathType: Prefix
path: "/"
backend:
service:
name: s2
port:
number: 80
|
cs |
Ingress-nginx 컨트롤러를 사용하므로 .metadata.annotaions의 하위 필드에 nginx.ingress.kubernetes.io/rewrite-target를 키로 / 를 값으로 설정합니다. "/" 경로로 리다이렉트하라는 의미입니다. 또한 Ingress-nginx 컨트롤러가 클러스터에 설치되어 있어야합니다. Ingress-nginx 설치는 다음 사이트를 참고하세요.
https://kubernetes.github.io/ingress-nginx/deploy/
.spec.rules 필드에서 어떤 규칙을 사용할지 지정할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
spec:
rules:
- host: foo.bar.com # foo.bar.com 주소에 대한 처리
http:
paths:
- pathType: Prefix # Prefix/Exact/ImplementationsSpecific
path: "/foos1" # foo.bar.com/foos1 주소에 대한 처리
backend:
# foo.bar.com/foos1 주소에 대한 요청을 s1 서비스의 80번 포트로 전송
service:
name: s1
port:
number: 80
|
cs |
위의 spec에서 .spec.rules[].host 의 필드가 foo.bar.com 입니다. foo.bar.com의 주소로 요청이 들어오면 다음에 설정하는 규칙에 따라 처리합니다.
.spec.rules[].http.paths[]. 필드는 HTTP 요청이 어떤 경로로 들어오는지 지정합니다. 위의 예시에서 /foos1 경로로 지정했으며 pathType이 Prefix이므로 foo.com/foos1으로 들어오는 요청을 처리합니다.
.spec.rules[].http.backend 필드에 위에서 지정한 요청에 어떻게 처리할 것인지 지정합니다. 위의 예시에서는 .backend.service: s1, .backend.service.port.number: 80 이므로 s1이라는 서비스의 80번 포트로 보내도록 설정하였습니다.
따라서 위의 spec은 요청된 url이 foo.bar.com/foos1 으로 시작하면 s1 서비스의 80번 포트로 전송하라라는 의미입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
spec:
rules:
...
- host: "*.foo.com"
http:
paths:
# *.foo.com의 모든 요청을 s2 서비스의 80번 포트로 전송
- pathType: Prefix
path: "/"
backend:
service:
name: s2
port:
number: 80
|
cs |
.spec.rules[].host 필드를 위와 같이 "*.foo.com" 으로 설정하면 .foo.com으로 끝나는 모든 요청에 대해 모두 처리할 수 있습니다. ex) foo.foo.com. bar.foo.com
이제 예시를 ingress_basic.yaml 파일로 저장한 후 kubectl 명령어를 이용하여 클러스터에 적용합니다. 그리고 나서 kubectl describe ingress [인그레스이름] 명령어를 실행하면 인그레스의 자세한 내용을 확인할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[root@k8s-master ingerss]# kubectl apply -f ingress_basic.yaml
ingress.networking.k8s.io/test created
[root@k8s-master ingerss]# kubectl describe ingress test
Name: test
Namespace: default
Address:
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foos1 s1:80 (<error: endpoints "s1" not found>)
/bars2 s2:80 (<error: endpoints "s2" not found>)
*.foo.com
/ s2:80 (<error: endpoints "s2" not found>)
Annotations: nginx.ingress.kubernetes.io/rewrite-target: /
Events: <none>
|
cs |
결과의 Rules 필드를 살펴보면 위에서 명시한대로 설정된 것을 확인할 수 있습니다. (위의 예시에서 서비스 s1, s2를 정의하지 않아 s1, s2 서비스가 없다라는 에러도 확인할 수 있습니다.)
또한 Default backend는 현재 default-http-backend로 설정되어 있는데, DefaultBackend는 규칙이 없는 모든 트래픽을 모두 전송하는 백엔드 입니다. 일반적으로 인그레스 컨트롤러의 구성옵션입니다.
(추가)인그레스 경로 유형, spec.rules[].http.paths[].pathType
1
2
3
4
5
6
7
8
9
10
11
12
13
|
spec:
rules:
- host: "foo.bar.com" # foo.bar.com 주소에 대한 처리
http:
paths:
- pathType: Prefix # Prefix/Exact/ImplementationsSpecific
path: "/foos1" # foo.bar.com/foos1 주소에 대한 처리
backend:
# foo.bar.com/foos1 주소에 대한 요청을 s1 서비스의 80번 포트로 전송
service:
name: s1
port:
number: 80
|
cs |
위 예시의 6번 줄처럼 Ingress path 설정 시 spec.rules[].http.paths[].pathType 필드에서 경로 유형을 지정해야합니다. 지원하는 경로 유형은 세 가지가 있습니다.
경로 유형 | 설명 |
ImplementationSpecific | 이 경로 유형의 일치 여부는 IngressClass에 따라 달라진다. 이를 구현할 때 별도 pathType 으로 처리하거나, Prefix 또는 Exact 경로 유형과 같이 동일하게 처리할 수 있다. |
Exact | URL 경로의 대소문자를 엄격하게 지킨다. |
Prefix | URL 경로의 접두사를 / 를 기준으로 분리한 값과 일치시킨다. 일치는 대소문자를 구분하고, 요소별로 경로 요소에 대해 수행한다. 모든 p 가 요청 경로의 요소별 접두사가 p 인 경우 요청은 p 경로에 일치한다. |
경로 유형에 따른 일치 여부는 다음 예제를 참고하세요.
종류 | 경로 | 요청 | 경로 일치 여부 |
Prefix | / | (모든 경로) | 예 |
Exact | /foo | /foo | 예 |
Exact | /foo | /bar | 아니오 |
Exact | /foo | /foo/ | 아니오 |
Exact | /foo/ | /foo | 아니오 |
Prefix | /foo | /foo, /foo/ | 예 |
Prefix | /foo/ | /foo, /foo/ | 예 |
Prefix | /aaa/bb | /aaa/bbb | 아니오 |
Prefix | /aaa/bbb | /aaa/bbb | 예 |
Prefix | /aaa/bbb/ | /aaa/bbb | 예, 마지막 슬래시 무시함 |
Prefix | /aaa/bbb | /aaa/bbb/ | 예, 마지막 슬래시 일치함 |
Prefix | /aaa/bbb | /aaa/bbb/ccc | 예, 하위 경로 일치함 |
Prefix | /aaa/bbb | /aaa/bbbxyz | 아니오, 문자열 접두사 일치하지 않음 |
Prefix | /, /aaa | /aaa/ccc | 예, /aaa 접두사 일치함 |
Prefix | /, /aaa, /aaa/bbb | /aaa/bbb | 예, /aaa/bbb 접두사 일치함 |
Prefix | /, /aaa, /aaa/bbb | /ccc | 예, / 접두사 일치함 |
Prefix | /aaa | /ccc | 아니오, 기본 백엔드 사용함 |
Mixed | /foo (Prefix), /foo (Exact) | /foo | 예, Exact 선호함 |
이처럼 인그레스를 사용하면 클러스터 외부에서 오는 요청에 대해 다양한 방식으로 처리할 수 있습니다.
쿠버네티스의 인그레스에 대하여 알아보았습니다.
참고
'About > Kubernetes' 카테고리의 다른 글
[k8s] 파드를 수평으로 Scale Out 하기(HorizontalPodAutoscaler, HPA) (0) | 2022.02.14 |
---|---|
[k8s] 쿠버네티스의 Autoscaler (HPA, VPA, CA 개념) (0) | 2022.02.14 |
[k8s] StatefulSet(스테이트풀셋) (2) | 2022.02.10 |
[k8s] RBAC(Role Based Access Control)란 (0) | 2022.02.04 |
[k8s] 쿠버네티스의 인증과 인가 (0) | 2022.02.04 |