[OpenShift]ResourceQuotaとLimitRangeの設定を確認する

#はじめに
今回はOpenShiftのResourceQuotaとLimitRange設定方法を確認します。

[第4章 クォータ](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.5/html/applications/quotas)
[6.3. 制限範囲の設定](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.5/html/nodes/nodes-cluster-limit-ranges)

#環境の確認
今回確認したクラスタ構成とバージョンです。

```
$ oc get node
NAME       STATUS   ROLES           AGE    VERSION
master01   Ready    master,worker   171d   v1.18.3+012b3ec
master02   Ready    master,worker   171d   v1.18.3+012b3ec
master03   Ready    master,worker   171d   v1.18.3+012b3ec
$ oc version
Client Version: 4.5.4
Server Version: 4.5.4
Kubernetes Version: v1.18.3+012b3ec
```

#ResourceQuota
今回はCPU、メモリ、configmapを設定します。このほかにserviceやPodなどの数も指定できます。

```
$ oc create quota test-quota --hard cpu=3,memory=1G,configmaps=5
resourcequota/test-quota created
```
コマンドで設定しましたが、yamlファイルを作ってapplyしても設定できます。

設定されているか確認します。

```
$ oc get resourcequotas 
NAME         AGE   REQUEST                                   LIMIT
test-quota   13s   configmaps: 0/5, cpu: 0/3, memory: 0/1G   
$ oc describe resourcequotas test-quota 
Name:       test-quota
Namespace:  test01
Resource    Used  Hard
--------    ----  ----
configmaps  0     5
cpu         0     3
memory      0     1G
```

#LimitRange
次はLimitRangeを設定します。
LimitRangeはコマンドでは設定できないようですので、yamlファイルを作成してapplyします。
以下のマニフェストを作成しました。マニュアルに記載されているそのままです。

```/tmp/limitrange.yaml
apiVersion: "v1"
kind: "LimitRange"
metadata:
  name: "resource-limits"
spec:
  limits:
    - type: "Container"
      max:
        cpu: "2"
        memory: "1Gi"
      min:
        cpu: "100m"
        memory: "4Mi"
      default:
        cpu: "300m"
        memory: "200Mi"
      defaultRequest:
        cpu: "200m"
        memory: "100Mi"
      maxLimitRequestRatio:
        cpu: "10"
```
```
$ oc apply -f /tmp/limitrange.yaml
limitrange/resource-limits created
```
確認します。

```
$ oc get limitranges 
NAME              CREATED AT
resource-limits   2021-01-24T14:03:33Z
$ oc describe limitranges 
Name:       resource-limits
Namespace:  test01
Type        Resource  Min   Max  Default Request  Default Limit  Max Limit/Request Ratio
----        --------  ---   ---  ca---------------  -------------  -----------------------
Container   cpu       100m  2    200m             300m           10
Container   memory    4Mi   1Gi  100Mi            200Mi          -
``` 

#デフォルトプロジェクトテンプレートへの設定
ResourceQuotaとLimitRangeは、デフォルトのテンプレートに設定することで、project作成時に設定するようにできます。

プロジェクトテンプレートをリダイレクトします。

```
$ oc adm create-bootstrap-project-template -o yaml >/tmp/template.yaml
```

以下のように編集します。
設定内容は、ResourceQuotaとLimitRangeで設定した内容と同じにしています。

```/tmp/template.yaml
apiVersion: template.openshift.io/v1
kind: Template
metadata:
  creationTimestamp: null
  name: project-request
objects:
- apiVersion: project.openshift.io/v1
  kind: Project
  metadata:
    annotations:
      openshift.io/description: ${PROJECT_DESCRIPTION}
      openshift.io/display-name: ${PROJECT_DISPLAYNAME}
      openshift.io/requester: ${PROJECT_REQUESTING_USER}
    creationTimestamp: null
    name: ${PROJECT_NAME}
  spec: {}
  status: {}
- apiVersion: rbac.authorization.k8s.io/v1
  kind: RoleBinding
  metadata:
    creationTimestamp: null
    name: admin
    namespace: ${PROJECT_NAME}
  roleRef:
    apiGroup: rbac.authorization.k8s.io
    kind: ClusterRole
    name: admin
  subjects:
  - apiGroup: rbac.authorization.k8s.io
    kind: User
    name: ${PROJECT_ADMIN_USER}
# ここから追記
- apiVersion: v1
  kind: ResourceQuota
  metadata:
    name: ${PROJECT_NAME}-quota
  spec:
    hard:
      configmaps: "5"
      cpu: "3"
      memory: 1G
- apiVersion: "v1"
  kind: "LimitRange"
  metadata:
    name: ${PROJECT_NAME}-limitrange
  spec:
    limits:
      - type: "Container"
        max:
          cpu: "2"
          memory: "1Gi"
        min:
          cpu: "100m"
          memory: "4Mi"
        default:
          cpu: "300m"
          memory: "200Mi"
        defaultRequest:
          cpu: "200m"
          memory: "100Mi"
        maxLimitRequestRatio:
          cpu: "10"
#ここまで
parameters:
- name: PROJECT_NAME
- name: PROJECT_DISPLAYNAME
- name: PROJECT_DESCRIPTION
- name: PROJECT_ADMIN_USER
- name: PROJECT_REQUESTING_USER
```

