Cloud Run for Anthos on Google Cloud を使用した HTTP(S) 負荷分散の統合

このチュートリアルでは、ネットワーク負荷分散ではなく、Cloud Run for Anthos on Google Cloud サービスで HTTP(S) 負荷分散を使用して、インターネット上にサービスを公開する方法について説明します。

HTTP(S) 負荷分散はグローバルな負荷分散を行い、Google Cloud ArmorCloud CDNIdentity-Aware Proxy(IAP)、HTTPS 用のマネージド TLS 証明書などのさまざまな Google Cloud プロダクトや機能と連携します。

Kubernetes Ingress と Istio Ingress ゲートウェイ

このチュートリアルでは、名前が似ている 2 つの関連コンセプトについて説明します。このチュートリアルでは、次の点に注意してください。

  • Istio Ingress ゲートウェイは、外部 HTTP / TCP トラフィックを Kubernetes クラスタ内のサービスにルーティングするためのルールを定義します。Istio Ingress ゲートウェイは Kubernetes ServiceKubernetes Deployment として実装されます。
  • Kubernetes Ingress は、クラスタ内の 1 つ以上の Kubernetes Service に外部 HTTP(S) トラフィックをルーティングするためのルールを定義します。GKE クラスタで Kubernetes Ingress オブジェクトを作成すると、GKE は HTTP(S) 負荷分散に必要なリソースをプロビジョニングします。

このチュートリアルでは、Kubernetes Ingress リソースを使用して外部トラフィックを Istio Ingress ゲートウェイに転送します。次に、以下の図に示すように、Istio Ingress ゲートウェイがクラスタ内のサービスにトラフィックをルーティングします。

外部 HTTP / TCP トラフィックのルーティングを表す図

Istio Ingress ゲートウェイを使用して、同じ GKE クラスタ内の複数のサービスにルーティングできます。

目標

  • GKE クラスタを作成して Cloud Run を有効にする。
  • ヘルスチェック リクエストを処理する Istio 仮想サービスを作成する。
  • Kubernetes Ingress オブジェクトで公開されるように、Istio Ingress ゲートウェイの Kubernetes Service オブジェクトを変更する。
  • Kubernetes Ingress オブジェクトを作成して HTTP(S) 負荷分散を構成する。
  • サンプル サービスをデプロイしてソリューションを確認する。

費用

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。新しい Google Cloud ユーザーは無料トライアルをご利用いただけます。

このチュートリアルを終了した後、作成したリソースを削除すると、それ以上の請求は発生しません。詳しくは、クリーンアップをご覧ください。

始める前に

  1. Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタのページに移動

  2. Cloud プロジェクトに対する課金を有効にします

  3. GKE, Cloud Run, and Google Cloud APIs を有効にします。

    API を有効にする

  4. Cloud Console で Cloud Shell を開きます。

    Cloud Shell を開く

    Cloud Console の下部で Cloud Shell セッションが開き、コマンドライン プロンプトが表示されます。Cloud Shell はシェル環境です。gcloud コマンドライン ツールなどの Cloud SDK がすでにインストールされており、現在のプロジェクトの値もすでに設定されています。セッションが初期化されるまで数秒かかることがあります。

    このチュートリアルでは、コマンドの実行はすべて Cloud Shell で行います。

Cloud Run を使用して GKE クラスタを作成する

  • Cloud Run アドオンを使用して GKE クラスタを作成する。

    CLUSTER=cloudrun-gke-gclb-tutorial
    ZONE=us-central1-f
    
    gcloud beta container clusters create $CLUSTER \
        --addons HorizontalPodAutoscaling,HttpLoadBalancing,CloudRun \
        --enable-ip-alias \
        --enable-stackdriver-kubernetes \
        --machine-type n1-standard-2 \
        --zone $ZONE
    

    このチュートリアルでは、cloudrun-gke-gclb-tutorial をクラスタ名と us-central1-f ゾーンとして使用します。これらの値は変更できます。詳細については、地域とリージョンをご覧ください。

    コマンドのオプションの意味は次のとおりです。

    • HttpLoadBalancing アドオンを使用すると、Kubernetes Ingress オブジェクトでクラスタの HTTP(S) 負荷分散を構成できます。

    • --enable-ip-alias オプションは、クラスタを VPC ネイティブにします。 このチュートリアルで紹介するコンテナ ネイティブの負荷分散を使用する場合は、このオプションは必須です。

    • --enable-stackdriver-kubernetes オプションは、GKE 用 Cloud オペレーションを使用して、クラスタのログ、イベント、指標を集約します。Cloud Run アドオンを使用する場合、このオプションは必須です。

