Project のクオータ/制限

本コンテンツは、MAD Workshop Ops Track の内容を利用しています。

演習の概要

OpenShiftでは、1つの プロジェクト 内で使用できるオブジェクトの数やリソース(CPU、メモリなど)を制限しません。 さらに、ユーザーは無制限に プロジェクト を作成することができます。しかし、現実的には少し制約をつける必要があります。


プロジェクト・リクエスト・テンプレート

ユーザーが oc new-project コマンドを呼び出すと、新しいプロジェクトのリクエストフローが開始されます。 このワークフローの中で、新たに要求されたプロジェクトを作成するためにデフォルトのプロジェクト・リクエスト・ テンプレート が処理されます。

デフォルトの プロジェクト・リクエスト・テンプレート

新しいプロジェクトのテンプレートを作成します。

oc get template -n openshift-config

組み込みのデフォルトの プロジェクト・リクエスト・テンプレート を表示するには、以下のコマンドを実行します。

oc adm create-bootstrap-project-template -o yaml

このコマンドのYAML出力を調べると、下の方に表示されているこの テンプレート に関連した様々なパラメータがあることに気づくでしょう。

...
parameters:
- name: PROJECT_NAME
- name: PROJECT_DISPLAYNAME
- name: PROJECT_DESCRIPTION
- name: PROJECT_ADMIN_USER
- name: PROJECT_REQUESTING_USER
...

次に、 oc new-project コマンドのヘルプ出力を見てみましょう:

oc new-project -h

oc new-project--display-name ディレクティブがあることに注意してください。 このオプションはデフォルトの テンプレート の出力で見た PROJECT_DISPLAYNAME パラメータに対応します。

テンプレート で定義されているオブジェクトを見てみると、クォータや制限についての記載がまだありません。 こちらを変更していきます。

テンプレート は、ユーザーがパラメーターと共にOpenShift のオブジェクト群を繰り返し作成可能とする強力なツールです。 これらはより複雑で関連性の高いコンポーネントを OpenShift に素早くデプロイする事に使う事ができ、 ソフトウェアの開発ライフサイクルにおいても有用です。詳細な情報は次のリンク先で確認できます。 template documentation

プロジェクト・リクエスト・テンプレート を編集する

このラボでは実際にテンプレートの変更を行う必要はありません。変更したものを既に作成済みです。

プロジェクト・リクエスト・テンプレート :

vi project_request_template.yaml
apiVersion: template.openshift.io/v1
kind: Template
metadata:
  creationTimestamp: null
  name: project-request-new
objects:
- apiVersion: 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: v1
  kind: ResourceQuota
  metadata:
    name: ${PROJECT_NAME}-quota
  spec:
    hard:
      pods: 10
      requests.cpu: 4000m
      requests.memory: 8Gi
      resourcequotas: 1
      requests.storage: 50Gi
      persistentvolumeclaims: 5
- apiVersion: v1
  kind: LimitRange
  metadata:
    name: ${PROJECT_NAME}-limits
    creationTimestamp: null
  spec:
    limits:
      -
        type: Container
        max:
          cpu: 4000m
          memory: 1024Mi
        min:
          cpu: 10m
          memory: 5Mi
        default:
          cpu: 4000m
          memory: 1024Mi
        defaultRequest:
          cpu: 100m
          memory: 512Mi
- apiVersion: v1
  groupNames:
  - system:serviceaccounts:${PROJECT_NAME}
  kind: RoleBinding
  metadata:
    creationTimestamp: null
    name: system:image-pullers
    namespace: ${PROJECT_NAME}
  roleRef:
    name: system:image-puller
  subjects:
  - kind: SystemGroup
    name: system:serviceaccounts:${PROJECT_NAME}
  userNames: null
- apiVersion: v1
  groupNames: null
  kind: RoleBinding
  metadata:
    creationTimestamp: null
    name: system:image-builders
    namespace: ${PROJECT_NAME}
  roleRef:
    name: system:image-builder
  subjects:
  - kind: ServiceAccount
    name: builder
  userNames:
  - system:serviceaccount:${PROJECT_NAME}:builder
