인그레스를 사용한 부하 분산용 HTTP/2

이 페이지에서는 Kubernetes 인그레스서비스 객체를 사용하여 백엔드 서비스와의 통신에 HTTP/2를 사용하도록 외부 HTTP(S) 부하 분산기를 구성하는 방법을 보여줍니다. 이 기능은 Google Kubernetes Engine 버전 1.11.2부터 사용할 수 있습니다.

개요

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

부하 분산기에서 pod까지의 HTTP/2를 보여주는 다이어그램(확대하려면 클릭)

이 연습에서는 배포, 서비스, 인그레스를 만듭니다. 부하 분산기가 HTTP/2를 사용하여 애플리케이션과 통신하도록 지정하기 위해 서비스 매니페스트에 cloud.google.com/app-protocols 주석을 추가합니다. 그런 다음 서비스를 호출하고 애플리케이션이 HTTP/2 요청을 수신했는지 확인합니다.

시작하기 전에

시작하기 전에 다음 태스크를 수행했는지 확인합니다.

다음 방법 중 하나를 사용하여 기본 gcloud 설정을 진행합니다.

  • gcloud init를 사용하여 기본값 설정 과정을 진행합니다.
  • gcloud config를 사용하여 프로젝트 ID, 영역, 리전을 개별적으로 설정합니다.

gcloud init 사용

  1. gcloud init를 실행하고 다음 안내를 따르세요.

    gcloud init

    원격 서버에서 SSH를 사용하는 경우 --console-only 플래그를 사용하여 다음 명령어로 브라우저를 실행하지 못하게 할 수 있습니다.

    gcloud init --console-only
  2. 안내를 따라 gcloud에서 Google Cloud 계정을 사용하도록 승인합니다.
  3. 새 구성을 만들거나 기존 구성을 선택합니다.
  4. Google Cloud 프로젝트를 선택합니다.
  5. 기본 Compute Engine 영역을 선택합니다.

gcloud config 사용

  • 기본 프로젝트 ID를 설정합니다.
    gcloud config set project project-id
  • 영역 클러스터를 사용하는 경우 기본 컴퓨팅 영역을 설정합니다.
    gcloud config set compute/zone compute-zone
  • 리전 클러스터를 사용하는 경우 기본 컴퓨팅 리전을 설정합니다.
    gcloud config set compute/region compute-region
  • gcloud를 최신 버전으로 업데이트합니다.
    gcloud components update

배포 만들기

이 배포 매니페스트는 echoheaders 웹 애플리케이션의 두 복제본을 실행한다고 선언합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echoheaders
spec:
  replicas: 2
  selector:
    matchLabels:
      app: echoheaders
  template:
    metadata:
      labels:
        app: echoheaders
    spec:
      containers:
      - name: echoheaders
        image: k8s.gcr.io/echoserver:1.10
        ports:
        - containerPort: 8443

my-deployment.yaml 파일에 매니페스트를 복사하고 배포를 만듭니다.

kubectl apply -f my-deployment.yaml

서비스 만들기

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

apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/app-protocols: '{"my-port":"HTTP2"}'
  name: echoheaders
  labels:
    app: echoheaders
spec:
  type: NodePort
  ports:
  - port: 443
    targetPort: 8443
    protocol: TCP
    name: my-port
  selector:
    app: echoheaders

my-service.yaml라는 파일에 매니페스트를 저장하고 서비스를 만듭니다.

kubectl apply -f my-service.yaml

서비스를 확인합니다.

kubectl get service echoheaders --output yaml

출력은 다음과 비슷합니다.

apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/app-protocols: '{"my-port":"HTTP2"}'
    ...
  labels:
    app: echoheaders
  name: echoheaders
  ...
spec:
  clusterIP: 10.39.251.148
  ...
  ports:
  - name: my-port
    nodePort: 30647
    port: 443
    protocol: TCP
    targetPort: 8443
  selector:
    app: echoheaders
  ...
  type: NodePort
...