ヘルスチェック リクエストの処理

  • Istio 仮想サービスを作成します。これにより、クラスタが負荷分散ヘルスチェック リクエストに応答する際に、Istio Ingress ゲートウェイのステータス エンドポイントにそのリクエストが転送されるようになります。

    作成している仮想サービスは、gke-system-gateway Istio ゲートウェイ リソースに関連付けられます。これは、Cloud Run アドオンによってインストールされます。

    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: health
      namespace: knative-serving
    spec:
      gateways:
      - gke-system-gateway
      hosts:
      - "*"
      http:
      - match:
        - headers:
            user-agent:
              prefix: GoogleHC
          method:
            exact: GET
          uri:
            exact: /
        rewrite:
          authority: istio-ingress.gke-system.svc.cluster.local:15020
          uri: /healthz/ready
        route:
        - destination:
            host: istio-ingress.gke-system.svc.cluster.local
            port:
              number: 15020
    EOF
    

Kubernetes Ingress で使用する Istio Ingress ゲートウェイに修正を加える

  1. Istio Ingress ゲートウェイに修正を加えるために、JSON パッチファイルを作成します。

    cat <<EOF > istio-ingress-patch.json
    [
      {
        "op": "replace",
        "path": "/spec/type",
        "value": "NodePort"
      },
      {
        "op": "remove",
        "path": "/status"
      }
    ]
    EOF
    
  2. パッチファイルを適用し、Istio Ingress ゲートウェイをバックエンドとして追加します。

    kubectl -n gke-system patch svc istio-ingress \
        --type=json -p="$(cat istio-ingress-patch.json)" \
        --dry-run=true -o yaml | kubectl apply -f -
    kubectl annotate svc istio-ingress -n gke-system cloud.google.com/neg='{"exposed_ports": {"80":{}}}'
    

    このパッチでは、Istio Ingress ゲートウェイの Kubernetes Service オブジェクトに次の修正を加えます。

Kubernetes Ingress オブジェクトの作成

  1. my-ingress という Kubernetes Ingress オブジェクトを作成します。

    kubectl apply -f - <<EOF
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: my-ingress
      namespace: gke-system
    spec:
      backend:
        serviceName: istio-ingress
        servicePort: 80
    EOF
    

    この Ingress オブジェクトは、すべての受信トラフィックを gke-system Namespace 内の istio-ingress Kubernetes Service に送信します。

    GKE クラスタで Kubernetes Ingress オブジェクトを作成すると、GKE は HTTP(S) 負荷分散に必要なリソースを作成します。

  2. 上記のコマンドの進行状況を確認します。my-ingress ADDRESS が IP アドレスに変わるまで待ちます。

    kubectl get ingress my-ingress -n gke-system --watch
    

    待機を停止するには、Control+C を押します。

  3. Kubernetes Ingress オブジェクトの IP アドレスを格納する環境変数を作成します。

    INGRESS_IP=$(kubectl get ingress my-ingress -n gke-system \
        --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
    

サービスのデプロイとソリューションの確認

  1. Cloud Run for Anthos on Google Cloud に my-service というサンプル サービスをデプロイします。

    gcloud run deploy my-service \
        --namespace default \
        --image gcr.io/knative-samples/simple-api \
        --platform gke \
        --cluster $CLUSTER \
        --cluster-location $ZONE
    

    Kubernetes Ingress オブジェクトの作成後に HTTP(S) 負荷分散がルーティングできるようになるまで数分かかる場合があります。その間に、クラスタ内のサービスにリクエストを送信すると、HTTP/1.1 404 Not FoundHTTP/1.1 502 Bad Gateway などのエラーが発生することがあります。

  2. サンプル サービスに HTTP GET リクエストを 2 秒ごとに送信します。

    while sleep 2; do
      curl -siH "Host: my-service.default.example.com" $INGRESS_IP | head -n1
    done
    

    次のような結果が表示されるまで、出力をモニタリングします。

    HTTP/1.1 200 OK
    

    リクエストの送信を停止するには、Control+C を押します。

  3. サンプル サービスに HTTP GET リクエストを送信します。

    curl -s -w"\n" -H "Host: my-service.default.example.com" $INGRESS_IP
    

    次のような出力が表示されます。

    OK
    

トラブルシューティング

このチュートリアルで問題が発生した場合は、次のドキュメントをご覧ください。

クリーンアップ

このチュートリアルで使用したリソースの Google Cloud アカウントが変更されないようにするには、このチュートリアル用に作成した Cloud プロジェクトを削除するか、このチュートリアルに関連付けられたリソースを削除します。

Cloud プロジェクトの削除

課金を停止する最も簡単な方法は、チュートリアル用に作成した Cloud プロジェクトを削除することです。

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] ページに移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

リソースの削除

このチュートリアルで使用した Cloud プロジェクトを保持する場合は、GKE クラスタを削除します。

```
gcloud container clusters delete $CLUSTER --zone $ZONE --async --quiet
```

次のステップ