- apiVersion: v1
  groupNames: null
  kind: RoleBinding
  metadata:
    creationTimestamp: null
    name: system:deployers
    namespace: ${PROJECT_NAME}
  roleRef:
    name: system:deployer
  subjects:
  - kind: ServiceAccount
    name: deployer
  userNames:
  - system:serviceaccount:${PROJECT_NAME}:deployer
- apiVersion: v1
  groupNames: null
  kind: RoleBinding
  metadata:
    creationTimestamp: null
    name: admin
    namespace: ${PROJECT_NAME}
  roleRef:
    name: admin
  subjects:
  - kind: User
    name: ${PROJECT_ADMIN_USER}
  userNames:
  - ${PROJECT_ADMIN_USER}
parameters:
- name: PROJECT_NAME
- name: PROJECT_DISPLAYNAME
- name: PROJECT_DESCRIPTION
- name: PROJECT_ADMIN_USER
- name: PROJECT_REQUESTING_USER

ResourceQuota

quota documentation のリンク先に ResourceQuota についての詳細があります。:

リソースクォータは、ResourceQuotaオブジェクトによって定義され、プロジェクトごとの総リソース消費量を制限する制約を提供します。
これは、プロジェクト内で作成できるオブジェクトの数をタイプ別に制限したり、そのプロジェクト内のリソースが消費するCPU/メモリなどの計算リソースとストレージの総量を制限したりすることができます。

今回は、CPU, memory, storage, persistentvolumeclaims と Pods に特定のクォータを設定しています。 project_request_template.yaml ファイルの ResourceQuota セクションを見てみましょう。

- apiVersion: v1
  kind: ResourceQuota
  metadata:
    name: ${PROJECT_NAME}-quota (1)
  spec:
    hard:
      pods: 10 (2)
      requests.cpu: 4000m (3)
      requests.memory: 8Gi (4)
      resourcequotas: 1
      requests.storage: 50Gi (5)
      persistentvolumeclaims: 5 (6)
1 プロジェクト には1つのクォータしか定義できませんが、そのクォータには一意の名前が必要です。
2 プロジェクト内に作成可能な Podの数です。
3 CPUは「ミリコア」で計測されます。どのように Kubernetes/OpenShift がコアを計算するかは次のリンクで確認できます。 Kubernetes公式ドキュメント.
4 limitsrequests の両方がありますが、これについては LimitRange オブジェクトを見てから詳しく説明します。
5 プロジェクト内のすべてのpersistentvolumeclaimsにおいて、要求されたストレージ容量の合計がこの値を超えることはできません。
6 プロジェクト内の persistentvolumeclaim の総数。

利用可能なクォータオプションの詳細については、 quota documentation を参照してください。

LimitRange

LimitRangeの概要については limit range documentation のリンクに情報があります。:

リミットレンジは、LimitRangeオブジェクトで定義され、プロジェクト内の、 pod、 container、 image、 image stream、persistentvolumeclaim 毎に消費可能な計算リソースを指定します。

ResourceQuota はプロジェクト内の総リソース消費量の上限を設定しますが、LimitRange は個々のリソースに適用されます。 例えば、個々の Pod やコンテナがどれだけの CPU を使用できるかを設定することができます。

サンプルの LimitRange 定義を見てみましょう。

project_request_template.yaml ファイル:

- apiVersion: v1
  kind: LimitRange
  metadata:
    name: ${PROJECT_NAME}-limits
    creationTimestamp: null
  spec:
    limits:
      -
        type: Container
        max: (1)
          cpu: 4000m
          memory: 1024Mi
        min: (2)
          cpu: 10m
          memory: 5Mi
        default: (3)
          cpu: 4000m
          memory: 1024Mi
        defaultRequest: (4)
          cpu: 100m
          memory: 512Mi

