GKE Gateway 環境を構築してみる
概要
今回は GKE Gateway を GKE で使えるところまでの設定を試してみます。
GKE Gateway API は Google が提供している Kubernetes の Gateway 実装です。
GKE クラスタ構築
GKE Gateway コントローラの要件を満たす様に以下のスペックで GKE クラスタを作成します。
resource "google_container_cluster" "default" {
name = "tetsuya28"
location = "asia-northeast1"
remove_default_node_pool = true
initial_node_count = 1
network = google_compute_network.default.name
subnetwork = google_compute_subnetwork.default.name
# Gateway API を利用するために VPC native モードで作成する
networking_mode = "VPC_NATIVE"
ip_allocation_policy {
cluster_ipv4_cidr_block = local.pod_cidr
services_ipv4_cidr_block = local.service_cidr
}
# ここで Gateway API を有効化する
gateway_api_config {
channel = "CHANNEL_STANDARD"
}
workload_identity_config {
workload_pool = "${local.project_id}.svc.id.goog"
}
cost_management_config {
enabled = true
}
}
クラスタ作成後 gatewayclass
リソースが取得出来ることを確認します。
▶ kubectl get gatewayclass
NAME CONTROLLER ACCEPTED AGE
gke-l7-global-external-managed networking.gke.io/gateway True 5m2s
gke-l7-gxlb networking.gke.io/gateway True 5m2s
gke-l7-rilb networking.gke.io/gateway True 5m3s
Gateway のデプロイ
Gateway API を有効化したクラスタの作成が完了したら実際に Gateway リソースの作成をしていきます。
今回は 2023 年 4 月 8 日 時点で GA になっている gke-l7-gxlb
class を利用します。
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: http
spec:
gatewayClassName: gke-l7-gxlb
listeners:
- name: http
protocol: HTTP
port: 80
上記マニフェストを適用後暫くすると IP アドレスが設定され Gateway のデプロイが完了します。
完了時のリソースとしては以下のような設定が取得出来ます。
▶ kubectl get gateway -o yaml http
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"gateway.networking.k8s.io/v1beta1","kind":"Gateway","metadata":{"annotations":{},"name":"http","namespace":"default"},"spec":{"gatewayClassName":"gke-l7-gxlb","listeners":[{"name":"http","port":80,"protocol":"HTTP"}]}}
networking.gke.io/addresses: /projects/PROJECT_NUMBER/global/addresses/gkegw1-fgki-default-http-1mmbg95k7amq
networking.gke.io/backend-services: /projects/PROJECT_NUMBER/global/backendServices/gkegw1-fgki-kube-system-gw-serve404-80-7cq0brelgzex
networking.gke.io/firewalls: /projects/PROJECT_NUMBER/global/firewalls/gkegw1-fgki-l7-tetsuya28-global
networking.gke.io/forwarding-rules: /projects/PROJECT_NUMBER/global/forwardingRules/gkegw1-fgki-default-http-s04zmpnbqq7f
networking.gke.io/health-checks: /projects/PROJECT_NUMBER/global/healthChecks/gkegw1-fgki-kube-system-gw-serve404-80-7cq0brelgzex
networking.gke.io/last-reconcile-time: "2023-04-08T05:58:10Z"
networking.gke.io/ssl-certificates: ""
networking.gke.io/target-http-proxies: /projects/PROJECT_NUMBER/global/targetHttpProxies/gkegw1-fgki-default-http-umg7zrlwi0u7
networking.gke.io/target-https-proxies: ""
networking.gke.io/url-maps: /projects/PROJECT_NUMBER/global/urlMaps/gkegw1-fgki-default-http-umg7zrlwi0u7
creationTimestamp: "2023-04-08T05:55:41Z"
finalizers:
- gateway.finalizer.networking.gke.io
generation: 1
name: http
namespace: default
resourceVersion: "10896"
uid: 0672def5-c5dd-4b7a-b947-d47dd55e9f49
spec:
gatewayClassName: gke-l7-gxlb
listeners:
- allowedRoutes:
namespaces:
from: Same
name: http
port: 80
protocol: HTTP
status:
addresses:
- type: IPAddress
value: 35.190.2.25
conditions:
- lastTransitionTime: "2023-04-08T05:57:31Z"
message: The OSS Gateway API has deprecated this condition, do not depend on it.
observedGeneration: 1
reason: Scheduled
status: "True"
type: Scheduled
- lastTransitionTime: "2023-04-08T05:57:31Z"
message: ""
observedGeneration: 1
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2023-04-08T05:57:31Z"
message: ""
observedGeneration: 1
reason: Ready
status: "True"
type: Ready
listeners:
- attachedRoutes: 0
conditions:
- lastTransitionTime: "2023-04-08T05:57:31Z"
message: ""
observedGeneration: 1
reason: Ready
status: "True"
type: Ready
name: http
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
GCP のリソースとしては HTTP ロードバランサ ( Classic ) が作成されています。
このタイミングではバックエンドをまだデプロイしていないので 404
が返ってきます。
▶ curl 35.190.2.25 -i
HTTP/1.1 404 Not Found
Date: Sat, 08 Apr 2023 06:00:16 GMT
Content-Length: 74
Content-Type: text/plain; charset=utf-8
Via: 1.1 google
response 404 (backend NotFound), service rules for the path non-existent
HTTPRoute のデプロイ
次に実際に Gateway のバックエンドをデプロイしていきます。
サンプルアプリケーションには Google のサンプルを利用します。
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yaml
次に、上記のサンプルアプリケーションへのルーティングを HTTP Route を利用して設定します。
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: store-external
spec:
parentRefs:
- kind: Gateway
name: http
hostnames:
- "store.example.com"
rules:
- backendRefs:
- name: store-v1
port: 8080
- matches:
- headers:
- name: env
value: canary
backendRefs:
- name: store-v2
port: 8080
- matches:
- path:
value: /de
backendRefs:
- name: store-german
port: 8080
この時点でロードバランサにバックエンドに対する設定が追加されます。
ドメインを store.example.com
で設定しているため curl
で強制的に store.example.com
のドメイン名を Gateway API の IP アドレスで名前解決をすることでアクセスの確認を行います。
無事、 Gateway API 経由でバックエンドへの疎通を行うことが出来ました。
▶ curl store.example.com/de --resolve "store.example.com:80:35.190.2.25" -i
HTTP/1.1 200 OK
Server: Werkzeug/2.2.2 Python/3.10.9
Date: Sat, 08 Apr 2023 06:19:31 GMT
Content-Type: application/json
Content-Length: 365
Access-Control-Allow-Origin: *
Via: 1.1 google
{
"cluster_name": "tetsuya28",
"gce_instance_id": "836092675233726340",
"gce_service_account": "tetsuya28.svc.id.goog",
"host_header": "store.example.com",
"metadata": "Gutentag!",
"pod_name": "store-german-678c8d4d54-dvkt9",
"pod_name_emoji": "😯",
"project_id": "tetsuya28",
"timestamp": "2023-04-08T06:19:31",
"zone": "asia-northeast1-b"
}
おまけ
Gateway ですが、権限分離の考え方など個人的に期待しているのですが現状以下の機能を使うことが出来ず、 GA にはなっているもののプロダクションに導入出来るレベル感かと言われると微妙なところではありますが、今後の機能改善にも期待していきたいと思います。
- Cloud CDN
- IAP
- Cloud Armor
- HTTPS リダイレクト
Discussion