이 연습에서 서비스와 관련하여 유의해야 할 사항은 다음과 같습니다.

  • 서비스의 유형은 NodePort입니다. 이 유형은 인그레스에 연결되는 서비스에 필요합니다.

  • app: echoheaders 라벨이 있는 모든 pod가 서비스의 구성원입니다. selector 필드에 이 항목이 지정되어 있습니다.

  • 서비스에는 포트가 하나 있고 포트 이름은 my-port입니다. cloud.google.com/app-protocols 주석은 my-port HTTP/2 프로토콜을 사용해야 합니다.

  • TCP 포트 443에서 서비스로 전달되는 트래픽은 구성원 pod 중 하나에서 TCP 포트 8443으로 라우팅됩니다. porttargetPort 필드에 이 항목이 지정되어 있습니다.

인그레스 만들기

인그레스의 매니페스트는 다음과 같습니다.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: echomap
spec:
  backend:
    serviceName: echoheaders
    servicePort: 443

my-ingress.yaml라는 파일에 매니페스트를 복사하고 인그레스를 만듭니다.

kubectl apply -f my-ingress.yaml

Kubernetes 인그레스 컨트롤러가 HTTP(S) 부하 분산기를 구성할 때까지 몇 분 정도 기다린 후 인그레스를 확인합니다.

kubectl get ingress echomap --output yaml

출력은 다음과 비슷합니다.

kind: Ingress
metadata:
  ...
  name: echomap
  ...
spec:
  backend:
    serviceName: echoheaders
    servicePort: 443
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.2

이 연습에서 인그레스에 대해 알아 두어야 할 중요한 사항은 다음과 같습니다.

  • 들어오는 트래픽의 IP 주소는 loadBalancer:ingress 아래에 나열됩니다.

  • 들어오는 요청은 echoheaders 서비스의 구성원인 pod로 라우팅됩니다. 이 연습에서는 구성원 pod에 app: echoheaders 라벨을 포함합니다.

  • 요청은 echoheaders 서비스 매니페스트에서 지정된 대상 포트에 있는 pod로 라우팅됩니다. 이 연습에서 pod 대상 포트는 8443입니다.

부하 분산기가 HTTP/2를 지원하는지 확인

gcloud

  1. 백엔드 서비스를 나열합니다.

    gcloud compute backend-services list
    
  2. 백엔드 서비스를 설명합니다.

    gcloud beta compute backend-services describe backend-service-name --global
    

    여기서 backend-service-name은 백엔드 서비스의 이름입니다.

  3. 출력에서 프로토콜이 HTTP/2인지 확인합니다.

    backends:
    ...
    description: '{...,"kubernetes.io/service-port":"443","x-features":["HTTP2"]}'
    ...
    kind: compute#backendService
    loadBalancingScheme: EXTERNAL
    protocol: HTTP2
    ...
    

Console

  1. Google Cloud Console의 부하 분산 페이지로 이동합니다.

    부하 분산 페이지로 이동

  2. 이름 아래에서 부하 분산기를 찾습니다.

    Google Cloud Console에 표시되는 HTTP 부하 분산기 스크린샷을 클릭합니다(확대하려면 클릭).
  3. 부하 분산기의 이름을 클릭하여 백엔드 서비스를 확인합니다.

  4. 백엔드 서비스의 엔드포인트 프로토콜HTTP/2인지 확인합니다.

    Google Cloud Console에 표시된 HTTP/2 백엔드 서비스의 스크린샷(확대하려면 클릭).

서비스 호출

부하 분산기와 백엔드 서비스가 구성될 때까지 몇 분 정도 기다립니다. 브라우저의 주소 표시줄에 부하 분산기의 외부 IP 주소를 입력합니다.

출력은 부하 분산기에서 Pod로 전송되는 요청에 대한 정보를 보여줍니다.

Hostname: echoheaders-7886d5bc68-xnrwj
...
Request Information:
  ...
  method=GET
  real path=/
  query=
  request_version=2
  request_scheme=https
  ...

Request Headers:
  ...
  x-forwarded-for=[YOUR_IP_ADDRESS], 203.0.113.2
  x-forwarded-proto=http
...

이 연습에서 이전 출력에 대해 알아야 할 중요한 사항은 다음과 같습니다.

  • request_version=2는 부하 분산기와 Pod 사이의 요청이 HTTP/2를 사용했음을 나타냅니다.

  • x-forwarded-proto=http는 사용자와 부하 분산기 사이의 요청이 HTTP/2가 아닌 HTTP 1.1을 사용했음을 나타냅니다.

다음 단계