はじめに
Kubernetesのドキュメントって英語だし、英検3級レベルで英語力のない私にはつらい・・・
そして、一回(google翻訳を使って)訳しながら読んでまた忘れてまた(google翻訳を使って)訳すを繰り返すのをやめたい。
調べるときは全文を見ずに、必要な部分だけを見てたりするので、公式ドキュメントを訳しながら全体を理解していこうと思う。
英語読むのめんどくせーーーとなっている人の助けになればと思い公開した
今回は Managing Compute Resources for Containers
注意事項
- 基本的にGoogle翻訳のまんまです。
- 一応、意味が分かるようには訳してるつもりですが、ちょいちょい意味分からない部分もあります。
誤訳がある可能性があるので、最後はちゃんと公式ドキュメントを読みましょう - 私の知りたい部分からやるので、訳す部分はバラバラになります。
- 公式ドキュメントに記載されていない部分(自分で調べた部分とか)は_italic_で記載しています。
- V1.11でのドキュメントを記載
Managing Compute Resources for Containers
Podを指定する場合は、オプションで、各コンテナに必要なCPUとメモリ(RAM)の量を指定できます。コンテナにリソース要求が指定されている場合、スケジューラはPodを配置するノードをより適切に決定できます。また、コンテナの制限が指定されている場合、ノード上のリソースの競合を指定された方法で処理できます。要求と制限の違いの詳細については、リソースQoSを参照してください。
Resource requests and limits of Pod and Container
ポッドの各コンテナは、以下の1つまたは複数を指定できます。
spec.containers[].resources.limits.cpu
spec.containers[].resources.limits.memory
spec.containers[].resources.requests.cpu
spec.containers[].resources.requests.memory
要求と制限は個々のコンテナでのみ指定できますが、Podリソースの要求と制限について話をすると便利です。特定のリソースタイプに対するPodリソース要求/制限は、Pod内の各コンテナに対するそのタイプのリソース要求/制限の合計です。
Meaning of CPU
CPUリソースの制限と要求は、CPU単位で測定されます。 Kubernetesにある1つのCPUは、次のものと同等です。
- 1 AWS vCPU
- 1 GCP Core
- 1 Azure vCore
- 1 Hyperthread on a bare-metal Intel processor with Hyperthreading
分数リクエストが許可されます。spec.containers[].resources.requests.cpu
が0.5
のコンテナは、CPUの1つを要求するものの半分のCPUが保証されています。式0.1は、式100mと等価であり、これは「100millicpu」と読み取ることができる。一部の人々は "100ミリコア"と言っています。これは同じことを意味すると理解されています。小数点を含む要求(0.1
など)はAPIによって100m
に変換され、1m
より細かい精度は許可されません。
CPUは常に絶対量として要求され、相対量としては決して要求されません。 0.1は、シングルコア、デュアルコア、または48コアマシン上のCPUの量と同じです。
Meaning of memory
制限とメモリ要求はバイト単位で測定されます。E、P、T、G、M、Kの接尾辞のいずれかを使用して、メモリを平方整数または固定小数点整数として表すことができます。Ei、Pi、Ti、Gi、Mi、Kiの2乗法を使うこともできます。たとえば、次の値はおおよそ同じ値を表します。
128974848, 129e6, 129M, 123Mi
ここに例があります。次のポッドには2つのコンテナがあります。各コンテナには、0.25 cpuと64MiB(2の26乗バイト)のメモリの要求があります。各コンテナには0.5 cpuと128MiBのメモリがあります。あなたは、ポッドに0.5 cpuと128 MiBのメモリ、1 cpuと256 MBbのメモリの要求があると言うことができます。
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: db
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: wp
image: wordpress
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
How Pods with resource requests are scheduled
Podを作成すると、KubernetesスケジューラーはPodのノードを選択して実行します。各ノードには、リソースタイプごとに最大容量(ポッドに提供できるCPUとメモリの量)があります。スケジューラは、各リソースタイプに対して、スケジュールされたコンテナのリソース要求の合計がノードの容量よりも少ないことを保証する。ノード上の実際のメモリまたはCPUリソース使用率は非常に低くても、スケジューラは容量チェックに失敗した場合でもノードにPodを配置することを拒否します。これは、リソースの使用率が後で増加する場合(たとえば、リクエストの1日のピーク時など)、ノード上のリソース不足から保護します。
How Pods with resource limits are run
kubeletがPodのコンテナを開始すると、CPUとメモリの制限がコンテナのランタイムに渡されます。
Dockerを使用する場合:
-
spec.containers[].resources.requests.cpu
は、コアの値に変換されます。これは、小数点以下の桁数で、1024を掛けたものです。この数または2のうち大きい方が、docker run
コマンドの--cpu-sharesフラグの値として使用されます。 -
spec.containers[].resources.limits.cpu
はミリコア値に変換され、100が乗算されます。結果の値は、コンテナが100msごとに使用できるCPU時間の合計量です。コンテナは、この間隔の間にCPU時間の共有以上を使用することはできません。
注:デフォルトのクォータ期間は100msです。 CPUクォータの最小解像度は1msです。
-
spec.containers[].resources.limits.memory
は整数に変換され、docker run
コマンドの--memoryフラグの値として使用されます。
コンテナがメモリ制限を超えると、コンテナが終了する可能性があります。再起動可能であれば、kubeletは他のタイプのランタイムエラーと同様に再起動します。
コンテナがそのメモリ要求を超えると、ノードがメモリ不足になるたびに、そのPodが追い出される可能性があります。
コンテナは、長時間にわたってCPU制限を超えても超えなくてもよい。ただし、CPU使用率が過剰になってもkillされません。
リソース制限のためにコンテナをスケジュールできない、または強制終了できないかどうかを判断するには、トラブルシューティングを参照してください。
Monitoring compute resource usage
ポッドのリソース使用状況は、ポッドステータスの一部として報告されます。
クラスタにオプションの監視が設定されている場合、監視システムからPodリソースの使用状況を取得できます。
Troubleshooting
My Pods are pending with event message failedScheduling
スケジューラがPodが収まるノードを見つけることができない場合、Podは場所が見つかるまでスケジュールされません。スケジューラが次のようにPodの場所を見つけられないたびにイベントが生成されます。
$ kubectl describe pod frontend | grep -A 3 Events
Events:
FirstSeen LastSeen Count From Subobject PathReason Message
36s 5s 6 {scheduler } FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others
前述の例では、ノード上のCPUリソースが不十分なため、「frontend」という名前のポッドがスケジュールされませんでした。同様のエラーメッセージは、不十分なメモリ(PodExceedsFreeMemory)による不具合を示唆することもあります。一般に、Podがこのタイプのメッセージで保留中の場合、試してみるべきいくつかのことがあります:
- クラスタにノードを追加してください。
- 保留中のポッドのためのスペースを確保するため、不要なポッドを終了します。
- ポッドがすべてのノードよりも大きくないことを確認します。たとえば、すべてのノードがcpu:1の容量を持つ場合、
cpu:1.1
の要求を持つポッドは決してスケジューリングされません。
kubectl describe nodes
コマンドで割り当てられたノードの容量と量を確認できます。例えば:
$ kubectl describe nodes e2e-test-minion-group-4lw4
Name: e2e-test-minion-group-4lw4
[ ... lines removed for clarity ...]
Capacity:
cpu: 2
memory: 7679792Ki
pods: 110
Allocatable:
cpu: 1800m
memory: 7474992Ki
pods: 110
[ ... lines removed for clarity ...]
Non-terminated Pods: (5 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
--------- ---- ------------ ---------- --------------- -------------
kube-system fluentd-gcp-v1.38-28bv1 100m (5%) 0 (0%) 200Mi (2%) 200Mi (2%)
kube-system kube-dns-3297075139-61lj3 260m (13%) 0 (0%) 100Mi (1%) 170Mi (2%)
kube-system kube-proxy-e2e-test-... 100m (5%) 0 (0%) 0 (0%) 0 (0%)
kube-system monitoring-influxdb-grafana-v4-z1m12 200m (10%) 200m (10%) 600Mi (8%) 600Mi (8%)
kube-system node-problem-detector-v0.1-fj7m3 20m (1%) 200m (10%) 20Mi (0%) 100Mi (1%)
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
CPU Requests CPU Limits Memory Requests Memory Limits
------------ ---------- --------------- -------------
680m (34%) 400m (20%) 920Mi (12%) 1070Mi (14%)
上記の出力では、Podが1120mを超えるCPUまたは6.23Giのメモリを要求した場合、ノードに収まらないことがわかります。
Pods
セクションを見ると、どのポッドがノード上のスペースを占めているのかが分かります。
Podsに利用可能なリソースの量は、システムデーモンが利用可能なリソースの一部を使用するため、ノードの容量よりも少なくなります。allocatable(割り当て可能)
フィールドNodeStatusは、Podで使用可能なリソースの量を示します。詳細については、ノード割り当て可能なリソースを参照してください。
リソースクォータ機能は、消費可能なリソースの総量を制限するように構成できます。名前空間と組み合わせて使用すると、1つのチームがすべてのリソースを奪うのを防ぐことができます。
My Container is terminated
あなたのContainerはリソースが枯渇しているため、終了する可能性があります。リソース制限に達しているためにコンテナが強制終了されているかどうかを確認するには、該当するPodのkubectl describe pod
を呼び出します。
[12:54:41] $ kubectl describe pod simmemleak-hra99
Name: simmemleak-hra99
Namespace: default
Image(s): saadali/simmemleak
Node: kubernetes-node-tf0f/10.240.216.66
Labels: name=simmemleak
Status: Running
Reason:
Message:
IP: 10.244.2.75
Replication Controllers: simmemleak (1/1 replicas created)
Containers:
simmemleak:
Image: saadali/simmemleak
Limits:
cpu: 100m
memory: 50Mi
State: Running
Started: Tue, 07 Jul 2015 12:54:41 -0700
Last Termination State: Terminated
Exit Code: 1
Started: Fri, 07 Jul 2015 12:54:30 -0700
Finished: Fri, 07 Jul 2015 12:54:33 -0700
Ready: False
Restart Count: 5
Conditions:
Type Status
Ready False
Events:
FirstSeen LastSeen Count From SubobjectPath Reason Message
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "k8s.gcr.io/pause:0.8.0" already present on machine
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD created Created with docker id 6a41280f516d
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD started Started with docker id 6a41280f516d
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a
上記の例では、Restart Count:5
は、Pod内のsimmemleak
コンテナが5回終了して再起動されたことを示しています。
以前に終了したコンテナのステータスを取得するには、-o go-template = ...
オプションを指定してkubectl get pod
を呼び出すことができます。
ドキュメントが崩れてているため後から記載
たとえば、次のポッドには2つのコンテナがあります。各コンテナには、2GiBのローカルephemeral storageの要求があります。各コンテナには、4GiBのローカルephemeral storageの制限があります。したがって、ポッドには一時的なローカルストレージの4GiBが要求され、ストレージには8GiBの制限があります。
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: db
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"
- name: wp
image: wordpress
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"
How Pods with ephemeral-storage requests are scheduled
Podを作成すると、KubernetesスケジューラーはPodのノードを選択して実行します。各ノードには、Podに提供できるローカルの一時的なストレージの最大量があります。詳細は、ノードの割り当て可能性(Node Allocatable)を参照してください。スケジューラは、スケジュールされたコンテナのリソース要求の合計がノードの容量より少ないことを確認します。
How Pods with ephemeral-storage limits run
コンテナレベルの分離では、コンテナの書き込み可能なレイヤーとログの使用量がストレージの制限を超えた場合、ポッドは追い出されます。ポッドレベルの分離の場合、すべてのコンテナからの一時的なストレージの使用量の合計とポッドのEmptyDirボリュームが上限を超えると、ポッドは追い出されます。
Extended Resources
拡張リソースは、kubernetes.io
ドメインの外部にある完全修飾リソース名です。これにより、クラスターオペレーターは宣言(advertise)し、ユーザーはKubernetesビルトインリソース以外を消費することができます。
拡張リソースを使用するには、2つのステップが必要です。まず、クラスタオペレータは拡張リソースを宣言しなければなりません。次に、ユーザーは、ポッドで拡張リソースを要求する必要があります。
Managing extended resources
Node-level extended resources
ノードレベルの拡張リソースはノードに結びついています。
Device plugin managed resources
デバイスプラグイン管理リソースを各ノードにアドバタイズする方法については、デバイスプラグインを参照してください。
Other resources
新しいノードレベルの拡張リソースをアドバタイズするには、クラスタオペレータはPATCH
HTTPリクエストをAPIサーバーに送信して、クラスタ内のノードのstatus.capacity
に使用可能な数量を指定します。この操作の後、ノードのstatus.capacity
に新しいリソースが含まれます。status.allocatable
フィールドは、kubeletによって非同期的に新しいリソースで更新されます。ポッドの適性を評価するときには、スケジューラはノードのstatus.allocatable値を使用するため、ノードの容量を新しいリソースにパッチすることと、そのノードでリソースをスケジュールするように要求する最初のポッドとの間に短い遅延が生じることに注意してください。
Example:
次は、curl
を使用して、マスターがk8s-master
であるノードk8s-node-1
に5つの "example.com/foo"リソースをアドバタイズするHTTPリクエストを作成する方法を示す例です。
curl --header "Content-Type: application/json-patch+json" \
--request PATCH \
--data '[{"op": "add", "path": "/status/capacity/example.com~1foo", "value": "5"}]' \
http://k8s-master:8080/api/v1/nodes/k8s-node-1/status
注:前の要求(request)では、〜1
はパッチパス内の文字/
のエンコーディングです。JSON-Patchの操作パス値はJSON-Pointerとして解釈されます。詳細については、IETF RFC 6901のセクション3を参照してください。
Cluster-level extended resources
クラスタレベルの拡張リソースはノードに結びついていません。それらは通常、スケジューラー エクステンダーによって管理され、リソースの消費、割り当てなどを処理します。スケジューラー・ポリシー構成でスケジューラー・エクステンダーによって処理される拡張リソースを指定できます。
Example:
スケジューラーポリシーの次の構成は、クラスター拡張リソース "example.com/foo"がスケジューラーエクステンダーによって処理されることを示します。スケジューラーは、ポッドが「example.com/foo」を要求する場合にのみスケジューラーエクステンダーにポッドを送信します。ignoredByScheduler
フィールドは、スケジューラーがPodFitsResources
述部の "example.com/foo"リソースをチェックしないことを指定します。
{
"kind": "Policy",
"apiVersion": "v1",
"extenders": [
{
"urlPrefix":"<extender-endpoint>",
"bindVerb": "bind",
"managedResources": [
{
"name": "example.com/foo",
"ignoredByScheduler": true
}
]
}
]
}
Consuming extended resources
ユーザーは、CPUとメモリのようなPodの仕様で拡張リソースを使用することができます。スケジューラーは、使用可能な量をPodに同時に割り当てることができないように、リソースアカウンティングを行います。APIサーバーは、拡張リソースの数を整数に制限します。有効な量の例は3,3000mと3Kiです。無効な量の例は、0.5と1500mです。
注:拡張リソースは不透明整数リソースを置き換えます。ユーザーは予約済みの"kubernetes.io
"以外の任意のドメイン名の接頭辞を使用できます。
Podで拡張リソースを使用するには、コンテナ仕様のspec.containers[].resources.limits
マップにキーとしてリソース名を含めます。
注:拡張リソースはオーバーコミットできません。したがって、両方がコンテナ・スペックに存在する場合、要求と制限は等しくなければなりません。
ポッドは、CPU、メモリ、拡張リソースなど、すべてのリソース要求が満たされている場合にのみスケジュールされます。リソース要求が満たされない限り、PodはPENDING
状態のままです。
Example:
以下のポッドは2つのCPUと1つの "example.com/foo"(拡張リソース)を要求します。
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: myimage
resources:
requests:
cpu: 2
example.com/foo: 1
limits:
example.com/foo: 1
Planned Improvements
Kubernetesバージョン1.5では、コンテナにリソース数量を指定することしかできません。emptyDirボリュームなど、ポッド内のすべてのコンテナで共有されるリソースのアカウンティングを改善する予定です。
Kubernetesバージョン1.5は、コンテナ要求とCPUとメモリの制限のみをサポートしています。ノードディスクスペースリソースやカスタムリソースタイプを追加するためのフレームワークなど、新しいリソースタイプを追加する予定です。
Kubernetesは、複数のレベルのサービス品質をサポートすることにより、リソースの過剰提供(overcommitment)をサポートしています。
Kubernetesバージョン1.5では、CPUの1つのユニットは、異なるクラウドプロバイダ上で、同じクラウドプロバイダ内の異なるマシンタイプ上で異なることを意味します。たとえば、AWSでは、ノードの容量はECUsでレポートされ、GCEでは論理コアでレポートされます。我々は、プロバイダーとプラットフォーム間のより一貫性を可能にするために、CPUリソースの定義を修正する予定です。