외부 부하 분산용 인그레스 구성

이 페이지에서는 Kubernetes 인그레스 객체를 만들어 외부 HTTP(S) 부하 분산기를 구성하는 방법을 설명합니다. 인그레스 객체는 각각 Pod 집합과 연결된 서비스 객체 한 개 이상과 연결되어야 합니다.

서비스 객체에는 servicePort 구조가 한 개 이상 있습니다. 인그레스에서 대상으로 지정된 각 servicePort는 Google Cloud 백엔드 서비스 리소스와 연결됩니다.

시작하기 전에

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

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

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

gcloud init 사용

One of [--zone, --region] must be supplied: Please specify location 오류가 표시되면 이 섹션을 완료합니다.

  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

여러 백엔드 서비스

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

이 연습에서는 외부 HTTP(S) 부하 분산기를 구성하여 URL 경로에 따라 서로 다른 백엔드 서비스로 요청을 라우팅합니다. 경로에 /가 있는 요청은 특정 백엔드 서비스로 라우팅되고, 경로에 /kube가 있는 요청은 다른 백엔드 서비스로 라우팅됩니다.

이 연습의 대략적인 단계는 다음과 같습니다.

  1. 배포를 만들고 hello-world라는 서비스로 노출합니다.
  2. 두 번째 배포를 만들고 hello-kubernetes라는 서비스로 노출합니다.
  3. 요청을 요청의 URL 경로에 따라 서비스 하나 또는 다른 서비스로 라우팅하는 규칙을 지정하는 인그레스를 만듭니다. 인그레스를 만들면 GKE 인그레스 컨트롤러가 외부 HTTP(S) 부하 분산기를 만들고 구성합니다.
  4. 외부 HTTP(S) 부하 분산기를 테스트합니다.

배포 만들기

첫 번째 배포의 매니페스트는 다음과 같습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world-deployment
spec:
  selector:
    matchLabels:
      greeting: hello
      department: world
  replicas: 3
  template:
    metadata:
      labels:
        greeting: hello
        department: world
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50000"

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

kubectl apply -f hello-world-deployment.yaml

서비스 만들기

다음은 첫 번째 배포를 노출하는 서비스의 매니페스트입니다.

apiVersion: v1
kind: Service
metadata:
  name: hello-world
spec:
  type: NodePort
  selector:
    greeting: hello
    department: world
  ports:
  - protocol: TCP
    port: 60000
    targetPort: 50000

이 연습을 진행하면서 이 서비스에 대해 반드시 알아야 할 사항은 다음과 같습니다.

  • greeting: hello 라벨과 department: world 라벨이 모두 있는 Pod는 서비스의 구성원입니다.

  • TCP 포트 60000의 서비스에 전송된 요청은 TCP 포트 50000의 구성원 포드 중 하나로 전달됩니다.

매니페스트를 hello-world-service.yaml 파일에 복사하고 서비스를 만듭니다.

kubectl apply -f hello-world-service.yaml

두 번째 배포 만들기

두 번째 배포의 매니페스트는 다음과 같습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes-deployment
spec:
  selector:
    matchLabels:
      greeting: hello
      department: kubernetes
  replicas: 3
  template:
    metadata:
      labels:
        greeting: hello
        department: kubernetes
    spec:
      containers:
      - name: hello-again
        image: "gcr.io/google-samples/node-hello:1.0"
        env:
        - name: "PORT"
          value: "8080"

hello-kubernetes-deployment.yaml이라는 파일에 매니페스트를 복사하고 배포를 만듭니다.

kubectl apply -f hello-kubernetes-deployment.yaml

두 번째 서비스 만들기

다음은 두 번째 배포를 노출하는 서비스의 매니페스트입니다.

apiVersion: v1
kind: Service
metadata:
  name: hello-kubernetes
spec:
  type: NodePort
  selector:
    greeting: hello
    department: kubernetes
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

이 연습을 진행하면서 이 서비스에 대해 반드시 알아야 할 사항은 다음과 같습니다.

  • greeting: hello 라벨과 department: kubernetes 라벨이 모두 있는 Pod는 서비스의 구성원입니다.

  • TCP 포트 80의 서비스에 전송된 요청은 TCP 포트 8080의 구성원 Pod 중 하나로 전달됩니다.

hello-kubernetes-service.yaml이라는 파일에 매니페스트를 복사하고 서비스를 만듭니다.

kubectl apply -f hello-kubernetes-service.yaml

인그레스 만들기

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

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    # If the class annotation is not specified it defaults to "gce".
    kubernetes.io/ingress.class: "gce"
spec:
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: hello-world
          servicePort: 60000
      - path: /kube
        backend:
          serviceName: hello-kubernetes
          servicePort: 80

