관리형 Anthos Service Mesh의 외부 HTTP(S) 부하 분산 구성

개요

Cloud Load Balancing은 글로벌 Anycast 부하 분산, Google 관리 인증서, ID 및 액세스 관리, 클라우드 방화벽 또는 IDS를 비롯하여 다양한 클라우드 관리 에지 기능을 제공합니다. Anthos Service Mesh는 다음 메시 인그레스 모델에서 이러한 에지 기능을 원활하게 통합할 수 있습니다. 서비스 메시 클라우드 게이트웨이는 Kubernetes Gateway API를 통해 Cloud Load Balancing과 동시에 Anthos Service Mesh 인그레스 게이트웨이를 통합적으로 구성하는 방법을 제공합니다.

Anthos Service Mesh를 사용하는 Cloud 부하 분산기를 보여주는 다이어그램

이전 사용자 가이드인 서비스 메시 클라우드 게이트웨이를 사용하는 에지에서 메시로: GKE 인그레스를 통해 서비스 메시 애플리케이션 노출과 비교하여 이 모델을 하나의 Kubernetes 게이트웨이 리소스를 통해 배포할 수 있으므로 클라우드 및 클러스터 호스팅 부하 분산의 배포 프로세스를 간소화할 수 있습니다.

미리보기 제한사항

이 기능의 미리보기 출시 버전에는 다음 제한사항이 적용됩니다.

  • 멀티 클러스터 게이트웨이는 지원되지 않습니다.
  • Autopilot 클러스터는 지원되지 않습니다.
  • 기본 애플리케이션 부하 분산기만 지원됩니다. 고급 부하 분산기 및 내부 HTTP(S) 부하 분산기는 지원되지 않습니다.
  • 외부 HTTP(S) 부하 분산기와 Anthos Service Mesh 인그레스 게이트웨이 간의 트래픽은 TLS로 암호화됩니다. 하지만 외부 HTTP(S) 부하 분산기는 Anthos Service Mesh 인그레스 게이트웨이에서 제공하는 인증서를 확인하지 않습니다. 이 제한사항은 Google Cloud HTTP(S) 부하 분산기의 모든 사용자에게 적용됩니다.
  • 클러스터에서 삭제된 Anthos Service Mesh GatewayClasses는 자동으로 다시 설치되지 않습니다. 그러나 기능의 사용성에는 영향이 없습니다.
  • 경로 일치 논리는 Gateway API 사양을 따르지 않으며 대신 HTTPRoute 순서로 일치합니다. 게이트웨이 API 사양을 따르도록 이후 버전에서 변경될 예정입니다.

요구사항

  • 1.24 이상을 실행하는 Google Kubernetes Engine(GKE) 클러스터에 설치된 관리형 Anthos Service Mesh. 다른 GKE Enterprise 클러스터는 지원되지 않습니다.
  • Kubernetes Gateway API v1beta1 버전만 지원됩니다.

기본 요건

  • 프로젝트에 다음 API 사용 설정:

    • compute.googleapis.com
    • container.googleapis.com
    • certificatemanager.googleapis.com
    • serviceusage.googleapis.com
    gcloud services enable \
       compute.googleapis.com \
       container.googleapis.com \
       certificatemanager.googleapis.com \
       serviceusage.googleapis.com
    

단일 클러스터 메시에 서비스 메시 클라우드 게이트웨이 배포

이 섹션에서는 전역 외부 HTTP(S) 부하 분산기(기본) 및 Anthos Service Mesh 인그레스 게이트웨이를 배포하는 Kubernetes 게이트웨이 리소스를 배포하는 방법을 보여줍니다.

관리형 Anthos Service Mesh로 Gateway API 사용 설정

  1. 클러스터에서 Gateway API를 사용 설정합니다. GKE 클러스터는 1.24 버전 이상이어야 합니다.

  2. rapid 또는 regular를 출시 채널로 관리형 Anthos Service Mesh를 설치합니다.

게이트웨이 리소스 배포

서비스 메시 클라우드 게이트웨이를 배포할 때 Kubernetes 게이트웨이 리소스는 Cloud Load Balancing 및 Anthos Service Mesh 인그레스 게이트웨이를 모두 단일 단계로 배포하는 데 사용됩니다. Kubernetes 게이트웨이 리소스는 Istio 게이트웨이 리소스와 다릅니다.

