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リソース

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

LimitRangeリソースを定義すると、そのLimitRangeリソースが属しているnamespace内にpodを作成するときに、pod内でResource RequestsResource Limitsを設定していなくても、 LimitRangeリソースで指定したResource RequestsResource Limitsを設定することができる(つまりデフォルト値を定義することができる)。 またLimitRangeリソースで指定したResource RequestsResource Limitsの最大値、最小値を超えるPodを作成できないようにすることができる。

つまりLimitRangeリソースには主に以下が設定できる。

  • podで指定できるResource RequestsResource Limitsの最大値、最小値
  • podでResource RequestsResource Limitsが設定されなかった場合のデフォルト値

(ちなみにLimitRangeリソースはLimitRanger Admission Control pluginによって動く)

例:

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には影響を与えない。なぜならLimitRangeリソースはpodが作成されるときのみ働く(validateする)からだ。

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

ResourceQuotaリソース

ResourceQuotaリソースを使用することでnamespaceに対して使用可能リソース量を指定することができる。 LimitRangeリソースはpodごとに適用される。それに対して、ResourceQuotaリソースはnamespaceに対して適用される。 制限できるのは、CPU, メモリ、PersistentVolumeClaimのディスク使用量, podの数, (ユーザがそのnamespace内に作成することを許した)他のAPI objects。 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には影響がない。

(ちなみにResourceQuotaリソースはResourceQuota Admission Control pluginによって働く)

apiVersion: v1
kind: ResourceQuota
metadata:
  name: cpu-and-mem
spec:
  hard:
   requests.cpu: 400m
    requests.memory: 200Mi
    limits.cpu: 600m
    limits.memory: 500Mi

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

kubectl describe quota で詳細がみれる。

% 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