KubernetesのPod、ReplicaSet、Deploymentの違いを理解する
皆さん、こんにちは。技術開発グループのn-ozawanです。
今週末は父の日ですね。母の日と父の日はアメリカが発祥って知ってましたか?
本題です。
Kubernetes、難しいですよね。Kubernetesを勉強すると最初に必ずPod、ReplicaSet、Deploymentの3つが出てきます。今日はKubernetesのPod、ReplicaSet、Deploymentの違いを理解したいと思います。
目次
Pod、ReplicaSet、Deploymentの違い
ノードとは
Kubernetesのクラスタは複数のノードから構成されています。ノードとはコンテナが動作するマシンで、仮想マシンでも物理マシンでもどちらでもノードになりえます。ノードには2つの種類があり、1つはControl Plane、1つはWorkerノードです。
Control Planeは、複数あるWorkderノードを管理して制御するノードです。Workerノードがそれぞれ好き勝手に動くとスケーリングなどの制御がままなりません。Control PlaneがWorkerノードの状況などを管理することでKubernetesが円滑に動くようになります。
Workerノードは、実際にコンテナが動くノードです。Workerノードにはkubeletと呼ばれるプロセスが動いており、kubeletがControl Planeと会話することにより、Control Planeは適切にノードを制御することが出来るようになっています。

ちなみに、Kubernetes関連のページや書籍を見ていると「マスターノード」と呼ばれるノードが登場します。「マスターノード」とは、Control Planeが動作するノードのことらしく、マスターノード=Control Planeという理解で良いかと思います。
Podとは
Podとは、Kubernetesが扱う最小のリソースで、1つ以上のコンテナで構成されています。また、KubernetesはPodごとにIPアドレスを付与します。もしPodが2つのコンテナで構成されている場合、2つのコンテナは1つのIPアドレスを共有します。
KubernetesはPodをWorkerノードのどこかに配置します。ノードへの配置は、ノードの性能や負荷などを考慮して、Kubernetesが適切に配置してくれます。

Podを作成する場合、Yamlファイルには以下のように記述します。
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
spec:
containers:
- name: nginx-container
image: nginx:latest
apiVersion
は「v1」固定です。kind
には「Pod」を指定します。metadata.name
はそのPodの名前です。spec.containers
にPodに配置したいコンテナを指定します。
ReplicaSetとは
ReplicaSetとは、Podを複製して、指定した数を維持するリソースです。コンテナを冗長化したいときに使います。ReplicaSetリソースを作成するときに、複製する数を指定します。ReplicaSetは指定された数分、Podを複製して、Workerノードに配置します。仮に複製するPodの数が、Workerノードよりも多い場合、1つのWorkerノードに2つ以上のPodが配置されます。
ReplicaSetはPodの数を維持します。例えば、Workerノードが故障した、コンテナで障害が発生したなどでコンテナが停止した場合、ReplicaSetはそれらを検知し、自動的にPodを配置しなおします。

ReplicaSetを作成する場合、Yamlファイルには以下のように記述します。
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: sample-replicaset
spec:
replicas: 4
selector:
matchLabels:
app: sample-replicaset
template:
metadata:
labels:
app: sample-replicaset
spec:
containers:
- name: nginx-container
image: nginx:latest
kind
に「ReplicaSet」を指定することで、そのリソースはReplicaSetになります。spec.replicas
には複製するPodの数を指定します。上記の場合「4」を指定しますので、Podは4つまで複製されます。
先ほど、ReplicaSetはPodの数を維持する、と書きました。これは、ReplicaSetは動作しているPodの数を把握していることを示します。ReplicaSetがどうやって数あるPodの中から該当するPodの数を把握しているかというと、クラスタ上で動作しているPodをラベルで検索して、その件数を見ています。
上記のYamlコードの場合、spec.template.metadata.labels
でPodに「app: sample-replicaset」というラベルを付与しています。そして、spec.selector.matchLabels
に「app: sample-replicaset」を指定することで、「「app: sample-replicaset」というラベルを付与したPodを4つまで複製する」という意味になります。

Deploymentとは
Deploymentとは、ReplicaSetに加えて、ローリングアップデートやロールバックなどを実現するリソースです。普段は1つのReplicaSetで動作するのですが、Podの変更を検知すると、新しいReplicaSetを作成して、新しいコンテナに置き換えていきます。徐々に新しいReplicaSetに置き換えていき、すべてのPodが新しいReplicaSetで動くようになればローリングアップデートは終了です。
古いReplicaSetはPod数が0のまま、定義だけが残っている状態になります。仮に新しいPodで問題が生じた場合、古いReplicaSetの方にPodを増やすことで以前の状態に戻す(ロールバック)ことが可能となります。

Deploymentを作成する場合、Yamlファイルには以下のように記述します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: 3
selector:
matchLabels:
app: sample-deployment
template:
metadata:
labels:
app: sample-deployment
spec:
containers:
- name: nginx-container
image: nginx:latest
kind
が「Deployment」になる以外、ReplicaSetと同じです。
Pod、ReplicaSet、Deploymentの関係性
既に述べた通り、PodはKubernetesが扱う最小のリソースです。ReplicaSetはそのPodを複製して、冗長化やスケーリングを実現します。そして、DeploymentはそのReplicaSetを管理してローリングアップデートやロールバックを実現します。
特別な理由がない限りは、Deploymentで環境を構築した方が良いかと思います。
おわりに
Kubernetesで必ず使われるPod、ReplicaSet、Deploymentについて纏めました。これらはまだコンテナをWorkerノードに配置しただけで、まだクラスタの外から見れない状態となっています。クラスタの外からコンテナにアクセスするにはClusterIPやNodePortなどのServiceAPIを利用する必要があります。次回はKubernetesのServiceAPIについてお話しします。
ではまた。