GKE Autopilot を安定稼働させるための設定リストを紹介します。
Kubernetes 全般で考慮すべき事項も含んでいますのでチェックしてみてください。
-
GKE 関連
- コネクションドレインで既存リクエストを完了させる
- Release channel で環境に応じたバージョン戦略を採る
- メンテナンスウィンドウで自動メンテナンスの影響を最小限にする
-
Kubernetes 全般
- HPA で負荷に応じて Pod をスケールさせる
- PDB で Node 排出時のサービス継続を担保する
- PriorityClass で重要な Pod を確実に起動させる
- ヘルスチェックでアプリケーションの正常性を担保する
GKE 関連
コネクションドレインで既存リクエストを完了させる
コネクションドレインのタイムアウトは Pod が削除された際に既存のリクエストを完了させるために設ける猶予時間です。
これによりデプロイによる Pod 入れ替わりのタイミングで502エラーが発生するのを抑制できる場合があります。
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: sample-api
spec:
timeoutSec: 300
connectionDraining:
drainingTimeoutSec: 30
同時に Pod の終了処理への考慮も必要です。Googoleのドキュメントが参考になります。
Pod の終了に関してはアルパカでもわかる安全なPodの終了が分かりやすかったです。
Release channel で環境に応じたバージョン戦略を採る
GKE は Release channel を使ってクラスタのバージョンアップを自動化できます。
チャネルには Rapid
, Regular
, Stable
の3種あります。
クラスタが所属するチャネルによって Kubernetes 本家のバージョンへの追従速度が変わります。
例えば、環境毎に次のように設定する運用が考えられます。
環境 | チャネル | 説明 |
---|---|---|
Dev | Rapid | 最悪壊れてもよいので先行して新バージョンを試していく |
Stg | Regular | Prd と同じチャネルにしておく |
Prd | Regular | Regular でもよいが Stable でもよさそう |
アップグレードの通知を Slack に流すことでアップデートの準備を進められます。
理想的には、UpgradeAvailableEvent 通知タイプを使用することで、今後のアップグレードを認識し、事前にアップグレードすることや、メンテナンスの時間枠の設定などの準備に必要な対策を講じることができます。
https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-notifications?hl=ja#upgradeavailable
メンテナンスウィンドウで自動メンテナンスの影響を最小限にする
GKE ではバージョンアップグレードを始めとした自動メンテナンスが実行されます。
サービスへの影響を最小限に抑えるためにメンテナンスウィンドウを設定しましょう。
トラフィックを分析して最もリクエストの少ない時間帯に設定しておくとよさそうです。
Kubernetes 全般
HPA でリソース状況に応じて Pod をスケールさせる
HPA は、特定の指標を基に自動的に Pod をスケールさせるリソースです。
下の例では、CPU 使用率をオートスケールの指標とし目標値を60%に定めています。
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
...(中略)
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: sample-api
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
minReplicas: 3
maxReplicas: 10
PDB で Node 排出時のサービス継続を担保する
PDB は Node の排出処理の際に停止してもよい(or 起動させておきたい) Pod 数を指定するリソースです。
下の例では、停止してもよい Pod 数を1台までに制限しています。(%での指定も可)
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
...(中略)
spec:
maxUnavailable: 1
selector:
matchLabels:
app.kubernetes.io/name: sample-api
PriorityClass で重要な Pod を確実に起動させる
PriorityClass は、Pod の起動に優先順位をつけるためのリソースです。
下の例では、nginx の Pod の優先度を1000に設定しています。priorityClassName
が未設定の Pod は優先度が0(default)なので、nginx の Pod は他の Pod をプリエンプトしてスケジューリングされます。
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000
globalDefault: false
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
priorityClassName: high-priority
Daemonset を使う場合は PriorityClass が有効です。
ヘルスチェックでアプリケーションの正常性を担保する
Kubernetes には3種のヘルスチェックが用意されています。
適切に設定することでアプリケーションの正常性を担保できます。
3種の使い分けはざっくり次の通りです。
種類 | 使い分け | 失敗時の動作 |
---|---|---|
Liveness Probe | コンテナの生存確認 | コンテナを再起動 |
Readiness Probe | 外部からの振る舞い確認 | Serviceからルーティングされない |
Startup Probe | Podの起動を確認 | 他のProbeを無効にする |
下の例では、startupProbe
で 300秒間 (failureThreshold * periodSeconds
) Pod の起動を待ち、 readinessProbe
が2回連続失敗したらルーティング先から外し、livenessProbe
が3回連続失敗したらコンテナを再起動するという設定をしています。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
startupProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 10
successThreshold: 1
failureThreshold: 30
timeoutSeconds: 1
readinessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 10
successThreshold: 1
failureThreshold: 2
timeoutSeconds: 1
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
timeoutSeconds: 1
その他
Key は限られますが Node Affinity や Pod Affnitiy が Autopilot でも利用できます。
ワークロードを分離したい場合や、特定の Pod がある Node にデプロイしたい場合などに使えそうです。