はじめに
Kubernetes 1.14 の CHANGELOG から SIG Node の取り組みについてまとめます。
主な変更点 (1.14 What's New)
Pid Limiting がベータになりました (#757)
- Pid リソースの枯渇を防ぐための機能です。
- Pid リソースを Pod-Pod 間および Node-Pod 間で隔離することができます。 kubernetes/kubernetes: #73651 / kubernetes/enhancements: #757
-
今回、1.14 でベータになったのは Pod 内で Pid の数を制限する、Pod-Pod 間の Pid Limiting の方です、1.13 では Feature Gate の
SupportPodPidsLimit
で有効化する必要がありました。 -
それとは別に Node が最低限確保する Pid の数を指定するための Node-Pod 間の Pid Limiting が kubernetes/kubernetes: #73651 で導入されました。この機能はまだアルファ機能ですので Feature Gate の
SupportNodePidsLimit
をtrue
にすることで有効化する必要があります。 -
ちなみに 2019/04/05 時点のドキュメント では未だ
SupportPodPidsLimit
はアルファ機能のままで、SupportNodePidsLimit
についての記載はありません…。
-
今回、1.14 でベータになったのは Pod 内で Pid の数を制限する、Pod-Pod 間の Pid Limiting の方です、1.13 では Feature Gate の
Windows Node のサポートが Stable になりました(#116)
- 詳しくは SIG Windows の記事を参照してください。
既知の問題 (Known Issues)
-
既存の Flexvolume でマウントされた PVC がたくさんのディレクトリを含んでいたり、空き容量が不足していた場合 kubelet の再起動が失敗する場合があります。 #75019
- kubelet は Plugin の登録に関して、plugin ディレクトリを常に監視していますが、古い plugin ディレクトリは Flexvolume によって実際の PV がマウントされるパスでもあります。そのため、マウントされた Flexvolume の PV が大量のディレクトリを含んでいた場合や、空き容量が不足していた場合に Plugin の登録に関する監視が失敗してしまうためこの問題が発生してしまうようです。
アップグレード時の注意点 (Urgent Upgrade Notes)
-
--experimental-fail-swap-on
フラグが削除されました。 #69552, @Pingan2017-
代わりに
--fail-swap-on
を使ってください。 -
--fail-swap-on
に関する議論は #7294 を参照してください。
-
代わりに
-
kubelet による Health check (liveness & readiness) が異なるホストに対するリダイレクトを行わなくなり、
Success
として扱われるようになりました。この場合、ProbeWarning
というイベントが生成され、リダイレクトが無視されたことがわかります。もし、異なるエンドポイントに対する health check のリダイレクトに依存しているようならば、リダイレクトではなく例えばプロキシするように変更してください。 #75416, @tallclair- チェックしているのは異なるホストへのリダイレクト のようですので、内部でリダイレクトする限りにおいては問題ないようです。
-
もともとドキュメントでは health check 時のレスポンスのステータスコードが 200-400 の間である場合は
Success
として看做すと書かれていたため、整合性を合わせるための修正のようです。
廃止される機能 (Deprecations)
-
OS やアーキテクチャの情報が Node オブジェクトの
kubernetes.io/os
とkubernetes.io/arch
ラベルに記録されるようになりました。beta.kubernetes.io/os
とbeta.kubernetes.io/arch
ラベルはまだ利用可能ですが、 v1.18 に削除予定です。 #73333, @yujuhong -
--containerized
フラグが非推奨となりました。将来のバージョンで削除されます。 #74267, @dims- kubelet のコンテナ化サポート自体が非推奨となったのか、このフラグが非推奨になっただけなのか気になるところです。issue の最初の方 では、このフラグが非推奨になっただけで使っていないのならば影響ないよとコメントされていますが、後のコメントでは 「この機能自体が非推奨だよ」 とされており、すでにコンテナ化された kubelet のテスト自体も削除 されてしまったようです。
注目機能 (Notable Features)
-
RunAsGroup
がベータ機能に昇格し、デフォルトで有効化されました。PodSpec
とPodSecurityPolicy
オブジェクトを利用して、サポートされたコンテナランタイムにおいては、プライマリGIDを制御することができます。 #73007, @ krmayankk-
これまでも
fsGroup
を指定することで補助グループを指定することはできましたが、プライマリグループを指定することはできませんでした。
-
これまでも
-
PodPresets
を利用した際に、init container に通常のコンテナと同じ情報が追加されるようになりました。 #71479, @ soggiest-
注目の機能と言うよりも仕様のバグのような気がしますが、今までは init container に
PodPresets
が適用されていなかったようです。
-
注目の機能と言うよりも仕様のバグのような気がしますが、今までは init container に
-
CRI による pod のログディレクトリが、
/var/log/pods/UID
から/var/log/pods/NAMESPACE_NAME_UID
に変更になりました。 #74441, @Random-Liu-
リリースノートからは分かりづらいですが、
/var/log/pods/${NAMESPACE_NAME}_${POD_NAME}_${POD_UID}
に変更した、と言うことです。これにより、ログの収集時などにメタデータとして Pod の名前やネームスペース名などを apiserver への問い合わせ無しでつけることができるようになります。
-
リリースノートからは分かりづらいですが、
-
RuntimeClass
がベータとなり、デフォルトで有効化されました。 #75003, @tallclair
API の変更 (API Changes)
-
[CRI]
PodSandbox
とPodSandboxStatus
にruntime_handler
という Pod の RuntimeClass の情報をトラックするためのフィールドが追加されました #73833, @haiyanmeng-
RuntimeClass
が導入された関係上、CRI の API で runtime に関する情報を取得する必要がありました。
-
バグ修正や変更など (Detailed Bug Fixes And Changes)
-
--container-runtime-endpoint
のヘルプメッセージが修正されました。Linux では unix socket しかサポートしていません。 #74712, @feiskyer- ヘルプメッセージには TCP エンドポイントも利用できると嘘情報が書かれていました。
-
複数のレポジトリに関連づけられている一つのタグしか持たないイメージに対するイメージガベージコレクションが失敗しなくなりました。 #73824, @jiayingz
- なんのこっちゃという感じですが、同一のイメージに対して異なるレポジトリのイメージ名を付与すると、kubelet によるノードディスク使用量削減のためのイメージガベージコレクションが失敗する、という問題があったようです。
-
kubelet は Unknown ステータスなコンテナを再起動もしくは削除する前に停止を試みるようになりました。 #73802, @Random-Liu
- Unknown ステータスは必ずしも該当するコンテナが終了していることを意味しないので、Unknown なステータスをランタイムから受け取った後に単にそれをエラーと看做して再度コンテナの起動を試みると、同じコンテナが複数起動してしまう可能性があります。例えば kube-proxy のように一つのノードに一つのPodのみ起動する必要があるようなコンテナの場合問題が発生する可能性がありました。
-
PLEG のイベントチャンネルが満杯であった場合、イベントが破棄されるようになりました。破棄された回数は metrics として収集することができます。
- PLEG とは、Pod Lifecycle Event Generator の略です。
- kubelet が大量の pod を処理している際に、イベントチャンネルが満杯になりメインループがブロックされてしまう問題があったようです。
-
ランタイムが dockersim の際に、ノードの IOPS が限界であった場合、予期せずノードのステータスが
NotReady
になっていた問題が修正されました。 #74389, @answer1991- Kubelet は CNI の状態を、設定ファイルから設定を同期した後にチェックしていました。そのため、ディスクの IOPS がフルになってしまった場合 CNI の状態を返せず、結果として CNI の状態を把握することができなくなり、ノードの状態が NotReady であると判断していたようです。修正では CNI の設定の同期を、CNIの状態確認とは別の go routine で確認するようにしたようです。
-
#73264 の修正。
cpuPeriod
はアルファゲートによって無効化されていましたが、リセットされずフラグ経由で利用されていました。 #73342, @szuecs- リリースノートを読むだけでは全く何言ってるのかわからない変更点が多いわけですが、これも特になんのこっちゃ感が高い。
-
k8s のアルファ機能として、CFS (Completely Fair Scheduler) の CPU Quota を計算する際に利用される
cpu.cfs_period_us
を任意に指定可能とするCustomCPUCFSQuotaPeriod
という Feature Gate があるわけですが、これが false に指定されているにも関わらず (アルファ機能なのでデフォルト false)、kubelet の引数として--cpu-cfs-quota-period
を指定すると、その値が中途半端に使われて意図しない CPU limit がコンテナに適用されてしまっていた、というバグを修正したようです。
- kubelet の CLI によるドキュメントと、生成されたウェブページが更新されました。#73256, @deitch
-
system-critical
のプライオリティを持った Pod 中のコンテナに低いoom_score_adj
を設定するようにしました。 #73758, @sjenning-
Critical Pod と判定された Pod 中のコンテナに、Guaranteed な Pod と同じ
oom_score_adj
が設定されるようになったようです。 -
ちなみに
oom_score_adj
の計算は現在の実装では以下のようになっており、高いスコアのコンテナほど OOM されやすくなります。- Guaranteed:
-998
- BestEffort:
1000
- Burstable:
1000 - (1000*memoryRequest)/memoryCapacity
- Guaranteed:
-
Critical Pod と判定された Pod 中のコンテナに、Guaranteed な Pod と同じ
-
単一の
ConfigMap/Secret
を参照しているたくさんの Pod がいると kubelet がタイムアウトしてしまう問題が修正されました。 #74755, @liggitt-
go1.10/1.11 では http/2 stream が飽和するという問題があったため、kubelet における
configMapAndSecretChangeDetectionStrategy
がkubeletconfigv1beta1.WatchChangeDetectionStrategy
からkubeletconfigv1beta1.TTLCacheChangeDetectionStrategy
にリバートされたようです。
-
go1.10/1.11 では http/2 stream が飽和するという問題があったため、kubelet における
-
コンテナの作成、起動と停止時のイベントメッセージに、コンテナ名が含まれるようになり、またメッセージのフォーマットも一貫性のあるものになりました。 #73892, @smarterclayton
-
以下のようにイベントがわかりやすくなってます。
- 変更前
35m Normal Created Pod Created container 35m Normal Started Pod Started container 10m Normal Killing Pod Killing container cri-o://container_name:Need to kill Pod
- 変更後
35m Normal Created Pod Created container container_name
-
以下のようにイベントがわかりやすくなってます。
35m Normal Started Pod Started container container_name
10m Normal Killing Pod Stopping container container_name
-
kubelet における古い
OutOfDisk
conditionが削除されました。 #72507, [@dixudx]-
ノードコンディションの
OutOfDisk
は 1.12 で削除されました。この変更ではさらに、古いノードオブジェクトに設定されていたOutOfDisk
を物理的に削除しています。
-
ノードコンディションの
-
vSphere CloudProvider でノードが複数の IP アドレスを持っていた際の
NodeAddresses
の設定を修正しました。 #70805, @danwinship -
docker image の削除時に dockershim が panic を起こしていた問題が修正されました。 #75367, @feiskyer
- dockershim の実装で、image が nil の際に今までは panic が起きる可能性があったところが修正されました。
- そもそも該当する docker image が存在しなかった場合は nil ではなく err を返す はずなのでこのような状況は考えづらいのですが、issue のコメントによると docker のアップグレードがこのような状況を引き起こす ことがあるようです。
-
kubelet が終了した Pod については
ConfigMaps
とSecrets
を監視しなくなりました。最悪なシナリオでは、この問題は kube-apiserver に対して他のリクエストを送れない状況を引き起こします。 #74809, @oxddr -
新しく導入された
TaintNodesByCondition
admission plugin は新しく追加された Node オブジェクトを "not ready" として taint します。これは新しく追加された Node オブジェクトが "not ready" であるという状態がシステムに反映されるまでに、Pod がそのノードにスケジューリングされてしまうというレースコンディションを修正します。この admission plugin はTaintNodesByCondition
機能が有効化されていた場合、デフォルトで有効化されます。 #73097, @bsalamat-
最後の一文がわかりづらいですが、
TaintNodesByCondition
はベータ機能であり デフォルトで有効化されています。 - 新しく追加された Node オブジェクトは、通常 "not ready" な場合が多いのですが、この admission plugin を利用しない場合、ノードが追加され、"not ready" なノードであると判断し、Node オブジェクトにその状態が反映されるまで "ready" な状態があり得てしまいます。この admission plugin は、この一瞬の隙をついて Pod がスケジューリングされてしまう場合を排除するための機能です。
-
最後の一文がわかりづらいですが、
-
kubelet が
--system-reserved
と--kube-reserved
オプションでpid=<number>
をサポートするようになりました。この値を指定することでシステム全体と kubernetes のシステムデーモンで利用する process IDs を予約することができるようになりました。詳しくはドキュメントを参照してください。この機能を有効化するために、SupportNodePidsLimit
feature gate をtrue
に設定する必要があります。 #73651, @RobertKrawitz- 主な変更点に記載されている Pid limiting の Node-Pod 間における Pid リソースの隔離についての PR です。
所感
誤読だと良いのですが、kubelet のコンテナ対応が非推奨になり、削除されていきそうな勢いです。(すでに e2e テストが flaky だ、という理由で削除されてしまいました。実装していた CoreOS/Red Hat が手を引いた、とissueにも書いてあり、今後 kubelet をコンテナで動かしている人たちはノードで直接 kubelet を動かさないとならなくなりそうです。個人的には kubelet が動作するのに必要なライブラリが同梱されているコンテナイメージはとても重宝しますし、もし、直接 kubelet をノードで直接実行しなければならなくなった場合、ノードのセットアップが面倒になるのでとても困ります。(例えば glusterfs を PV として利用していた場合、ノードに glusterfs のクライアントをインストールする必要があります。)
kubelet のコンテナ対応非推奨とは、純粋に --containerized
フラグとその関連する機能についてで、単に kubelet をコンテナで動かす限りにおいては問題なさそうです。