OpenShift Image Registry のリソース使用量を調べる

# はじめに

OpenShift に標準で付いてくる、Docker API に対応した Container Registry である、`Integrated OpenShift Registry` のリソース使用量について調べる。

呼び方は、[マニュアル](https://docs.openshift.com/container-platform/4.10/registry/index.html) でも`Integrated OpenShift Container registry` や、`build-in container registry` となっていたり、呼び方が一定していない。

マニュアルの小見出しのタイトルになっている`Integrated OpenShift Container registry`と呼ぶのが良さそうだが、長いので単に `Image Regsitry` と呼ぶ事にする。

# Image Regsitry を構成する

`Image Registry` は、OpenShift install 時から Pod はデプロイされているが、保管のための PVC 等を設定しないと使えるようにならない。

### 作業しやすいように namespace (project) を openshift-image-registry に設定する

```
[root@bastion openshift]# oc project openshift-image-registry
```

### OpenShift Install 直後にDeployされている Pod の確認

OpenShift Install 時に、Cluster Operators の一つとして導入されているので、特に明示的に Operator を導入しなくても Pod が稼働している。

```
[root@bastion openshift]# oc get pod -o wide
NAME                                               READY   STATUS      RESTARTS   AGE     IP             NODE                          NOMINATED NODE   READINESS GATES
cluster-image-registry-operator-76c559c75d-fgnq9   1/1     Running     3          18d     10.129.0.8     ocp48-6vldl-master-2          <none>           <none>       
image-pruner-27476640-jsd5z                        0/1     Completed   0          2d2h    10.131.2.9     ocp48-6vldl-infra-94vjm       <none>           <none>       
image-pruner-27478080-gq9wv                        0/1     Completed   0          26h     10.128.4.79    ocp48-6vldl-infra-gjgwb       <none>           <none>       
image-pruner-27479520-5722s                        0/1     Completed   0          159m    10.128.4.53    ocp48-6vldl-infra-gjgwb       <none>           <none>       
node-ca-4ss8j                                      1/1     Running     0          13d     172.18.0.37    ocp48-6vldl-infra-gjgwb       <none>           <none>       
node-ca-7k5ng                                      1/1     Running     0          18d     172.18.0.53    ocp48-6vldl-worker-xp4bf      <none>           <none>       
node-ca-8xr48                                      1/1     Running     0          18d     172.18.0.32    ocp48-6vldl-master-2          <none>           <none>       
node-ca-fzn97                                      1/1     Running     0          18d     172.18.0.124   ocp48-6vldl-master-0          <none>           <none>       
node-ca-g2dm7                                      1/1     Running     0          13d     172.18.0.43    ocp48-6vldl-infra-94vjm       <none>           <none>       
node-ca-m7jjb                                      1/1     Running     0          6d12h   172.18.0.154   ocp48-6vldl-infra-ocs-xdhvn   <none>           <none>       
node-ca-tlghq                                      1/1     Running     0          6d12h   172.18.0.113   ocp48-6vldl-infra-ocs-rdt8b   <none>           <none>       
node-ca-ttlkf                                      1/1     Running     0          18d     172.18.0.25    ocp48-6vldl-master-1          <none>           <none>       
node-ca-zfcmp                                      1/1     Running     0          18d     172.18.0.180   ocp48-6vldl-worker-85crs      <none>           <none>       
node-ca-zjkvh                                      1/1     Running     0          13d     172.18.0.67    ocp48-6vldl-infra-qvwvk       <none>           <none>
node-ca-zmnbn                                      1/1     Running     0          18d     172.18.0.126   ocp48-6vldl-worker-hdj9r      <none>           <none>       
node-ca-zxpb8                                      1/1     Running     0          6d12h   172.18.0.186   ocp48-6vldl-infra-ocs-dbjbd   <none>           <none>       
[root@bastion openshift]#
```

`cluster-image-registry-operator-xxxx` は、`Operator (controller)` の Pod で、この時点では `Image Regstry` のPodは、まだデプロイされていない。後続の手順で設定を `Managed` にする事で `Image Regsitry` の Replica が Deployされる。

`node-ca-xxxx` は、特に `tolearation` 対策を何もしていないが、`Manster Node` や `Infrastrucutre Node` にもそれぞれ一ずつデプロイされている。

### Image を保管するための PVC/PVを作成する

RWO の PVを作成する。`Container Registry` のレプリカが1つだけであれば(デフォルトは1つである）、RWOのPVもサポートされる。([OpenShift Container Platform supports ReadWriteOnce access for image registry storage when you have only one replica](https://docs.openshift.com/container-platform/4.10/registry/configuring_registry_storage/configuring-registry-storage-vsphere.html))

以下の PVC のマニフェストを作って適用する。
`thin` は、このクラスターがある VMware 環境の RWO の `storage class`。vmdk を使った PV が Dynamic Provisioning される。

```
[root@bastion openshift]# cat my-registry-pvc.yaml 
apiVersion: "v1"
kind: "PersistentVolumeClaim"
metadata:
  name: "image-registry-storage"
spec:
  accessModes:
    - "ReadWriteOnce"
  resources:
    requests:
      storage: "100Gi"
  storageClassName: thin
  psersistentVolumeRecliamPolicy: Delete
[root@bastion openshift]# 
```

上記のマニフェストを apply する。

```
[root@bastion openshift]# oc apply -f my-registry-pvc.yaml 
persistentvolumeclaim/image-registry-storage created
[root@bastion openshift]# oc get pvc
NAME                     STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
image-registry-storage   Bound    pvc-5757992a-320a-4a3f-91f4-74dd8f69e452   100Gi      RWO            thin           3s
[root@bastion openshift]#

```

RWO タイプのPVを使う場合は、Pod の rolloutStrategy は、`Recreate` (一旦、レプリカ数を 0にしてリソースを開放する) にする必要があるので、設定をアップデートする。

```
oc patch config.imageregistry.operator.openshift.io/cluster --type=merge -p '{"spec":{"rolloutStrategy":"Recreate","replicas":1}}'
```

**補則**
`Recreate` を設定しないと、1つしかない Pod を `Removed` に戻してから再度 `Managed` に戻した時に Pod が起動してこなかった。
以下は、その時の `oc describe co image-registry` のメッセージ。

```
 unable to sync storage configuration: cannot use ReadWriteOnce access mode with RollingUpdate rollout strategy
```

一般的には、Pod が一つであれば (replica =1) 、`RollingUpdate` と RWO のPV を組み合わせも Pod 再起動時に[PVはきちんとマウントされる](https://qiita.com/Yuhkih/items/b3b05cceda5ee4b629f9) 。
OpenShift の Image Registry のケースは、コンテナの生成すら開始されないので、コンテナ生成前にOperator が何か見ているような動きになっている。(通常のRWO PV のマウントの競合のケースであれば、コンテナは生成され、マウントの所で停止するはず)

尚、Image Registry の Pod も一度 Pod をマニュアルの設定通りに正常に起動してしまえば、Pod の delete をしても、きちんと Pod が再生成され、RWO PVもマウントされる。

### デフォルトで `Removed` になっている設定を `Managed` の状態にする

`Managed` にする事で、`Image Regsitry` の Pod がデプロイされる。

```
[root@bastion openshift]# oc get configs.imageregistry.operator.openshift.io cluster -o=jsonpath='{.spec.managementState}{"\n"}'
Removed
[root@bastion openshift]# oc patch configs.imageregistry.operator.openshift.io cluster --type merge --patch '{"spec":{"managementState":"Managed"}}'
config.imageregistry.operator.openshift.io/cluster patched
[root@bastion openshift]# oc get configs.imageregistry.operator.openshift.io cluster -o=jsonpath='{.spec.managementState}{"\n"}'
Managed
[root@bastion openshift]#
```

### 作成した PVC を Image Registry に参照させる

以下のコマンドで設定を変更する

```
[root@bastion openshift]# oc edit configs.imageregistry.operator.openshift.io
```

変更する場所は `spec.storage` の部分。Image を保管するために作った PVC 名を指定する。

```
<省略>
spec:
  httpSecret: f1cbccb18e364f85e7f2b74bf63c9ed1a120322a849c4b6567405526c1f954c58eb8b3f740e96783bddb97d5beb1c91d440c66adc0590b4b34f5099952d20b84
  logLevel: Normal
  managementState: Managed
  observedConfig: null
  operatorLogLevel: Normal
  proxy: {}
  replicas: 1
  requests:
    read:
      maxWaitInQueue: 0s
    write:
      maxWaitInQueue: 0s
  rolloutStrategy: RollingUpdate
  storage:                                # 変更
    pvc:                                  # 追加
      claim: image-registry-storage       # 追加
<省略>
```




# 主要 Pod の Requests / Limits 調査

openshift-registry namespace に存在する Pod に指定されている Requests と Limits を oc (kubectl) get pod を使って調べて行く。

## 起動している Pod の確認 

インストール時の設定 (`Removed`) を `Mnaged` に変更した後なので、OpenShift インストール後の一覧と見比べると、新たに `image-registry-xxxx` という Pod が起動しているのがわかる。(一人だけ 11m と新しい)

```
[root@bastion openshift]# oc get pods
NAME                                               READY   STATUS      RESTARTS   AGE
cluster-image-registry-operator-76c559c75d-fgnq9   1/1     Running     3          18d
image-pruner-27476640-jsd5z                        0/1     Completed   0          2d3h
image-pruner-27478080-gq9wv                        0/1     Completed   0          27h
image-pruner-27479520-5722s                        0/1     Completed   0          3h11m
image-registry-5db9dc4959-gqmhp                    1/1     Running     0          11m
node-ca-4ss8j                                      1/1     Running     0          13d
node-ca-7k5ng                                      1/1     Running     0          18d
node-ca-8xr48                                      1/1     Running     0          18d
node-ca-fzn97                                      1/1     Running     0          18d
node-ca-g2dm7                                      1/1     Running     0          13d
node-ca-m7jjb                                      1/1     Running     0          6d13h
node-ca-tlghq                                      1/1     Running     0          6d13h
node-ca-ttlkf                                      1/1     Running     0          18d
node-ca-zfcmp                                      1/1     Running     0          18d
node-ca-zjkvh                                      1/1     Running     0          13d
node-ca-zmnbn                                      1/1     Running     0          18d
node-ca-zxpb8                                      1/1     Running     0          6d13h
[root@bastion openshift]#
```

メジャーな Pod の Limits / Request を確認していく

```yaml
[root@bastion openshift]# oc get pod cluster-image-registry-operator-76c559c75d-fgnq9 -o=jsonpath='{range .spec.containers[*]}{.name}{" "}{.resources}{"\n"}{end}{range .spec.initContainers[*]}{.name} {" "}{.resources}{"\n"}{end}'
cluster-image-registry-operator {"requests":{"cpu":"10m","memory":"50Mi"}}
[root@bastion openshift]# oc get pod image-pruner-27476640-jsd5z -o=jsonpath='{range .spec.containers[*]}{.name}{" "}{.resources}{"\n"}{end}{range .spec.initContainers[*]}{.name} {" "}{.resources}{"\n"}{end}'
image-pruner {"requests":{"cpu":"100m","memory":"256Mi"}}
[root@bastion openshift]# oc get pod image-registry-5db9dc4959-gqmhp -o=jsonpath='{range .spec.containers[*]}{.name}{" "}{.resources}{"\n"}{end}{range .spec.initContainers[*]}{.name} {" "}{.resources}{"\n"}{end}'
registry {"requests":{"cpu":"100m","memory":"256Mi"}}
[root@bastion openshift]# oc get pod node-ca-4ss8j  -o=jsonpath='{range .spec.containers[*]}{.name}{" "}{.resources}{"\n"}{end}{range .spec.initContainers[*]}{.name} {" "}{.resources}{"\n"}{end}'
node-ca {"requests":{"cpu":"10m","memory":"10Mi"}}
[root@bastion openshift]#
```

## コマンド結果のまとめ

空白部分は特に指定が無かった事を示す。


|Pod 名                        | container名  |CPU (Limits) |CPU (Requests) | Memory (Limits) | Memory (Requests) |
|-----------------------------|-------------|------------|----------------|-----------------|-------------------|
|**cluster-image-registry-operator-xxxx** |cluster-image-registry-operator|       |    10m    |         |   50Mi   |
|**climage-pruner-xxxx**                  |image-pruner                   |       |    100m   |         |   256Mi  |
|**cluster-image-registry-operator-xxxx** |cluster-image-registry-operator|       |    100m   |         |   256Mi  |
|**cluster-image-registry-operator-xxxx** |cluster-image-registry-operator|       |    10m    |         |   10Mi   |



# 実際に利用しているリソース量の確認

インストール直後のクリーンな状態。
`cluster-image-registry-operator-xxxx` が、request した Memory 以上を使っている以外は、request 量に対して下回っている。

```
[root@bastion openshift]# kubectl top pods --use-protocol-buffers
NAME                                               CPU(cores)   MEMORY(bytes)   
cluster-image-registry-operator-76c559c75d-fgnq9   15m          66Mi
image-registry-5db9dc4959-gqmhp                    1m           35Mi
node-ca-4ss8j                                      0m           1Mi
node-ca-7k5ng                                      0m           2Mi
node-ca-8xr48                                      0m           1Mi
node-ca-fzn97                                      0m           1Mi
node-ca-g2dm7                                      0m           1Mi
node-ca-m7jjb                                      0m           1Mi
node-ca-tlghq                                      0m           1Mi
node-ca-ttlkf                                      0m           1Mi
node-ca-zfcmp                                      0m           1Mi
node-ca-zjkvh                                      0m           1Mi
node-ca-zmnbn                                      0m           1Mi
node-ca-zxpb8                                      0m           1Mi
[root@bastion openshift]# 
```