차이점에 대한 자세한 내용은 Kubernetes 게이트웨이 및 Istio 게이트웨이를 참조하세요. 모든 Kubernetes 게이트웨이에는 유형과 고유한 기능을 나타내는 GatewayClass가 있습니다. 서비스 메시 클라우드 게이트웨이에는 Cloud Load Balancing 및 Anthos Service Mesh 인그레스 게이트웨이를 모두 배포할 수 있는 GatewayClass가 있습니다.

  1. 다음 GatewayClass 매니페스트를 l7-gateway-class.yaml이라는 파일에 저장합니다.

    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: GatewayClass
    metadata:
      name: asm-l7-gxlb
    spec:
      controllerName: mesh.cloud.google.com/gateway
    
  2. 클러스터에 GatewayClass를 배포합니다.

    kubectl apply -f l7-gateway-class.yaml
    
  3. 설치 후 GatewayClass가 존재하는지 확인합니다.

    kubectl get gatewayclasses.gateway.networking.k8s.io
    

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

    NAME          CONTROLLER
    asm-l7-gxlb   mesh.cloud.google.com/gateway
    gke-l7-rilb   networking.gke.io/gateway
    gke-l7-gxlb   networking.gke.io/gateway
    

    모든 리소스가 배포되려면 몇 분 정도 걸릴 수 있습니다. 예상한 출력이 표시되지 않으면 기본 요건을 올바르게 충족했는지 확인합니다.

    다음 GatewayClass도 표시됩니다.

    gke-l7-gxlb   networking.gke.io/gateway
    

    기본 Google Cloud 전역 외부 HTTP(S) 부하 분산기를 배포하는 데 사용됩니다.

  4. 서비스 메시 클라우드 게이트웨이의 전용 네임스페이스를 만듭니다.

    kubectl create namespace istio-ingress
    
  5. 다음 게이트웨이 매니페스트를 gateway.yaml이라는 파일에 저장합니다.

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: servicemesh-cloud-gw
      namespace: istio-ingress
    spec:
      gatewayClassName: asm-l7-gxlb
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          namespaces:
            from: All
    
  6. istio-ingress 네임스페이스의 클러스터에 게이트웨이를 배포합니다.

    kubectl apply -f gateway.yaml
    
  7. Kubernetes Gateway API 객체가 생성되었는지 확인합니다.

    kubectl get gateways.gateway.networking.k8s.io -n istio-ingress
    

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

    NAME                                CLASS         ADDRESS         READY   AGE
    asm-gw-gke-servicemesh-cloud-gw     gke-l7-gxlb   34.111.114.64   True    9m40s
    asm-gw-istio-servicemesh-cloud-gw   istio                                 9m44s
    servicemesh-cloud-gw                asm-l7-gxlb                           9m44s
    

이 Kubernetes Gateway API 객체가 배포되면 다음과 같은 결과가 발생합니다.

  • 외부 HTTP(S) 부하 분산기가 배포되고 구성됩니다. 이를 표시하는 데 몇 분 정도 걸릴 수 있지만 이 경우 게이트웨이가 IP 주소를 표시하고 생성된 Compute Engine 부하 분산기 리소스의 이름으로 주석을 추가합니다.
  • Anthos Service Mesh 인그레스 게이트웨이 배포는 istio-ingress 네임스페이스에 생성됩니다. 이렇게 하면 Cloud 부하 분산기에서 트래픽을 수신하는 Envoy 프록시 인스턴스가 생성됩니다.
  • Cloud 부하 분산기는 모든 트래픽을 Anthos Service Mesh 인그레스 게이트웨이로 암호화 및 라우팅합니다.

이제 메시로 인터넷 트래픽을 허용하는 데 필요한 전체 인프라가 준비되었습니다. 이는 가장 간단한 게이트웨이 배포입니다. 다음 섹션에서는 프로덕션을 준비할 수 있는 추가 정책과 기능을 추가합니다.

앱 및 라우팅 배포

