kubernetes
kubelet

Kubernetes 1.14: SIG Node の変更内容


はじめに

Kubernetes 1.14 の CHANGELOG から SIG Node の取り組みについてまとめます。


主な変更点 (1.14 What's New)


Pid Limiting がベータになりました (#757) :tada:


  • Pid リソースの枯渇を防ぐための機能です。

  • Pid リソースを Pod-Pod 間および Node-Pod 間で隔離することができます。 kubernetes/kubernetes: #73651 / kubernetes/enhancements: #757



    • :pencil: 今回、1.14 でベータになったのは Pod 内で Pid の数を制限する、Pod-Pod 間の Pid Limiting の方です、1.13 では Feature Gate の SupportPodPidsLimit で有効化する必要がありました。


    • :pencil: それとは別に Node が最低限確保する Pid の数を指定するための Node-Pod 間の Pid Limiting が kubernetes/kubernetes: #73651 で導入されました。この機能はまだアルファ機能ですので Feature Gate の SupportNodePidsLimittrue にすることで有効化する必要があります。


    • :pencil: ちなみに 2019/04/05 時点のドキュメント では未だ SupportPodPidsLimit はアルファ機能のままで、 SupportNodePidsLimit についての記載はありません…。




Windows Node のサポートが Stable になりました(#116) :tada:


既知の問題 (Known Issues)



  • 既存の Flexvolume でマウントされた PVC がたくさんのディレクトリを含んでいたり、空き容量が不足していた場合 kubelet の再起動が失敗する場合があります。 #75019



    • :pencil: kubelet は Plugin の登録に関して、plugin ディレクトリを常に監視していますが、古い plugin ディレクトリは Flexvolume によって実際の PV がマウントされるパスでもあります。そのため、マウントされた Flexvolume の PV が大量のディレクトリを含んでいた場合や、空き容量が不足していた場合に Plugin の登録に関する監視が失敗してしまうためこの問題が発生してしまうようです。




アップグレード時の注意点 (Urgent Upgrade Notes)



  • --experimental-fail-swap-on フラグが削除されました。 #69552, @Pingan2017



    • :pencil: 代わりに --fail-swap-on を使ってください。


    • :pencil: --fail-swap-on に関する議論は #7294 を参照してください。




  • kubelet による Health check (liveness & readiness) が異なるホストに対するリダイレクトを行わなくなり、Success として扱われるようになりました。この場合、 ProbeWarning というイベントが生成され、リダイレクトが無視されたことがわかります。もし、異なるエンドポイントに対する health check のリダイレクトに依存しているようならば、リダイレクトではなく例えばプロキシするように変更してください。 #75416, @tallclair



    • :pencil: チェックしているのは異なるホストへのリダイレクト のようですので、内部でリダイレクトする限りにおいては問題ないようです。


    • :pencil: もともとドキュメントでは health check 時のレスポンスのステータスコードが 200-400 の間である場合は Success として看做すと書かれていたため、整合性を合わせるための修正のようです。




廃止される機能 (Deprecations)



  • OS やアーキテクチャの情報が Node オブジェクトの kubernetes.io/oskubernetes.io/arch ラベルに記録されるようになりました。 beta.kubernetes.io/osbeta.kubernetes.io/arch ラベルはまだ利用可能ですが、 v1.18 に削除予定です。 #73333, @yujuhong


  • --containerized フラグが非推奨となりました。将来のバージョンで削除されます。 #74267, @dims




注目機能 (Notable Features)



  • RunAsGroup がベータ機能に昇格し、デフォルトで有効化されました。PodSpecPodSecurityPolicy オブジェクトを利用して、サポートされたコンテナランタイムにおいては、プライマリGIDを制御することができます。 #73007, @ krmayankk



    • :pencil: これまでも fsGroup を指定することで補助グループを指定することはできましたが、プライマリグループを指定することはできませんでした。




  • PodPresets を利用した際に、init container に通常のコンテナと同じ情報が追加されるようになりました。 #71479, @ soggiest



    • :pencil: 注目の機能と言うよりも仕様のバグのような気がしますが、今までは init container に PodPresets が適用されていなかったようです。




  • CRI による pod のログディレクトリが、/var/log/pods/UID から /var/log/pods/NAMESPACE_NAME_UID に変更になりました。 #74441, @Random-Liu



    • :pencil: リリースノートからは分かりづらいですが、/var/log/pods/${NAMESPACE_NAME}_${POD_NAME}_${POD_UID} に変更した、と言うことです。これにより、ログの収集時などにメタデータとして Pod の名前やネームスペース名などを apiserver への問い合わせ無しでつけることができるようになります。




  • RuntimeClass がベータとなり、デフォルトで有効化されました。 #75003, @tallclair


API の変更 (API Changes)



  • [CRI] PodSandboxPodSandboxStatusruntime_handler という Pod の RuntimeClass の情報をトラックするためのフィールドが追加されました #73833, @haiyanmeng



    • :pencil: RuntimeClass が導入された関係上、CRI の API で runtime に関する情報を取得する必要がありました。




バグ修正や変更など (Detailed Bug Fixes And Changes)



  • --container-runtime-endpoint のヘルプメッセージが修正されました。Linux では unix socket しかサポートしていません。 #74712, @feiskyer



    • :pencil: ヘルプメッセージには TCP エンドポイントも利用できると嘘情報が書かれていました。




  • 複数のレポジトリに関連づけられている一つのタグしか持たないイメージに対するイメージガベージコレクションが失敗しなくなりました。 #73824, @jiayingz




  • kubelet は Unknown ステータスなコンテナを再起動もしくは削除する前に停止を試みるようになりました。 #73802, @Random-Liu


    • Unknown ステータスは必ずしも該当するコンテナが終了していることを意味しないので、Unknown なステータスをランタイムから受け取った後に単にそれをエラーと看做して再度コンテナの起動を試みると、同じコンテナが複数起動してしまう可能性があります。例えば kube-proxy のように一つのノードに一つのPodのみ起動する必要があるようなコンテナの場合問題が発生する可能性がありました。




  • PLEG のイベントチャンネルが満杯であった場合、イベントが破棄されるようになりました。破棄された回数は metrics として収集することができます。



    • :pencil: PLEG とは、Pod Lifecycle Event Generator の略です。


    • :pencil: kubelet が大量の pod を処理している際に、イベントチャンネルが満杯になりメインループがブロックされてしまう問題があったようです。




  • ランタイムが dockersim の際に、ノードの IOPS が限界であった場合、予期せずノードのステータスが NotReady になっていた問題が修正されました。 #74389, @answer1991



    • :pencil: Kubelet は CNI の状態を、設定ファイルから設定を同期した後にチェックしていました。そのため、ディスクの IOPS がフルになってしまった場合 CNI の状態を返せず、結果として CNI の状態を把握することができなくなり、ノードの状態が NotReady であると判断していたようです。修正では CNI の設定の同期を、CNIの状態確認とは別の go routine で確認するようにしたようです。




  • #73264 の修正。cpuPeriod はアルファゲートによって無効化されていましたが、リセットされずフラグ経由で利用されていました。 #73342, @szuecs



    • :pencil: リリースノートを読むだけでは全く何言ってるのかわからない変更点が多いわけですが、これも特になんのこっちゃ感が高い。


    • :pencil: 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



    • :pencil: Critical Pod と判定された Pod 中のコンテナに、Guaranteed な Pod と同じ oom_score_adj が設定されるようになったようです。


    • :pencil: ちなみに oom_score_adj の計算は現在の実装では以下のようになっており、高いスコアのコンテナほど OOM されやすくなります。


      • Guaranteed: -998

      • BestEffort: 1000

      • Burstable: 1000 - (1000*memoryRequest)/memoryCapacity






  • 単一の ConfigMap/Secret を参照しているたくさんの Pod がいると kubelet がタイムアウトしてしまう問題が修正されました。 #74755, @liggitt



    • :pencil: go1.10/1.11 では http/2 stream が飽和するという問題があったため、kubelet における configMapAndSecretChangeDetectionStrategykubeletconfigv1beta1.WatchChangeDetectionStrategy から kubeletconfigv1beta1.TTLCacheChangeDetectionStrategy にリバートされたようです。




  • コンテナの作成、起動と停止時のイベントメッセージに、コンテナ名が含まれるようになり、またメッセージのフォーマットも一貫性のあるものになりました。 #73892, @smarterclayton



    • :pencil: 以下のようにイベントがわかりやすくなってます。


      • 変更前
        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]



    • :pencil: ノードコンディションの OutOfDisk は 1.12 で削除されました。この変更ではさらに、古いノードオブジェクトに設定されていた OutOfDisk物理的に削除しています。




  • vSphere CloudProvider でノードが複数の IP アドレスを持っていた際の NodeAddresses の設定を修正しました。 #70805, @danwinship


  • docker image の削除時に dockershim が panic を起こしていた問題が修正されました。 #75367, @feiskyer




  • kubelet が終了した Pod については ConfigMapsSecrets を監視しなくなりました。最悪なシナリオでは、この問題は kube-apiserver に対して他のリクエストを送れない状況を引き起こします。 #74809, @oxddr


  • 新しく導入された TaintNodesByCondition admission plugin は新しく追加された Node オブジェクトを "not ready" として taint します。これは新しく追加された Node オブジェクトが "not ready" であるという状態がシステムに反映されるまでに、Pod がそのノードにスケジューリングされてしまうというレースコンディションを修正します。この admission plugin は TaintNodesByCondition 機能が有効化されていた場合、デフォルトで有効化されます。 #73097, @bsalamat



    • :pencil: 最後の一文がわかりづらいですが、TaintNodesByConditionベータ機能であり デフォルトで有効化されています。


    • :pencil: 新しく追加された 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



    • :pencil: 主な変更点に記載されている Pid limiting の Node-Pod 間における Pid リソースの隔離についての PR です。




所感

誤読だと良いのですが、kubelet のコンテナ対応が非推奨になり、削除されていきそうな勢いです。(すでに e2e テストが flaky だ、という理由で削除されてしまいました。実装していた CoreOS/Red Hat が手を引いた、とissueにも書いてあり、今後 kubelet をコンテナで動かしている人たちはノードで直接 kubelet を動かさないとならなくなりそうです。個人的には kubelet が動作するのに必要なライブラリが同梱されているコンテナイメージはとても重宝しますし、もし、直接 kubelet をノードで直接実行しなければならなくなった場合、ノードのセットアップが面倒になるのでとても困ります。(例えば glusterfs を PV として利用していた場合、ノードに glusterfs のクライアントをインストールする必要があります。)

kubelet のコンテナ対応非推奨とは、純粋に --containerized フラグとその関連する機能についてで、単に kubelet をコンテナで動かす限りにおいては問題なさそうです。