Kubernetesのresources管理入門

4 min read読了の目安(約4100字

コレは何?

100億番煎じくらいですが、Kubernetesのリソース管理について調べたことをまとめました。

kubernetesでのリソース管理

あるDeploymentで作成されるPodはアクセス負荷が低いため低めのスペックを設定したり、あるCronJobで作成されるPodに対しては大きめのデータを処理するために高いスペックを設定したりといった具合に、個々のPodに適したリソース(CPU, memory)を指定したくなります。
そんなリソース管理のための設定として resources があります。

resources

リソース指定には limitsrequests があります。
limits はコンテナに指定できる最低限のリソースのことであり、 requests はコンテナに指定できる最大限のリソースのことです。

以下のように spec.containers[].resources に指定します。

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: app
    image: images.my-company.example/app:v4
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: log-aggregator
    image: images.my-company.example/log-aggregator:v6
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

resourcesの単位

CPU

Kubernetesにおけるリソースの単位 - CPUの意味 によると、1 cpuは以下の意味を持ちます。

Kuberenetesにおける1つのCPUは、クラウドプロバイダーの1 vCPU/コアおよびベアメタルのインテルプロセッサーの1 ハイパースレッドに相当します。

例えば2 vCPUのEC2インスタンスのスペックをフルで使いたい場合には cpu: 2 と記載します。
1 vCPU分のリソースを割り当てたい場合には cpu: 1 または cpu: 1000m と記載します(Kubernetesでは1cpu = 1000m)。

Memory

memoryはバイト単位で割当可能である。 1G / 1Gi , 512 M / 512Mi のように指定することもできる。

Podのスケジュール

resourcesを用いてリソースを指定することでkube-schedulerがPodの配置先を選定する際に、nodeのスペックをより効率よく活用できるようPodが配置されます。
より具体的には、resourcesのrequestsに指定されたmemory,cpuの値を元に配置先のnodeを選定します。
requestsとlimitで大きな乖離があるPodがたくさんある場合には個々のPodが最大限利用できるリソースが小さくなり非効率なPod配分となってしまうため、注意が必要です。

resources.limitsを超えた場合

resources.limits.memory の値を超えた場合には、OOM Killerにより該当のPodは強制終了されます。
resources.limits.cpu の値を超えた場合にはPodの強制終了は発生しません。

CPUについて

CPUのリソース制限に関してはスロットリングというものがあるので、kubernetesのメトリクスを見つつ設定していくのが良さそうです。

詳細はこちらが大変参考になりました。

QoS class

Kubernetesはnodeのmemory上限を超えた際にnode上のPodを強制削除します。どのPodを優先的に削除するかはQoS classという仕組みによって決まります。
QoS classには3種類あり、優先度が高いものから削除されていきます。

# QoS class priority condition
1 Guaranteed 1 Pod内のすべてのコンテナにmemory,CPUのrequestsとlimitsが設定されており、かつrequestsとlimitsで同じ値であること
2 Burstable 2 Guaranteedではなく、1つ以上のrequestsかlimitsが設定されている場合
3 Best-Effort 3 requests, limitsともに未指定の場合

PodがどのQoS classであるかを確認したい場合には、 kubectl describe pod -o yaml した際に status.qosClass に表示されます。
簡単なハンズオンはこちらを参考にしてみて下さい。PodにQuality of Serviceを設定する

resourcesが未指定の場合

resourcesを指定しない場合、Podは使用できる限りのリソース(≒ nodeのリソース)を利用します。
ただし LimitRange を指定している場合にはそれが適用されます。

ResourceQuota

ResourceQuotaを使うことでnamespace単位で利用可能な総リソースを設定できます(Podなどの個々のリソースではなく特定のnamespaceに対するリソースの総量を制限する)。
*詳細はリソースクォータを参照して下さい。

Limit Range

namespace単位でのPod/containerのcpu/memoryやpvcのstorageのリソース制限を設定できます。
*詳細はLimit Rangeを参照して下さい。

雑感

resourcesの設定はkubernetesの出すメトリクスを見つつ設定(かつ、運用を通して見直していく)していくのが良さそう。

参考