このファイルを使用して、openshift-config namaspaceにカスタムテンプレートリソースを作成します。

```
$ oc create -f /tmp/template.yaml -n openshift-config
template.template.openshift.io/project-request created
```

このカスタムテンプレートリソースを使用するように、クラスタを更新します。

```
$ oc edit projects.config.openshift.io/cluster
project.config.openshift.io/cluster edited
```

以下のように編集します。

```
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: config.openshift.io/v1
kind: Project
metadata:
  annotations:
    release.openshift.io/create-only: "true"
  creationTimestamp: "2020-08-05T18:23:47Z"
  generation: 5
  managedFields:
  - apiVersion: config.openshift.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:release.openshift.io/create-only: {}
      f:spec: {}
    manager: cluster-version-operator
    operation: Update
    time: "2020-08-05T18:23:47Z"
  name: cluster
  resourceVersion: "340127"
  selfLink: /apis/config.openshift.io/v1/projects/cluster
  uid: d76fd39e-99c3-48b1-8d75-e460ca8eaad6
spec: 
  projectRequestTemplate: #追記
    name: project-request #追記
```

editすると、apiserverが再起動します。

```
$ oc get pod -n openshift-apiserver -w
NAME                         READY   STATUS        RESTARTS   AGE
apiserver-5cf8667d55-82xt6   1/1     Running       0          28m
apiserver-5cf8667d55-8bmj9   1/1     Running       0          28m
apiserver-5cf8667d55-9chnk   0/1     Terminating   0          27m
apiserver-5fd9b45d6f-57d4n   0/1     Pending       0          4s
apiserver-5cf8667d55-9chnk   0/1     Terminating   0          28m
apiserver-5cf8667d55-9chnk   0/1     Terminating   0          28m
apiserver-5fd9b45d6f-57d4n   0/1     Pending       0          9s
apiserver-5fd9b45d6f-57d4n   0/1     Init:0/1      0          9s
apiserver-5fd9b45d6f-57d4n   0/1     Init:0/1      0          11s
apiserver-5fd9b45d6f-57d4n   0/1     PodInitializing   0          12s
apiserver-5fd9b45d6f-57d4n   0/1     Running           0          13s
・・・
```

マスターノードが3台構成ですので、3つのapiserverが順次再起動します。

```
$ oc get pod -n openshift-apiserver 
NAME                         READY   STATUS    RESTARTS   AGE
apiserver-5fd9b45d6f-57d4n   1/1     Running   0          79s
apiserver-5fd9b45d6f-69q9z   1/1     Running   0          32s
apiserver-5fd9b45d6f-vmb2h   1/1     Running   0          53s
```

##確認
新しいprojectを作成して、ResourceQuotaとLimitRangeが設定されているか確認します。

```
$ oc new-project test02
```

```
$ oc get resourcequotas 
NAME           AGE   REQUEST                                   LIMIT
test02-quota   7s    configmaps: 0/5, cpu: 0/3, memory: 0/1G   
$ oc get limitranges 
NAME                CREATED AT
test02-limitrange   2021-01-24T14:19:34Z
$ oc describe resourcequotas test02-quota 
Name:       test02-quota
Namespace:  test02
Resource    Used  Hard
--------    ----  ----
configmaps  0     5
cpu         0     3
memory      0     1G
$ oc describe limitranges test02-limitrange 
Name:       test02-limitrange
Namespace:  test02
Type        Resource  Min   Max  Default Request  Default Limit  Max Limit/Request Ratio
----        --------  ---   ---  ---------------  -------------  -----------------------
Container   memory    4Mi   1Gi  100Mi            200Mi          -
Container   cpu       100m  2    200m             300m           10
```

どちらもprojectを作成するだけで設定されていますね。