이 실습을 진행하면서 이 인그레스 매니페스트에 대해 반드시 알아야 할 사항은 다음과 같습니다.

  • GKE 인그레스에 사용할 수 있는 인그레스 클래스에는 두 가지가 있습니다. gce 클래스는 외부 부하 분산기를 배포하고 gce-internal 클래스는 내부 부하 분산기를 배포합니다. 클래스가 없는 인그레스 리소스의 기본값은 gce로 설정됩니다.

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

    보다 구체적인 패턴이 덜 구체적인 패턴보다 우선합니다. /foo/*/foo/bar/*가 있다면 /foo/bar/*에 맞춰 /foo/bar/bat가 사용됩니다. 경로 제한사항과 패턴 일치에 대한 자세한 내용은 URL 맵 문서를 참조하세요.

  • 인그레스 매니페스트에는 쌍이 두 개(serviceName, servicePort) 있습니다. 각 (serviceName, servicePort)는 Google Cloud 백엔드 서비스와 연결됩니다.

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

kubectl apply -f my-ingress.yaml

인그레스를 만들면 GKE 인그레스 컨트롤러가 외부 HTTP(S) 부하 분산기를 만들고 다음과 같이 부하 분산기를 구성합니다.

  • 클라이언트가 URL 경로 /를 사용하는 부하 분산기로 전송한 요청은 포트 60000의 hello-world 서비스로 전달됩니다.

  • 클라이언트가 URL 경로 /kube를 사용하는 부하 분산기로 전송한 요청은 포트 80의 hello-kubernetes 서비스로 전달됩니다.

부하 분산기가 구성될 때까지 5분 정도 기다립니다.

외부 HTTP(S) 부하 분산기 테스트

외부 HTTP(S) 부하 분산기를 테스트하려면 다음 안내를 따르세요.

  1. 인그레스를 확인합니다.

    kubectl get ingress my-ingress --output yaml
    

    출력에 외부 HTTP(S) 부하 분산기의 IP 주소가 표시됩니다.

    status:
      loadBalancer:
        ingress:
        - ip: 203.0.113.1
    
  2. / 경로를 테스트합니다.

    curl load-balancer-ip/
    

    load-balancer-ip를 부하 분산기의 외부 IP 주소로 바꿉니다.

    출력에 Hello, world! 메시지가 표시됩니다.

    Hello, world!
    Version: 2.0.0
    Hostname: ...
    
  3. /kube 경로를 테스트합니다.

    curl load-balancer-ip/kube
    

    출력에 Hello Kubernetes! 메시지가 표시됩니다.

    Hello Kubernetes!
    

클라이언트와 부하 분산기 간 HTTPS

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

HTTP 중지

클라이언트와 부하 분산기 간의 모든 트래픽에 HTTPS를 사용하려면 HTTP를 중지하면 됩니다. 자세한 내용은 HTTP 중지를 참조하세요.

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

GKE Pod에서 실행되는 애플리케이션이 HTTPS 요청을 수신할 수 있으면 부하 분산기가 요청을 애플리케이션으로 전달할 때 HTTPS를 사용하도록 구성할 수 있습니다. 자세한 내용은 부하 분산기와 애플리케이션 간 HTTPS(TLS)를 참조하세요.

클라이언트와 부하 분산기 간 HTTP/2

클라이언트는 HTTP/2를 사용하여 부하 분산기에 요청을 보낼 수 있습니다. 별도로 구성할 필요는 없습니다.

부하 분산기와 애플리케이션 간 HTTP/2

GKE Pod에서 실행되는 애플리케이션이 HTTP/2 요청을 수신할 수 있으면 부하 분산기가 요청을 애플리케이션으로 전달할 때 HTTP/2를 사용하도록 구성할 수 있습니다. 자세한 내용은 인그레스를 사용한 부하 분산용 HTTP/2를 참조하세요

네트워크 엔드포인트 그룹

클러스터가 컨테이너 기반 부하 분산을 지원하는 경우 네트워크 엔드포인트 그룹(NEG)을 사용하는 것이 좋습니다. GKE 클러스터 1.17 이후 및 특정 조건에서는 컨테이너 기반 부하 분산이 기본적으로 사용되므로 명시적인 cloud.google.com/neg: '{"ingress": true}' 서비스 주석이 필요하지 않습니다.

외부 인그레스 주석 요약

인그레스 주석

주석 설명
kubernetes.io/ingress.allow-http 클라이언트와 HTTP(S) 부하 분산기 간에 HTTP 트래픽을 허용할지 여부를 지정합니다. 가능한 값은 'true', 'false'입니다. 기본값은 'true'입니다. HTTP 중지를 참조하세요.
ingress.gcp.kubernetes.io/pre-shared-cert Google Cloud 프로젝트에 인증서와 키를 업로드할 수 있습니다. 이 주석을 사용하여 인증서와 키를 참조합니다. HTTP(S) 부하 분산에서 여러 SSL 인증서 사용을 참조하세요.
kubernetes.io/ingress.global-static-ip-name 이 주석을 사용하여 부하 분산기에서 이전에 만든 고정 외부 IP 주소를 사용하도록 지정합니다. HTTP(S) 부하 분산기의 고정 IP 주소를 참조하세요.
networking.gke.io/v1beta1.FrontendConfig 이 주석을 사용하여 부하 분산기의 클라이언트 연결 구성을 맞춤설정합니다. 자세한 내용은 인그레스 기능을 참조하세요.
주석 설명
service.alpha.kubernetes.io/app-protocols 이 주석을 사용하여 부하 분산기와 애플리케이션 간의 통신 프로토콜을 설정합니다. 가능한 프로토콜은 HTTP, HTTPS, HTTP/2입니다. 부하 분산기와 애플리케이션 간 HTTPS인그레스를 사용한 부하 분산용 HTTP/2를 참조하세요.
beta.cloud.google.com/backend-config 이 주석을 사용하여 servicePort와 연결된 백엔드 서비스를 구성합니다. 자세한 내용은 인그레스 기능을 참조하세요.
cloud.google.com/neg 이 주석을 사용하여 부하 분산기에서 네트워크 엔드포인트 그룹을 사용하도록 지정합니다. 컨테이너 기반 부하 분산 사용을 참조하세요.

다음 단계