クラスタリソースのクォータ

本コンテンツは、MAD Workshop Ops Track の内容をベースに、一部変更しています。

ユーザをclusteradminとは別に一つ用意してください。

演習の概要

前の演習では、Project にクォータを適用する方法を見ました。デフォルトのクォータを設定したので、誰かが新しい Project をリクエストしたときにはいつでもデフォルトのクォータが割り当てられます。このような Project クォータは、クラスタ内のリソースを制御するのに最適です。

しかし、クォータを個々の Project ではなく、Projectを跨って適用したい場合には、別のやり方が必要です。それが、ClusterResourceQuota です。


ユースケース

Project ベースの quota の代わりに clusterresourcequota を使用する主なユースケースは2つあります。

一つは、特定のユーザにクォータを設定したい場合です。これは、ユーザに必要なだけの Project を作成させ(これによりマルチテナンシーを実現します)、またそこで消費できるリソースの量を制限することができます。

もう一つのユースケースは、アプリケーションごとにクォータを設定したい場合です。この場合、アプリケーションスタックは複数の Project にまたがっている可能性があります。

この演習では、両方のユースケースを調査します。

ユーザーごとのクォータの設定

clusterresourcequota をユーザに設定するには、clusteradmin権限を持つアカウントが必要です。(`admin`を使います。)

oc login -u admin -p <*** パスワード ***>

では、user1 にクォータを設定します。openshift.io/requester=annotation キーを使用して、これらのクォータが適用される Project を指定します。この演習では、10個より多くの Pod を作成することを禁止するハードクォータを設定します。

oc create clusterquota for-user-user1 \
    --project-annotation-selector openshift.io/requester=user1 \
    --hard pods=10
clusterquota は、 clusterresourcequotas の略です (oc api-resources | grep clusterresourcequotas のコマンドで確認できます)。

設定を表示します。

oc get clusterresourcequotas for-user-user1 -o yaml

設定は以下のようになっているはずです。

apiVersion: quota.openshift.io/v1
kind: ClusterResourceQuota
metadata:
  creationTimestamp: "2023-06-26T00:06:40Z"
  generation: 1
  name: for-user-user1
  resourceVersion: "44857"
  uid: 53217fca-8c3f-49a4-8a1c-bc6585447eb2
spec:
  quota:
    hard:
      pods: "10"
  selector:
    annotations:
      openshift.io/requester: user1
    labels: null

ユーザ user1 は、自身が作成したすべての Project で10個以下の Pod を作成することができます。これはこのユーザが作成した Project (openshift.io/requester: user1 annotationに基づく) にのみ適用され、このユーザがアクセスできるその他のProject(他のユーザが作成したproject)には適用されません。これについては後ほど説明します。

では user1 でログインしてみましょう。

oc login -u user1 -p <*** パスワード ***>

現在の Project をリストアップします。

oc get projects

このユーザは Project を持っていないはずなので、このような出力が表示されるはずです。

No resources found.

welcome1welcome2 の2つの Project を作成します。

oc new-project welcome1
oc new-project welcome2

次に二つのアプリケーションを作成します。1つは welcome1 Project に作り、もう1つは welcome2 Project に作ります.

oc new-app -n welcome1 --name=php1 quay.io/redhatworkshops/welcome-php:latest
oc new-app -n welcome2 --name=php2 quay.io/redhatworkshops/welcome-php:latest

デプロイが終わると、それぞれのNamespaceに1つずつ、2つの実行中の Pod ができるはずです。oc get pods コマンドで確認してください。(出力が表示されるまでに時間がかかる場合、何度か実行してみて下さい)

oc get pods -n welcome1 -l deployment=php1
oc get pods -n welcome2 -l deployment=php2

出力は以下のようになっているはずです。

[~] $ oc get pods -n welcome1 -l deployment=php1
NAME           READY   STATUS    RESTARTS   AGE
php1-1-nww4m   1/1     Running   0          4m20s
[~] $ oc get pods -n welcome2 -l deployment=php2
NAME           READY   STATUS    RESTARTS   AGE
php2-1-ljw9w   1/1     Running   0          4m20s

admin ユーザーに変更してクォータを確認してみましょう。

oc login -u admin -p <*** パスワード ***>

oc describe clusterresourcequotas for-user-user1 を実行してクォータの状態を確認します。

oc describe clusterresourcequotas for-user-user1

以下のような出力が表示されます。

Name:		for-user-user1
Created:	4 minutes ago
Labels:		<none>
Annotations:	<none>
Namespace Selector: ["welcome1" "welcome2"]
Label Selector:
AnnotationSelector: map[openshift.io/requester:user1]
Resource	Used	Hard
--------	----	----
pods		2	10

10個中2個の Pod が使用されていることと、クォータが適用されているNamespaceが確認できます。welcome1 のNamespaceをチェックして、クォータが見張るannotationを確認してください。

oc get ns welcome1 -o yaml

出力は以下のようになるはずです。特にannotationに注意してください。openshift.io/requester が `user1`です。

apiVersion: v1
kind: Namespace
metadata:
  annotations:
    openshift.io/description: ""
    openshift.io/display-name: ""
    openshift.io/requester: user1
    openshift.io/sa.scc.mcs: s0:c26,c20
    openshift.io/sa.scc.supplemental-groups: 1000690000/10000
    openshift.io/sa.scc.uid-range: 1000690000/10000
  creationTimestamp: "2023-06-26T00:08:42Z"
  labels:
    kubernetes.io/metadata.name: welcome1
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/audit-version: v1.24
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/warn-version: v1.24
  name: welcome1
  resourceVersion: "45450"
  uid: 6f17c5ef-eeb9-4e4e-9cd4-9bb3ae32e132
