Podとそのエンドポイントの終了動作を探る
アプリケーションをServiceに接続するで概略を示したステップに従ってアプリケーションをServiceに接続すると、ネットワーク上で公開され、継続的に実行されて、複製されたアプリケーションが得られます。 このチュートリアルでは、Podを終了する流れを見て、gracefulな(猶予のある)接続ドレインを実装する手法を模索するための手助けをします。
Podの終了手続きとそのエンドポイント
アップグレードやスケールダウンのために、Podを終了しなければならない場面はままあります。 アプリケーションの可用性を高めるために、適切なアクティブ接続ドレインを実装することは重要でしょう。
このチュートリアルでは概念のデモンストレーションのために、シンプルなnginx Webサーバーを例として、対応するエンドポイントの状態に関連したPodの終了および削除の流れを説明します。
エンドポイント終了の流れの例
以下は、Podの終了ドキュメントに記載されている流れの例です。
1つのnginx
レプリカを含むDeployment(純粋にデモンストレーション目的です)とServiceがあるとします:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
terminationGracePeriodSeconds: 120 # 非常に長い猶予期間
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
lifecycle:
preStop:
exec:
# 実際の活動終了はterminationGracePeriodSecondsまでかかる可能性がある。
# この例においては、少なくともterminationGracePeriodSecondsの間は待機し、
# 120秒経過すると、コンテナは強制的に終了される。
# この間ずっとnginxはリクエストを処理し続けていることに注意。
command: [
"/bin/sh", "-c", "sleep 180"
]
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
terminationGracePeriodSeconds: 120 # 非常に長い猶予期間
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
lifecycle:
preStop:
exec:
# 実際の活動終了はterminationGracePeriodSecondsまでかかる可能性がある。
# この例においては、少なくともterminationGracePeriodSecondsの間は待機し、
# 120秒経過すると、コンテナは強制終了される。
# この間ずっとnginxはリクエストを処理し続けていることに注意。
command: [
"/bin/sh", "-c", "sleep 180"
]
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
PodとServiceが実行中になったら、関連付けられたEndpointSliceの名前を得られます:
kubectl get endpointslice
この出力は以下のようなものになります:
NAME ADDRESSTYPE PORTS ENDPOINTS AGE
nginx-service-6tjbr IPv4 80 10.12.1.199,10.12.1.201 22m
状態からわかるように、1つのエンドポイントが登録されていることが確認できます:
kubectl get endpointslices -o json -l kubernetes.io/service-name=nginx-service
この出力は以下のようなものになります:
{
"addressType": "IPv4",
"apiVersion": "discovery.k8s.io/v1",
"endpoints": [
{
"addresses": [
"10.12.1.201"
],
"conditions": {
"ready": true,
"serving": true,
"terminating": false
では、Podを終了し、そのPodがgracefulな終了期間設定を守って終了されていることを確認してみましょう:
kubectl delete pod nginx-deployment-7768647bf9-b4b9s
全Podについて調べます:
kubectl get pods
この出力は以下のようなものになります:
NAME READY STATUS RESTARTS AGE
nginx-deployment-7768647bf9-b4b9s 1/1 Terminating 0 4m1s
nginx-deployment-7768647bf9-rkxlw 1/1 Running 0 8s
新しいPodがスケジュールされたことを見てとれます。
新しいPodのために新しいエンドポイントが作成される間、古いエンドポイントは終了中の状態のまま残っています:
kubectl get endpointslice -o json nginx-service-6tjbr
この出力は以下のようなものになります:
{
"addressType": "IPv4",
"apiVersion": "discovery.k8s.io/v1",
"endpoints": [
{
"addresses": [
"10.12.1.201"
],
"conditions": {
"ready": false,
"serving": true,
"terminating": true
},
"nodeName": "gke-main-default-pool-dca1511c-d17b",
"targetRef": {
"kind": "Pod",
"name": "nginx-deployment-7768647bf9-b4b9s",
"namespace": "default",
"uid": "66fa831c-7eb2-407f-bd2c-f96dfe841478"
},
"zone": "us-central1-c"
},
{
"addresses": [
"10.12.1.202"
],
"conditions": {
"ready": true,
"serving": true,
"terminating": false
},
"nodeName": "gke-main-default-pool-dca1511c-d17b",
"targetRef": {
"kind": "Pod",
"name": "nginx-deployment-7768647bf9-rkxlw",
"namespace": "default",
"uid": "722b1cbe-dcd7-4ed4-8928-4a4d0e2bbe35"
},
"zone": "us-central1-c"
これを使うと、終了中のアプリケーションがその状態について、接続ドレイン機能の実装目的でクライアント(ロードバランサーなど)と通信する、ということが可能です。 これらのクライアントではエンドポイントの終了を検出し、そのための特別なロジックを実装できます。
Kubernetesでは、終了中のエンドポイントのready
状態は全てfalse
にセットされます。
これは後方互換性のために必要な措置で、既存のロードバランサーは通常のトラフィックにはそれを使用しません。
Podの終了時にトラフィックのドレインが必要な場合、実際に準備できているかはserving
状態として調べられます。
Podが削除される時には、古いエンドポイントも削除されます。
次の項目
- アプリケーションをServiceに接続する方法を学びます。
- Serviceを利用したクラスター内のアプリケーションへのアクセスを学びます。
- Serviceを使用してフロントエンドをバックエンドに接続するを学びます。
- 外部ロードバランサーの作成を学びます。