🌐

Ingress のその先: Gateway API という選択

2023/01/08に公開

こんにちは。Enabling team の山本です。
Retail AI X では、Google Cloud 上でさまざまなサービスを稼働させており、日々、トライアルの店舗をご利用のお客様へ価値を提供しております。
この記事は、Enabling team の役割の 1 つである「Application stack の ecosystem に関する調査」の活動報告です。

Application stack


今回は、Ingress API(Ingress)の進化版である Gateway を調査します。

Kubernetes Gateway API(Gateway)

引用:Kubernetes Gateway API

ご存じのとおり、Ingress は、負荷分散・SSL 終端などの機能を提供します。
今回、Gateway が GA になったことで、弊社サービスへの導入に向けた調査を行います。

評価

弊社の採用基準としては、Technology Radar でいうところの
HOLD : 採用する場合は慎重に進める必要がある。
くらいの位置付けだと思います。

理由

Ingress でサポートされていた機能が現時点でサポートされていないためです。
具体的には、以下の機能を必要としています。

  • Google Cloud Armor
  • SSL ポリシー
  • カスタム リクエストとレスポンス ヘッダー

Production への適用は、もう少し待つ必要があると思います。
今後の Update に期待です!
それでは、先々の導入準備として、 Ingress との違いを確認していきます。

はじめに


弊社のサービスは、 ほぼ全てで Ingress を採用してきました。
Ingress について、Infra と Application の関心ごとが混在することに不満を感じます。
具体的には、ドメイン・証明書と Path rule が同じ manifest に存在するところです。
そもそも、Stream-aligned team は、Production 環境全体に責任を持つため、Infra が、Application がと言う境界は無いはずですが。

構築


GKE Cluster の作成

gcloud beta container --project "gw-sandbox-service-a" clusters create "case1a" --zone "asia-northeast1-a" --no-enable-basic-auth --cluster-version "1.24.7-gke.900" --release-channel "regular" --machine-type "e2-medium" --image-type "COS_CONTAINERD" --disk-type "pd-balanced" --disk-size "100" --metadata disable-legacy-endpoints=true --scopes "https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/trace.append" --max-pods-per-node "110" --num-nodes "1" --logging=SYSTEM,WORKLOAD --monitoring=SYSTEM --enable-ip-alias --network "projects/gw-sandbox-service-a/global/networks/default" --subnetwork "projects/gw-sandbox-service-a/regions/asia-northeast1/subnetworks/default" --no-enable-intra-node-visibility --default-max-pods-per-node "110" --no-enable-master-authorized-networks --addons HorizontalPodAutoscaling,HttpLoadBalancing,GcePersistentDiskCsiDriver --enable-autoupgrade --enable-autorepair --max-surge-upgrade 1 --max-unavailable-upgrade 0 --enable-shielded-nodes --node-locations "asia-northeast1-a" --gateway-api=standard
  • --gateway-api=standard : Gateway を有効にするパラメータ

SSL 証明書の作成

IP Address の予約は不要です。

  • --domains : 取得する FQDN
gcloud compute ssl-certificates create store-example-com \
    --domains=gw-test.example.com \
    --global

ゲートウェイと HTTPRoute を作成する

Gateway の作成時に、SSL 証明書で指定したドメインを設定します。

cat << EOF  | kubectl apply -f -
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: external-http
spec:
  gatewayClassName: gke-l7-gxlb
  listeners:
  - name: https
    protocol: HTTPS
    port: 443
    tls:
      mode: Terminate
      options:
        networking.gke.io/pre-shared-certs: store-example-com    # SSL 証明書名
EOF
cat << EOF  | kubectl apply -f -
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: store-external
  labels:
    gateway: external-http
spec:
  parentRefs:
  - name: external-http
  hostnames:
  - "gw-test.example.com"    # 取得する FQDN
  rules:
  - backendRefs:
    - name: store-v1
      port: 8080
EOF

IP Address を取得する

kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"

FQDN を登録します。
ステータスが ACTIVE になるまで15分程度待ちます。

ゲートウェイの動作を確認する

yamamoto_daisuke@cloudshell:~ (gw-sandbox-service-a)$ curl https://gw-test.example.com -v
*   Trying 34.120.89.76:443...
* Connected to gw-test.example.com (34.120.89.76) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=gw-test.example.com
*  start date: Jan  6 11:11:22 2023 GMT
*  expire date: Apr  6 11:56:31 2023 GMT
*  subjectAltName: host "gw-test.example.com" matched cert's "gw-test.example.com"
*  issuer: C=US; O=Google Trust Services LLC; CN=GTS CA 1D4
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x5651339d92c0)
> GET / HTTP/2
> Host: gw-test.example.com
> user-agent: curl/7.74.0
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 500
< date: Fri, 06 Jan 2023 23:04:10 GMT
< content-length: 14
< content-type: text/plain; charset=utf-8
< via: 1.1 google
< alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
<
response 500
* Connection #0 to host gw-test.example.com left intact
yamamoto_daisuke@cloudshell:~ (gw-sandbox-service-a)$

これで、Gateway の設定が完了しました。

Application を使用した動作確認は、公式を確認してください。

まとめ

Gateway resource と HTTPRoute resource が分かれていることで、SRE と Developer が役割分担を行うことができます。
Ingress の後継ということで違いを見てきましたが、問題となるような設定手順は存在しませんでした。
既存のサービスの Ingress の置き換えも問題なく進めることができると思います。
なお、今後、機能追加は、Gateway が中心になる予定ということです。
Stream-aligned team の Production への適用時のギャップを埋めるため、動向をウォッチしていきます。

Discussion