-
[Kubernetes] 서비스, 로드 밸런스, 네트워킹 - Ingress, 게이트웨이 API공부/쿠버네티스&헬름 2025. 1. 30. 17:38
Ingress
Ingress는 클러스터 외부에서 클러스터 내부의 서비스로 HTTP 및 HTTPS 라우트를 노출합니다. 트래픽 라우팅은 Ingress 리소스에 정의된 규칙에 따라 제어됩니다.
다음은 모든 트래픽을 하나의 서비스로 전달하는 간단한 Ingress 예시입니다.
Ingress는 서비스에 외부에서 접근 가능한 URL을 제공하고 트래픽을 로드 밸런싱하며 SSL/TLS를 종료하고 이름 기반 가상 호스팅을 제공할 수 있습니다. Ingress 컨트롤러는 일반적으로 로드 밸런서를 사용하여 Ingress를 처리하지만 엣지 라우터나 추가적인 프런트엔드를 구성하여 트래픽 처리를 지원할 수도 있습니다.
- Ingress 컨트롤러 목록: https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/
- GKE의 경우 다음과 같이 인그레스 컨트롤러가 동작
- Edge 라우터는 클러스터의 방화벽 정책을 적용하는 라우터입니다. 이는 클라우드 제공업체에서 관리하는 게이트웨이 또는 물리적인 하드웨어일 수 있습니다.
Ingress는 임의의 포트나 프로토콜을 노출하지 않습니다. HTTP 및 HTTPS 이외의 서비스를 인터넷에 노출하려면 일반적으로
Service.Type=NodePort
또는Service.Type=LoadBalancer
유형의 서비스를 사용합니다.필수조건
Ingress를 사용하려면 반드시 Ingress 컨트롤러가 필요합니다. Ingress 리소스만 생성한다고 해서 자동으로 트래픽이 라우팅되지 않습니다. ingress-nginx 등 다양한 Ingress 컨트롤러 중에서 선택하여 배포해야 합니다. Ingress 컨트롤러는 Ingress 리소스에 정의된 규칙에 따라 트래픽을 라우팅합니다.
Ingress 리소스
다음은 Ingress 를 구성하는 최소 리소스 예시입니다.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: minimal-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx-example rules: - http: paths: - path: /testpath pathType: Prefix backend: service: name: test port: number: 80
Ingress는
apiVersion
,kind
,metadata
및spec
필드를 포함해야 합니다. Ingress 객체의 이름은 유효한 DNS 서브도메인 이름이어야 합니다.Ingress는 Ingress 컨트롤러에 따라 일부 옵션을 구성하기 위해 주석(annotation)을 사용합니다. 예를 들어,
rewrite-target
주석을 사용할 수 있습니다.Ingress spec
에는 로드 밸런서 또는 프록시 서버를 구성하는 데 필요한 모든 정보가 포함되어 있습니다. 가장 중요한 것은 모든 수신 요청과 일치하는 규칙 목록입니다. Ingress 리소스는 HTTP(S) 트래픽에 대한 규칙만 지원합니다.ingressClassName
이 생략되면 기본 Ingress 클래스가 정의되어 있어야 합니다.일부 Ingress 컨트롤러는 기본 IngressClass를 정의하지 않고도 작동합니다. 예를 들어, Ingress-NGINX 컨트롤러는
--watch-ingress-without-class
플래그를 사용하여 구성할 수 있습니다. 그러나 기본 IngressClass를 지정하는 것이 권장됩니다.Ingress 규칙
각 HTTP 규칙은 다음과 같은 정보를 포함합니다.
- hosts (선택적): 이 예시에서는 호스트가 지정되지 않았으므로 규칙은 지정된 IP 주소를 통해 들어오는 모든 HTTP 트래픽에 적용됩니다. 호스트가 제공된 경우 (예: foo.bar.com) 규칙은 해당 호스트에 적용됩니다.
- paths (예: /testpath): 각 path에는
service.name
과service.port.name
또는service.port.number
를 사용하여 정의된 백엔드가 연결되어 있습니다. 로드 밸런서가 트래픽을 참조된 서비스로 라우팅하기 전에 호스트와 경로 모두가 들어오는 요청의 내용과 일치해야 합니다. - backend: 서비스 및 포트 이름의 조합으로, 서비스 문서에 설명된 대로 정의되거나 CRD(Custom Resource Definition)를 통한 사용자 정의 리소스 백엔드입니다. rule의 호스트와 경로와 일치하는 Ingress에 대한 HTTP(및 HTTPS) 요청은 목록에 있는 백엔드로 전송됩니다.
- defaultBackend: 많은 Ingress 컨트롤러에서 spec의 경로와 일치하지 않는 모든 요청을 처리하는 기본 백엔드를 구성합니다.
DefaultBackend
규칙이 없는 Ingress는 모든 트래픽을 단일 DefaultBackend로 전달하며,
spec.defaultBackend
는 이 경우 처리해야 하는 백엔드입니다. 일반적으로 DefaultBackend는 Ingress 컨트롤러의 구성 옵션이며, Ingress 리소스에 직접 지정하지 않습니다.spec.rules
가 지정되지 않은 경우,spec.defaultBackend
가 반드시 지정되어야 합니다.defaultBackend
가 설정되지 않은 경우, 규칙과 일치하지 않는 요청의 처리 방식은 Ingress 컨트롤러에 따라 달라집니다. Ingress 객체의 호스트 또는 경로와 일치하는 HTTP 요청이 없는 경우, 트래픽은 DefaultBackend로 라우팅됩니다.Resource backends
Resource 백엔드는 동일한 네임스페이스 내에 있는 다른 Kubernetes 리소스를 참조하는 ObjectRef입니다. Resource는 Service와 상호 배타적입니다. 즉, Resource와 Service를 동시에 지정할 수 없습니다. Resource 백엔드는 일반적으로 정적 자산을 포함하는 객체 스토리지 백엔드에 데이터를 Ingress하는 경우에 사용됩니다.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-resource-backend spec: defaultBackend: resource: apiGroup: k8s.example.com kind: StorageBucket name: static-assets rules: - http: paths: - path: /icons pathType: ImplementationSpecific backend: resource: apiGroup: k8s.example.com kind: StorageBucket name: icon-assets
위의 Ingress를 생성한 후 다음 명령어로 확인할 수 있습니다.
$ kubectl describe ingress ingress-resource-backend Name: ingress-resource-backend Namespace: default Address: Default backend: APIGroup: k8s.example.com, Kind: StorageBucket, Name: static-assets Rules: Host Path Backends ---- ---- -------- * /icons APIGroup: k8s.example.com, Kind: StorageBucket, Name: icon-assets Annotations: <none> Events: <none>
Path types
Ingress의 각 경로에는 반드시 해당하는
pathType
가 있어야 합니다.pathType
를 명시적으로 지정하지 않은 경로는 유효성 검사에서 실패합니다. 지원되는 pathType은 다음과 같습니다.- ImplementationSpecific: 매칭 방식은 IngressClass에 따라 달라집니다. 구현에 따라 별도의
pathType
로 처리되거나Prefix
또는Exact
와 동일하게 처리될 수 있습니다. - Exact: URL 경로와 정확히 일치하는 경우에만 매칭됩니다. 대소문자를 구분합니다.
- Prefix: URL 경로의 접두사와 일치하는 경우에 매칭됩니다. 대소문자를 구분하고, 경로를
/
로 구분하여 요소별로 비교합니다. 요청 경로의 각 요소가path
의 각 요소의 접두사와 일치하면 매칭됩니다.
Multiple matches
하나의 요청에 대해 여러 개의 Ingress 경로가 일치할 수 있습니다. 우선순위는 다음과 같습니다.
- 먼저 가장 길게 일치하는 경로가 우선적으로 선택됩니다.
- 길이가 동일한 경우
Exact
pathType이Prefix
pathType보다 우선적으로 선택됩니다.
호스트네임 와일드카드
Ingress는 호스트를 기반으로 트래픽을 라우팅할 수 있습니다. 호스트는 다음과 같은 두 가지 방식으로 정의할 수 있습니다.
- 정확 일치 (예: "foo.bar.com"): 이 경우 HTTP 요청의
host
헤더가 정확히 Ingress의host
필드와 일치해야 합니다. - 와일드카드 일치 (예: "*.foo.com"): 이 경우 HTTP 요청의
host
헤더가 와일드카드 규칙의 끝 부분과 일치해야 합니다.
Host Host header Match? *.foo.com
bar.foo.com
O *.foo.com
baz.bar.foo.com
X 와일드카드는 단일 DNS label만 커버 *.foo.com
foo.com
X 와일드카드는 단일 DNS label만 커버 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-wildcard-host spec: rules: - host: "foo.bar.com" http: paths: - pathType: Prefix path: "/bar" backend: service: name: service1 port: number: 80 - host: "*.foo.com" http: paths: - pathType: Prefix path: "/foo" backend: service: name: service2 port: number: 80
Ingress 클래스
Ingress는 다양한 컨트롤러를 통해 구현되며, 각 컨트롤러마다 다른 구성 방식을 가질 수 있습니다. 각 Ingress는
ingressClassName
을 지정하여 특정 IngressClass를 참조해야 합니다. IngressClass 리소스에는 해당 Ingress를 처리할 컨트롤러의 이름을 포함한 추가적인 구성 정보가 포함됩니다.apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: name: external-lb spec: controller: example.com/ingress-controller parameters: apiGroup: k8s.example.com kind: IngressParameters name: external-lb
IngressClass의
spec.parameters
필드는 해당 IngressClass와 관련된 구성 정보를 제공하는 다른 리소스를 참조합니다. 사용되는 parameter의 구체적인 유형은 IngressClass의spec.controller
필드에서 지정하는 Ingress 컨트롤러에 따라 달라집니다.더 이상 사용되지 않는 annotation
Kubernetes 1.18 이전에는 Ingress 클래스를 지정하는 방법이 달랐습니다.
이전 방식은 annotation을 활용했습니다.
kubernetes.io/ingress.class
라는 annotation을 Ingress 리소스에 추가하여 Ingress 클래스를 지정했습니다. 이 annotation은 공식적으로 정의된 것이 아니었지만, 대부분의 Ingress 컨트롤러에서 지원되었습니다. 이 annotation에는 일반적으로 Ingress를 구현해야 하는 Ingress 컨트롤러의 이름을 참조값으로 사용했습니다.현재 방식은 필드를 사용합니다. Kubernetes 1.18부터는 Ingress 리소스에
ingressClassName
필드를 사용하여 Ingress 클래스를 지정합니다. 이 필드는 이전의 annotation과 동일한 역할을 하는 것처럼 보이지만 실제로는 약간의 차이가 있습니다.ingressClassName
필드는 Ingress 클래스 리소스를 참조합니다. Ingress 클래스 리소스는 Ingress 컨트롤러 이름 외에도 추가적인 Ingress 설정 정보를 포함할 수 있습니다.핵심 차이점은 다음과 같습니다.
- 이전 방식은 간단하게 Ingress 컨트롤러 이름만 지정했지만 현재 방식은 Ingress 클래스 리소스를 통해 보다 세 granular 하게 설정을 관리할 수 있습니다.
- Ingress 클래스 리소스는 Ingress 컨트롤러 이름 외에도 다른 설정 정보를 포함할 수 있기 때문에 향후 기능 확장성이 더 좋습니다.
Kubernetes 1.18부터는
ingressClassName
필드를 사용하여 Ingress 클래스를 지정하는 것이 좋습니다. 이 방식은 보다 명확하고 유연한 설정 관리를 제공합니다.Ingress 유형
단일 서비스로 지원되는 Ingress
단일 서비스를 노출하기 위한 다른 Kubernetes 개념이 존재합니다. 규칙 없이
defaultBackend
를 지정하여 Ingress를 사용하여 단일 서비스를 노출할 수 있습니다.apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: test-ingress spec: defaultBackend: service: name: test port: number: 80
kubectl apply -f
명령을 사용하여 Ingress를 생성한 경우, 생성된 Ingress의 상태를 확인할 수 있습니다.$ kubectl get ingress test-ingress NAME CLASS HOSTS ADDRESS PORTS AGE test-ingress external-lb * 203.0.113.123 80 59s
203.0.113.123은 이 Ingress를 처리하기 위해 Ingress 컨트롤러에서 할당한 IP 주소입니다.
간단한 팬아웃
Fanout 구성은 단일 IP 주소에서 요청되는 HTTP URI에 따라 트래픽을 여러 서비스로 라우팅합니다. Ingress를 사용하면 로드 밸런서의 수를 최소화할 수 있습니다.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: simple-fanout-example spec: rules: - host: foo.bar.com http: paths: - path: /foo pathType: Prefix backend: service: name: service1 port: number: 4200 - path: /bar pathType: Prefix backend: service: name: service2 port: number: 8080
kubectl apply -f
명령을 사용하여 Ingress를 생성한 경우, 생성된 Ingress의 상태를 확인할 수 있습니다.$ kubectl describe ingress simple-fanout-example Name: simple-fanout-example Namespace: default Address: 178.91.123.132 Default backend: default-http-backend:80 (10.8.2.3:8080) Rules: Host Path Backends ---- ---- -------- foo.bar.com /foo service1:4200 (10.8.0.90:4200) /bar service2:8080 (10.8.0.91:8080) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 22s loadbalancer-controller default/test
Ingress 컨트롤러는 Ingress를 처리하기 위해 구현별 로드 밸런서를 프로비저닝합니다. (단, 서비스(service1, service2)가 존재해야 합니다.) 프로비저닝이 완료되면 Address 필드에서 로드 밸런서의 주소를 확인할 수 있습니다.
TLS
Ingress를 보호하려면 TLS 개인 키와 인증서가 포함된 Secret을 지정해야 합니다. Ingress 리소스는 단일 TLS 포트(443)만 지원하며 Ingress 지점에서 TLS 종료가 가정됩니다(서비스 및 해당 파드로의 트래픽은 일반 텍스트로 전송됨). Ingress의 TLS 구성 섹션에서 다른 호스트를 지정하는 경우, SNI TLS 확장을 통해 지정된 호스트 이름에 따라 동일한 포트에서 멀티플렉싱됩니다(Ingress 컨트롤러가 SNI를 지원하는 경우). TLS Secret은 TLS에 사용할 인증서와 개인 키를 포함하는
tls.crt
및tls.key
라는 이름의 키를 포함해야 합니다.apiVersion: v1 kind: Secret metadata: name: testsecret-tls namespace: default data: tls.crt: base64 encoded cert tls.key: base64 encoded key type: kubernetes.io/tls
Ingress에서 이 Secret을 참조하면 Ingress 컨트롤러에게 클라이언트와 로드 밸런서 간의 채널을 TLS를 사용하여 보안하도록 지시합니다. 생성한 TLS Secret은
https-example.foo.com
의 완전한 도메인 이름(FQDN) 또는 일반 이름(CN)이 포함된 인증서에서 생성되었는지 확인해야 합니다.apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tls-example-ingress spec: tls: - hosts: - https-example.foo.com secretName: testsecret-tls rules: - host: https-example.foo.com http: paths: - path: / pathType: Prefix backend: service: name: service1 port: number: 80
게이트웨이 API
게이트웨이 API는 동적 인프라 프로비저닝과 고급 트래픽 라우팅을 제공하는 API 종류의 집합입니다. 확장 가능하고 역할 중심적인 프로토콜 인식 구성 메커니즘을 사용하여 네트워크 서비스를 제공합니다. 게이트웨이 API는 동적 인프라 프로비저닝과 고급 트래픽 라우팅을 제공하는 API 종류를 포함하는 애드온입니다.
디자인원칙
역할 중심: 게이트웨이 API 종류는 Kubernetes 서비스 네트워킹 관리를 담당하는 조직의 역할을 모델로 합니다.
- 인프라 제공자: 여러 격리된 클러스터가 여러 테넌트를 제공할 수 있도록 인프라를 관리합니다 (예: 클라우드 제공업체).
- 클러스터 운영자: 클러스터를 관리하며 일반적으로 정책, 네트워크 접근, 애플리케이션 권한 등에 관심을 가집니다.
- 애플리케이션 개발자: 클러스터에서 실행되는 애플리케이션을 관리하며 일반적으로 애플리케이션 수준 구성 및 서비스 구성에 관심을 가집니다.
이식성: 게이트웨이 API 사양은 사용자 정의 리소스로 정의되며 많은 구현에서 지원됩니다.
표현력: 게이트웨이 API 종류는 헤더 기반 매칭, 트래픽 가중치 및 Ingress에서 사용자 정의 어노테이션을 사용해야만 가능했던 기타 일반적인 트래픽 라우팅 사용 사례에 대한 기능을 지원합니다.
확장성: 게이트웨이 API는 API의 다양한 계층에서 사용자 정의 리소스를 연결할 수 있도록 허용합니다. 이를 통해 API 구조 내 적절한 위치에서 세밀한 사용자 정의가 가능합니다.
리소스 모델
게이트웨이 API는 세 가지 안정적인 API 종류를 가지고 있습니다.
- GatewayClass: 공통 구성을 가진 게이트웨이 집합을 정의하며 해당 클래스를 구현하는 컨트롤러에 의해 관리됩니다.
- Gateway: 클라우드 로드 밸런서와 같은 트래픽 처리 인프라의 인스턴스를 정의합니다.
- HTTPRoute: 게이트웨이 리스너로부터 백엔드 네트워크 엔드포인트의 표현으로 트래픽을 매핑하기 위한 HTTP 관련 규칙을 정의합니다. 이러한 엔드포인트는 종종 서비스(Service)로 표현됩니다.
게이트웨이 API는 조직의 역할 중심적인 특성을 지원하기 위해 상호 의존적인 관계를 가진 여러 API 종류로 구성됩니다. Gateway 객체는 정확히 하나의 GatewayClass와 연결됩니다. GatewayClass는 이 클래스의 게이트웨이를 관리하는 게이트웨이 컨트롤러를 설명합니다. 하나 이상의 경로 종류 (예: HTTPRoute)는 Gateway와 연결됩니다. Gateway는 해당 리스너에 연결될 수 있는 경로를 필터링하여 경로와 양방향 신뢰 모델을 형성합니다.
다음 그림은 세 가지 안정적인 게이트웨이 API 종류의 관계를 보여줍니다.
GatewayClass
게이트웨이는 종종 다른 구성을 가진 여러 컨트롤러에 의해 구현될 수 있습니다. 게이트웨이는 해당 클래스를 구현하는 컨트롤러의 이름을 포함하는 GatewayClass를 참조해야 합니다.
다음은 최소한의 GatewayClass 예시입니다.
apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: example-class spec: controllerName: example.com/gateway-controller
이 예시는 게이트웨이 API를 구현한 컨트롤러는 컨트롤러 이름
example.com/gateway-controller
를 가진 GatewayClass를 관리하도록 구성됩니다. 이 클래스의 게이트웨이는 해당 구현의 컨트롤러에 의해 관리됩니다.GatewayClass에 대한 전체 정의는 https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass 에서 확인할 수 있습니다.
Gateway
게이트웨이는 트래픽 처리 인프라의 인스턴스를 설명합니다. 이는 서비스와 같은 백엔드에 대한 트래픽 필터링, 밸런싱, 분할 등을 처리하는 데 사용할 수 있는 네트워크 엔드포인트를 정의합니다. 예를 들어, 게이트웨이는 HTTP 트래픽을 수락하도록 구성된 클라우드 로드 밸런서 또는 클러스터 내 프록시 서버를 나타낼 수 있습니다.
다음은 최소한의 Gateway 예시입니다.
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: example-gateway spec: gatewayClassName: example-class listeners: - name: http protocol: HTTP port: 80
이 예시에서, 트래픽 처리 인프라의 인스턴스는 80번 포트에서 HTTP 트래픽을 수신하도록 프로그래밍됩니다.
addresses
필드가 지정되지 않았으므로, 주소 또는 호스트 이름은 구현 컨트롤러에 의해 게이트웨이에 할당됩니다. 이 주소는 경로에 정의된 백엔드 네트워크 엔드포인트의 트래픽 처리를 위한 네트워크 엔드포인트로 사용됩니다.Gateway에 대한 전체 정의는 https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Gateway 에서 확인할 수 있습니다.
HTTPRoute
HTTPRoute 종류는 게이트웨이 리스너로부터 백엔드 네트워크 엔드포인트로 HTTP 요청의 라우팅 동작을 지정합니다. 서비스 백엔드의 경우, 구현은 백엔드 네트워크 엔드포인트를 서비스 IP 또는 서비스의 지원 엔드포인트로 나타낼 수 있습니다. HTTPRoute는 기본 게이트웨이 구현에 적용되는 구성을 나타냅니다. 예를 들어, 새 HTTPRoute를 정의하면 클라우드 로드 밸런서 또는 클러스터 내 프록시 서버에 추가 트래픽 경로를 구성할 수 있습니다.
다음은 최소한의 HTTPRoute 예시입니다.
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: example-httproute spec: parentRefs: - name: example-gateway hostnames: - "www.example.com" rules: - matches: - path: type: PathPrefix value: /login backendRefs: - name: example-svc port: 8080
이 예시에서,
Host
헤더가www.example.com
으로 설정되고 요청 경로가/login
으로 지정된 게이트웨이example-gateway
의 HTTP 트래픽은 8080 포트의 서비스example-svc
로 라우팅됩니다.HTTPRoute에 대한 전체 정의는 https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRoute에서 확인할 수 있습니다.
요청 흐름
다음은 게이트웨이와 HTTPRoute를 사용하여 HTTP 트래픽을 서비스로 라우팅하는 간단한 예제입니다.
이 예시에서 리버스 프록시로 구현된 게이트웨이의 요청 흐름은 다음과 같습니다.
- 클라이언트는
http://www.example.com
URL에 대한 HTTP 요청 준비를 시작합니다. - 클라이언트의 DNS 해석기는 대상 이름에 대한 쿼리를 수행하고 게이트웨이와 연결된 하나 이상의 IP 주소에 대한 매핑을 학습합니다.
- 클라이언트는 게이트웨이 IP 주소로 요청을 보냅니다. 역방향 프록시는 HTTP 요청을 수신하고
Host
헤더를 사용하여 게이트웨이에서 파생되어 연결된 HTTPRoute에서 파생된 구성을 매치합니다. - (선택 사항) 역방향 프록시는 HTTPRoute의 매치 규칙에 따라 요청 헤더 및/또는 경로 매칭을 수행할 수 있습니다.
- (선택 사항) 역방향 프록시는 HTTPRoute의 필터 규칙에 따라 요청을 수정할 수 있습니다 (예: 헤더 추가 또는 제거).
- 마지막으로, 역방향 프록시는 요청을 하나 이상의 백엔드로 전달합니다.
궁금증
로드밸런서 없이 인그레스가 요청을 받을 수 있는지?
할 순 있지만 권장하는 방법은 아닙니다. 인그레스는 호스팅, 경로 기반에 따라 다른 서비스로 트래픽을 라우팅하고 TLS/SSL 암호화 처리하여 보안 연결을 제공합니다. 서비스를 NodePort 또는 HostPort 유형으로 노출하거나 인그레스 규칙에 따라 트래픽을 라우팅하는 인그레스 컨트롤러가 필요합니다.
트래픽이 증가하면 라우팅하는 인그레스도 늘려야 하는지?
인그레스 자체는 트래픽을 처리하는 로드 밸런서가 아니기 때문에 트래픽 증가에 직접적으로 영향을 받지는 않습니다. 하지만 인그레스 컨트롤러와 백엔드 서비스는 트래픽 증가에 따라 확장되어야 합니다.
인그레스 컨트롤러는 인그레스 규칙에 따라 트래픽을 라우팅하는 역할을 합니다. 트래픽이 증가하면 인그레스 컨트롤러의 CPU 및 메모리 사용량이 증가할 수 있습니다. 따라서 인그레스 컨트롤러의 파드 수를 수동이나 HPA로 늘려서 트래픽 처리 능력을 확장해야 합니다.
백엔드 서비스는 실제 트래픽을 처리하는 애플리케이션입니다. 트래픽이 증가하면 백엔드 서비스의 파드 수를 늘려 트래픽 처리 능력을 확장해야 합니다.
인그레스 클래스가 없으면 어떤 문제가 있는지?
Ingress 클래스는 Ingress 컨트롤러가 Ingress 리소스를 해석하고 트래픽을 라우팅하는 데 필요한 정보를 제공합니다. 하지만 몇 가지 상황에서는 Ingress 클래스 없이도 트래픽 처리가 가능할 수 있습니다.
$ kubectl get ingress -n {namespace} NAME CLASS HOSTS ADDRESS PORTS AGE elasticsearch <none> * 172.11.0.66 80 23d
위 명령어를 입력 후, CLASS 부분에 이라고 되어 있으면 인그레스 클래스가 없는 것입니다.
IngressClass가 없는 경우 발생하는 문제점은 다음과 같습니다.
IngressClass는 Ingress를 어떻게 처리할지 정의하는 리소스입니다. IngressClass가 없으면 다음과 같은 문제가 발생할 수 있습니다.
- 어떤 Ingress 컨트롤러가 Ingress를 처리해야 하는지 알 수 없습니다. Ingress 컨트롤러는 Ingress 리소스에 정의된 규칙에 따라 트래픽을 라우팅하는 역할을 합니다. IngressClass가 없으면 어떤 컨트롤러가 Ingress를 처리해야 하는지 불분명해집니다.
- 예상치 못한 동작이 발생할 수 있습니다. Ingress 컨트롤러가 IngressClass 없이도 Ingress를 처리할 수 있도록 구성되어 있다면, 예상치 못한 동작이 발생할 수 있습니다.
- 문제 해결이 어려워집니다. 문제가 발생했을 때 어떤 Ingress 컨트롤러에서 문제가 발생했는지 파악하기 어려워 문제 해결에 더 많은 시간이 소요될 수 있습니다.
IngressClass가 있는지는 다음 명령어로 확인할 수 있습니다.
$ kubectl get ingressclasses
만약 Ingress 클래스없이도 운영을 잘했다면 다음과 같은 이유일 수 있습니다.
- 기본 Ingress 컨트롤러: 일부 환경(특히 클라우드 환경)에서는 기본 Ingress 컨트롤러가 자동으로 배포 및 구성되어 Ingress 클래스 없이도 Ingress 리소스를 처리할 수 있습니다. 이 경우, Ingress 리소스는 암묵적으로 기본 Ingress 컨트롤러에 의해 관리됩니다.
- 특정 Ingress 컨트롤러 설정: 일부 Ingress 컨트롤러는 Ingress 클래스 없이도 Ingress 리소스를 처리하도록 구성될 수 있습니다. 예를 들어, Nginx Ingress Controller는
-watch-ingress-without-class
플래그를 사용하여 Ingress 클래스 없이 Ingress 리소스를 감시하도록 설정할 수 있습니다. - 간단한 라우팅 규칙: Ingress 리소스에 정의된 라우팅 규칙이 매우 단순한 경우, Ingress 컨트롤러가 Ingress 클래스 없이도 트래픽을 처리할 수 있습니다. 예를 들어, 모든 트래픽을 특정 서비스로 라우팅하는 규칙만 있는 경우 Ingress 클래스가 필수가 아닐 수 있습니다.
GKE 기준
GKE에서는 기본적으로 Google Cloud HTTP(S) Load Balancer를 인그레스 컨트롤러로 사용합니다. 이 로드 밸런서는 GKE 클러스터와 통합되어 인그레스 리소스에 정의된 규칙에 따라 트래픽을 라우팅하는 역할을 합니다.
Ingress 리소스에
ingressClassName
필드를 명시하지 않으면 GKE는 다음과 같은 방식으로 트래픽을 처리합니다.- 기본 IngressClass 사용: GKE 클러스터에는 기본 IngressClass가 자동으로 생성되어 있습니다. 이 IngressClass는 Google Cloud HTTP(S) Load Balancer를 사용하도록 구성되어 있습니다.
- 암묵적 연결: Ingress 리소스에
ingressClassName
필드가 없으면 GKE는 암묵적으로 기본 IngressClass를 사용하여 트래픽을 처리합니다. 즉, 별도의 설정 없이도 Google Cloud HTTP(S) Load Balancer를 통해 트래픽이 라우팅됩니다.
HTTPS를 사용할 때, 도메인을 Ingress의 TLS에 등록하지 않고도 사용 가능한지?
크게 Ingress의 TLS 기능을 사용하는 방법과 로드 밸런서에 직접 도메인을 등록하는 방법이 있습니다.
Ingress TLS 기능을 사용하면 로드밸런서 ↔ 인그레스 컨트롤러 간 통신할 때도 HTTPS를 사용하므로 보안에 좋습니다. 단점으로는 당연히 로드 밸런서와 함께 사용해야 하며 Ingress 컨트롤러, Ingress 리소스, Secret 등 여러 리소스를 함께 설정해야 하므로 초기 설정이 다소 복잡할 수 있습니다. Ingress의 TLS를 사용한다 해도 로드밸런서에 도메인과 외부 IP, 로드 밸런서의 IP 연결 설정이 필요합니다.
로드 밸런서에만 등록해 사용하면 설정이 비교적 간단합니다. 단점으로는 클라이언트 ↔ 로드 밸런서 간 HTTPS 통신을 사용하고 로드밸런서 ↔ 인그레스 컨트롤러 간 통신에선 HTTP를 사용합니다.
보안 강화 측면으로 봤을 때, 인그레스 TLS를 설정하는 것이 낫고 보안을 크게 강화하지 않아도 된다면 로드 밸런서에 직접 등록하여 사용하는 것이 좋습니다.
Ingress VS 게이트웨이 API
Ingress와 게이트웨이 API는 Kubernetes 환경에서 외부 트래픽을 내부 서비스로 라우팅하는 데 사용되는 리소스로 둘 다 비슷한 역할을 수행하지만, 몇 가지 중요한 차이점을 가지고 있습니다.
기능 인그레스(Ingress) 게이트웨이 API(Gateway API) 역사 Kubernetes 초기부터 존재 Kubernetes 1.18부터 도입 기능 HTTP/HTTPS 트래픽 라우팅에 특화 HTTP/HTTPS 외 다양한 프로토콜 지원 (TCP/UDP, gRPC 등) 확장성 기능 확장에 한계 사용자 정의 리소스(CRD)를 통해 확장 가능 유연성 라우팅 규칙 설정에 제한적 헤더 기반 매칭, 트래픽 가중치 등 고급 라우팅 기능 지원 역할 기반 클러스터 운영자 중심 인프라 제공자, 클러스터 운영자, 애플리케이션 개발자 등 다양한 역할 지원 구현 Ingress Controller를 통해 구현 Gateway Controller를 통해 구현 Ingress 장점으로는 비교적 간단한 설정 및 사용법과 대부분의 Ingress Controller에서 지원하는 것이 있고 단점으론 기능 확장에 제한적, 복잡한 트래픽 관리 시나리오에 어려움, 역할 기반 관리 미흡이 있습니다.
게이트웨이 API의 장점은 높은 확장성 및 유연성, 다양한 프로토콜 지원, 고급 라우팅 기능, 역할 기반 관리가 있고 단점으론 인그레스에 비해 비교적 새로운 기술, 지원하는 컨트롤러가 아직 많지 않음 입니다.
간단한 HTTP/HTTPS 트래픽 라우팅, 기존 시스템과의 호환성 유지가 목표라면 Ingress를 사용하고 복잡한 트래픽 관리 시나리오, 다양한 프로토콜 지원, 서비스 메시(Istio 등)와의 통합, 미래 지향적인 아키텍처가 목표라면 게이트웨이 API를 사용하는 것이 좋습니다.
레퍼런스
https://kubernetes.io/docs/concepts/services-networking/ingress/
https://kubernetes.io/docs/concepts/services-networking/gateway/
https://cloud.google.com/kubernetes-engine/docs/concepts/ingress?hl=ko