Ingress를 사용한 HTTP(S) 부하 분산

Google Kubernetes Engine에서 Ingress 객체는 외부 HTTP(S) 트래픽을 클러스터에서 실행되는 애플리케이션으로 라우팅하기 위한 규칙을 정의합니다. Ingress 객체는 각각 포드 집합에 연결된 하나 이상의 서비스 객체에 연결됩니다.

Ingress 객체를 만들면 GKE Ingress 컨트롤러Google Cloud Platform HTTP(S) 부하 분산기를 만들고 Ingress 및 연결된 서비스의 정보에 따라 부하 분산기를 구성합니다.

HTTP(S) 부하 분산의 특징

Ingress에 의해 구성되는 HTTP(S) 부하 분산의 특징은 다음과 같습니다.

서비스를 위한 유연한 구성
Ingress는 트래픽이 서비스에 도달하는 방법과 트래픽이 애플리케이션으로 라우팅되는 방법을 정의합니다. 또한 Ingress는 클러스터의 여러 서비스를 위한 단일 IP 주소를 제공할 수 있습니다.
GCP 네트워크 서비스와의 통합
Ingress는 Cloud Armor, Cloud Content Delivery Network, Cloud Identity-Aware Proxy 같은 GCP 기능을 구성할 수 있습니다.
여러 TLS 인증서 지원
Ingress는 요청 종료를 위한 여러 TLS 인증서의 사용을 지정할 수 있습니다.

이러한 특징에 대한 자세한 내용은 HTTP(S) 부하 분산 개념을 참조하세요.

제한사항

HTTP(S) 부하 분산은 부하 분산기와 백엔드 서비스 간 통신을 위한 WebSocket 프로토콜을 지원하지 않습니다.

여러 백엔드 서비스

HTTP(S) 부하 분산기는 다양한 백엔드 서비스로 요청을 라우팅하는 데 사용할 수 있는 안정적인 IP 주소 하나를 제공합니다.

예를 들어 URL 경로에 따라 서로 다른 백엔드 서비스로 요청을 라우팅하도록 부하 분산기를 구성할 수 있습니다. your-store.example로 전송되는 요청은 정가 품목을 표시하는 백엔드 서비스로 라우팅될 수 있고, your-store.example/discount로 전송되는 요청은 할인 품목을 표시하는 백엔드 서비스로 라우팅될 수 있습니다.

호스트 이름에 따라 요청을 라우팅하도록 부하 분산기를 구성할 수도 있습니다. your-store.example로 전송되는 요청과 your-experimental-store.example로 전송되는 요청은 서로 다른 백엔드 서비스로 라우팅될 수 있습니다.

GKE 클러스터에서는 Kubernetes Ingress 객체를 만들어 HTTP(S) 부하 분산기를 만들고 구성합니다. Ingress 객체는 각각 포드 집합에 연결된 하나 이상의 서비스 객체에 연결되어야 합니다.

Ingress의 매니페스트는 다음과 같습니다.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: my-products
          servicePort: 60000
      - path: /discounted
        backend:
          serviceName: my-discounted-products
          servicePort: 80

Ingress를 만들면 GKE Ingress 컨트롤러는 Ingress 및 연결된 서비스에 있는 정보에 따라 HTTP(S) 부하 분산기를 만들고 구성합니다. 또한 부하 분산기에는 도메인 이름과 연결할 수 있는 안정적인 IP 주소가 제공됩니다.

앞의 예에서 부하 분산기의 IP 주소를 도메인 이름 your-store.example에 연결했다고 가정해 보세요. 클라이언트가 your-store.example에 전송하는 요청은 포트 60000에서 my-products라는 Kubernetes 서비스로 라우팅됩니다. 클라이언트가 your-store.example/discount에 전송하는 요청은 포트 80에서 my-discounted-products라는 Kubernetes 서비스로 라우팅됩니다.

Ingress의 path 필드에서 지원되는 유일한 와일드카드 문자는 * 문자입니다. * 문자는 슬래시(/) 다음에 와야 하며, 패턴의 마지막 문자여야 합니다. 예를 들어 /*, /foo/*, /foo/bar/*는 유효한 패턴이지만 *, /foo/bar*, /foo/*/bar는 아닙니다.

