Google Kubernetes Engine

関連ページ:

Getting Started

Documentation

ベストプラクティス

機能

負荷分散

HTTP(S) 負荷分散

Ingressで複数のバックエンドServiceを設定できる。設定例:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: my-products
          servicePort: 60000
      - path: /discounted
        backend:
          serviceName: my-discounted-products
          servicePort: 80
Managed SSL certificateを使う

https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs

  • GCPの静的IPを払い出し、対象のDNSレコードに設定する必要がある

See also https://sites.google.com/site/progrhymetechwiki/cloud/gcp/gclb#TOC-SSL-

HTTPの無効化

https://cloud.google.com/kubernetes-engine/docs/concepts/ingress?hl=ja#disabling_http

HTTPSのみを使うときはアノテーション kubernetes.io/ingress.allow-http の値を "false" に設定する。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress-2
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: my-secret
  ...

※2020-03-04現在、K8sのバージョンによっては、マネージドSSL証明書を使う場合は、 ingress.gcp.kubernetes.io/pre-shared-cert アノテーションの値に証明書名を入れる必要がある。1.15.x-gke.y の場合は自動でアノテーション付けてくれるっぽい。
See https://github.com/kubernetes/ingress-gce/issues/1001

内部TCP/UDP負荷分散

内部 TCP / UDP 負荷分散 | Kubernetes Engine のドキュメント | Google Cloud

2020-03-25現在、β版

  • Serviceを type: LoadBalancer で作成し、所定のannotationを入れる
  • 内部LBが作成される
  • Ingressは不要
  • Compute InstanceGroupで振り分けされる
    • 2020-03-25現在、ネットワークエンドポイントグループには対応していない
  • 同じDeploymentで、内部LBのServiceと外部HTTP(S)負荷分散用の2つのServiceを持つことができる

Example:

apiVersion: v1
kind: Service
metadata:
  name: ilb-service
  annotations:
    cloud.google.com/load-balancer-type: "Internal"
  labels:
    app: hello
spec:
  type: LoadBalancer
  selector:
    app: hello
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP

BackendConfig(β on 2020-04-27)

https://cloud.google.com/kubernetes-engine/docs/concepts/backendconfig?hl=en

GKE固有のcustom resource.

BackendConfigによって、HTTP(S) Load Balancingに以下の機能を設定できる:

Example:

  • タイムアウトを40秒に設定
  • 接続ドレインタイムアウトを60秒に設定
apiVersion: cloud.google.com/v1beta1
    kind: BackendConfig
    metadata:
      name: my-bsc-backendconfig
    spec:
      timeoutSec: 40
      connectionDraining:
        drainingTimeoutSec: 60

Workload Identity

Workload Identity | Kubernetes Engine ドキュメント | Google Cloud

  • GCP Service AccountとK8s Service Accountの紐付け設定をすることができる
  • GKE Metadata Serverを有効にしている必要があるようだ

メリット:

  • GCP Service Account Keyが不要になる

Config Connector

Config Connector の概要 | Config Connector のドキュメント | Google Cloud

  • K8s addon.
  • K8sのCRDと関連するコントローラを提供してくれる
  • あたかもK8sのリソースかのようにGCPリソースを管理できるようになる

参考:

仕様

Quota

https://cloud.google.com/kubernetes-engine/quotas

Last updated at 2020-04-13

  • GKEクラスタごと
    • クラスタあたりの最大ノード数: 5,000
    • ノードプールあたりの最大ノード数: 1,000
    • ノードあたりの最大ポッド数: 110

限定公開クラスタ

Documents:

要点:

  • ノードは内部IPアドレスのみを持つため、インターネットから隔離される
  • 限定公開クラスタでは、マスターへのアクセスを制御できる
  • LB経由で受信トラフィックを受けられる。また、内部LB経由でVPC内のトラフィックを受けることもできる
  • 外と通信したいときは、上記の「Example GKE Setup」にあるように、Cloud NAT + Cloud Routerをセットアップする

Tips:

  • (2019-12-02現在) gcloud container clusters create コマンドでは --enable-private-nodes --master-ipv4-cidr <CIDR> オプションをつける

制限事項

限定公開クラスタの作成 | Kubernetes Engine ドキュメント | Google Cloud#要件、制約、制限

Horizontal Pod Autoscaler

HPA.

参考:

コンテナネイティブの負荷分散

コンテナ ネイティブの負荷分散を使用する | Kubernetes Engine のドキュメント | Google Cloud

TL;DR:

  • ネットワークエンドポイントグループ(NEG)を作成して、Podに均等にトラフィックを分配できる
  • 従来の方式だとインスタンスグループ経由のアクセスで、iptablesを介してPodにアクセスしており、余分なネットワークオーバーヘッドが発生していた

既知の問題(2020-04-27時点):

  • GKEのガベージコレクションが2分間隔なので、LBが完全に削除される前にクラスタが削除された場合、NEGを手動で削除する必要がある
  • Podのreadinessフィードバック使っていない場合、ワークロードをデプロイするときや再起動するときに、ワークロードの更新完了に要する時間よりも、新しいエンドポイントの伝播に要する時間のほうが長くなる場合がある

VPCネイティブクラスタ

VPC ネイティブ クラスタを作成する | Kubernetes Engine ドキュメント | Google Cloud

2020-05-04現在、GCPコンソールから作成する場合はデフォルトでVPCネイティブクラスタになるが、REST APIやgcloudコマンドではルートベースクラスタになるので注意。

2つのやり方がある:

  1. 既存のサブネットにクラスタを作成する。アドレス範囲の割り当て方は下の2つ:
    • GKE管理のセカンダリ範囲割り当て
    • ユーザー管理のセカンダリ範囲割り当て
  2. クラスタとサブネットを同時に作成する。セカンダリアドレス範囲の割り当てはGKE管理となる

How-to

アップグレード

https://cloud.google.com/kubernetes-engine/docs/how-to/upgrading-a-cluster

Tips:

kubeconfigエントリを生成

gcloud container clusters get-credentials [CLUSTER_NAME] [--project PROJECT] [--region REGION]

↑のコマンドは更に、クラスタをデフォルトのkubectlのcontextに設定する。

参考:

ノードプールを作り直す

マシンタイプやサービスアカウントを変えるときなどには、ノードプールの作り直しが発生する。
次の要領でやれば良い:

  1. 新しいプールを作成
  2. ワークロードを新しいプールに移行
  3. 古いプールを削除

ドキュメントでは、 異なるマシンタイプへのワークロードの移行 | Kubernetes Engine のチュートリアル | Google Cloud の手順に従う形になる。

ただし、この手順に愚直に従うとドレインした瞬間に旧プール上のPodがevictionされ、サービス停止することもあり得るので、常時稼働のワークロードであれば、cordonでノードへのスケジューリングを停止した後、Podをスケールさせて新しいプールにPodが配置された後にドレインした方がよさそう。

GKEのノードにSSH

参考:

メンテナンス時間枠と除外枠の設定

メンテナンスの時間枠と除外の構成 | Kubernetes Engine ドキュメント | Google Cloud

  • クラスタやノードのアップグレードが行われる時間枠を設定可能。
  • (たぶん)最短4時間

Docker Hubのイメージを使うには?

公開イメージだったら普通に使える。

プライベートなイメージでも認証情報を渡せば普通に使えるんじゃないかな。

MEMO:

  • 日本語の記事だとミラーしたり、GCRにpushしてる例が多い

参考:

Topics

Logging

参考

最終更新 2020-06-13: [gcp] Mainly about GCS (1d1cfbc59)