
【GKE再入門】GKE Autopilotクラスタ上にNginxをデプロイしてGlobal external Application Load Balancer経由で外部からアクセスしてみた
はじめに
こんにちは。
コンサルティング部の渡邉です。
Google Kubernetes Engine (GKE) を久しぶりに触る機会があるため、GKE Autopilotクラスタ上にNginxをデプロイし、Global external Application Load Balancer経由で外部からアクセスできる環境を構築して再入門しようと思います。
GKEでWebアプリケーションを外部に公開する際、KubernetesのGateway API(Gateway + HTTPRoute)リソースを作成すると、GKE Gatewayコントローラーが自動的にGoogle CloudのApplication Load Balancerを構成してくれます。私がGKEの運用をしていたときはIngressが標準でしたが、Gateway APIは従来のIngressの後継としてKubernetesコミュニティが策定した次世代の標準であり、GKEでも新規構築では Gateway APIの使用が推奨されています。特にAutopilotクラスタでは Container-native load balancing(NEG ベース) がデフォルトで有効になっており、ロードバランサーからPodに直接トラフィックを送信する効率的な構成が手軽に実現できます。
本記事では、構築の過程で登場するGKEやKubernetesの各種コンポーネントについても解説しています。
全体アーキテクチャ
今回構築する構成の全体像は以下の通りです。
上の図では、左側がクライアントからロードバランサーへのアクセスの流れ、右側がGKE Autopilotクラスタ内のKubernetesリソースとPodの関係を表しています。
Kubernetesリソースの一部は、GKE Autopilot上に作成すると、対応するGoogle Cloudのリソースも同時に作成されます。
- Gateway(
nginx-gateway)を作成すると、GKE GatewayコントローラーがGoogle Cloud上のLoad BalancerリソースであるForwarding Rule・Target HTTP Proxy・URL Map・Backend Service・Health Checkを自動的に作成・構成します。 - HTTPRoute(
nginx-httproute)が Gatewayにアタッチされ、トラフィックのルーティング先(Service)を定義します。 - Service(
nginx-service)をバックエンドとして、対応する NEG が自動作成されます。 - Deployment(
nginx-deployment)がNginx Podのレプリカを管理し、NEGが各 Podのエンドポイント(IP:port)を追跡します。 - クライアントからのトラフィックはForwarding Rule → Target HTTP Proxy → URL Map → Backend Service → NEG → Podという経路で流れます。
GKE Autopilot とは
GKE Autopilotとは、Googleが推奨するGKEの運用モードです。ノードの管理をGoogleに任せることで、ユーザーはアプリケーションのデプロイに集中できます。
GKEにはAutopilotとStandardの2つの運用モードがあります。
| 項目 | Autopilot | Standard |
|---|---|---|
| ノード管理 | Google が自動管理(プロビジョニング・スケーリング・アップグレード・修復) | ユーザーが管理(ノードプールの作成・サイズ変更・アップグレードなど) |
| スケーリング | Pod 数に応じてノードが自動スケール(ワークロードがない場合はゼロノードまでスケールダウン) | Cluster Autoscaler を有効化すればノード自動スケール可能。ただしノードプールの設定はユーザーが管理 |
| セキュリティ | デフォルトで強化されたセキュリティ設定が適用(特権コンテナの制限、ホストネットワーク使用不可など) | ユーザーが個別に設定。特権コンテナやホストネットワークも利用可能 |
| ネットワーク | VPC ネイティブクラスタのみ。Container-native load balancing がデフォルトで有効 | VPC ネイティブ / ルートベースを選択可能 |
| 料金 | Pod が要求したリソース(CPU・メモリ)に基づく課金 | ノード(VM)のリソースに対して課金。Pod の有無に関わらずノードが起動していれば課金 |
| カスタマイズ性 | 制限あり(マシンタイプの直接指定不可、DaemonSet に制約ありなど) | ノードプール単位でマシンタイプ・GPU・ローカル SSD 等を自由に選択可能 |
| SLA | コントロールプレーンと Pod の計算容量の両方をカバーする SLA | コントロールプレーンのみ SLA 対象(Pod の可用性はユーザーの設計に依存) |
| 適したケース | 運用負荷を最小化したい場合、標準的なワークロード | ノードレベルの細かい制御が必要な場合、GPU / TPU ワークロード、特殊な要件がある場合 |
GoogleはAutopilotを推奨運用モードとしています。特にノード管理の運用負荷を減らしたい場合や、標準的なWebアプリケーションのデプロイではAutopilotが適しています。
一方で、GPU を使用した機械学習ワークロードやノードの細かいチューニングが必要な場合はStandardが適しています。
Global external Application Load Balancer とは
Global external Application Load Balancer は、Google Cloudが提供する HTTP(S) ロードバランサーの一種です。GFE(Google Front End)上に実装されたグローバルなマネージドサービスであり、世界中に分散配置されたエッジロケーションでトラフィックを終端します。
| 項目 | 内容 |
|---|---|
| 動作モード | グローバル(Premium Tier) |
| 実装 | Google Front End(GFE) + Envoy プロキシ |
| 対応プロトコル | HTTP/1.1、HTTP/2、WebSocket |
| 主な機能 | Cloud CDN 統合、Cloud Armor 統合、トラフィック管理(ミラーリング・重み付け分割) |
| GKE 連携 | Gateway API(推奨)、Ingress、または Standalone NEG(手動オーケストレーション) |
GKEではGatewayリソースを作成すると、GKE Gatewayコントローラーが自動的にGlobal ALBを構成してくれるため、ユーザーが個々のロードバランサーコンポーネントを手動で作成する必要はありません。
Container-native load balancing(NEG)
GKE Autopilotクラスタでは、Gateway APIやIngress経由でサービスを公開する際にContainer-native load balancingがデフォルトで有効になります。これは Network Endpoint Group(NEG) を使用して、ロードバランサーからPodのIPアドレスに直接トラフィックを送信する仕組みです。
NEG を使用することで以下のメリットがあります。
- パフォーマンス向上: kube-proxy のネットワーキングをバイパスし、Podに直接トラフィックを送信するため、レイテンシとスループットが改善。
- ヘルスチェックの強化: Pod readiness gateにより、ロードバランサーの観点からPodの正常性を判断。
- 可視性の向上: ロードバランサーから各Podへのレイテンシが個別に確認可能
Autopilot クラスタでは、Gateway APIを使用する場合、GKE Gatewayコントローラーが HTTPRouteのbackendRefsで参照されたServiceに対して自動的にNEGを作成・管理します。
Kubernetes リソースの基本
本記事で使用する主要なKubernetesリソース(Pod・Deployment・Service・Gateway・HTTPRoute)について解説します。
Pod
Pod は、Kubernetesにおけるデプロイの最小単位です。1つ以上のコンテナをまとめたグループであり、同じPod内のコンテナはネットワーク名前空間とストレージボリュームを共有します。
Podは障害やスケーリングによって削除・再作成されるリソースであるため、Podを直接作成するのではなく、次に説明するDeploymentなどの上位リソースを通じて管理するのが一般的です。
Deployment
Deploymentは、Podのレプリカ数などを宣言的に管理するリソースです。「この Pod を何個維持するか」を定義すると、Kubernetesが常にその状態を維持するように動作します。
Deploymentの主な機能は以下のとおりです。
| 機能 | 説明 |
|---|---|
| レプリカ管理 | replicas フィールドで指定した数の Pod を常に維持。Pod が異常終了した場合は自動的に新しい Pod を起動 |
| ローリングアップデート | コンテナイメージの変更時に、Pod を段階的に新バージョンへ入れ替え。maxSurge(超過可能な Pod 数)と maxUnavailable(停止可能な Pod 数)で更新速度を制御 |
| ロールバック | 更新に問題があった場合、kubectl rollout undo で以前の ReplicaSet へ即座に戻せる |
| スケーリング | kubectl scale コマンドや HPA(Horizontal Pod Autoscaler)と連携して、レプリカ数を動的に変更可能 |
Deploymentは内部でReplicaSetを自動作成し、ReplicaSetが実際のPodを管理します。更新が発生すると新しいReplicaSetが作成され、古いReplicaSetのPodを段階的に縮小しながら新しいReplicaSet のPodを拡大することで、ダウンタイムのない更新を実現します。
本記事では以下のように Deployment を定義しています。
spec:
replicas: 2 # Pod を 2 つ維持
selector:
matchLabels:
app: nginx # このラベルを持つ Pod を管理対象とする
template:
metadata:
labels:
app: nginx # Pod に付与するラベル(selector と一致させる)
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
selector.matchLabels と template.metadata.labels は一致させる必要があります。Deployment はこのラベルを使って管理すべきPodを識別します。
Service
Service は、動的に変化するPodのセットに対して安定したネットワークエンドポイントを提供するリソースです。
PodはスケーリングやアップデートのたびにIPアドレスが変わるため、他のサービスやロードバランサーがPodに直接アクセスするのは困難です。Serviceはラベルセレクターで対象のPodを動的に追跡し、一つの安定した仮想IP(ClusterIP)とDNS 名でアクセスできるようにします。
Service には複数のタイプがあり、用途に応じて使い分けます。
| タイプ | 説明 | 用途 |
|---|---|---|
| ClusterIP | クラスタ内部のみからアクセス可能な仮想 IP を割り当て。デフォルトのタイプ | クラスタ内のサービス間通信、Gateway API + NEG 構成 |
| NodePort | 各ノードの指定ポートで外部からアクセス可能にする。ClusterIP も自動作成される | 開発・テスト環境での簡易的な外部公開 |
| LoadBalancer | クラウドプロバイダーのロードバランサー(L4)を自動作成。NodePort と ClusterIP も自動作成される | L4 ロードバランサーによる外部公開 |
本記事では ClusterIP を使用しています。従来のロードバランシングではNodePortが必要でしたが、Autopilotクラスタでは Container-native load balancing(NEG)がデフォルトで有効なため、ロードバランサーがPod IPに直接トラフィックを送信します。そのためNodePortを経由する必要がなく、ClusterIPで十分です。
本記事の Service 定義のポイントは以下の通りです。
spec:
type: ClusterIP
selector:
app: nginx # app=nginx ラベルを持つ Pod にトラフィックを転送
ports:
- port: 80 # Service が受け付けるポート
targetPort: 80 # Pod 内コンテナのポートへ転送
selector.app: nginx は、Deploymentの template.metadata.labels で定義した app: nginx と一致します。これにより、ServiceはDeploymentが管理するPodを自動的にバックエンドとして認識します。
Gateway API(Gateway + HTTPRoute)
Gateway APIは、クラスタ外部からのHTTP(S)トラフィックをクラスタ内のServiceにルーティングするためのKubernetes標準APIです。従来のIngressの後継として登場しました。LoadBalancerタイプのServiceがTCP/UDPレベルのL4ロードバランシングを提供するのに対し、Gateway APIはアプリケーション層のL7で動作し、URLパスやホスト名に基づいたルーティングが可能です。
Gateway APIでは、従来Ingressが1つのリソースで担っていた役割を Gateway と HTTPRoute の2つのリソースに分離しています。
| リソース | 役割 |
|---|---|
| Gateway | ロードバランサーのポート・プロトコル・リスナーなどのフロントエンド定義。GatewayClass を指定することでロードバランサーの種類を決定 |
| HTTPRoute | トラフィックのパス・ホスト名に基づく振り分けなどのルーティングルールを定義。Gateway にアタッチして使用 |
GKE ではGKE Gateway コントローラーがデフォルトで有効になっており、Gatewayリソースを作成すると自動的に Google CloudのApplication Load Balancerを構成します。使用する GatewayClass によって作成されるロードバランサーの種類が決まります。
| GatewayClass | ロードバランサー |
|---|---|
gke-l7-global-external-managed |
Global external Application Load Balancer(推奨) |
gke-l7-regional-external-managed |
Regional external Application Load Balancer |
gke-l7-rilb |
Internal Application Load Balancer |
gke-l7-gxlb |
Classic Application Load Balancer |
Ingress との比較
Gateway API はIngressの上位互換であり、GKEでは新規構築にGateway APIの使用が推奨されています。
| 観点 | Ingress | Gateway API |
|---|---|---|
| リソース構造 | 1 つのリソースにフロントエンドとルーティングが混在 | Gateway(フロントエンド)と HTTPRoute(ルーティング)に分離 |
| マルチテナンシー | 制限的 | Gateway と Route を異なるチーム・Namespace で管理可能 |
| ルーティング機能 | パス・ホストベース | パス・ホストベースに加えて、トラフィック分割(重み付け)、ヘッダーマッチ、リダイレクトなど |
| 拡張性 | アノテーション依存(実装ごとに異なる) | Policy リソースによる標準化された拡張 |
| Kubernetes 標準 | レガシー標準 | SIG-Network が策定した次世代標準 |
本記事では以下のようにシンプルな構成で Gateway APIを使用しています。
# Gateway: ロードバランサーのフロントエンド定義
spec:
gatewayClassName: gke-l7-global-external-managed # Global ALB を使用
listeners:
- name: http
protocol: HTTP
port: 80
---
# HTTPRoute: ルーティングルール
spec:
parentRefs:
- name: nginx-gateway # この Gateway にアタッチ
rules:
- backendRefs:
- name: nginx-service # すべてのリクエストをこの Service に転送
port: 80
GKE Gatewayコントローラーは、この定義をもとにForwarding Rule・Target HTTP Proxy・URL Map・Backend Service・Health Checkを自動作成し、Global ALBを構成します。
実際に試してみる
前提条件
- Google Cloud プロジェクトが作成済みであること
gcloudCLI がインストール・認証済みであることkubectlがインストール済みであること- 課金が有効なプロジェクトであること
手順の流れ
1. 環境変数の設定
まず、作業で使用する環境変数を設定します。
プロジェクトIDに関しては、自身の検証するプロジェクトIDに修正してください。
# プロジェクトIDとリージョンを設定
export PROJECT_ID=YOUR_PROJECT_ID
export REGION=asia-northeast1
export CLUSTER_NAME=nginx-autopilot-cluster
export NETWORK_NAME=nginx-demo-network
export SUBNET_NAME=nginx-demo-subnet
export ROUTER_NAME=nginx-demo-router
export NAT_NAME=nginx-demo-nat
2. API の有効化
VPC やサブネットの作成に Compute Engine API、GKE クラスタの作成に Kubernetes Engine API が必要なので、先に有効化しておきます。
# 必要な API を有効化
gcloud services enable compute.googleapis.com \
container.googleapis.com \
--project=$PROJECT_ID
Operation "operations/acf.p2-xxxxxxxxxxxx-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" finished successfully.
3. VPC ネットワークとサブネットの作成
GKE クラスタを作成するには、VPC ネットワークとサブネットが必要です。
GKEではノードへのIPアドレスはプライマリIP範囲から、Podやサービスに対するIPアドレスはセカンダリIP範囲から割り当てるため、合わせて作成します。
# VPC ネットワークを作成
gcloud compute networks create $NETWORK_NAME \
--subnet-mode=custom \
--project=$PROJECT_ID
Created [https://www.googleapis.com/compute/v1/projects/YOUR_PROJECT_ID/global/networks/nginx-demo-network].
NAME: nginx-demo-network
SUBNET_MODE: CUSTOM
BGP_ROUTING_MODE: REGIONAL
IPV4_RANGE:
GATEWAY_IPV4:
INTERNAL_IPV6_RANGE:
Instances on this network will not be reachable until firewall rules
are created. As an example, you can allow all internal traffic between
instances as well as SSH, RDP, and ICMP by running:
$ gcloud compute firewall-rules create <FIREWALL_NAME> --network nginx-demo-network --allow tcp,udp,icmp --source-ranges <IP_RANGE>
$ gcloud compute firewall-rules create <FIREWALL_NAME> --network nginx-demo-network --allow tcp:22,tcp:3389,icmp
# サブネットを作成(Pod・サービス用のセカンダリ範囲を含む)
gcloud compute networks subnets create $SUBNET_NAME \
--network=$NETWORK_NAME \
--region=$REGION \
--range=10.0.0.0/20 \
--secondary-range=pods=10.4.0.0/14,services=10.8.0.0/20 \
--project=$PROJECT_ID
Created [https://www.googleapis.com/compute/v1/projects/YOUR_PROJECT_ID/regions/asia-northeast1/subnetworks/nginx-demo-subnet].
NAME: nginx-demo-subnet
REGION: asia-northeast1
NETWORK: nginx-demo-network
RANGE: 10.0.0.0/20
STACK_TYPE: IPV4_ONLY
IPV6_ACCESS_TYPE:
INTERNAL_IPV6_PREFIX:
EXTERNAL_IPV6_PREFIX:
各 IP 範囲の用途は以下のとおりです。
| IP 範囲 | CIDR | 用途 |
|---|---|---|
| プライマリ範囲 | 10.0.0.0/20 |
ノードの IP アドレス |
セカンダリ範囲 pods |
10.4.0.0/14 |
Pod の IP アドレス |
セカンダリ範囲 services |
10.8.0.0/20 |
Service の ClusterIP |
4. Cloud Router と Cloud NAT の作成
本記事ではノードに外部IPを付与しないプライベートクラスタを構成します。プライベートノードからインターネットへ通信するために、Cloud Router と Cloud NATを作成します。
Cloud NAT は、外部 IP を持たないノードがコンテナイメージの取得などインターネットへの通信を行うために必要です。--nat-all-subnet-ip-ranges を指定することで、VPC内のすべてのサブネットのプライマリ・セカンダリIP 範囲がNATの対象になります。
# Cloud Router を作成
gcloud compute routers create $ROUTER_NAME \
--network=$NETWORK_NAME \
--region=$REGION \
--project=$PROJECT_ID
Creating router [nginx-demo-router]...done.
NAME: nginx-demo-router
REGION: asia-northeast1
NETWORK: nginx-demo-network
# Cloud NAT を作成
gcloud compute routers nats create $NAT_NAME \
--router=$ROUTER_NAME \
--region=$REGION \
--auto-allocate-nat-external-ips \
--nat-all-subnet-ip-ranges \
--project=$PROJECT_ID
Creating NAT [nginx-demo-nat] in router [nginx-demo-router]...done.
5. GKE Autopilot クラスタの作成
GKE Autopilotクラスタを作成します。先ほど作成したVPCネットワークとサブネットを指定し、--enable-private-nodes でノードに外部IPを付与しない構成にします。
# GKE Autopilot クラスタの作成
gcloud container clusters create-auto $CLUSTER_NAME \
--location=$REGION \
--network=$NETWORK_NAME \
--subnetwork=$SUBNET_NAME \
--cluster-secondary-range-name=pods \
--services-secondary-range-name=services \
--enable-private-nodes \
--project=$PROJECT_ID
Note: This cluster has private nodes. If you need connectivity to the public internet, for example to pull public containers, you must configure Cloud NAT. To enable NAT for the network of this cluster, run the following commands:
gcloud compute routers create my-router --region asia-northeast1 --network default --project=YOUR_PROJECT_ID
gcloud beta compute routers nats create nat --router=my-router --region=asia-northeast1 --auto-allocate-nat-external-ips --nat-all-subnet-ip-ranges --project=YOUR_PROJECT_ID
Creating cluster nginx-autopilot-cluster in asia-northeast1... Cluster is being health-checked (Kubernetes Control Plane is healthy)...done.
Created [https://container.googleapis.com/v1/projects/YOUR_PROJECT_ID/zones/asia-northeast1/clusters/nginx-autopilot-cluster].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/asia-northeast1/nginx-autopilot-cluster?project=YOUR_PROJECT_ID
kubeconfig entry generated for nginx-autopilot-cluster.
NAME: nginx-autopilot-cluster
LOCATION: asia-northeast1
MASTER_VERSION: 1.35.6-gke.1641000
MASTER_IP: xx.xxx.xx.xxx
MACHINE_TYPE: ek-standard-8
NODE_VERSION: 1.35.6-gke.1641000
NUM_NODES: 3
STATUS: RUNNING
STACK_TYPE: IPV4
Autopilot クラスタの作成には10分~20分くらいかかります。--enable-private-nodes を指定すると、ノードにはプライベートIPのみが割り当てられ、外部IPは付与されません。作成完了後、新しいクラスタではワークロードをデプロイするまでノードが0の状態となる場合があります。最初のワークロードデプロイ時にノードがプロビジョニングされるため、スケジューリングに通常より時間がかかることがあります。
クラスタが作成されたら、kubectl でクラスタを操作するための認証情報を取得します。
# kubectl の認証情報を取得
gcloud container clusters get-credentials $CLUSTER_NAME \
--location=$REGION \
--project=$PROJECT_ID
Fetching cluster endpoint and auth data.
kubeconfig entry generated for nginx-autopilot-cluster.
このコマンドは、kubectl がクラスタと通信するために必要な情報を kubeconfig ファイル(デフォルトでは ~/.kube/config)に書き込みます。具体的には以下の情報が設定されます。
| 設定項目 | 内容 |
|---|---|
| cluster | GKE クラスタの API サーバーのエンドポイント(IP アドレス)と CA 証明書 |
| user | 認証情報(GKE では gke-gcloud-auth-plugin を使用した OAuth トークンベースの認証) |
| context | cluster と user の組み合わせに名前を付けたもの。kubectl が「どのクラスタに」「どのユーザーとして」接続するかを定義 |
get-credentials を実行すると、対象クラスタの context が自動的に current-context として設定されるため、以降の kubectl コマンドはこのクラスタに対して実行されます。
# 現在の context を確認
kubectl config current-context
gke_YOUR_PROJECT_ID_asia-northeast1_nginx-autopilot-cluster
複数のクラスタを扱う場合は kubectl config get-contexts で一覧を確認し、kubectl config use-context <context名> で切り替えることができます。
最後に、クラスタがAutopilotモードで作成されていることを確認します。
# Autopilot モードの確認
gcloud container clusters describe $CLUSTER_NAME \
--location=$REGION \
--project=$PROJECT_ID \
--format="value(autopilot.enabled)"
True
6. Nginx Deployment の作成
Nginx をデプロイする Deploymentマニフェストを作成・適用します。
cat <<'EOF' | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
EOF
Warning: autopilot-default-resources-mutator:Autopilot updated Deployment default/nginx-deployment: defaulted unspecified 'cpu' resource for containers [nginx] (see http://g.co/gke/autopilot-defaults).
deployment.apps/nginx-deployment created
readinessProbeを設定しておくと、GKE Gateway コントローラーがその設定をもとにGoogle Cloudのヘルスチェックを自動構成します。ヘルスチェックのパス(/)やポート(80)が readinessProbeから推論されるため、Nginxの場合は特別なHealthCheckPolicyの設定なしでヘルスチェックが正常に動作します。
なお、KubernetesにはreadinessProbeとlivenessProbeの2種類の主要なヘルスチェックがあります。
| Probe | 役割 | 失敗時の動作 |
|---|---|---|
| readinessProbe | Pod がトラフィックを受け入れる準備ができているかを確認 | Service のエンドポイントから除外(トラフィックが送られなくなる) |
| livenessProbe | Pod 内のプロセスが正常に動作しているかを確認 | Pod を再起動(コンテナを kill して再作成) |
本記事では readinessProbeのみ設定しています。本番環境では、アプリケーションの特性に応じてlivenessProbeの追加も検討してください。
Pod がRunningになっていることを確認します。
kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-6fddd4d468-2cqwx 1/1 Running 0 70s
nginx-deployment-6fddd4d468-85m9l 1/1 Running 0 70s
7. Service の作成
Nginx Podを公開するServiceを作成します。
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: default
spec:
type: ClusterIP
selector:
app: nginx
ports:
- port: 80
protocol: TCP
targetPort: 80
EOF
service/nginx-service created
前述のとおり、Autopilot クラスタでは Container-native load balancing(NEG)がデフォルトで有効なため、Serviceタイプは ClusterIP で十分です。
Gateway API を使用する場合、GKE GatewayコントローラーがHTTPRouteのbackendRefsで参照されたServiceに対して自動的にNEG を作成・管理します。
8. Gateway と HTTPRoute の作成
Gateway APIリソースを作成して、Global ALBを構成します。まずGatewayを作成し、次にHTTPRouteを作成します。
cat <<'EOF' | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: nginx-gateway
namespace: default
spec:
gatewayClassName: gke-l7-global-external-managed
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
EOF
gateway.gateway.networking.k8s.io/nginx-gateway created
gatewayClassName: gke-l7-global-external-managed を指定することで、GKE Gateway コントローラーが Global external Application Load Balancer を作成します。allowedRoutes.namespaces.from: Same により、同じNamespaceのHTTPRouteのみがこのGatewayにアタッチできます。
次に、HTTPRouteを作成してトラフィックのルーティングルールを定義します。
cat <<'EOF' | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: nginx-httproute
namespace: default
spec:
parentRefs:
- name: nginx-gateway
rules:
- backendRefs:
- name: nginx-service
port: 80
EOF
httproute.gateway.networking.k8s.io/nginx-httproute created
parentRefsで先ほど作成したGatewayを参照し、backendRefs ですべてのトラフィックを nginx-service に転送するルールを定義しています。
Gateway の作成後、GKE Gateway コントローラーが以下のリソースを自動的に作成します。
- 外部 IP アドレス
- 転送ルール(Forwarding Rule)
- ターゲット HTTP プロキシ
- URL マップ
- バックエンドサービス
- ヘルスチェック
ロードバランサーが完全に構成されるまで数分かかる場合があります。構成が完了するまで HTTP 404 や HTTP 500 エラーが返ることがあります。
9. 動作確認
Gateway のステータスを確認し、外部 IP アドレスが割り当てられていることを確認します。
kubectl get gateway nginx-gateway
NAME CLASS ADDRESS PROGRAMMED AGE
nginx-gateway gke-l7-global-external-managed xxx.xxx.xxx.xxx 2m3s
Gateway の Programmed 条件が True になるまで待ちます。
kubectl wait --for=condition=Programmed gateway/nginx-gateway --timeout=300s
gateway.gateway.networking.k8s.io/nginx-gateway condition met
kubectl get gateway nginx-gateway
NAME CLASS ADDRESS PROGRAMMED AGE
nginx-gateway gke-l7-global-external-managed xxx.xxx.xxx.xxx True 4m12s
外部 IP アドレスが割り当てられたら、curl でアクセスしてみます。
NginxのデフォルトのウェルカムページのHTMLが取得できました。
# Gateway の外部 IP を取得
GATEWAY_IP=$(kubectl get gateway nginx-gateway -o jsonpath='{.status.addresses[0].value}')
# curl でアクセス
curl http://${GATEWAY_IP}/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, nginx is successfully installed and working.
Further configuration is required for the web server, reverse proxy,
API gateway, load balancer, content cache, or other features.</p>
<p>For online documentation and support please refer to
<a href="https://nginx.org/">nginx.org</a>.<br/>
To engage with the community please visit
<a href="https://community.nginx.org/">community.nginx.org</a>.<br/>
For enterprise grade support, professional services, additional
security features and capabilities please refer to
<a href="https://f5.com/nginx">f5.com/nginx</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
ブラウザ上から正常にアクセスできれば、Nginx のデフォルトのウェルカムページ(Welcome to nginx!)が表示されます。

また、ロードバランサーの構成も確認できます。
Gateway APIにより各種ロードバランサーのコンポーネントも自動作成されていることが確認できました。
# バックエンドサービスの一覧を確認
gcloud compute backend-services list \
--project=$PROJECT_ID
NAME: gkegw1-vac7-default-gw-serve404-80-8zjp3d8cqfsu
BACKENDS:
PROTOCOL: HTTP
NAME: gkegw1-vac7-default-gw-serve500-80-iuaooq9vq8f6
BACKENDS:
PROTOCOL: HTTP
NAME: gkegw1-vac7-default-nginx-service-80-6nogpxd8beyn
BACKENDS: asia-northeast1-b/networkEndpointGroups/k8s1-245b1ac3-default-nginx-service-80-0f49dc9e
PROTOCOL: HTTP
# NEG の一覧を確認
gcloud compute network-endpoint-groups list \
--project=$PROJECT_ID
NAME: k8s1-245b1ac3-default-nginx-service-80-0f49dc9e
LOCATION: asia-northeast1-b
ENDPOINT_TYPE: GCE_VM_IP_PORT
SIZE: 2
# ヘルスチェックのステータスを確認
gcloud compute backend-services get-health gkegw1-vac7-default-nginx-service-80-6nogpxd8beyn \
--global \
--project=$PROJECT_ID
backend: https://www.googleapis.com/compute/v1/projects/YOUR_PROJECT_ID/zones/asia-northeast1-b/networkEndpointGroups/k8s1-245b1ac3-default-nginx-service-80-0f49dc9e
status:
healthStatus:
- healthState: HEALTHY
instance: https://www.googleapis.com/compute/v1/projects/YOUR_PROJECT_ID/zones/asia-northeast1-b/instances/gk3-nginx-autopilot-cluster-pool-1-xxxxxxxx-xxxx
ipAddress: 10.4.0.5
port: 80
- healthState: HEALTHY
instance: https://www.googleapis.com/compute/v1/projects/YOUR_PROJECT_ID/zones/asia-northeast1-b/instances/gk3-nginx-autopilot-cluster-pool-1-xxxxxxxx-xxxx
ipAddress: 10.4.0.13
port: 80
kind: compute#backendServiceGroupHealth
まとめ
本記事では、GKE Autopilotクラスタ上に Nginx をデプロイし、Gateway API(Gateway + HTTPRoute)を使ってGlobal external Application Load Balancer経由でアクセスする手順を紹介しました。
IngressよりもGateway APIが推奨になっていたこと以外は、基本的に昔に構築したような形ですんなり構築することができました。
今回はNginxをGKE上にデプロイするシンプルな構成でしたが、Kubernetesはかなり奥が深く、様々なコンポーネントがたくさんあります。
さらにGoogle Cloudの各種リソースが絡み合ったりもするため、今回の構成をベースに以下のような追加の検証を行ってより理解を深めたいと思います。
- HTTPS 対応: Gateway に Google マネージド SSL 証明書を設定し、HTTPS でのアクセスを有効化
- Cloud Armor 統合: WAF ルールを適用して DDoS 防御やアクセス制御を追加
- HPA(Horizontal Pod Autoscaler): CPU やカスタムメトリクスに基づく Pod の自動スケーリング
- パスベースルーティング: HTTPRoute で複数の Service にパスベースでトラフィックを振り分け
- トラフィック分割: HTTPRoute の
backendRefsに重みを設定し、カナリアデプロイを実現
この記事が誰かの助けになれば幸いです。
以上、コンサルティング部の渡邉でした!