보다 구체적인 패턴이 덜 구체적인 패턴보다 우선합니다. /foo/*/foo/bar/*가 있다면 /foo/bar/*에 맞춰 /foo/bar/bat가 사용됩니다.

경로 제한사항과 패턴 일치에 대한 자세한 내용은 URL 맵 문서를 참조하세요.

my-products 서비스의 매니페스트는 다음과 같습니다.

apiVersion: v1
kind: Service
metadata:
  name: my-products
spec:
  type: NodePort
  selector:
    app: products
    department: sales
  ports:
  - protocol: TCP
    port: 60000
    targetPort: 50000

서비스 매니페스트에서 typeNodePort임에 유의하세요. 이것은 HTTP(S) 부하 분산기를 구성하는 데 사용되는 Ingress에 필요한 유형입니다.

서비스 매니페스트에서 selector 필드는 app: products 라벨과 department: sales 라벨이 모두 있는 포드가 이 서비스의 구성원임을 나타냅니다.

포트 60000에서 서비스에 도달하는 요청은 TCP 포트 50000에서 구성원 포드 중 하나로 라우팅됩니다.

각 구성원 포드에는 TCP 포트 50000에서 수신 대기하는 컨테이너가 있어야 합니다.

my-discounted-products 서비스의 매니페스트는 다음과 같습니다.

apiVersion: v1
kind: Service
metadata:
  name: my-discounted-products
spec:
  type: NodePort
  selector:
    app: discounted-products
    department: sales
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

서비스 매니페스트에서 selector 필드는 app: discounted-products 라벨과 department: sales 라벨이 모두 있는 포드가 이 서비스의 구성원임을 나타냅니다.

포트 80에서 서비스에 도달하는 요청은 TCP 포트 8080에서 구성원 포드 중 하나로 라우팅됩니다.

각 구성원 포드에는 TCP 포트 8080에서 수신 대기하는 컨테이너가 있어야 합니다.

상태 확인

Ingress를 통해 노출되는 서비스는 부하 분산기의 상태 확인에 응답해야 합니다. 부하 분산된 트래픽의 최종 목적지인 모든 컨테이너는 정상 상태임을 표시하기 위해 다음 중 하나를 수행해야 합니다.

  • / 경로에서 GET 요청에 대해 HTTP 200 상태가 포함된 응답을 제공합니다.

  • HTTP 준비 프로브를 구성합니다. 준비 프로브가 지정하는 path 경로에서 GET 요청에 대해 HTTP 200 상태가 포함된 응답을 제공합니다.

    예를 들어 컨테이너가 다음 준비 프로브를 지정한다고 가정해 보세요.

    ...
    readinessProbe:
      httpGet:
        path: /healthy
    

    그런 다음 컨테이너의 /healthy 경로에 대한 핸들러가 HTTP 200 상태를 반환하면 부하 분산기는 컨테이너가 활성 상태이고 정상이라고 간주합니다.

Kubernetes 서비스와 GCP 백엔드 서비스 비교

A Kubernetes 서비스GCP 백엔드 서비스는 서로 다릅니다. 둘 사이에는 강한 관계가 있지만 이 관계가 꼭 일대일 관계는 아닙니다. GKE Ingress 컨트롤러는 Ingress 매니페스트에서 각 (serviceName, servicePort) 쌍을 위한 GCP 백엔드 서비스를 만듭니다. 따라서 Kubernetes 서비스 객체 하나가 여러 GCP 백엔드 서비스와 관련될 수 있습니다.

GCP 기능 지원

BackendConfig를 사용하여 Cloud Armor, Cloud CDN, Cloud IAP 같은 기능을 사용하도록 HTTP(S) 부하 분산기를 구성할 수 있습니다.

BackendConfig는 GCP 기능의 구성 정보를 보존하는 커스텀 리소스입니다.

Ingress 매니페스트는 서비스를 참조하고, 서비스 매니페스트는 beta.cloud.google.com/backend-config 주석을 사용하여 BackendConfig를 참조합니다.

...
kind: Ingress
...
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80
...

kind: Service
metadata:
  name: my-service
  ...
  annotations:
    beta.cloud.google.com/backend-config: '{"ports": {"80":"my-backend-config"}}'
spec:
  type: NodePort
  ...
 

HTTP(S) 부하 분산기용 고정 IP 주소

Ingress 객체를 만들면 클라이언트가 서비스 및 실행 중인 컨테이너에 액세스하는 데 사용할 수 있는 안정적인 외부 IP 주소를 얻게 됩니다. 이 IP 주소는 Ingress 객체의 수명 동안 지속된다는 점에서 안정적입니다. Ingress를 삭제하고 동일한 매니페스트 파일에서 새 Ingress를 만드는 경우, 동일한 외부 IP 주소를 얻게 된다고 보장할 수 없습니다.

Ingress를 삭제하고 새 Ingress를 만들어도 동일하게 유지되는 영구 IP 주소를 원한다면 전역 고정 외부 IP 주소를 예약해야 합니다. 그런 다음 Ingress 매니페스트에서 예약된 고정 IP 주소의 이름을 제공하는 주석을 포함시킵니다.

예를 들어 이름이 my-static-address인 전역 고정 외부 IP 주소를 예약했다고 가정해 보세요. Ingress 매니페스트에서 여기 나온 것처럼 kubernetes.io/ingress.global-static-ip-name 주석을 포함시킵니다.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: my-static-address

Ingress의 고정 외부 IP 주소를 만드는 자세한 방법은 고정 IP 주소 구성고정 IP 주소로 도메인 이름 구성을 참조하세요.

클라이언트와 부하 분산기 간 HTTPS(TLS) 설정

HTTP(S) 부하 분산기는 클라이언트와 애플리케이션 사이의 프록시 역할을 합니다. 클라이언트의 HTTPS 요청을 수락하려는 경우, 부하 분산기에 인증서가 있어야 부하 분산기가 클라이언트에게 ID를 증명할 수 있습니다. HTTPS 핸드셰이크를 완료하려면 부하 분산기에 비공개 키도 있어야 합니다.

부하 분산기가 클라이언트의 HTTPS 요청을 수락하면 클라이언트와 부하 분산기 간 트래픽은 TLS를 사용하여 암호화됩니다. 하지만 부하 분산기는 TLS 암호화를 종료하고 암호화 없이 요청을 애플리케이션에 전달합니다. 부하 분산기와 애플리케이션 간 트래픽을 암호화하는 방법은 부하 분산기와 애플리케이션 간 HTTPS를 참조하세요.

HTTP(S) 부하 분산기에게 인증서와 키를 제공하려면 Ingress 매니페스트의 tls 필드에서 Kubernetes 보안 비밀의 이름을 지정하면 됩니다. 이전에 만든 이 보안 비밀은 인증서와 키를 보존합니다.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress-2
spec:
  tls:
  - secretName: my-secret
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: my-metrics
          servicePort: 60000

보안 비밀을 사용하여 부하 분산기에게 인증서를 제공하는 자세한 방법은 Ingress를 사용한 HTTP(S) 부하 분산에서 여러 SSL 인증서 사용을 참조하세요.

부하 분산기용 사전 공유된 인증서

HTTP(S) 종료를 위해 Kubernetes 보안 비밀을 사용하여 부하 분산기에게 인증서를 제공하는 대신 이전에 GCP 프로젝트에 업로드한 인증서를 사용할 수 있습니다. 자세한 내용은 사전 공유된 인증서 사용Ingress를 사용한 HTTP(S) 부하 분산에서 여러 SSL 인증서 사용을 참조하세요.

부하 분산기와 애플리케이션 간 HTTPS(TLS)

HTTP(S) 부하 분산기는 클라이언트와 애플리케이션 사이의 프록시 역할을 합니다. 클라이언트는 HTTP 또는 HTTPS를 사용하여 부하 분산기 프록시와 통신할 수 있습니다. 하지만 부하 분산기 프록시에서 애플리케이션까지의 연결은 기본적으로 HTTP를 사용합니다. GKE 포드에서 실행되는 애플리케이션이 HTTPS 요청을 수신할 수 있는 경우, 요청을 애플리케이션으로 전달할 때 HTTPS를 사용하도록 부하 분산기를 구성할 수 있습니다.

부하 분산기와 애플리케이션 사이에서 사용되는 프로토콜을 구성하려면 서비스 매니페스트에서 cloud.google.com/app-protocols 주석을 사용하세요.

다음 서비스 매니페스트는 두 포트를 지정합니다. 주석은 HTTP(S) 부하 분산기가 서비스의 포트 80을 대상으로 지정하는 경우, HTTP를 사용해야 한다고 말합니다. 또 부하 분산기가 서비스의 포트 443을 대상으로 지정하는 경우에는 HTTPS를 사용해야 합니다.

apiVersion: v1
kind: Service
metadata:
  name: my-service-3
  annotations:
    cloud.google.com/app-protocols: '{"my-https-port":"HTTPS","my-http-port":"HTTP"}'
spec:
  type: NodePort
  selector:
    app: metrics
    department: sales
  ports:
  - name: my-https-port
    port: 443
    targetPort: 8443
  - name: my-http-port
    port: 80
    targetPort: 50001

cloud.google.com/app-protocols 주석의 용도는 이전 service.alpha.kubernetes.io/app-protocols 주석과 동일합니다. 다음 서비스 매니페스트에 나온 것처럼 이전 주석 이름과 새 주석 이름은 공존할 수 있습니다. 같은 서비스 매니페스트에 두 주석이 모두 나타나는 경우, service.alpha.kubernetes.io/app-protocols가 우선적으로 적용됩니다.

apiVersion: v1
kind: Service
metadata:
  name: my-service-3
  annotations:
    cloud.google.com/app-protocols: '{"my-https-port":"HTTPS","my-http-port":"HTTP"}'
    service.alpha.kubernetes.io/app-protocols: '{"my-first-port":"HTTPS","my-second-port":"HTTP"}'
spec:
  type: NodePort
  selector:
    app: metrics
    department: sales
  ports:
  - name: my-first-port
    port: 443
    targetPort: 8443
  - name: my-second-port
    port: 80
    targetPort: 50001

여러 TLS 인증서 사용

HTTP(S) 부하 분산기로 your-store.example과 your-experimental-store.example이라는 두 호스트 이름에서 콘텐츠를 제공하려 한다고 가정해 보세요. 또한 부하 분산기가 your-store.example과 your-experimental-store.example에 각기 다른 인증서를 사용하도록 하려 합니다.

Ingress 매니페스트에서 여러 인증서를 지정할 수 있으며, 부하 분산기는 인증서의 일반 이름(CN)이 요청에서 사용되는 호스트 이름과 일치하면 인증서를 선택합니다. 여러 인증서를 구성하는 자세한 방법은 Ingress를 사용한 HTTP(S) 부하 분산에서 여러 SSL 인증서 사용을 참조하세요.

다음 단계

이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

Kubernetes Engine