ReplicaSetとLabel


はじめに

前回はReplicaSetの動作を確認しました。
サーバーが落ちてレプリカの数が減ると、セルフヒーリング機能でレプリカの数を修復しました。
Masterサーバがレプリカの数が減ったことを検知して、Workerノードに対してレプリカを増やすよう指示を出すわけですが、レプリカの数をどうやってカウントしているかというと、「label」でカウントしています。Podの数ではありません。
今回はこの動作を確認してみたいと思います。

ReplicaSetとLabelの関係

図で書くとこのような感じです。細かく書くともっといろいろありますが、ここでは大体のイメージがつかめれば。

マニフェスト(yamlファイル)だと、「spec.selector.matchLabels」と「spec.template.metadata.labels」の記述を合わせる必要があります。

sampleReplicaSet.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-E.yaml
The ReplicaSet "sample-pod3" is invalid: spec.template.metadata.labels: Invalid value: map[string]string{"app":"nginx-redis-e"}: `selector` does not match template `labels`

ReplicaSetと同じLabelをPodで指定したらどうなるか。

次は、ReplicaSetで指定しているLabelと同じLabelを別のPodで指定してデプロイしてみます。
まず、今の状態を確認します。

$ kubectl get rs -o wide
NAME          DESIRED   CURRENT   READY   AGE   CONTAINERS    IMAGES                      SELECTOR
sample-pod3   3         3         3       24h   nginx,redis   nginx:latest,redis:latest   app=nginx-redis
$ kubectl get pod -L app
NAME                READY   STATUS    RESTARTS   AGE   APP
sample-pod3-7nxxr   2/2     Running   2          24h   nginx-redis
sample-pod3-ngw8x   2/2     Running   2          23h   nginx-redis
sample-pod3-thbbx   2/2     Running   2          24h   nginx-redis

次に、同じLabelを持つ以下のyamlファイルのPodをデプロイします。

nginx_redis.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-pod1
  labels:
    app: nginx-redis
spec:
  containers:
    - name: nginx
      image: nginx:latest
    - name: redis
      image: redis:latest
$ kubectl apply -f nginx_redis.yaml
pod/sample-pod1 created
$ kubectl get pod
NAME                READY   STATUS        RESTARTS   AGE
sample-pod1         0/2     Terminating   0          2s
sample-pod3-7nxxr   2/2     Running       2          24h
sample-pod3-ngw8x   2/2     Running       2          23h
sample-pod3-thbbx   2/2     Running       2          24h
$ kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
sample-pod3-7nxxr   2/2     Running   2          24h
sample-pod3-ngw8x   2/2     Running   2          23h
sample-pod3-thbbx   2/2     Running   2          24h

Podはデプロイされますが、Terminatingの状態ですぐに削除されてしまいます。
何度かやってみましたが、常に新規にデプロイしたPodが削除されました。

マニュアルの記載は見つけられなかったので、常にこうなることがKubernetesの動作として正しいのかまでは確認できていませんが、Labelの設定には注意する必要があることがわかりました。
少なくとも、ReplicaSetで使用するラベルは、独立したユニークなものである必要があります。