Request と Limit の違いは重要で、それについては次のリンク中で説明しています。

上記のyamlの例では:

1 max は limits や requests に指定できる最高の値です。
2 min は limits や requests に指定できる最低の値です。
3 default は、何も指定されていない場合に、コンテナが消費できる最大量(制限)です。
4 defaultRequest は何も指定されてない場合に、コンテナが消費する最小量です。

詳しくは、limit range documentationを参考してください.

以下のようにプロジェクトを制限することができます。:

  • 合計の CPU が4 core (4000m) のクォータで

    • 個々のコンテナーは、

      • 4 core 以下でないといけない

      • 10 milicore 未満の定義は持つ事ができない

      • 100 milicore のリクエストがデフォルト(もし指定されなければ)

      • 4 core までバーストが可能 (もし指定されなければ)

  • 合計メモリが 8 Gibibyte (8192 Megabytes)で

    • 個々のコンテナーは

      • 1 Gi かそれ未満の使用量でなければならない

      • 5 Mi 未満の定義は持つ事ができない

      • デフォルトで 512 Mi をリクエストする

      • 1024 Mi までバーストが可能

  • 合計のストレージのクレームが、25 Gi かそれ未満

  • 合計で 5 つの volume のクレームまで。

  • 10 以下の Pods

ResourceQuotaと組み合わせることで、ユーザーが OpenShift の様々なリソースを要求し、利用する方法について、非常に細かいコントロールを作成することができます。

Quota と Limits は、プロジェクト レベルで適用されます。 ユーザー は複数の プロジェクト にアクセスすることができますが、Quota と Limits は ユーザー には直接適用されません。 複数の プロジェクト に1つの Quota を適用したい場合は、ClusterReqoureQuotaの記載のある multi-project quota を参照して下さい。

プロジェクト・リクエスト・テンプレートをインストールする

この背景を踏まえて、実際に OpenShift にこの新しい プロジェクト・リクエスト・テンプレート を使用するように変更をしていきます。

Template を作成する

先ほど説明したように、 テンプレート はOpenShiftオブジェクトの一つのタイプにすぎません。 oc コマンドは create を提供し、YAML/JSON を入力として受け取り、提供されたオブジェクトをインスタンス化します。

次に以下を実行します。:

oc create -f project_request_template.yaml -n openshift-config

これで、openshift-config プロジェクト 内に テンプレート オブジェクトが作成されました。:

oc get template -n openshift-config

上記のコマンドを実行すると以下のようなが表示されます。:

NAME                  DESCRIPTION   PARAMETERS    OBJECTS
project-request                     5 (5 blank)   8
project-request-new                 5 (5 blank)   7

デフォルトのプロジェクト・リクエスト・テンプレートの設定

デフォルトの projectRequestTemplate は OpenShift API Server の設定の一部です。 この設定は最終的に openshift-apiserver プロジェクト内の ConfigMap に格納されます。 API Server の構成は、以下のコマンドで表示できます。:

oc get cm config -n openshift-apiserver -o jsonpath --template="{.data.config\.yaml}" | jq

様々な CustomResource (CR)インスタンスを見て、定義したコンフィグレーションがクラスタに適用されていることを保証するための OpenShift の Operator があります。

言い換えれば、 その OpenShift Operator は ConfigMap の作成/変更に最終的な責任を持っています。

jq の出力を見ると、 projectRequestMessage はありますが、projectRequestTemplate は "project-request" が定義されています。

デフォルトのプロジェクト・リクエスト・テンプレートの設定を追加するには、CR を作成する必要があります。 CustomResource は次のようになります。:

apiVersion: "config.openshift.io/v1"
kind: "Project"
metadata:
  name: "cluster"
  namespace: ""
spec:
  projectRequestMessage: ""
  projectRequestTemplate:
    name: "project-request-new"

