#はじめに
Podの性能や可用性を高めるために、Kubernetesは基本的に「スケールアウト」させます。スケールアウトはノード(ここではPod/コンテナ)のCPU/メモリを増やすのではなく、ノード(Pod/コンテナ)を増やします。
ちなみに、CPUやメモリを増やすのは「スケールアップ」。
このスケールアウトの仕組みとしてReplicaSetがあるので、今回はこの動作を確認してみます。
#ReplicaSetの作成
以下のyamlファイルを作成しました。
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: sample-pod3
spec:
replicas: 3
selector:
matchLabels:
app: nginx-redis
template:
metadata:
labels:
app: nginx-redis
spec:
containers:
- name: nginx
image: nginx:latest
- name: redis
image: redis:latest
デプロイします。
$ kubectl apply -f sampleReplicaSet.yaml
replicaset.apps/sample-pod3 created
ここでは、一発でデプロイできてることになってますが、実際にはyamlファイルのミスで何度かエラーが出てます。
・スペルミス
・インデントがずれてる
yamlの書式にも慣れていかないと。
##確認
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
sample-pod3 3 3 3 16m
$ kubectl get replicasets.apps -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
sample-pod3 3 3 3 16m nginx,redis nginx:latest,redis:latest app=nginx-redis
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
sample-pod3-7nxxr 2/2 Running 0 18m 192.168.69.216 k8s-worker02 <none> <none>
sample-pod3-86kqh 2/2 Running 0 18m 192.168.79.74 k8s-worker01 <none> <none>
sample-pod3-thbbx 2/2 Running 0 18m 192.168.69.202 k8s-worker02 <none> <none>
sample-pod3のレプリカが3つ作成されていることが確認できます。
Pod名は「[metadata.name]-[ランダムな英数字]」になっています。
ちなみに、レプリカセットを確認するサブコマンドの「rs」と「replicasets.apps」は同じ意味です。
Podがデプロイされているworkerノードも分散されていますね。
図で書くとこんな感じです。
#セルフヒーリング機能の確認
Kubernetesの特徴としてセルフヒーリング機能があります。これは、何かしら障害が発生した場合にもあらかじめ設定してある「あるべき姿」に戻す機能です。
この場合の「あるべき姿」はsample-pod3のレプリカが3つであることです。
##workerノードの停止
ここではworker01を停止します。shutdownするだけなので、割愛。
状態を確認します。worker01がNotReadyになっています。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master Ready master 11d v1.17.3
k8s-worker01 NotReady <none> 11d v1.17.3
k8s-worker02 Ready <none> 11d v1.17.3
##ReplicaSetの確認
停止して少し待ってから状態を確認します。
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
sample-pod3-7nxxr 2/2 Running 0 66m 192.168.69.216 k8s-worker02 <none> <none>
sample-pod3-86kqh 2/2 Terminating 0 66m 192.168.79.74 k8s-worker01 <none> <none>
sample-pod3-ngw8x 2/2 Running 0 20m 192.168.69.217 k8s-worker02 <none> <none>
sample-pod3-thbbx 2/2 Running 0 66m 192.168.69.202 k8s-worker02 <none> <none>
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
sample-pod3 3 3 3 70m
worker01にあった「sample-pod3-86kqh」が「Terminating」状態になって、新たに「sample-pod3-ngw8x」がworker02にデプロイされています。
新しく作成されているところがポイントで、Active-Standbyのようなデータを引き継いだフェイルオーバーではなく、新しいPodがデプロイされています。つまり、いままでworker01で処理されていたデータは引き継がれていません。
Kubernetesで実現するマイクロサービスは、このようにデータを保持しない「ステートレス」なアプリを基本とします。
そのために、保持しなければいけないデータやログなんかは別のボリュームに保存したりするので、この辺りはまた調べたいと思います。
なお、Podのデプロイ履歴は以下で確認できます。
$ kubectl describe rs sample-pod3
Name: sample-pod3
・・・
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 49m replicaset-controller Created pod: sample-pod3-thbbx
Normal SuccessfulCreate 49m replicaset-controller Created pod: sample-pod3-86kqh
Normal SuccessfulCreate 49m replicaset-controller Created pod: sample-pod3-7nxxr
Normal SuccessfulCreate 3m30s replicaset-controller Created pod: sample-pod3-ngw8x
このTerminatingになっているPodは、deleteで消せばいいらしいです。
Kubernetes.io
$ kubectl delete pod sample-pod3-86kqh
pod "sample-pod3-86kqh" deleted
なんとなく、使えなくなったPodのdeleteまでやってくれればいい気がしますが、何か理由でもあるのかな?
これで一通りReplicaSetの動作の確認ができました。ReplicaSetはKubernetesを使っていくうえで重要な要素だと思いますので、もう少し調べてみたいと思います。