애플리케이션을 Anthos Service Mesh에 배포하고 예시 목적으로 게이트웨이를 통해 인터넷 트래픽을 수신하여 기능을 완전히 시연합니다.

  1. 사이드카 삽입을 사용 설정하려면 default 네임스페이스에 라벨을 지정합니다.

    kubectl label namespace default istio-injection=enabled istio.io/rev- --overwrite
    
  2. 다음 게이트웨이 매니페스트를 whereami.yaml이라는 파일에 저장합니다.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whereami-v1
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: whereami-v1
      template:
        metadata:
          labels:
            app: whereami-v1
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20
            ports:
              - containerPort: 8080
            env:
            - name: METADATA
              value: "whereami-v1"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: whereami-v1
    spec:
      selector:
        app: whereami-v1
      ports:
      - port: 8080
        targetPort: 8080
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whereami-v2
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: whereami-v2
      template:
        metadata:
          labels:
            app: whereami-v2
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20
            ports:
              - containerPort: 8080
            env:
            - name: METADATA
              value: "whereami-v2"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: whereami-v2
    spec:
      selector:
        app: whereami-v2
      ports:
      - port: 8080
        targetPort: 8080
    

    이 매니페스트는 JSON을 출력하여 ID와 위치를 표시하는 간단한 애플리케이션인 whereami용 Service/whereami-v1, Service/whereami-v2, Deployment/whereami-v1, Deployment/whereami-v2를 만듭니다. 두 가지 버전을 배포합니다.

  3. 서비스 및 배포 생성:

    kubectl apply -f whereami.yaml
    

    준비되어 실행되면 클러스터에 4개의 whereami 포드가 생깁니다.

  4. 4개의 포드가 모두 실행 중인지 확인하세요.

    kubectl get pods
    

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

    whereami-v1-7c76d89d55-qg6vs       2/2     Running   0          28s
    whereami-v1-7c76d89d55-vx9nm       2/2     Running   0          28s
    whereami-v2-67f6b9c987-p9kqm       2/2     Running   0          27s
    whereami-v2-67f6b9c987-qhj76       2/2     Running   0          27s
    
  5. 다음 HTTPRoute 매니페스트를 http-route.yaml이라는 파일에 저장합니다.

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: where-route
    spec:
     parentRefs:
     - kind: Gateway
       name: servicemesh-cloud-gw
       namespace: istio-ingress
     hostnames:
     - "where.example.com"
     rules:
     - matches:
       - headers:
         - name: version
           value: v2
       backendRefs:
       - name: whereami-v2
         port: 8080
     - backendRefs:
       - name: whereami-v1
         port: 8080
    
  6. 클러스터에 http-route.yaml을 배포합니다.

    kubectl apply -f http-route.yaml
    

    이 HTTPRoute는 servicemesh-cloud-gw를 참조하여, 이러한 라우팅 규칙으로 기본 Anthos Service Mesh 인그레스 게이트웨이를 구성하도록 서비스 메시 클라우드 게이트웨이를 구성합니다. HTTPRoute는 Istio VirtualService와 동일한 기능을 수행하지만 Kubernetes Gateway API를 사용하여 이를 수행합니다. Gateway API는 여러 기본 구현이 포함된 OSS 사양이므로 서로 다른 부하 분산기(예: Anthos Service Mesh 프록시 및 Cloud 부하 분산기)의 조합에서 라우팅을 정의하는 데 가장 적합한 API입니다.

  7. 애플리케이션에 트래픽을 전송할 수 있도록 게이트웨이에서 IP 주소를 검색합니다.

    VIP=$(kubectl get gateways.gateway.networking.k8s.io asm-gw-gke-servicemesh-cloud-gw -o=jsonpath="{.status.addresses[0].value}" -n istio-ingress)
    

    출력은 IP 주소입니다.

    echo $VIP
    
    34.111.61.135
    
  8. 게이트웨이 IP 주소로 트래픽을 전송하여 이 설정이 올바르게 작동하는지 확인합니다. 두 애플리케이션 버전에서 라우팅이 올바르게 수행되었는지 확인하기 위해 version: v2 헤더가 포함된 요청 하나와 헤더가 없는 요청 하나를 보냅니다.

    curl ${VIP} -H "host: where.example.com"
    
    {
      "cluster_name": "gke1",
      "host_header": "where.example.com",
      "metadata": "whereami-v1",
      "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal",
      "pod_name": "whereami-v1-67d9c5d48b-zhr4l",
      "pod_name_emoji": "⚒",
      "project_id": "church-243723",
      "timestamp": "2021-02-08T18:55:01",
      "zone": "us-central1-a"
    }
    
    curl ${VIP} -H "host: where.example.com" -H "version: v2"
    
    {
      "cluster_name": "gke1",
      "host_header": "where.example.com",
      "metadata": "whereami-v2",
      "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal",
      "pod_name": "whereami-v2-67d9c5d48b-zhr4l",
      "pod_name_emoji": "⚒",
      "project_id": "church-243723",
      "timestamp": "2021-02-08T18:55:01",
      "zone": "us-central1-a"
    }
    

프로덕션 게이트웨이 배포

이전 섹션에서는 서비스 메시 클라우드 게이트웨이의 매우 간단한 예시를 설명했습니다. 다음 단계에서는 인그레스 라우팅 기능 중 일부를 Cloud 부하 분산기에 위임하는 이점에 대한 프로덕션 지원 설정을 보여주는 간단한 예시를 바탕으로 빌드되었습니다.

