リソースのリクエストと制限について

コンテナの実装に使用される中核的なLinuxテクノロジの1つはcgroupです。cgroupを使用すると、プロセス(1つまたは複数)に対してCPUおよびメモリーの使用制限を強制適用できます。

Kubernetesには、コンテナで使用されるCPUおよびメモリーの量を指定できる機能があります。指定した場合、Kubernetesでは、リクエストの内容を基に次のことが実行されます:
  • 特定のポッドをどのノードに作成するかを決める: Kubernetesにより、リクエストに対応するための十分な空きリソースがあるノードが特定されます。

  • 実行時にこれらの制限を強制適用する: Kubernetesにより、アプリケーションがそれらのリクエストを超えないように制限されます。

Kubernetesにより、ポッドのリソース・リクエスト、およびクラスタ内の各ノード上の使用可能リソースに基づいて、そのポッドを実行するクラスタのノードが選択されます。ただし、ポッドがノード上でスケジュールされた後は、Kubernetesによって実行時に制限が直接的に強制適用されることはなくなります。かわりに、cgroupを介してKubernetesからLinuxにリクエストが渡されます。その後、Kubernetesのかわりに、そのノードのLinuxカーネルによって制限が強制適用されます。

次のように定義されているポッドの例を見てみましょう。
apiVersion: v1
kind: Pod
metadata:
  name: samplePod
spec:
  containers:
  - image: container-registry.oracle.com/timesten/timesten:22.1.1.30.0
    name: sample
    resources:
      limits:
        cpu: 20
        memory: 200Gi
      requests:
        cpu: 20
        memory: 200Gi

Kubernetesにより、ポッドを実行するノードが決定されます。これは、ポッドのリソース・リクエストを調べて、そのポッドに対応できる十分な空きリソースがあるノードを特定することによって決められます。

ノードが決まると、Kubernetesによってコンテナ(この例ではsample)のcpu cgroupが作成され、そのcgroupが、CPUの上限が20個になるように構成されます。また、Kubernetesによってコンテナのmemory cgroupが作成され、上限が200 GBになるようにそれが構成されます。その後、Kubernetesによって、新規作成されたコンテナのリード・プロセスが分けられて、最初のプロセスがcpuおよびmemory cgroupに関連付けられます。

リード・プロセスはこれらのcgroupに関連付けられているかこれらの下で実行されているため、そのプロセスとそのすべての子は、それらのcgroupで定義されている制限の対象となります。このコンテナが実行されているノード上のLinuxカーネルにより、Kubernetesによる関与なしで、これらの制限が自動的に強制適用されます。

CPU制限はLinuxによって簡単に強制適用されます。アプリケーションでその上限より多くのCPUを使用する必要が生じた場合は、その使用量を制御し続けるために、カーネルによって、そのアプリケーションを一定期間ディスパッチしないことが選択される可能性があります。

メモリー制限の強制適用は、CPUの場合とは異なります。Linuxには、out of memory (OOM)キラーというコンポーネントがあります。プロセスのメモリー使用量が予定より多くなった場合や、システムがストレスを受けた場合は、OOMキラーによってプロセスが突然終了されます。

次は、次のように定義されているポッドについて考えてみましょう。
apiVersion: v1
kind: Pod
metadata:
  name: samplePod
spec:
  containers:
  - image: container-registry.oracle.com/timesten/timesten:22.1.1.30.0
    name: sample
このポッドには、メモリー制限は指定されていません。コンテナは、制限のない、デフォルトのcgroupで実行されます。このcgroupは、プロセスがコンテナ内で実行されているかどうかに関係なく、メモリー制限が指定されていないノード上のすべてのプロセスによって共有されます。この場合は、Linuxノードにメモリーの制約が生じると、OOMキラーによって、そのノード全体から、終了するプロセスが選択されます。対象になるのは、TimesTen、Kubernetesのkubelet、その他のプロセス、またはそれらすべてである可能性があります。