GAミント至上主義

Web Monomaniacal Developer.

GKEでIngressを使ってService単位でロードバランシングする

以前の下記記事の続きで
uyamazak.hatenablog.com

本番とステージング環境で、管理コストを削減するために

を使いまわし、
/api/* → 本番用Service
/api-staging/* → ステージング用Service
とパスでサービスを分けたいときはIngressが必要だったのでやってみた。

クラスタでよければ、HTTP(S)ロードバランサーの設定だけでクラスタ単位で向けられるのでできる。

Ingressとは

Nianticのゲーム名ではなく、直訳すると「入ること」とか「入場権」的な意味らしい。
ネットワークの文脈だともっといい訳があるかもしんない。
2016年夏ごろにGKEで構築した時は見た覚えがなく、HTTP(S)ロードバランサーの設定でやっていたので、新しめの機能なんだと思う。
今からGKEで構築してドメインSSLを使うならGoogle推奨のやり方となる。

Setting up HTTP Load Balancing with Ingress  |  Kubernetes Engine Tutorials  |  Google Cloud

GKE上でロードバランサーが動くわけではなく、実装はHTTP(S)ロードバランサーで行われている。

それぞれの環境のDeployment, Serviceを作る

今回の主題ではないのでハマりどころ以外はざっくり

以下kcはkubectlのエイリアス

Deploymentは下記二つ

% kc get deploy
NAME                     DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
varuna-django            1         1         1            1           21h
varuna-django-staging    1         1         1            1           21h

それに対するServiceは下記

% kc get service
NAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes               ClusterIP   10.27.240.1     <none>        443/TCP          21h
varuna-django            NodePort    10.27.254.67    <none>        8080:30001/TCP   21h
varuna-django-staging    NodePort    10.27.242.187   <none>        8080:30002/TCP   21h

Ingress用のyamlを書く

公式ドキュメントを参考に振り分けする
ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: varuna-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: varuna-django
          servicePort: 8080
      - path: /api/*
        backend:
          serviceName: varuna-django
          servicePort: 8080
      - path: /api-staging/*
        backend:
          serviceName: varuna-django-staging
          servicePort: 8080

Deploymentでのヘルスチェック用のパスの設定

IngressのDeploymentに対するヘルスチェックはデフォルトで/、ステータス200になっている。
今回のサービスだと/api/hc的なパスにしていたので、readinessの設定が必要。しばらくハマった。
下記ページでも上がっていた。

github.com
edit deploy でreadinessProbeとついでに同じようなlivenessProbeも設定しておく。

readinessProbeとlivenessProbeについて、それぞれ詳しくは公式ドキュメント
Configure Liveness and Readiness Probes - Kubernetes

kc edit deploy varuna-django
# 適当にいろいろ削った
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    run: varuna-django
  name: varuna-django
spec:
  replicas: 1
  selector:
    matchLabels:
      run: varuna-django
  template:
    metadata:
      creationTimestamp: null
      labels:
        run: varuna-django
    spec:
      containers:
      - image: asia.gcr.io/your-project/tag
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /api/hc_pdf
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 3
          periodSeconds: 3
          successThreshold: 1
          timeoutSeconds: 3
        name: varuna-django
        ports:
        - containerPort: 8080
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /api/hc
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 3
          periodSeconds: 3
          successThreshold: 1
          timeoutSeconds: 3

その他いろいろ

ロードバランサーのIPを静的にするとか、ロードバランサーSSL証明書(Let's Encrypt)の設定をする

Googleが自動でやってくれるのを待ち望んでいるがまだのようなので自分で作ったスクリプトで設置した
自分で作っておいてなんだけど、なかなか設定がめんどくさい。
GitHub - uyamazak/gcp-ssl-auto-renewer: Auto renew SSL Certificates commands on Google Cloud Platform (GCP).

これでクラスタを複数作らずに、サービス単位に振り分けることができた。
GKEというかKubernetesは発展途上なので、時間が空いたら以前やった手順を使わずに、公式ドキュメントを見直した方がよさそう。

コンテナ・ベース・オーケストレーション Docker/Kubernetesで作るクラウド時代のシステム基盤

コンテナ・ベース・オーケストレーション Docker/Kubernetesで作るクラウド時代のシステム基盤

Kubernetes完全ガイド (impress top gear)

Kubernetes完全ガイド (impress top gear)

Docker/Kubernetes 実践コンテナ開発入門

Docker/Kubernetes 実践コンテナ開発入門