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についてお話しします。

ではまた。

採用情報

「チームアイオス」入団者募集

〜就活で悩むアナタに来て欲しい〜