NamespaceのメモリおよびCPUクォータを設定する

Namespaceに対するメモリおよびCPUリソース制限の全体を定義します。

このページでは、Namespace内で実行されているすべてのPodが使用できるメモリとCPUの総量に対するクォータを設定する方法を説明します。 クォータはResourceQuotaオブジェクトで指定します。

始める前に

Kubernetesクラスターが必要、かつそのクラスターと通信するためにkubectlコマンドラインツールが設定されている必要があります。 このチュートリアルは、コントロールプレーンのホストとして動作していない少なくとも2つのノードを持つクラスターで実行することをおすすめします。 まだクラスターがない場合、minikubeを使って作成するか、 以下のいずれかのKubernetesプレイグラウンドも使用できます:

クラスター内でNamespaceを作成できる権限が必要です。

クラスター内の各ノードには、少なくとも1 GiBのメモリが必要です。

Namespaceの作成

この演習で作成するリソースをクラスター内の他のリソースから分離するために、Namespaceを作成します。

kubectl create namespace quota-mem-cpu-example

ResourceQuotaの作成

ResourceQuotaの例として、次のマニフェストを示します:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-cpu-demo
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi

ResourceQuotaを作成します:

kubectl apply -f https://k8s.io/examples/admin/resource/quota-mem-cpu.yaml --namespace=quota-mem-cpu-example

ResourceQuotaの詳細情報を参照します:

kubectl get resourcequota mem-cpu-demo --namespace=quota-mem-cpu-example --output=yaml

ResourceQuotaは、quota-mem-cpu-example Namespaceに対して次の要件を課します:

  • そのNamespace内のすべてのPodについて、各コンテナはメモリ要求、メモリ制限、CPU要求、CPU制限を持っている必要があります。
  • そのNamespace内のすべてのPodのメモリ要求の合計は、1 GiBを超えてはいけません。
  • そのNamespace内のすべてのPodのメモリ制限の合計は、2 GiBを超えてはいけません。
  • そのNamespace内のすべてのPodのCPU要求の合計は、1 CPUを超えてはいけません。
  • そのNamespace内のすべてのPodのCPU制限の合計は、2 CPUを超えてはいけません。

Kubernetesにおける「1 CPU」の意味については、CPUの意味を参照してください。

Podの作成

Podの例として、次のマニフェストを示します:

apiVersion: v1
kind: Pod
metadata:
  name: quota-mem-cpu-demo
spec:
  containers:
  - name: quota-mem-cpu-demo-ctr
    image: nginx
    resources:
      limits:
        memory: "800Mi"
        cpu: "800m" 
      requests:
        memory: "600Mi"
        cpu: "400m"
      

Podを作成します:

kubectl apply -f https://k8s.io/examples/admin/resource/quota-mem-cpu-pod.yaml --namespace=quota-mem-cpu-example

Podが実行中であり、その(唯一の)コンテナが正常であることを検証します:

kubectl get pod quota-mem-cpu-demo --namespace=quota-mem-cpu-example

再度、ResourceQuotaの詳細情報を参照します:

kubectl get resourcequota mem-cpu-demo --namespace=quota-mem-cpu-example --output=yaml

出力には、クォータとそのクォータのうちどれだけが使用されているかが表示されます。PodのメモリとCPUの要求および制限がクォータを超えていないことがわかります。

status:
  hard:
    limits.cpu: "2"
    limits.memory: 2Gi
    requests.cpu: "1"
    requests.memory: 1Gi
  used:
    limits.cpu: 800m
    limits.memory: 800Mi
    requests.cpu: 400m
    requests.memory: 600Mi

jqツールがある場合、JSONPathを使用してusedの値だけをクエリし、さらに出力を見やすく整形することもできます。 例えば:

kubectl get resourcequota mem-cpu-demo --namespace=quota-mem-cpu-example -o jsonpath='{ .status.used }' | jq .

2つ目のPodを作成する試み

2つ目のPodのマニフェストを次に示します:

apiVersion: v1
kind: Pod
metadata:
  name: quota-mem-cpu-demo-2
spec:
  containers:
  - name: quota-mem-cpu-demo-2-ctr
    image: redis
    resources:
      limits:
        memory: "1Gi"
        cpu: "800m"      
      requests:
        memory: "700Mi"
        cpu: "400m"
      

このマニフェストでは、Podのメモリ要求が700 MiBであることがわかります。 使用済みのメモリ要求とこの新しいメモリ要求を合計すると、メモリ要求のクォータを超過することに注意してください: 600 MiB + 700 MiB > 1 GiB。

このPodを作成しようとします:

kubectl apply -f https://k8s.io/examples/admin/resource/quota-mem-cpu-pod-2.yaml --namespace=quota-mem-cpu-example

2つ目のPodは作成されません。 この出力から、2つ目のPodを作成するとメモリ要求の合計がメモリ要求クォータを超過することがわかります。

Error from server (Forbidden): error when creating "examples/admin/resource/quota-mem-cpu-pod-2.yaml":
pods "quota-mem-cpu-demo-2" is forbidden: exceeded quota: mem-cpu-demo,
requested: requests.memory=700Mi,used: requests.memory=600Mi, limited: requests.memory=1Gi

考察

この演習で見たように、ResourceQuotaを使用してNamespace内で実行されているすべてのPodのメモリ要求の合計を制限できます。 メモリ制限、CPU要求、CPU制限の合計も制限できます。

Namespace内のリソース使用量の合計を管理する代わりに、個々のPodやそれらのPod内のコンテナを制限したい場合があります。 そのような制限を実現するには、LimitRangeを使用します。

備考:

インプレースPodのリサイズを使用する際、ResourceQuotaの適用はリサイズ後の値に適用されます。 リサイズによって名前空間のクォータ制限を超過する場合、そのリサイズは拒否され、Podのリソースは変更されません。

クリーンアップ

Namespaceを削除します:

kubectl delete namespace quota-mem-cpu-example

次の項目

クラスター管理者向け

アプリケーション開発者向け