ReplicaSetのスケーリング


はじめに

ReplicaSetは設定を変更することによって、レプリカの数を変更することができます。
今回はその動作を確認しました。

方法は二つあります。
1.kubectl scaleコマンドで変更する
2.マニフェストを書き換えて、kubectl applyコマンドで反映する

kubectl scaleコマンドで変更する

初期状態を確認します。

$ kubectl get pod -o wide
NAME                READY   STATUS    RESTARTS   AGE   IP               NODE           NOMINATED NODE   READINESS GATES
sample-pod3-rzmhb   2/2     Running   0          38s   192.168.79.91    k8s-worker01   <none>           <none>
sample-pod3-tjsdm   2/2     Running   0          38s   192.168.69.220   k8s-worker02   <none>           <none>
sample-pod3-zmjkj   2/2     Running   0          38s   192.168.79.83    k8s-worker01   <none>           <none>
$ kubectl get rs -o wide
NAME          DESIRED   CURRENT   READY   AGE   CONTAINERS    IMAGES                      SELECTOR
sample-pod3   3         3         3       47s   nginx,redis   nginx:latest,redis:latest   app=nginx-redis

レプリカを 3 -> 5 にスケールさせます。

$ kubectl scale replicaset --replicas=5 sample-pod3
replicaset.apps/sample-pod3 scaled
$ kubectl get pod -o wide
NAME                READY   STATUS    RESTARTS   AGE     IP               NODE           NOMINATED NODE   READINESS GATES
sample-pod3-bv9x8   2/2     Running   0          68s     192.168.79.87    k8s-worker01   <none>           <none>
sample-pod3-rzmhb   2/2     Running   0          2m42s   192.168.79.91    k8s-worker01   <none>           <none>
sample-pod3-tjsdm   2/2     Running   0          2m42s   192.168.69.220   k8s-worker02   <none>           <none>
sample-pod3-vg2g8   2/2     Running   0          68s     192.168.69.223   k8s-worker02   <none>           <none>
sample-pod3-zmjkj   2/2     Running   0          2m42s   192.168.79.83    k8s-worker01   <none>           <none>
$ kubectl get rs -o wide
NAME          DESIRED   CURRENT   READY   AGE     CONTAINERS    IMAGES                      SELECTOR
sample-pod3   5         5         5       2m37s   nginx,redis   nginx:latest,redis:latest   app=nginx-redis

レプリカが増えました。

Pod削除時の動作

ここで意図的にPodを削除して、セルフヒーリング機能が働くか確認してみます。

$ kubectl get pod -o wide
NAME                READY   STATUS    RESTARTS   AGE     IP               NODE           NOMINATED NODE   READINESS GATES
sample-pod3-bv9x8   2/2     Running   0          68s     192.168.79.87    k8s-worker01   <none>           <none>
sample-pod3-rzmhb   2/2     Running   0          2m42s   192.168.79.91    k8s-worker01   <none>           <none>
sample-pod3-tjsdm   2/2     Running   0          2m42s   192.168.69.220   k8s-worker02   <none>           <none>
sample-pod3-vg2g8   2/2     Running   0          68s     192.168.69.223   k8s-worker02   <none>           <none>
sample-pod3-zmjkj   2/2     Running   0          2m42s   192.168.79.83    k8s-worker01   <none>           <none>
$ kubectl delete pod sample-pod3-rzmhb
pod "sample-pod3-rzmhb" deleted
$ kubectl get pod -o wide
NAME                READY   STATUS    RESTARTS   AGE     IP               NODE           NOMINATED NODE   READINESS GATES
sample-pod3-bv9x8   2/2     Running   0          2m41s   192.168.79.87    k8s-worker01   <none>           <none>
sample-pod3-dgh4k   2/2     Running   0          9s      192.168.69.219   k8s-worker02   <none>           <none>
sample-pod3-tjsdm   2/2     Running   0          4m15s   192.168.69.220   k8s-worker02   <none>           <none>
sample-pod3-vg2g8   2/2     Running   0          2m41s   192.168.69.223   k8s-worker02   <none>           <none>
sample-pod3-zmjkj   2/2     Running   0          4m15s   192.168.79.83    k8s-worker01   <none>           <none>

