Kubernetes ReplicaSetの概要
Kubernetes ReplicaSet とは?概要を解説
KubernetesにおけるReplicaSet(レプリカセット)は、クラスター内で実行されているレプリカPodのセット管理に使われるオブジェクトです。Podの安定した管理に役立つことから、うまく活用することにより、スケーラビリティや可用性を高められるでしょう。
Kubernetes レプリケーションコントローラの主な役割は、失敗した Pod の置き換えをスケジュールすることで、Pod のライフサイクルが維持されることを保証することです。コントローラにはいくつかの種類があり、それぞれが異なるユースケースに対応します。
しかし、すべてに共通する点が あります。それは、特定の Pod クラスターを常に監視し、適切な数のPodが常に稼働していることを確認することです。
この記事では、主要なコントローラの 1 つとしてReplicaSetの概要を説明したうえで、混同されがちな他のコントローラなどとの違いを解説します。
関 連 記 事
Kubernetesとは? | Kubernetesセキュリティ の基礎 | Kubernetesアーキテクチャの 設計方法 |
AWSのEKS (Elastic Kubernetes Service) | Kubernetesの クラスターとは? | Kubernetes のノードとは? |
KubernetesのPodとは? | KubernetesのHelmとは? | クラウドセキュリティと ランタイムインサイト |
Kubernetes ReplicaSetとは?
ReplicaSetとは、複数のPodに対しレプリカをセットで作るKubernetesオブジェクトのことで、コントローラの一種です。任意の時点において、クラスター内で実行されているレプリカ Pod のセット管理を安定させるために使用され、「RS」とも表記されます。
Kubernetes Pod は、通常は 1 つまたは複数のコンテナを含むクラスターデプロイユニットです。ただし、Pod(さらに、コンテナ)の存続期間は短いです。Pod は、Pending フェーズから始まり、プライマリコンテナの少なくとも 1 つが正常に開始されると、Running フェーズに進みます。
たとえば、サンプルアプリケーションをホストするコンテナが失敗することがあります。kubelet プロセスがホストとしてそれを自動的に再作成すると考えがちですが、コンテナが失敗したときに Pod は自動的には再スケジュールされません。その結果、リソースがないために Pod が再スケジュールされず、破棄されてしまうことがあるため、Pod 内のコンテナにも影響が及びます。アプリケーションの運用を維持するには、Pod の状態を追跡する必要があります。
Kubernetesの役割と機能
Kubernetes コントローラの主な目的は、どの時点でも同じ種類の N 個の Pod が常に稼働し続けていることを保証することで、望ましい状態を定義することです。そのために、サービスの可用性を保証するためによく使われるのが RS です。
Kubernetes は失敗またはアクセス不能になった Pod を置き換えるために、追加の Pod を自動的にデプロイすることで、ユーザーがアプリケーションにアクセスできなくなる事態を回避します。ReplicaSet を使用しない場合、必要な Pod と同数のマニフェストを構築しなければならないため、アプリケーションごとに多くの作業が発生します。
ReplicaSet には主に 2 つの機能があります。既存の Pod が失敗したときに新しい Pod を作成するための Pod テンプレートと、コントローラが実行し続ける必要がある望ましいレプリカ数を維持するためのレプリカカウントです。さらに ReplicaSet は、同じラベルのインスタンスが作成されたときに、追加の Pod のスケールダウンまたは削除を保証します。
その結果、指定した数のレプリカ Pod が常に稼働し続けることが保証されます。Kubernetes RS は、ロードバランシング、信頼性、スケーリングを次のようにサポートします:
- ロードバランシング: レプリケーションによって複数の Pod インスタンスを実行できます。これにより、複数の異なるインスタンスにトラフィックが送信されるため、単一のインスタンスに負荷がかかり過ぎる事態を回避できます。
- 信頼性: レプリケーションによって、複数のアプリケーションインスタンスを実行できるため、コンテナの 1 つが失敗しただけでアプリケーションが失敗することがなくなります。
- スケーリング: Kubernetes では、インスタンスを追加または削除することで、アプリケーションのスケールアップまたはスケールダウンを迅速に行うことができます。
ReplicaSet 構成
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: my-replicaset
labels:
my-label: my-value
spec:
replicas: 3
selector:
matchLabels:
my-label: my-value
template:
metadata:
labels:
my-label: my-value
spec:
containers:
- name: app-container
image: my-image:latest
ReplicaSet の定義に使用されるフィールドは次のとおりです:
- selector: この ReplicaSet に割り当てる Pod の特定に使用されます。
- replicas: ReplicaSet が維持すべき Pod の数を示します。
- template: 必要な数のレプリカを満たすために Pod を作成および追加するときに ReplicaSet が使用する Pod テンプレートを定義します。
- apiVersion: リソース ReplicaSet をサポートする Kubernetes API を定義します。API はそれぞれ特定のリソースをサポートします。Kind とともに明示的に定義できます。
- kind: Kubernetes API 用のリソースを ReplicaSet として定義します。
前述の RS マニフェストファイルは、ReplicaSet を使用して、my-image: latest コンテナイメージの 3 つのコピーを実行します。マニフェスト内の値を調整し、再適用することで、コピーの数を変更できます(kubectl apply -f my-manifest.yml)。
ReplicaSet と Deployment の違い
Deployment は ReplicaSet の代替です。Deployment は ReplicaSet を管理するために使用されます。Deployment は、ReplicaSet 経由で Pod セットに変更をロールアウトする場合に便利です。Deployment を使って ReplicaSet を管理するときには、直前の Deployment リビジョンにロールバックするだけです。
また、Deployment を使って新しい ReplicaSet リビジョンを作成し、既存の Pod を古いリビジョンから新しいリビジョンに移行することもできます。その後に、Deployment は古い未使用の ReplicaSet をクリーンアップできます。
使用法については、ReplicaSet が Pod の可用性を保証し、Deployment は 1 つまたは複数の ReplicaSet を制御することで異なるバージョンのアプリケーションを管理します。Deployment は、1 つまたは複数の ReplicaSet を管理することで、新しいバージョンのリリースを制御する、抽象度の高いツールです。ReplicaSet も Pod を管理し、特定の Pod インスタンスをスケールできますが、ローリングアップデートを行うことはできず、他のいくつかの機能を使用できません。これらの機能は代わりに、Deployment によって管理されます。Deployment は、Kubernetes ユーザーが現在やり取りする可能性が最も高いリソースです。
Deployment 構成
Deployment は、ReplicaSet と同様に、apiVersion、kind、metadata が定義されている必要がある、Kubernetes API オブジェクトです。Deployment の基本機能は、Kubernetes ドキュメントに掲載されている nginx-deployment.yaml の例を参照してください。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec: (1)
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec: (2)
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
上の例で、Deployment の名前は nginx-deployment です。まず、その宣言が ReplicaSet の宣言とほとんど同じであることを確認してください。実際、この ReplicaSet の内容がこの宣言からコピーされます。
ここで、望ましい状態を達成するために、3 つの nginx Pod が必要であることに注目してください。このために、nginx アプリケーションを 3 つのインスタンスにスケールするために必要なすべての情報を含んだ ReplicaSet が作成されます。
これにより、ReplicaSet と Pod を制御できる、宣言型インターフェイスが提供されます。その(最初の spec サブリソース内の)selector が、(2 つ目の spec サブリソース内で宣言された)app: nginx ラベルを照合することで、この Deployment で管理されるクラスター内の Pod を検出します。また、Deploymentの Pod テンプレートで宣言された nginx コンテナを参照します。Deployment について詳しくは、 上流ドキュメントをご覧ください。
ReplicaSet と ReplicationController の違い
Kubernetes ReplicaSet は、以前の Kubernetes ReplicationController を置き換えたものです。どちらも同じ目的のために同じように動作しますが、主な違いがいくつかあります。1 つ目は、ReplicationController ではセットベースの selector 条件が許可されませんでした。そのため、ReplicaSet に置き換えられることになりました。もう 1 つの主な違いは、ReplicaSet では、「ラベルセレクター」と呼ばれる Kubernetes 機能を使用してアイテムのセットを特定できることです。
「ローリングアップデート」機能は、ReplicationController の最も重要な機能の 1 つでした。この機能によって、ReplicationController は監督対象の Pod を、それらの Pod が提供しているサービスに最小限のダウンタイムで、またはダウンタイムなしで、更新できました。これを達成するために、古い Pod インスタンスは 1 つずつアップグレードされました。それでも、ReplicationController は柔軟性に欠けると見なされていました。これが、ReplicaSet とデプロイが ReplicationController 置き換えるために導入された理由です。
公式ドキュメントに掲載されている ReplicationController config YAML の以下の例では、nginx Web サーバーの 3 つのコピーを実行します。
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
ReplicaSet と StatefulSet の違い
StatefulSet を使用すると、起動順序と一意の識別子が保証された状態で Pod を作成できます。これらを使用することで、Pod が StatefulSet のライフサイクル全体で識別情報を維持することを保証できます。重要なことは、この機能によって、ストレージやネットワーキングなどのよく使われるコンポーネントの永続性が保証されるため、ステートフルなアプリケーションを Kubernetes 内で機能させることができます。
さらに、Pod が常に同じ順序で形成され、作成時にホスト名と内部クラスター DNS に適用される識別子が割り当てられます。これらの識別子により、環境内の Pod が安定した予測可能なネットワーク識別情報を維持することが保証されます。
StatefulSet は、一意の命名規則を使用して各 Pod の永続的な識別情報を維持することで、Pod の順序と一意性を保証するのに役立ちます。 こちらの Pod は同じ仕様で作成されますが、交換可能ではなく、各 Pod にはどのような再スケジュールが実行されても保持される一意の識別情報が割り当てられます。
各 Pod に割り当てられる DNS 名は、次の規則に従います。
- <StatefulSet 名>-<順序インデックス>
PersistentVolumeClaim テンプレートは、StatefulSet の主要機能です。各レプリカに独自のボリュームと状態を割り当てることで、StatefulSet の永続性を保証します。各 Pod は独自の PVC(PersistentVolumeClaim)を生成します。その結果、高可用性データベースのコンポーネントなど、大きなデータセットをレプリケーションするときに、この強力なボリュームが役立ちます。
StatefulSet は、次の 1 つ、または複数の要件を必要とするアプリケーション向けに多くのユースケースを用意しています:
- 安定性と一意性を持つネットワーク識別情報。
- 安定性と永続性を持つストレージ。
- 順序が正しくシームレスなスケーリングとデプロイ。
- 順序付けされ、自動化されたローリングアップデート。
StatefulSet について詳しくは、上流ドキュメントを参照してください。
ReplicaSet と DaemonSet の違い
DaemonSet は Kubernetes クラスターの主要コンポーネントです。管理者は、すべてのノードまたはノードのサブセットにサービス(Pod)を簡単に構成できます。一部またはすべてのノードで Pod がレプリケーションされることを保証します。新しいノードが Kubernetes クラスターに追加されると、新しい Pod がそのノードに作成されます。そのため、DaemonSet がデプロイする必要があるレプリカ数を指定する必要がありません。
DaemonSet コントローラは、ノードに関連付けられた Pod が削除されるときに、ガベージコレクションが実行されることを保証します。DaemonSet を削除すると、その DaemonSet が作成したすべての Pod を削除することになります。DaemonSet はクラスターレベルアプリケーションを実行するためによく使用されます。たとえば、次のようなタスクのために使用されます:
- 各ノードにクラスターストレージデーモン(glusterd や Ceph など)をインストールする
- 各ノードでログ収集デーモン(Fluentd や Logstash など)を使用する
- 各ノードでノードモニタリングデーモン(Prometheus Node Exporter、collectd、Datadog Agent など)を実行する
ReplicaSet と同様に、DaemonSet は Pod がクラスター内のすべてのノードで運用されることを保証するコントローラです。ノードがクラスターに追加されるときまたはクラスターから削除されるときに Pod を自動的に追加または削除する点に関しては、DaemonSet も類似の機能を備えています。
マシンレベルの機能(マシンモニタリングやマシンロギングなど)を実行する Pod の場合は、ReplicaSet ではなく DaemonSet を使用することをお勧めします。これらの Pod のライフサイクルは、マシンのライフサイクルに関連付けられます。これらの Pod はそのマシン上で運用する必要があります。そうでないと、他の Pod は開始できません。これらの Pod は、マシンが再起動またはシャットダウンできる状態になったときに、安全に終了できます。
DaemonSet を記述するために YAML ファイルを使用できます。たとえば、次のファイル(daemonset.yaml)は、fluentd-elasticsearch Docker イメージを実行する DaemonSet を記述しています。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
Code language: JavaScript (javascript)
まとめ
この投稿で、Kubernetes ReplicaSet を使用してアプリケーションライフサイクル管理を自動化して生産性を高める方法を解説しました。また、Deployment、StatefulSet、DaemonSet など、さまざまな代替リソースとそのユースケースについても説明しました。
この知識を Kubernetes クラスターで最大限に活用するには、ユースケースに最適な機能を持つ最適なリソースを選択できるように、Pod のニーズを評価する必要があるでしょう。