次にこの CustomResource を作成します。 この CR が作成されると、OpenShift のオペレータは CR に気付き、構成の変更を適用します。 この CustomResource を作成するには、次のコマンドを発行します。:

vi cr_project_request.yaml
apiVersion: "config.openshift.io/v1"
kind: "Project"
metadata:
  name: "cluster"
  namespace: ""
spec:
  projectRequestMessage: ""
  projectRequestTemplate:
    name: "project-request-new"
oc apply -f cr_project_request.yaml -n openshift-config

このコマンドを実行すると、OpenShift API Server の設定が Operator によって更新されます。 この更新には数分かかります。 apiserver のDeploymentの状況を見ることで更新状況を確認することができます。

sleep 30
oc rollout status deploy apiserver -n openshift-apiserver

ConfigMapを見ることで設定の更新を確認できます。:

oc get cm config -n openshift-apiserver -o jsonpath --template="{.data.config\.yaml}" | jq

新しい projectConfig セクションに注目してください。:

...
  "kind": "OpenShiftAPIServerConfig",
  "projectConfig": {
    "projectRequestMessage": "",
    "projectRequestTemplate": "openshift-config/project-request-new"
  },
...

新しいプロジェクトを作成する

新しいプロジェクトを作成すると、 QuotaLimitRange が一緒に作成されているのがわかるはずです。 template-test という新しいプロジェクトを作成します。:

oc new-project template-test

そして、 describe を使って、この プロジェクトの 詳細を見てください:

oc describe project template-test

出力は以下のような感じになります。:

Name:           template-test
Created:        22 seconds ago
Labels:         <none>
Annotations:    openshift.io/description=
                openshift.io/display-name=
                openshift.io/requester=system:serviceaccount:lab-ocp-cns:dashboard-user
                openshift.io/sa.scc.mcs=s0:c24,c19
                openshift.io/sa.scc.supplemental-groups=1000590000/10000
                openshift.io/sa.scc.uid-range=1000590000/10000
Display Name:   <none>
Description:    <none>
Status:         Active
Node Selector:  <none>
Quota:
        Name:                   template-test-quota
        Resource                Used    Hard
        --------                ----    ----
        persistentvolumeclaims  0       5
        pods                    0       10
        requests.cpu            0       4
        requests.memory         0       8Gi
        requests.storage        0       50Gi
        resourcequotas          1       1
Resource limits:
        Name:           template-test-limits
        Type            Resource        Min     Max     Default Request Default Limit   Max Limit/Request Ratio
        ----            --------        ---     ---     --------------- -------------   -----------------------
        Container       cpu             10m     4       100m        4       -
        Container       memory          5Mi     1Gi     512Mi       1Gi     -
Quota と Resource limits のセクションが表示されていない場合は、コマンド実行が早すぎた可能性があります。 オペレータは必要なことをすべて実行するのに多少の時間がかかることを覚えておいてください。 マスターが新しい設定を読み込む前にプロジェクトを作成した可能性があります。 その場合 oc delete project template-test を削除して、しばらくしてから再作成してください。

また、 QuotaLimitRange オブジェクトが作成されたことがわかります。:

oc describe quota -n template-test

以下のようなものが見えるはずです。:

Name:                   template-test-quota
Namespace:              template-test
Resource                Used  Hard
--------                ----  ----
persistentvolumeclaims  0     5
pods                    0     10
requests.cpu            0     4
requests.memory         0     8Gi
requests.storage        0     50Gi
resourcequotas          1     1

そして:

oc get limitrange -n template-test

以下のようなものが見えるはずです。:

NAME                   CREATED AT
template-test-limits   2023-06-26T00:02:47Z
project-request-new テンプレートが openshift-config プロジェクト内に作成されていることを確認してください。 テンプレートを作成せずに OpenShift API サーバー設定で定義すると、新規プロジェクトの作成に失敗します。

クリーンナップ

他のラボに移る前に、先ほど作成した プロジェクト を削除してください:

oc delete project template-test