다음 예시에서는 이전 섹션의 servicemesh-cloud-gw를 가져와서 다음 기능을 추가하여 보다 안전하고 관리 가능한 게이트웨이를 만듭니다.

  • 기본 인프라가 변경되더라도 보존되는 고정 IP 주소로 게이트웨이를 배포합니다.
  • 자체 서명 인증서로 HTTPS 트래픽을 수신하도록 게이트웨이를 변환합니다.
  1. 고정 외부 IP 주소를 만듭니다. 이후에 IP 주소를 유지하면서 기본 인프라가 변경되는 경우도 있으므로 고정 IP가 유용합니다.

    gcloud compute addresses create whereami-ip \
        --global \
        --project PROJECT_ID
    
  2. where-example-com 도메인에 자체 서명 인증서를 만듭니다.

    openssl genrsa -out key.pem 2048
    cat <<EOF >ca.conf
    [req]
    default_bits              = 2048
    req_extensions            = extension_requirements
    distinguished_name        = dn_requirements
    prompt                    = no
    [extension_requirements]
    basicConstraints          = CA:FALSE
    keyUsage                  = nonRepudiation, digitalSignature, keyEncipherment
    subjectAltName            = @sans_list
    [dn_requirements]
    0.organizationName        = example
    commonName                = where.example.com
    [sans_list]
    DNS.1                     = where.example.com
    EOF
    
    openssl req -new -key key.pem \
        -out csr.pem \
        -config ca.conf
    
    openssl x509 -req \
        -signkey key.pem \
        -in csr.pem \
        -out cert.pem \
        -extfile ca.conf \
        -extensions extension_requirements \
        -days 365
    
    gcloud compute ssl-certificates create where-example-com \
        --certificate=cert.pem \
        --private-key=key.pem \
        --global \
        --project PROJECT_ID
    

    TLS 인증서는 여러 방법으로 생성됩니다. 명령줄에서 수동으로 생성하거나, Google 관리 인증서를 사용하여 생성하거나, 회사의 공개 키 인프라(PKI) 시스템에 따라 내부적으로 생성할 수도 있습니다. 이 예시에서는 자체 서명된 인증서를 수동으로 생성합니다. 자체 서명 인증서는 일반적으로 공개 서비스에 사용되지 않지만, 이러한 개념을 보다 쉽게 보여줍니다.

    Kubernetes 보안 비밀을 통해 자체 서명 인증서를 만드는 방법에 대한 자세한 내용은 게이트웨이 보호를 참조하세요.

  3. 다음 매니페스트로 gateway.yaml을 업데이트합니다.

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: servicemesh-cloud-gw
      namespace: istio-ingress
    spec:
      gatewayClassName: asm-l7-gxlb
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          namespaces:
            from: All
      - name: https
        protocol: HTTPS
        port: 443
        allowedRoutes:
          namespaces:
            from: All
        tls:
          mode: Terminate
          options:
            networking.gke.io/pre-shared-certs: where-example-com
      addresses:
      - type: NamedAddress
        value: whereami-ip
    
  4. 클러스터에 게이트웨이를 다시 배포합니다.

    kubectl apply -f gateway.yaml
    
  5. 고정 IP의 IP 주소를 가져옵니다.

    VIP=$(gcloud compute addresses describe whereami-ip --global --format="value(address)")
    
  6. curl을 사용하여 게이트웨이의 도메인에 액세스합니다. DNS가 이 도메인에 대해 구성되지 않았기 때문에 확인 옵션을 사용하여 curl이 게이트웨이의 IP 주소로 도메인 이름을 확인하도록 지시합니다.

    curl https://where.example.com --resolve where.example.com:443:${VIP} --cacert cert.pem -v
    

    완료되면 출력은 다음과 비슷합니다.

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=where.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: where.example.com (matched)
    *  issuer: O=example; CN=where.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gke1",
      "host_header": "where.example.com",
      "metadata": "where-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "where-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08",
      "zone": "us-west1-a"
    }
    

상세 출력에는 다음 출력과 같이 성공한 TLS 핸드셰이크와 이후 애플리케이션 응답이 포함됩니다. 이것은 TLS가 게이트웨이에서 올바르게 종료되고 있고, 애플리케이션이 클라이언트에 안전하게 응답하고 있음을 증명합니다.

다음 아키텍처를 성공적으로 배포했습니다.

ASM 아키텍처

servicemesh-cloud-gwasm-l7-gxlb GatewayClass는 사용자 환경을 단순화하기 위해 일부 내부 인프라 구성요소를 추상화했습니다. Cloud Load Balancing은 내부 인증서를 사용하여 TLS 트래픽을 종료하고 Anthos Service Mesh 인그레스 게이트웨이 프록시 레이어의 상태도 점검합니다. 앱 및 라우팅 배포에 배포된 whereami-route는 Anthos Service Mesh 인그레스 게이트웨이 프록시를 올바른 메시 호스팅 서비스로 트래픽을 라우팅하도록 구성합니다.

다음 단계