spec:
  finalizers:
  - kubernetes
status:
  phase: Active

それでは user1 になって、10個を超える Pod にスケールしてみます。

oc login -u user1 -p <*** パスワード ***>
oc scale deploy/php1 -n welcome1 --replicas=5
oc scale deploy/php2 -n welcome2 --replicas=6

実行中の Pod の数に注意して見てみましょう。

oc get pods --no-headers -n welcome1 -l deployment=php1 | wc -l
oc get pods --no-headers -n welcome2 -l deployment=php2 | wc -l

これらのコマンドはどちらも、合計で10個以上の Pod を返しません。イベントをチェックして、クオータが動作しているのを確認してください。

oc get events -n welcome1 | grep "quota" | head -1
oc get events -n welcome2 | grep "quota" | head -1

以下のようなメッセージが表示されるはずです。

3m24s       Warning   FailedCreate        replicaset/php1-89fcb8d8b    Error creating: pods "php1-89fcb8d8b-spdw2" is forbid
den: exceeded quota: for-user-user1, requested: pods=1, used: pods=10, limited: pods=10

ステータスを確認するには、admin になって先程の describe コマンドを実行します。

oc login -u admin -p <*** パスワード ***>
oc describe clusterresourcequotas for-user-user1
*Pod* のハードクォータの上限に達したことが確認できます。
Name:           for-user-user1
Created:        15 minutes ago
Labels:         <none>
Annotations:    <none>
Namespace Selector: ["welcome1" "welcome2"]
Label Selector:
AnnotationSelector: map[openshift.io/requester:user1]
Resource        Used    Hard
--------        ----    ----
pods            10      10

Labelによるクォータ

複数の Project にまたがる可能性のあるアプリケーションスタックでクォータを設定するには、Labelを使って Project を識別する必要があります。まず、admin でログインします。

oc login -u admin -p <*** パスワード ***>

Labelに基づいてクォータを設定します。この演習では Project を識別するために appstack=pricelist のLabelを使用します。

oc create clusterresourcequota for-pricelist \
    --project-label-selector=appstack=pricelist \
    --hard=pods=5

ここで2つの Project を作成します。

oc adm new-project pricelist-frontend
oc adm new-project pricelist-backend

2つの Project のユーザ user1edit ロールを割り当てます。

oc adm policy add-role-to-user edit user1 -n pricelist-frontend
oc adm policy add-role-to-user edit user1 -n pricelist-backend

これら2つの Projectpricelist アプリケーションスタックに属するものであることを識別するには、対応するNamespaceにLabelを付ける必要があります。

oc label ns pricelist-frontend appstack=pricelist
oc label ns pricelist-backend appstack=pricelist

oc describe clusterresourcequotasfor-pricelist を指定します。

oc describe clusterresourcequotas for-pricelist

両方の Project がトラッキングされていることがわかるはずです。

Name:           for-pricelist
Created:        21 seconds ago
Labels:         <none>
Annotations:    <none>
Namespace Selector: ["pricelist-frontend" "pricelist-backend"]
Label Selector: appstack=pricelist
AnnotationSelector: map[]
Resource        Used    Hard
--------        ----    ----
pods            0       5

user1 でログインし、それぞれの Project にアプリケーションを作成します。

oc login -u user1 -p <*** パスワード ***>
oc new-app -n pricelist-frontend --name frontend quay.io/redhatworkshops/pricelist:frontend
oc new-app -n pricelist-backend --name backend quay.io/redhatworkshops/pricelist:backend

admin でログインし、describe コマンドを実行して、クォータの状態を確認してください。

oc login -u admin -p <*** パスワード ***>
oc describe clusterresourcequotas for-pricelist

5つの Pod クォータに対して2つが使用されていることを確認できます。

Name:           for-pricelist
Created:        About a minute ago
Labels:         <none>
Annotations:    <none>
Namespace Selector: ["pricelist-frontend" "pricelist-backend"]
Label Selector: appstack=pricelist
AnnotationSelector: map[]
Resource        Used    Hard
--------        ----    ----
pods            2       5

user1 は、admin によって pricelist-frontendpricelist-backend のユーザとして割り当てられているため、決められた数の Pod を作成することができます。user1Project を作成していないので、openshift.io/requester=user1 annotationはありません。仕様に合わせてQuota のポリシーを設定することができます。

user1 でログインして、合計5つの Pod を超えてアプリケーションをスケールしてみてください。

oc login -u user1 -p <*** パスワード ***>
oc scale -n pricelist-frontend deploy/frontend --replicas=3
oc scale -n pricelist-backend deploy/backend --replicas=3

先ほどと同じように、スケールできないというエラーが表示されるはずです。

oc get events -n pricelist-frontend | grep "quota" | head -1
oc get events -n pricelist-backend | grep "quota" | head -1

出力は先の演習と同じようになっているはずです。

39s         Warning   FailedCreate        replicaset/backend-577cf89b68   Error creating: pods "backend-577cf89b68-l5svw" is
 forbidden: exceeded quota: for-pricelist, requested: pods=1, used: pods=5, limited: pods=5

クリーンアップ

admin で行った作業をクリーンアップします。

oc login -u admin -p <*** パスワード ***>

これらのクォータは他の演習と干渉する可能性があるので、この演習で作成した clusterresourcequota の両方を削除してください。

oc delete clusterresourcequotas for-pricelist for-user-user1

また、この演習で作成した Project も削除してください。

oc delete projects pricelist-backend pricelist-frontend welcome1 welcome2

次の演習では必ず admin でログインしてください。

oc login -u admin -p <*** パスワード ***>
oc project default