인그레스는 주로 클러스터 외부에서 안에 있는 파드에 접근할 때 사용하는 방법이다.
📚 막간 용어 정리
🧩 클러스터(Cluster): 쿠버네티스에서 관리되는 컨테이너화 된 앱을 실행하는 노드 집합
🧩 노드(Node): 클러스터의 일부로, 쿠버네티스에 속한 워커 머신
🧩 서비스(Service): 레이블 셀렉터를 사용해서 파드 집합을 식별하는 쿠버네티스 서비스 (달리 언급하지 않으면 서비스는 클러스터 내에서만 라우팅 가능한 가상 IP를 가지는 것을 가정)
출처: kubernetes.io/ko/docs/concepts/services-networking/ingress
인그레스는 클러스터 외부에서 안으로 접근하는 요청들을 어떻게 처리할지 정의해둔 규칙 모음이다.
클러스터 외부에서 접근해야 할 URL을 사용할 수 있도록 하고, 트래픽 로드밸런싱, SSL 인증서 처리, 도메인 기반 가상 호스팅도 제공한다. 인그레스 자체는 이런 규칙들을 정의해둔 자원이고, 실제로 동작시키는 것은 인그레스 컨트롤러이다.
각 로드밸런서 서비스는 그 자신만의 공개 IP를 갖는 자체 로드 밸런서를 필요로 하는 반면, 인그레스는 수십 개의 서비스에 대한 액세스를 제공할 때도 하나의 IP만 필요로 한다.
다수의 서비스는 단일 인그레스로 노출할 수 있다 (출처: github.com/sungsu9022/study-kubernetes-in-action/issues/5)
클라우드 서비스를 사용하면 별다른 설정없이 로드밸런서 서비스와 연동해서 인그레스를 사용할 수 있다. 클라우드 서비스를 사용하지 않고 직접 쿠버네티스 클러스터를 구축해서 사용한다면 인그레스 컨트롤러를 직접 인그레스와 연동해야 한다. 이때 가장 많이 사용하는 도구는 쿠버네티스에서 제공하는 ingress-nginx
이다. ingress-nginx 컨트롤러는 인그레스에서 설정한 내용을 nginx 환경 설정으로 변경해서 nginx에 적용한다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foo.bar.com # foo.bar.com 도메인 이름을 서비스로 매핑
http:
paths:
- path: /foos1
pathType: Prefix
backend:
service:
name: s1
port:
number: 80
- path: /bars2
pathType: Prefix
backend:
service:
name: s2 # 모든 요청은 s2 서비스의 포트 80로 전달된다
port:
number: 80
- host: bar.foo.com # bar.foo.com 도메인 이름을 서비스로 매핑
http:
paths:
- backend:
serviceName: s2 # 모든 요청은 s2 서비스의 포트 80로 전달된다
servicePort: 80
인그레스에는 apiVersion
, kind
, metadata
필드가 필요하다.
🎀 .metadata.annotations
.metadata.annotations
의 하위 필드 설정은 인그레스 컨트롤러마다 다르다. 위 코드는 ingress-nginx 컨트롤러를 사용하기에 nginx.ingress.kubernetes.io/rewrite-target
을 키로 하고 /
을 값으로 하는 필드 값을 설정했다. / 경로로 리다이렉트 하라는 뜻이다.
🎀 spec.rules
.spec.rules[]
의 하위 필드에는 어떤 규칙들을 사용할지 지정할 수 있다. 예를 들어 첫 번째 .spec.rules[].host
의 필드 값인 foo.bar.com
의 주소로 요청이 들어오면 다음에 설정하는 규칙에 따라 처리한다.
🎀 spec.rules[].http.paths
경로(path)
: HTTP 요청이 어떤 경로에서 들어오는 지를 뜻한다.
백엔드(backend)
: 서비스와 포트 이름의 조합이다.
경로 유형(pathType)
: 경로의 유형을 결정한다.
Prefix
: 경로의 접두사를 / 기준으로 분리한 값과 일치시킨다.Exact
: URL 경로의 대소문자를 엄격하게 일치시킨다.경로 유형 예제 :
종류 | 경로 | 요청 경로 | 일치여부 |
---|---|---|---|
Prefix | / | (모든 경로) | Y |
Exact | /foo | /foo | Y |
Exact | /foo | /bar | N |
Exact | /foo | /foo/ | N |
Exact | /foo/ | /foo | N |
Prefix | /foo | /foo, /foo/ | Y |
Prefix | /foo/ | /foo, /foo/ | Y |
Prefix | /aaa/bb | /aaa/bbb | N |
Prefix | /aaa/bbb | /aaa/bbb/ccc | Y |
위의 인그레스 리소스를 해석하면 다음과 같다.
foo.bar.com/foos1
으로 오는 요청을 s1
이라는 서비스의 80
포트로 보내라.foo.bar.com/bars2
으로 오는 요청은 s2
서비스의 80
포트로 보내라.bar.foo.com
으로 오는 요청은 s2
서비스의 80
포트로 보내라.즉,
foo.bar.com
으로 요청이 오더라도 뒷부분의 경로에 따라서/foo1
이면 서비스s1
으로 연결되고bars2
면 서비스s2
로 연결되도록 설정된다. 또다른 호스트네임인bar.foo.com
도 서비스s2
로 연결된다.
출처: kubernetes.io/ko/docs/concepts/services-networking/ingress
TLS 개인 키와 인증서가 포함된 시크릿(Secret)을 지정해서 인그레스를 보호할 수 있다. 시크릿은 쿠버네티스 내부에서 보안이 필요한 설정들을 다룰 때 사용한다.
보통 CA(Certificate Authority) 역할을 하는 공인인증기관에서 사용하려는 도메인의 SSL 인증서를 발급받아서 사용한다.
신뢰받는 인증기관인 CA
에 인증서 발급을 요청하면 CA 측에서 관리하는 키와 인증서로 서명한 인증서를 발급한다. 발급받은 인증서를 서버
에 설정하면 웹 브라우저
에서 통신할 때 서버에 있는 인증서가 유효한 인증서인지 확인한 후 SSL 통신을 한다.
시크릿을 인그레스에 적용시키는 설정 예를 살펴보면 다음과 같다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-ssl
spec:
tls:
- hosts:
- https-example.foo.com
secretName: testsecret-tls
rules:
- host: https-example.foo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: s1
port:
number: 80
.spec
의 하위 필드로 .tls[]
필드가 명시되어 있고 .spec.tls[].hosts[]
필드값을 https-example.foo.com
이라는 호스트네임을 설정이 되었다. .spec.tls[].secretName
필드에는 시크릿을 사용하기 위해 시크릿 이름인 testsecret-tls
이 설정된다.