pod#
Kubernetes において、基本的にすべてのリソースの主要属性は同じで、主に 5 つの部分から構成されています:
apiVersion <string>
バージョン、Kubernetes 内部で定義されており、バージョン番号は kubectl api-versions で確認できる必要があります。kind <string>
タイプ、Kubernetes 内部で定義されており、バージョン番号は kubectl api-resources で確認できる必要があります。metadata <object>
メタデータ、主にリソースの識別と説明が含まれ、一般的には name、namespace、labels などがあります。spec <object>
説明、これは設定の中で最も重要な部分で、さまざまなリソースの設定に関する詳細な説明が含まれています。status <object>
ステータス情報、内部の内容は定義する必要がなく、Kubernetes によって自動生成されます。
Pod のライフサイクル#
Pod オブジェクトが作成から終了までの時間範囲を Pod のライフサイクルと呼びます。そのライフサイクルの主要なプロセスは以下の通りです:
- pod の作成
- 初期化コンテナの実行
- 主コンテナの実行
(1)スタートフック、終了フック
(2)生存性プローブ、準備性プローブ - pod の終了
ライフサイクル全体で、Pod は 5 つの状態に分かれます:
- 保留中 (Pending):apiserver が pod リソースオブジェクトを作成しましたが、まだスケジュールが完了していないか、イメージのダウンロード中です。
- 実行中 (Running):pod が特定のノードにスケジュールされ、すべてのコンテナが kubelet によって作成されています。
- 成功 (Succeeded):pod 内のすべてのコンテナが正常に終了し、再起動されません。
- 失敗 (Failed):すべてのコンテナが終了しましたが、少なくとも 1 つのコンテナが失敗して終了し、非 0 の終了ステータスを返しました。
- 不明 (Unknown):apiserver が pod オブジェクトのステータス情報を正常に取得できず、通常はネットワーク通信の失敗によって引き起こされます。
pod の作成プロセス#
kubectl を使用して pod の設定を apiserver に送信し、apiserver は pod 情報を変換して etcd に保存し、次に「ハンドシェイク」フィードバックを行います。scheduler は apiserver 内の pod 情報の変化を監視し、アルゴリズムを使用して pod にホストを割り当て、apiserver の情報を更新します。対応する node ノードのホストは更新された情報を監視し、コンテナを作成し、情報を apiserver に更新します。apiserver は最終情報を etcd に保存し、これで pod の作成が完了します。
- ユーザーは kubectl または他の API クライアントを使用して、作成する必要がある pod 情報を apiServer に提出します。
- apiServer は pod オブジェクトの情報を生成し、etcd に情報を保存し、クライアントに確認情報を返します。
- apiServer は etcd 内の pod オブジェクトの変化を反映し、他のコンポーネントは watch メカニズムを使用して apiServer 上の変動を追跡します。
- scheduler は新しい pod オブジェクトを作成する必要があることを発見し、Pod にホストを割り当て、結果情報を apiServer に更新します。
- node ノード上の kubelet は pod がスケジュールされていることを発見し、docker を呼び出してコンテナを起動し、結果を apiServer に返します。
- apiServer は受信した pod ステータス情報を etcd に保存します。
pod の終了プロセス#
ユーザーが pod 削除コマンドを送信すると、apiserver は受け入れて情報を更新し、pod のステータスが terminating に変わります。kubelet は受信後、pod の終了指示を開始し、エンドポイントコントローラーは pod の終了指示を監視し、対応するサービスリソースを削除します。pod は実行を停止し、kubelet は apiServer に pod リソースの猶予期間を 0 に設定するよう要求し、削除操作を完了します。apiserver は最終情報を etcd に保存し、これで pod の削除が完了します。
- ユーザーは apiServer に pod オブジェクトの削除コマンドを送信します。
- apiServer 内の pod オブジェクト情報は時間の経過とともに更新され、猶予期間内(デフォルト 30 秒)では、pod は dead と見なされます。
- pod を terminating 状態にマークします。
- kubelet は pod オブジェクトが terminating 状態に変わるのを監視し、pod の終了プロセスを開始します。
- エンドポイントコントローラーは pod オブジェクトの終了動作を監視し、すべての一致するエンドポイントのサービスリソースのエンドポイントリストからそれを削除します。
- 現在の pod オブジェクトが preStop フックハンドラーを定義している場合、terminating にマークされた後、同期的に実行を開始します。
- pod オブジェクト内のコンテナプロセスは停止信号を受け取ります。
- 猶予期間が終了した後、pod 内にまだ実行中のプロセスが存在する場合、pod オブジェクトは即時終了の信号を受け取ります。
- kubelet は apiServer にこの pod リソースの猶予期間を 0 に設定するよう要求し、削除操作を完了します。この時点で pod はユーザーにとっては見えなくなります。
初期化コンテナ#
初期化コンテナは Pod の主コンテナが起動する前に実行されるコンテナで、主コンテナの前処理を行います。主に 2 つの特徴があります:
- 初期化コンテナは終了するまで実行を完了する必要があります。もし初期化コンテナの実行が失敗した場合、Kubernetes は成功するまで再起動する必要があります。
- 初期化コンテナは定義された順序で実行する必要があります。前のコンテナが成功した場合にのみ、次のコンテナが実行されます。
初期化コンテナには多くのアプリケーションシーンがあり、以下は最も一般的なものです: - 主コンテナのイメージに存在しないツールプログラムやカスタムコードを提供します。
- 初期化コンテナはアプリケーションコンテナよりも先にシリアルに起動し、実行を完了する必要があるため、アプリケーションコンテナの起動を遅延させるために使用できます。
次に、以下の要求をシミュレートするケースを作成します:
主コンテナとして Nginx を実行するが、Nginx を実行する前に MySQL と Redis が存在するサーバーに接続できる必要があります。
テストを簡素化するために、MySQL と Redis の IP アドレスをそれぞれ 192.168.18.103 と 192.168.18.104 に設定します(注意:これらの IP は ping 通しません、環境にこれらの IP がないため)。
pod-initcontainer.yaml ファイルを作成し、内容は以下の通りです:
apiVersion: v1
kind: Pod
metadata:
name: pod-initcontainer
namespace: dev
labels:
user: xudaxian
spec:
containers: # コンテナ設定
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
resources:
limits:
cpu: "2"
memory: "10Gi"
requests:
cpu: "1"
memory: "10Mi"
initContainers: # 初期化コンテナ設定
- name: test-mysql
image: busybox:1.30
command: ["sh","-c","until ping 192.168.18.103 -c 1;do echo waiting for mysql ...;sleep 2;done;"]
securityContext:
privileged: true # 特権モードでコンテナを実行
- name: test-redis
image: busybox:1.30
command: ["sh","-c","until ping 192.168.18.104 -c 1;do echo waiting for redis ...;sleep 2;done;"]
コマンドを実行した後、test-mysql は正常に作成されず、その後のコンテナも作成できません。アクセス可能な IP に変更してから再度コマンドを実行すると、順番に正常に作成されます。
フック関数#
Kubernetes は主コンテナの起動後と停止前に 2 つのフック関数を提供します:
-
post start:コンテナ作成後に実行され、失敗した場合はコンテナを再起動します。
-
pre stop:コンテナ終了前に実行され、実行が完了した後にコンテナは正常に終了します。完了するまでコンテナの削除操作はブロックされます。
フックハンドラーは以下の 3 つの方法でアクションを定義することをサポートします:
- exec コマンド:コンテナ内で 1 回コマンドを実行します。
.......
lifecycle:
postStart:
exec:
command:
- cat
- /tmp/healthy
.......
- tcpSocket:現在のコンテナが指定されたソケットにアクセスしようとします。
.......
lifecycle:
postStart:
tcpSocket:
port: 8080
.......
- httpGet:現在のコンテナ内で特定の URL に HTTP リクエストを発行します。
.......
lifecycle:
postStart:
httpGet:
path: / #URIアドレス
port: 80 #ポート番号
host: 192.168.109.100 #ホストアドレス
scheme: HTTP #サポートされるプロトコル、httpまたはhttps
.......
コンテナプローブ#
コンテナプローブは、コンテナ内のアプリケーションインスタンスが正常に動作しているかどうかを検出するために使用され、ビジネスの可用性を保証するための伝統的なメカニズムです。プローブを通じて、インスタンスの状態が期待通りでない場合、Kubernetes はその問題のあるインスタンスを「取り除き」、ビジネスのトラフィックを負担しません。Kubernetes は、コンテナプローブを実現するために 2 種類のプローブを提供します:
-
liveness probes:生存性プローブ、アプリケーションインスタンスが現在正常に動作しているかどうかを検出します。そうでない場合、k8s はコンテナを再起動します。
-
readiness probes:準備性プローブ、アプリケーションインスタンスがリクエストを受け入れることができるかどうかを検出します。できない場合、k8s はトラフィックを転送しません。
livenessProbe:生存性プローブ、コンテナを再起動するかどうかを決定します。
readinessProbe:準備性プローブ、リクエストをコンテナに転送するかどうかを決定します。
k8s は 1.16 バージョン以降に startupProbe プローブを追加し、コンテナ内のアプリケーションプログラムが起動したかどうかを判断します。startupProbe プローブが設定されている場合、他のプローブは startupProbe プローブが成功するまで禁止されます。一度成功すると、再度プローブは行われません。
上記の 2 種類のプローブは現在 3 つのプローブ方法をサポートしています:
- exec コマンド:コンテナ内で 1 回コマンドを実行し、コマンドの終了コードが 0 の場合、プログラムは正常と見なされます。それ以外は異常と見なされます。
……
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
……
- tcpSocket:ユーザーコンテナのポートにアクセスしようとし、接続を確立できればプログラムは正常と見なされます。それ以外は異常と見なされます。
……
livenessProbe:
tcpSocket:
port: 8080
……
- httpGet:コンテナ内の Web アプリケーションの URL を呼び出し、返されたステータスコードが 200 と 399 の間であればプログラムは正常と見なされます。それ以外は異常と見なされます。
……
livenessProbe:
httpGet:
path: / #URIアドレス
port: 80 #ポート番号
host: 127.0.0.1 #ホストアドレス
scheme: HTTP #サポートされるプロトコル、httpまたはhttps
……
再起動ポリシー#
コンテナプローブで問題が発生した場合、Kubernetes はコンテナが存在する Pod を再起動します。これは Pod の再起動ポリシーによって決定されます。Pod の再起動ポリシーには 3 種類があります:
- Always:コンテナが失敗した場合、自動的にそのコンテナを再起動します。デフォルト値です。
- OnFailure:コンテナが終了し、終了コードが 0 でない場合に再起動します。
- Never:状態に関係なく、そのコンテナを再起動しません。
再起動ポリシーは Pod オブジェクト内のすべてのコンテナに適用され、最初に再起動が必要なコンテナは、必要なときに即座に再起動され、その後の再起動操作は kubelet によって一定の時間遅延されます。再起動操作の遅延時間は 10 秒、20 秒、40 秒、80 秒、160 秒、300 秒で、300 秒が最大の遅延時間です。
Pod のスケジューリング#
デフォルトでは、Pod がどの Node ノードで実行されるかは、Scheduler コンポーネントが適切なアルゴリズムを使用して計算します。このプロセスは人工的に制御されません。しかし、実際の使用では、特定の Pod を特定のノードに到達させたい場合が多く、これには Kubernetes の Pod スケジューリングルールを理解する必要があります。Kubernetes は 4 つの主要なスケジューリング方法を提供しています。
- 自動スケジューリング:どの Node ノードで実行されるかは、Scheduler が一連のアルゴリズムを使用して計算します。
- 指向スケジューリング:NodeName、NodeSelector。
- アフィニティスケジューリング:NodeAffinity、PodAffinity、PodAntiAffinity。
- 汚染(耐性)スケジューリング:Taints、Toleration。
指向スケジューリング#
指向スケジューリングは、Pod に宣言されたnodeName
またはnodeSelector
を利用して、Pod を希望する Node ノードにスケジュールすることを指します。注意すべきは、ここでのスケジューリングは強制的であり、スケジュール対象の Node が存在しなくても、上記にスケジュールされますが、Pod の実行は失敗します。
nodeName#
nodeName は Pod を指定された名前の Node ノードに強制的にスケジュールするために使用されます。この方法は、Scheduler のスケジューリングロジックを直接スキップし、Pod を指定された名前のノードに直接スケジュールします。
pod-nodename.yaml ファイルを作成し、内容は以下の通りです:
apiVersion: v1
kind: Pod
metadata:
name: pod-nodename
namespace: dev
labels:
user: xudaxian
spec:
containers: # コンテナ設定
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
nodeName: k8s-node1 # k8s-node1ノードにスケジュールするよう指定
nodeSelector#
nodeSelector は、指定されたラベルが追加された Node ノードに Pod をスケジュールするために使用されます。これは Kubernetes の label-selector メカニズムによって実現されます。言い換えれば、Pod が作成される前に、Scheduler は MatchNodeSelector スケジューリングポリシーを使用してラベルをマッチングし、ターゲットノードを見つけ、Pod をターゲットノードにスケジュールします。このマッチングルールは強制的です。
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeselector
namespace: dev
spec:
containers: # コンテナ設定
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
nodeSelector:
nodeenv: pro # nodeenv=proのNodeノードにスケジュールするよう指定
アフィニティスケジューリング#
指向スケジューリングの 2 つの方法は非常に便利ですが、条件を満たす Node が存在しない場合、Pod は実行されません。たとえクラスター内に利用可能な Node のリストがあっても、これが使用シーンを制限します。
上記の問題に基づいて、Kubernetes はアフィニティスケジューリング(Affinity)を提供します。これは nodeSelector の基礎の上に拡張され、条件を満たす Node を優先的に選択してスケジュールすることができ、条件を満たさないノードにもスケジュールできるため、スケジューリングがより柔軟になります。Affinity は主に 3 つのカテゴリに分かれます:
- nodeAffinity(node アフィニティ):Node をターゲットにし、Pod がどの Node にスケジュールできるかを解決します。
- podAffinity(pod アフィニティ):Pod をターゲットにし、Pod がどの既存の Pod と同じトポロジー領域にデプロイできるかを解決します。
- podAntiAffinity(pod 反アフィニティ):Pod をターゲットにし、Pod がどの既存の Pod と同じトポロジー領域にデプロイできないかを解決します。
アフィニティと反アフィニティの使用シーンの説明:
- アフィニティ:2 つのアプリケーションが頻繁に相互作用する場合、アフィニティを利用して 2 つのアプリケーションをできるだけ近くに配置する必要があります。これにより、ネットワーク通信によるパフォーマンスの損失を減らすことができます。
- 反アフィニティ:アプリケーションが複数のレプリカデプロイを採用している場合、反アフィニティを利用して各アプリケーションインスタンスを異なる Node に分散させる必要があります。これにより、サービスの高可用性が向上します。
nodeAffinity(node アフィニティ)#
nodeAffinity のオプション設定を確認します:
pod.spec.affinity.nodeAffinity
requiredDuringSchedulingIgnoredDuringExecution Nodeノードは指定されたすべてのルールを満たす必要があり、これはハード制約に相当します。
nodeSelectorTerms ノード選択リスト
matchFields ノードフィールドに基づくノード選択器要求リスト
matchExpressions ノードラベルに基づくノード選択器要求リスト(推奨)
key キー
values 値
operator 演算子はExists, DoesNotExist, In, NotIn, Gt, Ltをサポートします。
preferredDuringSchedulingIgnoredDuringExecution 指定されたルールを満たすNodeに優先的にスケジュールされます。これはソフト制約(傾向)です。
preference ノード選択器項目、関連する重み付けと関連付けられています。
matchFields ノードフィールドに基づくノード選択器要求リスト
matchExpressions ノードラベルに基づくノード選択器要求リスト(推奨)
key キー
values 値
operator 演算子はIn, NotIn, Exists, DoesNotExist, Gt, Ltをサポートします。
weight 傾向の重み、範囲は1-100です。
演示 requiredDuringSchedulingIgnoredDuringExecution:
pod-nodeaffinity-required.yaml ファイルを作成し、内容は以下の通りです:
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeaffinity-required
namespace: dev
spec:
containers: # コンテナ設定
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
affinity: # アフィニティ設定
nodeAffinity: # nodeアフィニティ設定
requiredDuringSchedulingIgnoredDuringExecution: # Nodeノードは指定されたすべてのルールを満たす必要があり、これはハードルールに相当します。定向スケジューリングに似ています。
nodeSelectorTerms: # ノード選択リスト
- matchExpressions:
- key: nodeenv # nodeenvラベルを持つノードをマッチングし、valueが"xxx"または"yyy"のノード
operator: In
values:
- "xxx"
- "yyy"
nodeAffinity の注意事項:
- nodeSelector と nodeAffinity の両方が定義されている場合、Pod は指定された Node で実行されるために両方の条件を満たす必要があります。
- nodeAffinity が複数の nodeSelectorTerms を指定している場合、1 つのマッチが成功すれば十分です。
- 1 つの nodeSelectorTerms 内に複数の matchExpressions がある場合、ノードはすべてを満たす必要があります。
- Pod が実行中にその Node のラベルが変更され、Pod の nodeAffinity の要件を満たさなくなった場合、システムはこの変化を無視します。
podAffinity(pod アフィニティ)#
podAffinity は主に実行中の Pod を参照として、新しく作成された Pod を参照の Pod と同じ領域に配置する機能を実現します。
PodAffinity のオプション設定:
pod.spec.affinity.podAffinity
requiredDuringSchedulingIgnoredDuringExecution ハード制約
namespaces 参照podのnamespaceを指定
topologyKey スケジューリングのスコープを指定
labelSelector ラベル選択器
matchExpressions ノードラベルに基づくノード選択器要求リスト(推奨)
key キー
values 値
operator 演算子はIn, NotIn, Exists, DoesNotExistをサポートします。
matchLabels 複数のmatchExpressionsのマッピング内容
preferredDuringSchedulingIgnoredDuringExecution ソフト制約
podAffinityTerm オプション
namespaces
topologyKey
labelSelector
matchExpressions
key キー
values 値
operator
matchLabels
weight 傾向の重み、範囲は1-1
topologyKey はスケジューリングのスコープを指定します。例えば:
- kubernetes.io/hostname を指定すると、Node ノードで区別されます。
- beta.kubernetes.io/os を指定すると、Node ノードのオペレーティングシステムの種類で区別されます。
requiredDuringSchedulingIgnoredDuringExecution を演示します。
pod-podaffinity-requred.yaml ファイルを作成し、内容は以下の通りです:
apiVersion: v1
kind: Pod
metadata:
name: pod-podaffinity-requred
namespace: dev
spec:
containers: # コンテナ設定
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
affinity: # アフィニティ設定
podAffinity: # Podアフィニティ
requiredDuringSchedulingIgnoredDuringExecution: # ハード制約
- labelSelector:
matchExpressions: # このPodはpodenv=xxxまたはpodenv=yyyのラベルを持つPodと同じNode上に存在する必要があります。明らかにそのようなPodは存在しません。
- key: podenv
operator: In
values:
- "xxx"
- "yyy"
topologyKey: kubernetes.io/hostname
podAntiAffinity(pod 反アフィニティ)#
podAntiAffinity は主に実行中の Pod を参照として、新しく作成された Pod と参照の Pod が同じ領域に存在しない機能を実現します。
その設定方法は podAffinity と同じです。
apiVersion: v1
kind: Pod
metadata:
name: pod-podantiaffinity-requred
namespace: dev
spec:
containers: # コンテナ設定
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
affinity: # アフィニティ設定
podAntiAffinity: # Pod反アフィニティ
requiredDuringSchedulingIgnoredDuringExecution: # ハード制約
- labelSelector:
matchExpressions:
- key: podenv
operator: In
values:
- "pro"
topologyKey: kubernetes.io/hostname
汚染と耐性#
汚染(Taints)#
前述のスケジューリング方法はすべて Pod の視点から、Pod に属性を追加することで、Pod が特定の Node にスケジュールされるかどうかを決定します。実際には、Node の視点から、Node に汚染属性を追加することで、Pod がスケジュールされるかどうかを決定することもできます。
Node が汚染されると、Pod との間に排他的な関係が生じ、Pod のスケジューリングを拒否し、すでに存在する Pod を追放することさえできます。
汚染の形式は:key=valueで、key と value は汚染のラベルで、effect は汚染の作用を説明します。以下の 3 つのオプションをサポートします:
- PreferNoSchedule:Kubernetes は、他にスケジュールできるノードがない場合を除いて、汚染された Node に Pod をスケジュールすることをできるだけ避けます。
- NoSchedule:Kubernetes は、汚染された Node に Pod をスケジュールしませんが、すでに存在する Pod には影響しません。
- NoExecute:Kubernetes は、汚染された Node に Pod をスケジュールせず、すでに存在する Pod を追放します。
耐性(Toleration)#
上記で汚染の作用を説明しました。Node に汚染を追加して Pod のスケジュールを拒否することができますが、もし Pod を汚染された Node にスケジュールしたい場合は、耐性を使用する必要があります。
汚染は拒否、耐性は無視です。Node は汚染によって Pod のスケジュールを拒否し、Pod は耐性によって拒否を無視します。
耐性の詳細設定:
kubectl explain pod.spec.tolerations
......
FIELDS:
key # 容認する汚染のキーに対応し、空はすべてのキーにマッチします。
value # 容認する汚染の値に対応します。
operator # key-valueの演算子、EqualとExists(デフォルト)をサポートします。
effect # 汚染のeffectに対応し、空はすべての影響にマッチします。
tolerationSeconds # 耐性時間、effectがNoExecuteのときに有効で、PodがNodeに滞在する時間を示します。
operator が Equal の場合、Node ノードに複数の Taint がある場合、Pod は各 Taint に対して耐性を持つ必要があります。
operator が Exists の場合、以下の 3 つの書き方があります:
- 指定された汚染を容認し、汚染は指定された effect を持ちます:
- 指定された汚染を容認し、具体的な effect を考慮しません:
- すべての汚染を容認します(注意が必要です):
tolerations: # 耐性
- key: "tag" # 容認する汚染のkey
operator: Exists # 演算子
effect: NoExecute # 耐性のルールを追加します。ここではラベルの汚染ルールと一致する必要があります。
tolerations: # 耐性
- key: "tag" # 容認する汚染のkey
operator: Exists # 演算子
tolerations: # 耐性
- operator: Exists # 演算子
Pod コントローラー#
Kubernetes では、Pod の作成方法に応じて、Pod を 2 つのカテゴリに分けることができます:
- 自律型 Pod:Kubernetes が直接作成した Pod で、この Pod は削除されると消え、再作成されません。
- コントローラーによって作成された Pod:Pod コントローラーによって作成された Pod で、この Pod は削除されても自動的に再作成されます。
Pod コントローラー:Pod を管理する中間層で、Pod コントローラーを使用すると、必要な Pod の数と種類を指定するだけで、条件を満たす Pod を作成し、各 Pod がユーザーの期待する状態にあることを保証します。Pod が実行中に故障が発生した場合、コントローラーは指定されたポリシーに基づいて Pod を再起動または再作成します。
Kubernetes には多くの種類の Pod コントローラーがあり、それぞれに適したシーンがあります。一般的なものは以下の通りです:
- ReplicationController:比較的原始的な Pod コントローラーで、すでに廃止され、ReplicaSet に置き換えられました。
- ReplicaSet:指定された数の Pod が実行されることを保証し、Pod の数の変更やイメージのバージョン変更をサポートします。
- Deployment:ReplicaSet を制御して Pod を制御し、ローリングアップグレードやバージョンのロールバックをサポートします。
- Horizontal Pod Autoscaler:クラスターの負荷に応じて Pod の数を自動的に調整し、ピークを平準化します。
- DaemonSet:クラスター内の指定された Node 上で 1 つのレプリカを実行し、一般的にはデーモンプロセスタスクに使用されます。
- Job:作成された Pod はタスクを完了するとすぐに終了し、一時的なタスクを実行するために使用されます。
- CronJob:作成された Pod は定期的に実行され、定期的なタスクを実行するために使用されます。
- StatefulSet:状態を持つアプリケーションを管理します。
ReplicaSet(RS)#
ReplicaSet の主な役割は、一定数の Pod が正常に実行されることを保証することで、これらの Pod の実行状態を継続的に監視し、Pod に障害が発生した場合は再起動または再作成します。
ReplicaSet のリソースマニフェストファイル:
apiVersion: apps/v1 # バージョン
kind: ReplicaSet # タイプ
metadata: # メタデータ
name: # rs名
namespace: # 所属ネームスペース
labels: # ラベル
controller: rs
spec: # 詳細説明
replicas: 3 # レプリカ数
selector: # セレクター、どのPodをこのコントローラーが管理するかを指定
matchLabels: # Labelsマッチングルール
app: nginx-pod
matchExpressions: # Expressionsマッチングルール
- {key: app, operator: In, values: [nginx-pod]}
template: # テンプレート、レプリカ数が不足している場合、以下のテンプレートに基づいてpodレプリカを作成します
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
ここで新たに理解する必要がある設定項目は spec の下のいくつかのオプションです:
- replicas:レプリカ数を指定します。実際には、現在の rs が作成する Pod の数です。デフォルトは 1 です。
- selector:セレクターで、Pod コントローラーと Pod の関連関係を確立する役割を果たします。Label Selector メカニズムを採用しています(Pod モジュールにラベルを定義し、コントローラーにセレクターを定義することで、現在のコントローラーがどの Pod を管理できるかを示すことができます)。
- template:テンプレートで、現在のコントローラーが Pod を作成するために使用するテンプレートです。実際には、前に学んだ Pod の定義が含まれています。
Deployment(Deploy)#
サービスオーケストレーションの問題をより良く解決するために、Kubernetes は v1.2 バージョンから Deployment コントローラーを導入しました。特に言及すべきは、Deployment コントローラーは Pod を直接管理するのではなく、ReplicaSet を管理することによって Pod を間接的に管理します。つまり、Deployment は ReplicaSet を管理し、ReplicaSet は Pod を管理します。したがって、Deployment の機能は ReplicaSet よりも強力です。
Deployment の主な機能は以下の通りです:
- ReplicaSet のすべての機能をサポートします。
- 公開の停止、再開をサポートします。
- バージョンのローリングアップデートとバージョンのロールバックをサポートします。
Deployment のリソースマニフェスト:
apiVersion: apps/v1 # バージョン
kind: Deployment # タイプ
metadata: # メタデータ
name: # rs名
namespace: # 所属ネームスペース
labels: # ラベル
controller: deploy
spec: # 詳細説明
replicas: 3 # レプリカ数
revisionHistoryLimit: 3 # 歴史的バージョンを保持します。デフォルトは10です。
paused: false # デプロイを一時停止します。デフォルトはfalseです。
progressDeadlineSeconds: 600 # デプロイのタイムアウト時間(秒)、デフォルトは600です。
strategy: # 戦略
type: RollingUpdate # ローリングアップデート戦略
rollingUpdate: # ローリングアップデート
maxSurge: 30% # 最大で追加で存在できるレプリカ数。パーセントまたは整数で指定できます。
maxUnavailable: 30% # アップグレード中に最大で不可用状態のPodの最大数。パーセントまたは整数で指定できます。
selector: # セレクター、どのPodをこのコントローラーが管理するかを指定
matchLabels: # Labelsマッチングルール
app: nginx-pod
matchExpressions: # Expressionsマッチングルール
- {key: app, operator: In, values: [nginx-pod]}
template: # テンプレート、レプリカ数が不足している場合、以下のテンプレートに基づいてpodレプリカを作成します
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
Deployment は 2 つのイメージ更新戦略をサポートします:再構築更新とローリングアップデート(デフォルト)で、strategy オプションを通じて設定できます。
strategy: 新しいPodが古いPodを置き換える戦略を指定します。2つの属性をサポートします。
type: 戦略タイプを指定します。2つの戦略をサポートします。
Recreate:新しいPodを作成する前に、すべての既存のPodを殺します。
RollingUpdate:ローリングアップデート、つまり一部を殺し、一部を起動し、更新プロセス中に2つのバージョンのPodが存在します。
rollingUpdate:typeがRollingUpdateの場合に有効で、rollingUpdateのパラメータを設定します。2つの属性をサポートします:
maxUnavailable:アップグレード中に不可用のPodの最大数を指定します。デフォルトは25%です。
maxSurge:アップグレード中に期待されるPodの最大数を超えることができる最大数を指定します。デフォルトは25%です。
Deployment はバージョンアップグレードプロセス中の一時停止、再開機能やバージョンのロールバックなど、多くの機能をサポートしています。以下に具体的に見てみましょう:
# バージョンアップグレード関連機能
kubetl rollout パラメータ deploy xx # 以下の選択をサポート
# status 現在のアップグレード状態を表示
# history アップグレードの履歴を表示
# pause アップグレードプロセスを一時停止
# resume 一時停止されたアップグレードプロセスを再開
# restart アップグレードプロセスを再起動
# undo 前のバージョンにロールバック(--to-revisionを使用して指定のバージョンにロールバックできます)
Deployment がバージョンのロールバックを実現できるのは、歴史的な ReplicaSet を記録することによって実現されます。ロールバックしたいバージョンがある場合、現在のバージョンの Pod 数を 0 に減らし、ロールバックバージョンの Pod 数を目標数に引き上げるだけで済みます。
カナリアリリース#
Deployment は更新プロセス中の制御をサポートし、更新操作を一時停止(pause)したり、更新操作を再開(resume)したりできます。
たとえば、新しい Pod リソースが作成された後、すぐに更新プロセスを一時停止します。この時点で、新しいバージョンのアプリケーションが一部だけ存在し、主に古いバージョンが残ります。その後、少数のユーザーリクエストを新しいバージョンの Pod アプリケーションにルーティングし、期待通りに安定して動作するかどうかを観察します。問題がなければ、残りの Pod リソースのローリングアップデートを続行します。問題があれば、すぐにロールバック操作を行います。
Horizontal Pod Autoscaler(HPA)#
手動で kubectl scale コマンドを実行して Pod のスケールを調整できますが、これは明らかに Kubernetes の位置付け目標である自動化とインテリジェンスには合致しません。Kubernetes は Pod の使用状況を監視し、Pod の数を自動的に調整できることを期待しており、これにより HPA というコントローラーが生まれました。
HPA は各 Pod の利用率を取得し、HPA で定義された指標と比較し、スケールする具体的な値を計算し、最終的に Pod の数を調整します。実際、HPA も以前の Deployment と同様に Kubernetes リソースオブジェクトの一種であり、ターゲット Pod の負荷変動を追跡分析することによって、ターゲット Pod のレプリカ数を調整する必要があるかどうかを判断します。
クラスターにリソース使用状況を収集するプログラムがない場合は、metrics-server をインストールすることを選択できます。
テスト例:
apiVersion: autoscaling/v1 # バージョン
kind: HorizontalPodAutoscaler # タイプ
metadata: # メタデータ
name: pc-hpa # deploymentの名前
namespace: dev # ネームスペース
spec:
minReplicas: 1 # 最小Pod数
maxReplicas: 10 # 最大Pod数
targetCPUUtilizationPercentage: 3 # CPU使用率指標
scaleTargetRef: # 制御するNginxの情報を指定
apiVersion: apps/v1
kind: Deployment
name: nginx
DaemonSet(DS)#
DaemonSet タイプのコントローラーは、クラスター内のすべての(または指定された)ノードで 1 つのレプリカが実行されることを保証します。一般的には、ログ収集やノード監視などのシーンに使用されます。つまり、Pod が提供する機能がノードレベルのものである場合(各ノードが必要とし、かつ 1 つだけ必要とする場合)、この種の Pod は DaemonSet タイプのコントローラーを使用して作成するのが適しています。
DaemonSet コントローラーの特徴:
- クラスターにノードが追加されるたびに、指定された Pod レプリカもそのノードに追加されます。
- ノードがクラスターから削除されると、Pod もガベージコレクションされます。
DaemonSet のリソースマニフェスト:
apiVersion: apps/v1 # バージョン
kind: DaemonSet # タイプ
metadata: # メタデータ
name: # 名称
namespace: # ネームスペース
labels: # ラベル
controller: daemonset
spec: # 詳細説明
revisionHistoryLimit: 3 # 歴史的バージョンを保持します。
updateStrategy: # 更新戦略
type: RollingUpdate # ローリングアップデート戦略
rollingUpdate: # ローリングアップデート
maxUnavailable: 1 # 最大不可用状態のPodの最大数。パーセントまたは整数で指定できます。
selector: # セレクター、どのPodをこのコントローラーが管理するかを指定
matchLabels: # Labelsマッチングルール
app: nginx-pod
matchExpressions: # Expressionsマッチングルール
- key: app
operator: In
values:
- nginx-pod
template: # テンプレート、レプリカ数が不足している場合、以下のテンプレートに基づいてPodテンプレートを作成します
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
Job#
Job は、バッチ処理の短期的な一時的タスクを担当します。
Job の特徴:
- Job が作成した Pod が成功裏に終了すると、Job は成功裏に終了した Pod の数を記録します。
- 成功裏に終了した Pod が指定された数に達すると、Job は実行を完了します。
Job は指定された数の Pod が実行されることを保証します。
Job のリソースマニフェスト:
apiVersion: batch/v1 # バージョン
kind: Job # タイプ
metadata: # メタデータ
name: # 名称
namespace: # ネームスペース
labels: # ラベル
controller: job
spec: # 詳細説明
completions: 1 # Jobが成功裏に実行されるPodの総数を指定します。デフォルトは1です。
parallelism: 1 # Jobが任意の時点で並行して実行するPodの数を指定します。デフォルトは1です。
activeDeadlineSeconds: 30 # Jobが実行できる時間制限を指定します。時間を超えると、システムは終了を試みます。
backoffLimit: 6 # Jobが失敗した後の再試行回数を指定します。デフォルトは6です。
manualSelector: true # セレクターを使用してPodを選択できるかどうか。デフォルトはfalseです。
selector: # セレクター、どのPodをこのコントローラーが管理するかを指定
matchLabels: # Labelsマッチングルール
app: counter-pod
matchExpressions: # Expressionsマッチングルール
- key: app
operator: In
values:
- counter-pod
template: # テンプレート、レプリカ数が不足している場合、以下のテンプレートに基づいてPodテンプレートを作成します
metadata:
labels:
app: counter-pod
spec:
restartPolicy: Never # 再起動ポリシーはNeverまたはOnFailureに設定する必要があります。
containers:
- name: counter
image: busybox:1.30
command: ["/bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1;do echo $i;sleep 20;done"]
テンプレート内の再起動ポリシーに関する説明:
- OnFailure に設定すると、Job は Pod が故障したときにコンテナを再起動しますが、Pod を作成せず、失敗回数は変わりません。
- Never に設定すると、Job は Pod が故障したときに新しい Pod を作成し、故障した Pod は消えず、再起動せず、失敗回数が + 1 されます。
- Always に設定すると、常に再起動され、Pod タスクが繰り返し実行されることを意味し、Job の定義と矛盾するため、Always に設定することはできません。
CronJob(CJ)#
CronJob コントローラーは Job コントローラーリソースを管理対象としており、Job コントローラーが定義した作業タスクはそのコントローラーリソースが作成された後に即座に実行されますが、CronJob は Linux オペレーティングシステムの周期的なタスク作業計画のように、実行時間点と繰り返し実行の方法を制御できます。つまり、CronJob は特定の時間点で(繰り返し)Job タスクを実行できます。
CronJob のリソースマニフェストファイル:
apiVersion: batch/v1beta1 # バージョン
kind: CronJob # タイプ
metadata: # メタデータ
name: # rs名
namespace: # 所属ネームスペース
labels: # ラベル
controller: cronjob
spec: # 詳細説明
schedule: # cron形式の作業スケジュール実行時間点、タスクがいつ実行されるかを制御します。
concurrencyPolicy: # 同時実行ポリシー、前回の作業がまだ完了していない場合、次の作業をどのように実行するかを定義します。
failedJobHistoryLimit: # 失敗したタスク実行の履歴を保持する数。デフォルトは1です。
successfulJobHistoryLimit: # 成功したタスク実行の履歴を保持する数。デフォルトは3です。
startingDeadlineSeconds: # 作業開始エラーのタイムアウト時間。
jobTemplate: # jobコントローラーのテンプレートで、cronjobコントローラーがjobオブジェクトを生成するために使用します。以下は実際にはjobの定義です。
metadata:
spec:
completions: 1
parallelism: 1
activeDeadlineSeconds: 30
backoffLimit: 6
manualSelector: true
selector:
matchLabels:
app: counter-pod
matchExpressions: ルール
- {key: app, operator: In, values: [counter-pod]}
template:
metadata:
labels:
app: counter-pod
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox:1.30
command: ["bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 20;done"]
重点的に説明する必要があるいくつかのオプション:
schedule:cron 式で、タスクの実行時間を指定します。
*/1 * * * *
<分> < 時間 > < 日 > < 月 > < 曜日 >
分:値は0から59まで。
時間:値は0から23まで。
日:値は1から31まで。
月:値は1から12まで。
曜日:値は0から6まで、0は日曜日を表します。
複数の時間はカンマで区切ることができます。範囲はハイフンで指定できます。*はワイルドカードとして使用できます。/は毎...を示します。
concurrencyPolicy:
Allow: Jobs の同時実行を許可(デフォルト)
Forbid: 同時実行を禁止し、前回の実行がまだ完了していない場合は次の実行をスキップします。
Replace: 現在実行中の作業をキャンセルし、新しい作業で置き換えます。
StatefulSet(有状態)#
無状態アプリケーション:
- Pod はすべて同じと見なされます。
- 順序の要件はありません。
- どの Node ノードで実行されるかを考慮する必要はありません。
- 自由にスケールアップおよびスケールダウンできます。
有状態アプリケーション:
- 順序の要件があります。
- 各 Pod は異なると見なされます。
- どの Node ノードで実行されるかを考慮する必要があります。
- 順序に従ってスケールアップおよびスケールダウンする必要があります。
- 各 Pod は独立しており、Pod の起動順序と一意性を保持します。
StatefulSet は Kubernetes が提供する有状態アプリケーションの負荷管理コントローラーです。
StatefulSet のデプロイには HeadlessService(無頭サービス)が必要です。
なぜ HeadlessService(無頭サービス)が必要なのか?
- Deployment を使用する場合、各 Pod の名前は順序がなく、ランダムな文字列であるため、Pod の名前は無秩序ですが、StatefulSet では順序が必要であり、各 Pod は自由に置き換えられることはできません。Pod が再構築されると、Pod の名前は同じままです。
- Pod の IP は変化するため、Pod の名前で識別されます。Pod の名前は Pod の一意の識別子であり、持続的で安定した有効性を持つ必要があります。この場合、無頭サービスを使用して、各 Pod に一意の名前を付けることができます。
StatefulSet は RabbitMQ クラスター、Zookeeper クラスター、MySQL クラスター、Eureka クラスターなどのデプロイに一般的に使用されます。
演示例:
apiVersion: v1
kind: Service
metadata:
name: service-headliness
namespace: dev
spec:
selector:
app: nginx-pod
clusterIP: None # clusterIPをNoneに設定すると、headliness Serviceが作成されます。
type: ClusterIP
ports:
- port: 80 # Serviceのポート
targetPort: 80 # Podのポート
...
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: pc-statefulset
namespace: dev
spec:
replicas: 3
serviceName: service-headliness
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
サービス#
Kubernetes において、Pod はアプリケーションのキャリアであり、Pod の IP を通じてアプリケーションにアクセスできますが、Pod の IP アドレスは固定されていないため、サービスへのアクセスに直接 Pod の IP を使用するのは不便です。
この問題を解決するために、Kubernetes は Service リソースを提供します。Service は同じサービスを提供する複数の Pod を集約し、統一されたエントリーアドレスを提供します。Service のエントリーアドレスにアクセスすることで、背後の Pod サービスにアクセスできます。
Service は多くの場合、単なる概念であり、実際に機能するのは kube-proxy サービスプロセスです。各 Node ノード上で kube-proxy サービスプロセスが実行されています。Service を作成すると、API Server は作成された Service の情報を etcd に書き込み、kube-proxy はリスニングメカニズムに基づいてこの Service の変化を検出し、最新の Service 情報を対応するアクセスルールに変換します。
kube-proxy は現在 3 つの動作モードをサポートしています:
-
userspace モード:
-
userspace モードでは、kube-proxy は各 Service のリスニングポートを作成し、Cluster IP へのリクエストは iptables ルールによって kube-proxy のリスニングポートにリダイレクトされます。kube-proxy は LB アルゴリズム(負荷均衡アルゴリズム)に基づいてサービスを提供する Pod を選択し、接続を確立してリクエストを Pod に転送します。
-
このモードでは、kube-proxy は 4 層負荷均衡器の役割を果たします。kube-proxy が userspace で実行されているため、転送処理中にカーネルとユーザースペース間のデータコピーが増加し、安定性は高いですが、効率は非常に低下します。
-
-
iptables モード:
-
iptables モードでは、kube-proxy は Service のバックエンドの各 Pod に対応する iptables ルールを作成し、Cluster IP へのリクエストを直接 Pod の IP にリダイレクトします。
-
このモードでは、kube-proxy は 4 層負荷均衡器の役割を果たさず、iptables ルールを作成するだけです。このモードの利点は、userspace モードよりも効率が高いことですが、柔軟な LB 戦略を提供できず、バックエンド Pod が利用できない場合は再試行できません。
-
-
ipvs モード:
-
ipvs モードは iptables に似ており、kube-proxy は Pod の変化を監視し、対応する ipvs ルールを作成します。ipvs は iptables よりも転送効率が高く、さらに多くの LB(負荷均衡)アルゴリズムをサポートします。
サービスの種類#
Service のリソースマニフェスト:
apiVersion: v1 # バージョン
kind: Service # タイプ
metadata: # メタデータ
name: # リソース名
namespace: # ネームスペース
spec:
selector: # ラベルセレクター、現在のServiceがどのPodを代理するかを決定します。
app: nginx
type: NodePort # Serviceのタイプ、Serviceのアクセス方法を指定します。
clusterIP: # 仮想サービスのIPアドレス
sessionAffinity: # セッション親和性、ClientIP、Noneの2つのオプションをサポートし、デフォルト値はNoneです。
ports: # ポート情報
- port: 8080 # Serviceポート
protocol: TCP # プロトコル
targetPort : # Podポート
nodePort: # ホストポート
spec.type の説明:
- ClusterIP:デフォルト値で、Kubernetes システムが自動的に割り当てる仮想 IP で、クラスター内部からのみアクセスできます。
- NodePort:Service を指定された Node のポートを介して外部に公開し、この方法でクラスター外部からサービスにアクセスできます。
- LoadBalancer:外部負荷均衡器を使用してサービスへの負荷分散を行います。このモードは外部クラウド環境のサポートが必要です。
- ExternalName:クラスター外部のサービスをクラスター内部に引き入れ、直接この Service を使用してアクセスします。
ClusterIP タイプの Service#
エンドポイント(実際にはあまり使用されません)
- エンドポイントは Kubernetes 内のリソースオブジェクトで、etcd に保存され、Service に対応するすべての Pod のアクセスアドレスを記録します。これは service 設定ファイル内の selector 記述に基づいて生成されます。
- Service は一組の Pod で構成され、これらの Pod は Endpoints によって公開されます。言い換えれば、service と Pod の間の関連は Endpoints によって実現されます。
負荷分散戦略
Service へのアクセスはバックエンドの Pod に分散されます。現在、Kubernetes は 2 つの負荷分散戦略を提供しています:
- 定義しない場合、デフォルトで kube-proxy の戦略を使用します。たとえば、ランダム、ラウンドロビンなど。
- クライアントアドレスに基づくセッション保持モード、つまり同じクライアントからのすべてのリクエストが固定の Pod に転送されます。これは、従来のセッションベースの認証プロジェクトにとって非常に便利です。このモードは、spec に sessionAffinity: ClusterIP オプションを追加することで実現できます。
HeadLiness タイプの Service#
特定のシーンでは、開発者は Service が提供する負荷均衡機能を使用したくない場合があり、負荷均衡戦略を自分で制御したいと考えています。このような場合、Kubernetes は Headless Service を提供します。この種の Service は Cluster IP を割り当てず、Service にアクセスするには Service のドメイン名を使用する必要があります。
NodePort タイプの Service#
前のケースで作成した Service の IP アドレスは、クラスター内部からのみアクセス可能です。Service をクラスター外部に公開したい場合は、NodePort タイプの Service を使用する必要があります。NodePort の動作原理は、Service のポートを Node のポートにマッピングすることで、NodeIPを介して Service にアクセスできるようにします。
LoadBalancer タイプの Service#
ExternalName タイプの Service#
ExternalName タイプの Service は、クラスター外部のサービスを引き入れるために使用され、externalName 属性を使用してサービスのアドレスを指定し、クラスター内部からこの Service にアクセスすることで外部のサービスにアクセスできます。
Ingress#
Service がクラスター外部にサービスを公開する主な方法は NodePort と LoadBalancer の 2 つですが、これらの方法にはいくつかの欠点があります:
- NodePort 方式の欠点は、多くのクラスターのマシンのポートを占有することです。クラスターサービスが増えると、この欠点はますます顕著になります。
- LoadBalancer の欠点は、各 Service に LB が必要で、無駄で面倒であり、Kubernetes の外部デバイスのサポートが必要です。
このような状況に基づいて、Kubernetes は Ingress リソースオブジェクトを提供します。Ingress は、NodePort または LB の 1 つだけで複数の Service を公開するニーズを満たすことができます。動作メカニズムは以下の図のようになります:
実際、Ingress は 7 層の負荷均衡器に相当し、Kubernetes によるリバースプロキシの抽象化です。その動作原理は Nginx に似ており、Ingress 内に多くのマッピングルールが構築され、Ingress Controller はこれらの設定ルールの変化を監視し、Nginx のリバースプロキシ設定に変換して外部にサービスを提供します。
- Ingress:Kubernetes 内のオブジェクトで、リクエストが Service にどのように転送されるかのルールを定義します。
- Ingress Controller:リバースプロキシおよび負荷均衡を具体的に実装するプログラムで、Ingress が定義したルールを解析し、設定されたルールに基づいてリクエストを転送します。実装方法は多く、Nginx、Contour、Haproxy などがあります。
Ingress(Nginx を使用)の動作原理は以下の通りです:
- ユーザーは Ingress ルールを作成し、どのドメイン名が Kubernetes クラスター内のどの Service に対応するかを示します。
- Ingress コントローラーは Ingress サービスルールの変化を動的に感知し、対応する Nginx のリバースプロキシ設定を生成します。
- Ingress コントローラーは生成された Nginx 設定を実行中の Nginx サービスに書き込み、動的に更新します。
- これで、実際に機能しているのは Nginx であり、ユーザーが定義したリクエストルールが内部に設定されています。
Ingress は Http プロキシと Https プロキシをサポートします。
データストレージ#
前述のように、コンテナのライフサイクルは非常に短く、頻繁に作成および削除される可能性があります。このため、コンテナが削除されると、コンテナ内に保存されているデータも消去されます。この結果は、ユーザーにとっては望ましくない場合があります。コンテナのデータを永続的に保存するために、Kubernetes は Volume の概念を導入しました。
Volume は Pod 内で複数のコンテナがアクセスできる共有ディレクトリで、Pod に定義され、Pod 内の複数のコンテナが具体的なファイルディレクトリにマウントされます。Kubernetes は Volume を通じて、同じ Pod 内の異なるコンテナ間でのデータ共有およびデータの永続的な保存を実現します。Volume のライフは Pod 内の単一のコンテナのライフサイクルとは関連しておらず、コンテナが終了または再起動しても Volume 内のデータは失われません。
Kubernetes の Volume は多くのタイプをサポートしており、一般的なものは以下の通りです:
- シンプルストレージ:EmptyDir、HostPath、NFS
- 高度なストレージ:PV、PVC
- 設定ストレージ:ConfigMap、Secret
基本ストレージ#
EmptyDir#
EmptyDir は最も基本的な Volume タイプで、EmptyDir はホスト上の空のディレクトリです。
EmptyDir は Pod が Node に割り当てられたときに作成され、その初期内容は空であり、ホスト上の対応するディレクトリファイルを指定する必要はありません。Kubernetes が自動的にディレクトリを割り当てます。Pod が破棄されると、EmptyDir 内のデータも永続的に削除されます。EmptyDir の用途は以下の通りです:
- 一時的なスペース、たとえば、アプリケーションが実行中に必要な一時ディレクトリとして、永続的に保持する必要がない場合。
- 1 つのコンテナが別のコンテナからデータを取得するためのディレクトリ(複数のコンテナ