GKE ingressのヘルスチェック構成

Google Kubernetes Engineのフロントエンドを ingressにする場合、自動でGCPのヘルスチェックが作られ、これを通過しないとPodが正常動作していたとしてもバックエンドサービスが開通しません。

自動作成されるデフォルトのヘルスチェック挙動は、/をHTTP GETして200OKが得られることをチェックしています。バックエンドがこのリクエストに対応できるよう実装できればヘルスチェックを通過します。

これ以外の構成にする場合には、kubernetesではなくGCPの操作により適切な構成にする必要があります。

該当のヘルスチェックは、クラウドコンソールの Cloud Load Balancingからたどれます。
バックエンドサービスごとにヘルスチェックがあり、監視対象などの設定を変更できます。

ヘルスチェックのカスタマイズ

BackendConfig CRDというカスタムリソースを作成すると、GCPのヘルスチェックを制御できます。
参照はServiceのアノテーションです。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: envoy-beconfig
spec:
  healthCheck:
    checkIntervalSec: 15
    timeoutSec: 15
    healthyThreshold: 1
    unhealthyThreshold: 2
    type: HTTPS
    requestPath: /healthz
    port: 8443
---
apiVersion: v1
kind: Service
metadata:
  name: envoy
  labels:
    name: envoy
  annotations:
    cloud.google.com/backend-config: '{"default": "envoy-beconfig"}'
    cloud.google.com/app-protocols: '{"https":"HTTPS"}'
spec:
  ports:
  - name: https
    port: 443
    targetPort: https
  selector:
    name: envoy

分かりにくいポイントとして、コンテナネイティブの負荷分散構成の場合spec.headlthCheck.portに指定するポートは、ServiceではなくPodのcontainerPortです。

envoyの例

バックエンドがenvoyの場合、GCPのヘルスチェック設定を変更して200OKを返すリクエストを飛ばす構成にする必要がありそうです。
プロトコルやホスト、パスを変更することで、実際に動作するリクエストを設定できます。

  • ヘルスチェックのデフォルトプロトコルはHTTPだが、envoyがHTTPSサービスを提供する構成の場合HTTPに対応しない
  • envoyでSNI構成をとった場合、リクエストに適切なホストが必要
  • /が無条件に200OKを返すサービスとは限らない

特定のPathで200OKを返したい場合、ルーティングのvirtual_hostsに以下のようなルートを追加するとenvoyが直接応答します。

  virtual_hosts:
  - name: example
    domains:
    - "*"
    routes:
    - match:
        prefix: "/healthz"
      direct_response:
        status: "200"

ドメインにワイルドカードを指定しておくと、ホスト指定のないヘルスチェックも対応可能です。

⁋ 2021/12/02↻ 2024/11/07
中馬崇尋
Chuma Takahiro