LoginSignup
13
14

More than 5 years have passed since last update.

【第四弾】Kubernetesベストプラクティス:Requests & Limits

Posted at

ベストプラクティス第四弾です

こんにちは、jackです。

今回でKubernetesベストプラクティスもいよいよ中盤です。
今回も前回同様、概念的な部分が多いので長くなりますがお付き合いください。

公式ブログはこちら
Kubernetes best practices: Resource requests and limits

Kubernetesベストプラクティスまとめ一覧 というページも作りました。

TL;DR

  • プロジェクトやチームが大きくなってきたら、リソース管理をするべし
  • リソース管理には RequestsLimits がある
    • Requestsは最低限割り振られるリソース(CPUやメモリ)
    • Limitsは割り振られるリソースの上限
  • CPUユニットは m (millicores)
  • Memoryユニットは Mi (mebibyte)

もっと詳しく

リソース管理をするべし

Kubernetesを運用する上でリソースを十分に確保するのは重要なことです。例えば巨大なアプリケーションをリソースの限られたNode上で動かそうとすれば、メモリやCPUが足りなくなり正常に動作しなくなります。

また、大規模な開発をする上でも設定の人為的なミスであったり、プログラムの誤動作で不用意にリソースを奪い合い、パフォーマンスが低下するといったことが考えられます。

今回はこのような問題を未然に防ぐため、Kubernetesのrequestsとlimitsを見ていきましょう。

RequestsとLimits

簡単にいうと、
Requestsはコンテナに最低限割り振られるリソース(CPUやメモリ)を指します。Limitsは言葉通り、割り振られるリソースの上限を指します。

もう少し詳しく言うと、Kubernetesは与えられたrequestを確保できるNodeにしかコンテナを生成しませんし、コンテナのリソースは与えられたlimitを超えてはいけません。また、limitがrequestを下回る設定はできません(エラーになります)。

ここで1つ注意する必要があるのが、requestsとlimitsはそれぞれコンテナ基準である点です。仮に、1つのPodに複数のコンテナがある場合、requestsとlimitsは複数コンテナの合算になります。

コンテナでのリソース設定

リソースタイプは2つあります。CPUとMemoryです。
Kubernetesのスケジューラーはこれらを元にどこにPodを生成するか判断します。

GKEを使っている場合のデフォルトNamespaceでは以下の初期設定がされています。

CPU Memory
Requests 0.1 Cores なし
Limits なし なし

"Hello World"のようなアプリケーションならデフォルトでも構いませんが、通常Podを作成する場合はデフォルトではなく以下にのように指定してあげます。

pod.yml
containers:
  - name: container1
    image: busybox
    resources:
      requests:
        memory: "32Mi"
        cpu: "200m"
      limits:
        memory: "64Mi"
        cpu: "250m"
  - name: container2
    image: busybox
    resources:
      requests:
        memory: "96Mi"
        cpu: "300m"
      limits:
        memory: "192Mi"
        cpu: "750m"

上の設定では合計で500m CPUと128 MiBのMemoryとなります。

CPU

KubernetesのCPUの概念として、millicoresというものがあります。
CPU1コアが1000 unitとして換算されるので、1CPU = 1000mです。
例えば、1/4コアのリソースが欲しい場合は 250m となります。

*CPUのRequestがNodeよりも多い場合、そのPodは永遠に立ち上がらないので注意しましょう。

また、CPU Limitsで指定したリソースに達するとスロットリングします。パフォーマンスが低下したりしますが、terminateはしません。ここで前回お話したLivenessプローブ等でhealth checkするといったことも考えられます。

Memory

メモリは bytes で表せます。bytesからpetabytesまで対応してますが、一般的には mebibyte(Mi) を使用することが多いでしょう。
CPUと同じようにメモリもNodeのリソースを超える場合はPodが生成されないので注意しましょう。

CPUとは違いMemoryはLimitを超えてしまうとPodが消失します。DeploymentやStatefulSet、DeamonSetを使用している場合、コントローラーが再度Podを生成してくれます。

名前空間でのリソース設定

一つのアプリケーションがクラスターの大部分のリソースを使ってしまうことが考えられます。それを防ぐために、Namespaceでのリソースを指定することも可能です。

ResourceQuotas

Namespace上にリソースを定義するには以下のようにします。

quota.yml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: demo
spec:
  hard:
    requests.cpu: 500m
    requests.memory: 100Mib
    limits.cpu: 700m
    limits.memory: 500Mib

requests.cpurequests.memoryはそれぞれCPUとMemory Requestsの合計最大値です。要するに10m CPUのコンテナが50個、もしくは100m CPUが5つ、といった具合です。

limits.cpulimits.memoryはLimitsの合計最大値です。

LimitRange

Quotaの他にLimitRangeというものがあります。
極端に大きなコンテナや、また逆に小さすぎるコンテナを作れないように、RequestsとLimitsを制約できます。

LimitRangeについては至ってシンプルなのでここではスキップします。
原文もしくは公式ドキュメントをどうぞ。

まとめ

いかがでしたか?
すこし端折りましたが、基本的なことはまとめられたかと思います。

なにも考えずにKubernetesを使ってもうまく行ってしまうことが多いからこそ、内部を知って未然に思わぬ事故を防ぐことも大事ですね。

それでは、また次回!

13
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
14