分かりづらいんですが、二行目の「sample-pod3-rzmhb」を削除すると、「sample-pod3-dgh4k」が新たにデプロイされています。

これによって、kubectl scaleコマンドで設定したレプリカの数が、Masterサーバのマニュアルにも反映されていることが確認できます。

また、kubectl describeコマンドで、Podのデプロイ履歴も確認しておきます。

$ kubectl describe rs sample-pod3
Name:         sample-pod3
・・・
Events:
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  4m47s  replicaset-controller  Created pod: sample-pod3-rzmhb <-- 最初のデプロイ
  Normal  SuccessfulCreate  4m47s  replicaset-controller  Created pod: sample-pod3-tjsdm <-- 最初のデプロイ
  Normal  SuccessfulCreate  4m47s  replicaset-controller  Created pod: sample-pod3-zmjkj <-- 最初のデプロイ
  Normal  SuccessfulCreate  3m13s  replicaset-controller  Created pod: sample-pod3-vg2g8 <-- kubectl scaleでの追加
  Normal  SuccessfulCreate  3m13s  replicaset-controller  Created pod: sample-pod3-bv9x8 <-- kubectl scaleでの追加
  Normal  SuccessfulCreate  41s    replicaset-controller  Created pod: sample-pod3-dgh4k <-- セルフヒーリング機能による追加

ReplicaSetの削除

kubectl scaleコマンドでスケールさせると、当然yamlファイルは更新していません。
kubectl scaleコマンドでスケールさせた後に、変更していないyamlファイルで削除できるのか確認してみました。

sampleReplicaSet.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: sample-pod3
spec:
  replicas: 3  <-- レプリカの数は「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 get rs -o wide
NAME          DESIRED   CURRENT   READY   AGE     CONTAINERS    IMAGES                      SELECTOR
sample-pod3   5         5         5       4m35s   nginx,redis   nginx:latest,redis:latest   app=nginx-redis

yamlファイルのレプリカ数は「3」、実際のレプリカ数は「5」です。

削除してみます。

$ kubectl delete -f sampleReplicaSet.yaml
replicaset.apps "sample-pod3" deleted
$ kubectl get pod
NAME                READY   STATUS        RESTARTS   AGE
sample-pod3-bv9x8   0/2     Terminating   0          17m
sample-pod3-dgh4k   0/2     Terminating   0          14m
sample-pod3-tjsdm   0/2     Terminating   0          18m
sample-pod3-vg2g8   0/2     Terminating   0          17m
sample-pod3-zmjkj   0/2     Terminating   0          18m
$ kubectl get rs
No resources found in default namespace.

削除されました。

マニフェストを書き換えて、kubectl applyコマンドで反映する

初期状態を確認します。

$ kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
sample-pod3-67b24   2/2     Running   0          35s
sample-pod3-fk967   2/2     Running   0          35s
sample-pod3-ssn7z   2/2     Running   0          35s

yamlファイルのreplicasの値を変更して、applyします。

$ kubectl apply -f sampleReplicaSet.yaml
replicaset.apps/sample-pod3 configured
$ kubectl get rs
NAME          DESIRED   CURRENT   READY   AGE
sample-pod3   5         5         5       97s
$ kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
sample-pod3-67b24   2/2     Running   0          99s
sample-pod3-fk967   2/2     Running   0          99s
sample-pod3-mp6cs   2/2     Running   0          15s
sample-pod3-ssn7z   2/2     Running   0          99s
sample-pod3-w559b   2/2     Running   0          15s

これだけです。

まとめ

ReplicaSetのスケーリングの動作を確認できました。
kubectl scaleコマンドでのスケーリングは、今までのインフラ運用(一度設定したらあまり変えない)に慣れている方だと馴染みやすいかもしれません。(私もそうです)
しかし、Kubernetesで実現するマイクロアーキテクチャは、頻繁に環境を変更します。そのため、手作業で変更するのはあまり現実的ではなく、実際には、コードをGitリポジトリで管理しておいて、変更がコミットされたら自動で適用するCI/CDのパイプラインを構築することが多いです。
そのため、検証などでCI/CDのパイプラインを作るまでもない環境でも、マニフェストを書き換えてapplyする方法に慣れておいた方がよいでしょう。