1.18(以降、1.18)が2020年3月24日にリリースされました。StartupProbeを紹介し、最後にStartupProbeを試していきます。最初に1.18リリースノートにおける5つの注目機能について、それぞれ解説します。Access、ヌマ)の環境において、コンテナの使用するCPUとデバイスの同一ソケット(NUMAノード)への割り当てを可能にします。Manager(トポロジマネージャ)は1.18でベータに昇格し、デフォルトで使用できるようになりました。NUMAアーキテクチャは、図1のように複数のCPUから構成されるアーキテクチャで、各ソケット(NUMAノードと呼ぶ)それぞれが自身のCPU、メモリ、PCIデバイスを持ちます。CPUは他のソケットのメモリやI/Oデバイスにアクセスできますが、自身の持つメモリやデバイスに対するアクセスと比較して性能に影響があります。Managerがあります。それらはリソースの割り当てを互いに独立して行っているため、NUMAアーキテクチャにおいて要求されたリソースが異なるソケットへ割り当てられ、性能に影響が出る可能性がありました。Managerにより、できる限り同一のNUMAノードに割り当てるといったコンテナのNUMAアウェアなリソースの割り当てが可能になります。Managerには次のような制約があります。Managerの具体的な使用方法や関連するより詳しい情報は、次のドキュメントを参照してください(※すべて英文サイトです)。applyコマンドによるKubernetesリソースの適用をこれまでクライアント(kubectl)側で実施していたのをサーバ(kube-apiserver)側で実施するようにします。Applyは1.18で2回目のベータとアナウンスされました。applyコマンドは以前から次のような問題があると言われていました。Applyは、Kubernetesリソースの各フィールドが誰(人間もKubernetesコンポーネントもここでは同等)によって管理されているかを記録し、もし管理者(フィールドマネージャと呼ぶ)以外がフィールドを変更しようとするとコンフリクトとして扱い、forceオプションを使用しない限り変更されません。これにより、他の管理者が管理しているフィールドを誤って変更してしまうことを防ぎます。applyコマンドに明示的に--server-sideオプションを指定する必要があります。このオプションは将来的にはデフォルトになるでしょう。そのほか、関連するオプションとして、フィールドの変更がコンフリクトした場合に強制的に解決する--force-conflictsオプションが追加されています。オブジェクトの各フィールドが誰によって定義および変更されたのかを管理するためのフィールドとして、全てのリソースに共通してmetadata.managedFieldsフィールドが追加されています。Applyにより、これまで以上に安全に宣言的にオブジェクト管理ができるようになります。apply相当のことを行うのは難しかったのですが、実装がサーバ側に移ったことでGoクライアントライブラリはもちろんPythonといった他のプログラミング言語やcurlでさえも簡単に利用できるようになります。Applyに関するより詳しい情報は、次のドキュメントを参照してください。APIに3つの大きな改善が行われました。Exact(完全一致)、Prefix(前方一致)という3つのパスタイプを指定します。ImplementationSpecificタイプがデフォルトです。(2)のIngressClassリソースは、これまで1つのクラスタで複数のIngressコントローラを使用したい場合には、kubernetes.io/ingress.classアノテーションにIngressコントローラ名を指定していました。spec.ingressClassNameフィールドで使用するコントローラを指定します。デフォルトで使用するIngressコントローラはIngressClassのingressclass.kubernetes.io/is-default-classアノテーションの値を"true"(boolではなく文字列)に設定することで指定できます。external-lb(3)のホスト名に対するワイルドカードのサポートは*.example.comと指定することでfoo.example.comに一致するようになります。実はこれまではFQDNとの完全一致が仕様だったにも関わらず、多くのIngressコントローラでワイルドカードをサポートしていました。API自体の仕様を変更してワイルドカードをサポートするようにしたというのが正確です。これらの新しい機能を使用できるかは、使用するIngressコントローラがサポートしているか次第です。そのため、クラスタのバージョンを1.18以上にアップグレードしてもこれらの機能が使えるとは限りません。自身の利用するクラスタがどのIngressコントローラを使用しており、そのコントローラが新しい機能をサポートしているかを確認してください。マネージドKubernetesサービスを使用している場合は、パブリッククラウドが出す変更内容を確認しましょう。自身でクラスタを構築している場合は、クラスタの運用者に確認すると良いでしょう。最後にIngressはコントローラの実装依存な部分が多く、Kubernetesのなかでは異質なリソースです。今回のパスタイプやホスト名のワイルドカードといった機能もコントローラの実装次第で仕様通りに機能するかは分かりません。APIのGAに向けてコンフォーマンステストの提供が予定されているため、将来的には仕様に定義されている機能については挙動が統一されていくことが期待できます。APIに関するより詳しい情報は、次のドキュメントを参照してください。1.18(英語)・Ingress(KEP)(英語)【TIP】アルファ、ベータ、GAってなに?Kubernetesの機能紹介で、よく「この機能はベータです」といった記述があります。Availability、安定版)があり、アルファから始まり、ベータを経てGAに至るという流れになっています。アルファステージの機能は実験的なもので、ベータ昇格時に破壊的変更が入ったり、その後機能自体が削除されることがあるため、基本的に本番では利用しないほうが良いでしょう。デフォルトで無効になっているため、利用するには明示的にフィーチャーゲート(feature-gate*1)で有効にする必要があります。ベータステージの機能はデフォルトで有効になります。十分にテストを行い、利用しても問題ないレベルと判断されると昇格します。そのあとの昇格で互換性のない変更が入る可能性もありますが、マイグレーションパスが用意されることになっています。このステージの機能を利用されたくない場合は明示的に無効化できます。GAステージの機能はデフォルトで有効になり、無効化はできません。今後、Kubernetesのドキュメントでアルファ、ベータ、GAの単語を見かけたら上記を思い出してみてください。詳細な機能ステージの説明は、次のドキュメントを参照してください。・フィーチャーゲート*1:フィーチャゲートは特定機能を有効/無効にするフラグのことで、各コンポーネントの--feature-gatesオプションで設定します。アルファ機能はデフォルトで無効になっているので、フィーチャゲートのオプションで有効化すると使用できるようになります。debugコマンドは、実行中のPodにデバッグを目的として一時的なコンテナを後から追加実行できる機能で、アルファステージで提供されました。実は1.16時点で一度アルファで紹介されていたので、1.18で2度目の紹介になります。execコマンドを使って対象のコンテナ内で任意のコマンドを実行していました。イメージ(ランタイムのみを含むイメージ)をベースとしているとデバッグに必要なコマンドやそもそもシェルさえも含まれていない場合もあり、デバッグが難しいという問題がありました。デバッグ用のコンテナをサイドカーとして実行させておくということも考えられますが、全てのPodに追加しておくことはコストがかかります。debugは、実行中のPodにエフェメラルコンテナと呼ばれる一時的なコンテナ(デバッグコンテナ)を後から追加するコマンドです。これにより、デバッグに必要なコマンドをアプリケーションコンテナに含ませておく必要がなく、コンテナイメージ作成のベストプラクティスであるイメージサイズの最小化などにscratchイメージやDistrolessイメージを使用して素直に取り組むことができます。自身が使い慣れたデバッグ専用のコンテナイメージを用意しておくことで、サードパーティのイメージにも慣れた環境でデバッグできます。使い方はとても簡単で、次のようにデバッグの対象となるPodとデバッグコンテナで使用するイメージを指定するだけです。この例は、デバッグ対象のPodがnginxでデバッグコンテナにbusyboxイメージを指定しています。Podにbusyboxをデバッグコンテナとして追加実行するデバッグコンテナからはアプリケーションコンテナで実行されているnginxにローカルホスト(127.0.0.1)でアクセスできます。そのほかに--targetオプションを使用すると、指定したコンテナとPIDネームスペースを共有してコンテナを実行します。これにより指定したコンテナで実行されているプロセスを参照し、シグナルの送信などができるようになります。含まれるnginxコンテナとPIDネームスペースを共有したうえでデバッグコンテナを実行します。--target=nginxここまでで、デバッグコンテナを使用すれば、あとからサイドカーコンテナを追加するなど「デバッグ用途以外にも便利に使えそうだ」と思った方もいるかもしれません。Podに対する大きな機能追加は影響が大きくなりすぎる可能性があることから、現時点で次のような制約があります。gate(フィーチャゲート)を有効にする必要があります。debugに関する詳しい情報は、次のドキュメントを参照してください。debugを試してみたい方は、次のエントリが参考になります。CSIサポート(アルファ)1.18でWindows向けのCSIプロキシがアルファストレージで提供されました。これにより、WindowsクラスタにおいてCSIドライバが使用できるようになります。Interface、コンテナストレージインターフェイス)は、Kubernetesのようなコンテナオーケストレータで任意のストレージシステムでのボリュームの作成/削除やアタッチ/デタッチなどの操作を標準化するために策定された仕様です。それまでのKubernetesでは、サードベンダが新しいボリュームプラグインを追加するにはin-tree(Kubernetes本体のコード)で開発する必要があり、プラグインのリリースがKubernetesのリリースサイクルに縛られる、Kubernetes本体のセキュリティの問題を引き起こす可能性があるなどの課題がありました。KubernetesのCSIサポートにより、サードベンダはCSIに準拠したドライバをKubernetesの外で開発し提供することで、独自のリリースサイクルを取れるようになりました。1.21までに全てのin-treeのボリュームプラグインのCSIへの移行が予定されています。csi-proxy.exeは、すべてのWindowsノード上で実行され、Podで実行されるCSIノードプラグインからgRPCで命令を受け取り代理として特権が必要なストレージの操作を行う(https://kubernetes.io/blog/2020/04/03/kubernetes-1-18-feature-windows-csi-support-alpha/からの引用)このリリースでは、WindowsクラスタでCSIドライバが使用できるようになりました。KubernetesのCSIドライバはコントローラプラグインとノードプラグインの2つから成っています。APIや外部のストレージシステムを操作するため、Windowsクラスタでも問題なく使用できていました。一方でノードプラグインは一般に全てのノードにDaemonSetで実行され、ボリュームのフォーマットやマウント/アンマウントやフォーマットなどを行うため、ホストに直接アクセスし、特権コンテナとして実行させる必要があります。現時点でWindowsは特権コンテナの実行をサポートしていないため、ノードプラグインが機能しませんでした。そこで、Windowsノードのホスト上で直接実行され、ノードプラグインに代わってストレージの操作を実行するCSIプロキシが開発されました。これにより、CSIプロキシがホストを操作することでノードプラグインが特権コンテナとして実行される必要がなくなり、CSIドライバがWindowsクラスタで使用できるようになります。CSIプロキシは1.18時点でアルファです。Platformのクラウドプロバイダがアルファでサポートしています。今後使用が見込まれる方は検証環境で使用し、問題があればフィードバックするなどしましょう。詳しいCSIプロキシに関する情報は、次のドキュメントを参照してください。StartupProbeを紹介し、最後にStartupProbeを試してみます。HorizontalPodAutoscalerのspec.behaviorフィールドの追加autoscaling/v2beta2のHorizontalPodAutoscalerにspec.behaviorフィールドが追加され、スケールアップ/スケールダウンのそれぞれの挙動を設定できるようになりました。これまではスケールダウンの速度をクラスタレベルで設定できるだけのチューニングしか行なえませんでした。この機能が追加されたことで、アプリケーションの性質により個々にスケールアップ/スケールダウンの設定をチューニングできます。この機能はautoscaling/v2beta2からしか利用できないことに注意してください。explainコマンドでフィールドの説明を参照したい場合は--api-version=autoscaling/v2beta2オプションを付与する必要があります。used.この機能に関する詳細は、次のドキュメントを参照してください(いずれも英語)。DNSCache(ノードローカルDNSキャッシュ)は、DNSのキャッシュサーバをDaemonSetとして各ノード上で実行させることで、クラスタDNSのパフォーマンスと信頼性を向上するアドオンです。この機能は1.13ではアルファ、1.15ではベータで提供されていましたが、このリリースでGAに昇格しました。KubernetesはServiceによるサービスディスカバリなどのために、クラスタのなかでDNSサーバ(CoreDNS)を実行しています。このDNSサーバのデプロイにDeploymentを使用していることで、他のノード上で実行されているDNSサーバにクエリすることとなり、パフォーマンスに影響があるケースがありました。DNSパケットの送信にUDPを使用していることで、conntrackテーブルが溢れることもありました。DNSCacheを使用するとPodは自身が実行されているノード上にあるDNSキャッシュエージェントにクエリできるようになり、パフォーマンスが向上します。DNSキャッシュエージェントからメインのDNSサーバへの問い合わせにはTCPが使用されます。TCPのconntrackエントリはUDPとは異なりタイムアウトを待つ必要がなく接続が閉じられると削除できるため、conntrackテーブルが溢れにくくなります。DNSCacheのクエリパス(https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/からの引用)最後にDNSキャッシュエージェントのキャッシュとネガティブキャッシュのTTLは、デフォルトでそれぞれ30秒と5秒に設定されています。この値は必要であればクラスタによりチューニングできます。DNSCacheに関する詳細は、次のドキュメントを参照してください(すべて英語)。新しいプローブであるStartupProbe(スタートアッププローブ)がベータステージに昇格し、デフォルトで使用できるようになりました。PodにはこれまでLivenessProbe(ライブネスプローブ)とReadinessProbe(レディネスプローブ)の2つがありました。LivenessProbeはコンテナの死活監視を行い、このプローブが失敗するとrestartPolicy(リスタートポリシ)によっては対象のコンテナが再起動されます。ReadinessProbeはコンテナがアクセスを受ける準備ができているかを確認します。Serviceのルーティング対象から除かれ、アクセスされなくなります。ReadinessProbeStartupProbeは、コンテナの起動時のみに使用される新しいプローブです。これまで起動にある程度時間がかかるコンテナではLivenessProbeの設定調整が難しく、もしinitialDelaySeconds(プローブの実行開始を遅延する秒数)の値が小さすぎればコンテナが起動しきる前に強制終了されてしまい、大きすぎればPodが利用可能になるまで無駄に時間がかかります。StartupProbeは、これらの課題を解決するために追加されました。StartupProbeは、このプローブが成功するまでLivenessProbeとReadinessProbeの2つのプローブが開始されません(下図)。そのため、起動に時間がかかるコンテナの場合、StartupProbeのfailureThreshold(失敗と判断するしきい値)の回数を大きく設定し、またperiodSeconds(プローブの実行間隔)を小さくすることで強制終了されることを避け、起動までの時間を短縮できます。failureThresholdの値を30とすることで、LivenessProbeが開始されるまでに300秒間の猶予があります。10StartupProbeが失敗した場合は、LivenessProbeと同様にコンテナが強制終了され、restartPolicyの設定によってはコンテナが再起動されます。細かい機能ですが、これまでLivenessProbeの説明では必ずと言っていいほどInitialDelaySecondsの値への注意と設定が難しいと説明していたため、StartupProbeの登場で簡単に対処できるようになりました。StartupProbeのより詳しい情報は、次のドキュメントを参照してください(いずれも英語)。StartupProbeの挙動を確認してみます。手元で試してみたい方はMinikubeやKindで1.18のクラスタをご用意ください。Platform:"linux/amd64"}例えば、ここで次のようなDeploymentがあるとします。5このDeploymentから作成されるPodsは、健全と判断されるまでに15秒かかるようになっています。LivenessProbeの設定はfailureThresholdの値が1(失敗と判断されるしきい値でデフォルトは3)、periodSecondsの値は5(プローブの実行間隔でデフォルトは10)です。これをmyapp.yamlとして保存し、クラスタに適用します。myapp.yaml作成されたPodを見ると再起動を繰り返していき(RESTARTSの数が増えていく)、最終的にステータスがCrashLoopBackOff(クラッシュを繰り返した)となって再起動されなくなります。3m37sこれは、このPodが健全になるまでに15秒かかることで、LivenessProbeの確認が常に失敗する状況になってしまっているためです。このような状況では、これまでinitialDelaySeconds(プローブの実行開始を遅延する秒数)を設定することが定石でしたが、どのような値に設定すべきか難しいという課題がありました(ここでは15秒固定のため見て分かるが、外部要件等で時間が見積もれない場合なども考える)。failureThresholdやperiodSecondsを調整するという手もありますが、アプリケーションによっては一度健全になってからは厳し目の値を使いたいということもあります。そこでStartupProbeの出番です。ここではfailureThresholdの値が30で、periodSecondsの値が3というStartupProbeを追加するようにマニフェストを修正します。command:変更後のマニフェストを再度クラスタに適用します。myapp.yaml作成されたPodを見ると、今度は再起動されずに正常に実行されていることが確認できます。2m22sこれは、Podが起動するまでに3秒間隔で30回まで失敗できるStartupProbeが、ここでは4回目以降のプローブの実行で成功し、そこからLivenessProbeの実行が開始されるためです。以上のように、これまでの起動までに時間がかかるPodにはLivenessProbeのinitialDelaySecondsの難しい調整で対処する必要がありましたが、今後はStartupProbeで容易に対処できるようになります。【TIP】新マイナーバージョン、どのパッチバージョンから使うべき?Kubernetesのマイナーバージョンがリリースされたら、どのバージョンから使うべきでしょうか。少なくとも最初のバージョン(1.18の場合は1.18.0)は避けることをお勧めします。diffコマンドを実行すると差分を出力すべきところマニフェストを適用してしまうというバグもありました*3(kubectlとクラスタのバージョンは揃えましょう)。1.18.1で修正されています。1.18の注目機能を紹介しました。今後役に立ちそうな機能はあったでしょうか。debugで、今後Kubernetesにおけるアプリケーションデバッグの手法が大きく変わり、より便利になっていくことが期待できます。debugに比べれば地味な機能ですが、うれしい人も多いのではないでしょうか。この著者の記事一覧ゼットラボ株式会社/ヤフー株式会社ヤフー株式会社所属。