Kubernetes勉強会第3回 〜Resource RequestとResource Limit、pod QoSクラス、LimitRangeリソース、ResourceQuotaリソース〜

Kubernetes in Action

Kubernetes in Action

Kubernetes in Action」を読んで学んだ結果を社内で共有しました。 その第3回の内容です。

podの使用リソースを管理する

Resource RequestとResource Limit

KubernetesのResource RequestとResource Limit

pod QoSクラス

KubernetesのQuality of Service(QoS)クラスについて

LimitRangeリソース

LimitRangeリソースを利用すると、Pod、Container、 PersistentVolumeClaimに対して、CPUやメモリのリソースの最小値/最大値、デフォルト値を設定することが可能。 LimitRangeはNamespaceに対して制限をかけるため、Namespaceごとに設定する必要がある。 LimitRangeは新規でpodを作成する際に利用されるため、既存のpodには影響を与えない。

Resource RequestsResource Limitsを設定していないと、QoSクラスがBestEffortになってしまいkillされやすくなってしまう。それを避けたいならそれぞれのコンテナにResource RequestsResource Limitsを設定する必要がある。

LimitRangeを設定可能なリソースはpod / Container / PersistentVolumeClaim の3種類 Podでは、 max / min / PersistentRequestRatio のみが設定可能。Pod内で利用しているコンテナのリソースの合計での制限でminとmaxを利用する PersistentVolumeClaimでは max /minのみが設定可能。要求可能なストレージのサイズを制限する。 Requestsを設定しないと無限にスケジューリングされてしまうため、GKEではCPUのdefaultRequestが100mに設定されている。

LimitRangeリソースで設定可能な制限項目

設定項目 概要
default デフォルトのResource Limits値
defaultRequest デフォルトのResource Requests値
max 最大のResource Requests, Resource Limits値
min 最小のResource Requests, Resource Limits値
maxLimitRequestRatio Resource Limit / Resource Requests の割合

apiVersion: v1
kind: LimitRange
metadata:
  name: example
spec:
  limits:
  - type: Pod # Pod全体に対する制限
    min: # Pod全体で要求される最小のCPUとメモリ
      cpu: 50m
      memory: 5Mi
    max: cpu: 1 # Pod全体で要求される最大のCPUとメモリ
      memory: 1Gi
  - type: Container # コンテナに対する制限
    defaultRequest: # Resource Requestsを設定していないコンテナはこのデフォルト値が設定される
      cpu: 100m
      memory: 10Mi
    default: # Resource Limitsが設定されていないコンテナはこのデフォルト値が設定される。
      cpu: 200m
      memory: 100Mi
    min: # コンテナが設定できる最小のRequests/Limits値
      cpu: 50m
      memory: 5Mi
    max: # コンテナが設定できる最大のRequests/Limits値
      cpu: 1
      memory: 1Gi
    maxLimitRequestRatio: # Maximum ratio between the limit and request for each resource(※)
      cpu: 4
      memory: 10
  - type: PersistentVolumeClaim # PVCに対する制限
    min:
      storage: 1Gi
    max:
      storage: 10Gi

※ CPU maxLimitRequestRatioが4の場合、CPU LimitsはCPU Requestsの4倍以上設定できないことを指す。つまりCPU Requestsが200millicoresだったら、CPU Limitは801millicores以上は設定できない。メモリも同様。

ちなみに、たとえLimitRangeリソースを設定してpodが使用可能なResource量を制限しても、podを何個も作成したらClusterのリソースを食い尽くしてしまう。それを防ぐにはResourceQuotaリソースを使う必要がある。

ResourceQuotaリソース

ResourceQuotaリソースを使用することで各Namespaceに対して利用可能なリソース量を制限することができる。 LimitRangeリソースはPodごとに適用されるがそれに対してResourceQuotaリソースはNamespaceに対して適用される。 制限可能な対象は大きく分けて「作成可能なリソース数の制限」と「リソース使用量の制限」の2種類がある。

制限できる対象は例えば、CPU, メモリ、PersistentVolumeClaimのディスク使用量, Podの数がある

Podを作成するとき、ResourceQuotaリソースで定義された制限を超えていないかチェックされる。超えていたらPodは作成できない。以下のようなエラーメッセージが表示される。

$ kubectl apply -f resource-request-and-limit.yaml
Error from server (Forbidden): error when creating "resource-request-and-limit.yaml": pods "limited-pod" is forbidden: exceeded quota: cpu-and-mem, requested: limits.cpu=1,requests.cpu=1, used: limits.cpu=0,requests.cpu=0, limited: limits.cpu=600m,requests.cpu=400m

既存のResourceQuotaリソースの設定を変更しても、既存のpodには影響がない。

作成可能なリソース数の制限

apiVersion: v1
kind: ResourceQuota
metadata:
  name: sample-resouce-quota-new
spec:
  hard:
    count/services: 10
    count/configmaps: 10
    count/deployments: 10

リソース使用量の制限

apiVersion: v1
kind: ResourceQuota
metadata:
  name: sample-resource-quota-usable
spec:
  hard:
    # 合計のRequestsの制限
    requests.cpu: 400m
    requests.memory: 200Mi
    # 合計のLimitsの制限
    limits.cpu: 600m
    limits.memory: 500Mi

ResourceQuotaリソースはそのnamespace内のpodのResource Requests、Resource Limitsのトータル値に対して制限がかかる。

kubectl describe resourcequotas で詳細がみれる。

% kubectl describe resourcequotas
Name:            cpu-and-mem
Namespace:       default
Resource         Used  Hard
--------         ----  ----
limits.cpu       200m  600m
limits.memory    20Mi  500Mi
requests.cpu     200m  400m
requests.memory  20Mi  200Mi