これは、このセクションの複数ページの印刷可能なビューです。 印刷するには、ここをクリックしてください.
クラスターの管理
- 1: クラスター管理の概要
- 2: スワップメモリの管理
- 3: ノードの自動スケーリング
- 4: 証明書
- 5: リソースの管理
- 6: クラスターのネットワーク
- 7: 可観測性(オブザーバビリティ)
- 8: ロギングのアーキテクチャ
- 9: Kubernetesコントロールプレーンコンポーネントの互換性バージョン
- 10: Kubernetesオブジェクトの状態メトリクス
- 11: システムログ
- 12: Kubernetesシステムコンポーネントのトレース
- 13: Kubernetesのプロキシ
- 14: アドオンのインストール
- 15: 協調的リーダー選出
1 - クラスター管理の概要
このページはKubernetesクラスターの作成や管理者向けの内容です。Kubernetesのコアコンセプトについてある程度精通していることを前提とします。
クラスターのプランニング
Kubernetesクラスターの計画、セットアップ、設定の例を知るには設定のガイドを参照してください。この記事で列挙されているソリューションはディストリビューション と呼ばれます。
ガイドを選択する前に、いくつかの考慮事項を挙げます。
- ユーザーのコンピューター上でKubernetesを試したいでしょうか、それとも高可用性のあるマルチノードクラスターを構築したいでしょうか?あなたのニーズにあったディストリビューションを選択してください。
- もしあなたが高可用性を求める場合、 複数ゾーンにまたがるクラスターの設定について学んでください。
- Google Kubernetes EngineのようなホストされているKubernetesクラスターを使用するのか、それとも自分自身でクラスターをホストするのでしょうか?
- 使用するクラスターはオンプレミスなのか、それともクラウド(IaaS) でしょうか?Kubernetesはハイブリッドクラスターを直接サポートしていません。その代わりユーザーは複数のクラスターをセットアップできます。
- Kubernetesを 「ベアメタル」なハードウェア上で稼働させますか?それとも仮想マシン(VMs) 上で稼働させますか?
- もしオンプレミスでKubernetesを構築する場合、どのネットワークモデルが最適か検討してください。
- ただクラスターを稼働させたいだけでしょうか、それともKubernetesプロジェクトのコードの開発を行いたいでしょうか?もし後者の場合、開発が進行中のディストリビューションを選択してください。いくつかのディストリビューションはバイナリリリースのみ使用していますが、多くの選択肢があります。
- クラスターを稼働させるのに必要なコンポーネントについてよく理解してください。
注意: 全てのディストリビューションがアクティブにメンテナンスされている訳ではありません。最新バージョンのKubernetesでテストされたディストリビューションを選択してください。
クラスターの管理
クラスターをセキュアにする
-
Certificatesでは、異なるツールチェインを使用して証明書を作成する方法を説明します。
-
Kubernetes コンテナの環境では、Kubernetesノード上でのKubeletが管理するコンテナの環境について説明します。
-
Kubernetes APIへのアクセス制御では、Kubernetesで自身のAPIに対するアクセスコントロールがどのように実装されているかを説明します。
-
認証では、様々な認証オプションを含むKubernetesでの認証について説明します。
-
認可では、認証とは別に、HTTPリクエストの処理方法を制御します。
-
アドミッションコントローラーの使用では、認証と認可の後にKubernetes APIに対するリクエストをインターセプトするプラグインについて説明します。
-
Kubernetesクラスターでのsysctlの使用では、管理者向けにカーネルパラメーターを設定するため
sysctlコマンドラインツールの使用方法について解説します。 -
クラスターの監査では、Kubernetesの監査ログの扱い方について解説します。
kubeletをセキュアにする
オプションのクラスターサービス
-
DNSのインテグレーションでは、DNS名をKubernetes Serviceに直接名前解決する方法を解説します。
-
クラスターアクティビィのロギングと監視では、Kubernetesにおけるロギングがどのように行われ、どう実装されているかについて解説します。
2 - スワップメモリの管理
Kubernetesは、ノード上でスワップメモリを使用するように構成でき、カーネルがページをバッキングストレージにスワップアウトすることで物理メモリを解放できるようにします。 これは複数のユースケースで有用です。 たとえば、大きなメモリフットプリントを持つが、特定の時点ではそのメモリの一部しかアクセスしないようなワークロードのように、スワップを使用することで恩恵を受けられるワークロードを実行するノードがあります。 また、メモリ圧迫時にPodが終了されるのを防いだり、システムの安定性を損なう可能性のあるシステムレベルのメモリ急増からノードを保護したり、ノード上でより柔軟なメモリ管理を可能にしたりするなど、さまざまな点で役立ちます。
クラスターでスワップを構成する方法については、Kubernetesノードでのスワップメモリの構成を参照してください。
オペレーティングシステムのサポート
- Linuxノードはスワップをサポートします。 各ノードでスワップを有効にするように構成する必要があります。 デフォルトでは、スワップが有効なLinuxノードでkubeletは起動しません。
- Windowsノードはスワップスペースを必要とします。 デフォルトでは、スワップが無効なWindowsノードでkubeletは起動しません。
どのように動作するか?
ノード上でのスワップの使用方法については、いくつかの方法が考えられます。 kubeletがすでにノード上で実行されている場合、スワップがプロビジョニングされた後にkubeletを再起動して認識させる必要があります。
スワップがプロビジョニングされて利用可能なノードでkubeletが起動する場合(failSwapOn: falseの設定を使用)、kubeletは以下を行います:
- このスワップが有効なノードで起動できるようになります。
- Container Runtime Interface(CRI)実装(コンテナランタイムと呼ばれることが多い)に対して、デフォルトでKubernetesワークロードにスワップメモリをゼロに割り当てるように指示します。
ノード上のスワップ構成は、KubeletConfigurationのmemorySwapを介してクラスター管理者に公開されます。
クラスター管理者として、memorySwap.swapBehaviorを設定することで、スワップメモリが存在する場合のノードの動作を指定できます。
スワップの動作
使用するスワップの動作を選択する必要があります。 クラスター内のノードごとに異なるスワップの動作を設定することができます。
Linuxノードで選択できるスワップの動作は以下の通りです:
NoSwap(デフォルト)- このノード上でPodとして実行されるワークロードは、スワップを使用しませんし、使用できません。
LimitedSwap- Kubernetesワークロードはスワップメモリを利用できます。
備考:
NoSwapの動作を選択し、kubeletがスワップスペースを許容するように構成した場合(failSwapOn: false)、ワークロードはスワップを使用しません。
ただし、Kubernetesが管理するコンテナ外のプロセス(systemdサービスやkubelet自体までも!)はスワップを利用できます。
クラスターでスワップを有効にする方法については、Kubernetesノードでのスワップメモリの構成を参照してください。
コンテナランタイムとの統合
kubeletはコンテナランタイムAPIを使用し、コンテナランタイムに対して特定の構成(たとえばcgroup v2の場合はmemory.swap.max)を適用するように指示します。
これにより、コンテナに対して目的のスワップ構成が有効になります。
コントロールグループ(cgroups)を使用するランタイムの場合、コンテナランタイムがこれらの設定をコンテナレベルのcgroupに書き込む責任を負います。
スワップ使用の監視
ノードおよびコンテナレベルのメトリック統計
kubeletはノードおよびコンテナレベルのメトリック統計を収集するようになりました。
これらは、kubeletのHTTPエンドポイントである/metrics/resource(主にPrometheusなどの監視ツールによって使用される)および/stats/summary(主にAutoscalerによって使用される)からアクセスできます。
これにより、kubeletに直接リクエストできるクライアントが、LimitedSwapを使用する際のスワップ使用量と残りのスワップメモリを監視できます。
さらに、マシンの合計物理スワップ容量を示すmachine_swap_bytesメトリックがcadvisorに追加されました。
詳細についてはこちらのページを参照してください。
たとえば、以下の/metrics/resourceがサポートされています:
node_swap_usage_bytes: ノードの現在のスワップ使用量(バイト単位)。container_swap_usage_bytes: コンテナの現在のスワップ使用量(バイト単位)。container_swap_limit_bytes: コンテナの現在のスワップ制限(バイト単位)。
kubectl top --show-swapの使用
メトリックのクエリは有用ですが、これらのメトリックは人間ではなくソフトウェアが使用するように設計されているため、少し面倒です。
このデータをよりユーザーフレンドリーな方法で利用するために、kubectl topコマンドが--show-swapフラグを使用してスワップメトリックをサポートするように拡張されました。
ノードのスワップ使用量に関する情報を取得するには、kubectl top nodes --show-swapを使用できます:
kubectl top nodes --show-swap
出力は次のようになります:
NAME CPU(cores) CPU(%) MEMORY(bytes) MEMORY(%) SWAP(bytes) SWAP(%)
node1 1m 10% 2Mi 10% 1Mi 0%
node2 5m 10% 6Mi 10% 2Mi 0%
node3 3m 10% 4Mi 10% <unknown> <unknown>
Podのスワップ使用量に関する情報を取得するには、kubectl top pods --show-swapを使用できます:
kubectl top pod -n kube-system --show-swap
出力は次のようになります:
NAME CPU(cores) MEMORY(bytes) SWAP(bytes)
coredns-58d5bc5cdb-5nbk4 2m 19Mi 0Mi
coredns-58d5bc5cdb-jsh26 3m 37Mi 0Mi
etcd-node01 51m 143Mi 5Mi
kube-apiserver-node01 98m 824Mi 16Mi
kube-controller-manager-node01 20m 135Mi 9Mi
kube-proxy-ffgs2 1m 24Mi 0Mi
kube-proxy-fhvwx 1m 39Mi 0Mi
kube-scheduler-node01 13m 69Mi 0Mi
metrics-server-8598789fdb-d2kcj 5m 26Mi 0Mi
ノードステータスの一部としてスワップ容量を報告するノード
新しいノードステータスフィールドnode.status.nodeInfo.swap.capacityが追加され、ノードのスワップ容量を報告するようになりました。
たとえば、クラスター内のノードのスワップ容量を取得するには、以下のコマンドを使用できます:
kubectl get nodes -o go-template='{{range .items}}{{.metadata.name}}: {{if .status.nodeInfo.swap.capacity}}{{.status.nodeInfo.swap.capacity}}{{else}}<unknown>{{end}}{{"\n"}}{{end}}'
出力は次のようになります:
node1: 21474836480
node2: 42949664768
node3: <unknown>
備考:
<unknown>の値は、そのノードの.status.nodeInfo.swap.capacityフィールドが設定されていないことを示します。
これはおそらく、ノードにスワップがプロビジョニングされていないか、または、より可能性は低いですが、kubeletがノードのスワップ容量を判定できないことを意味します。Node Feature Discovery(NFD)を使用したスワップの検出
Node Feature Discoveryは、ハードウェアの機能と構成を検出するためのKubernetesアドオンです。 これを利用して、どのノードにスワップがプロビジョニングされているかを検出できます。
たとえば、どのノードにスワップがプロビジョニングされているかを確認するには、以下のコマンドを使用します:
kubectl get nodes -o jsonpath='{range .items[?(@.metadata.labels.feature\.node\.kubernetes\.io/memory-swap)]}{.metadata.name}{"\t"}{.metadata.labels.feature\.node\.kubernetes\.io/memory-swap}{"\n"}{end}'
出力は次のようになります:
k8s-worker1: true
k8s-worker2: true
k8s-worker3: false
この例では、ノードk8s-worker1とk8s-worker2にはスワップがプロビジョニングされていますが、k8s-worker3にはプロビジョニングされていません。
リスクと注意事項
注意:
スワップスペースを暗号化することを強くお勧めします。 詳細については、メモリバックボリュームを参照してください。システム上でスワップが利用可能な場合、予測可能性が低下します。 スワップはより多くのRAMを利用可能にすることでパフォーマンスを向上させることができますが、データをメモリにスワップインする操作は重い処理であり、時には桁違いに遅くなることがあり、予期しないパフォーマンスの低下を引き起こす可能性があります。 さらに、スワップはメモリ圧迫時のシステムの動作を変化させます。 スワップを有効にすると、RAMを頻繁に使用するPodが他のPodのスワップを引き起こす可能性があるため、ノイジーネイバーのリスクが高まります。 さらに、スワップによりKubernetesのワークロードのメモリ使用量が予測不能に増大し、予期しないパッキング構成のために、スケジューラーは現在スワップメモリの使用量を考慮していません。 これにより、ノイジーネイバーのリスクが高まります。
スワップメモリが有効なノードのパフォーマンスは、基盤となる物理ストレージに依存します。 スワップメモリが使用されている場合、I/O制限のあるクラウドVMなどのIOPS制約のある環境では、SSDやNVMeなどの高速なストレージメディアと比較して、パフォーマンスが大幅に低下します。 スワップはIO圧迫を引き起こす可能性があるため、システムクリティカルなデーモンに対してIOレイテンシーの優先度を高く設定することが推奨されます。 以下の推奨プラクティスセクションの該当箇所を参照してください。
メモリバックボリューム
Linuxノードでは、メモリバックボリューム(secretボリュームマウントやmedium: Memoryを使用したemptyDirなど)はtmpfsファイルシステムで実装されています。
このようなボリュームの内容は常にメモリに保持されるべきであり、ディスクにスワップされるべきではありません。
このようなボリュームの内容がメモリに保持されることを保証するために、noswap tmpfsオプションが使用されています。
Linuxカーネルはバージョン6.3からnoswapオプションを公式にサポートしています(詳細はLinuxカーネルバージョンの要件を参照してください)。
ただし、ディストリビューションによっては、このマウントオプションを古いLinuxバージョンにバックポートすることがよくあります。
ノードがnoswapオプションをサポートしているかどうかを確認するために、kubeletは以下を行います:
- カーネルのバージョンが6.3以上の場合、
noswapオプションがサポートされていると見なされます。 - それ以外の場合、kubeletは起動時に
noswapオプションを使用してダミーのtmpfsをマウントしようとします。 kubeletが不明なオプションを示すエラーで失敗した場合、noswapはサポートされていないと見なされ、使用されません。 メモリバックボリュームがディスクにスワップされる可能性があることをユーザーに警告するkubeletのログエントリが出力されます。 kubeletが成功した場合、ダミーのtmpfsは削除され、noswapオプションが使用されます。noswapオプションがサポートされていない場合、kubeletは警告ログエントリを出力し、実行を続行します。
暗号化されていないスワップの設定例については、上記のセクションを参照してください。 ただし、暗号化されたスワップの処理はkubeletの範囲外であり、一般的なOSの構成の問題として対処されるべきです。 このリスクを軽減するために暗号化されたスワップをプロビジョニングするのは管理者の責任です。
退避
スワップが有効なノードに対するメモリエビクションのしきい値の構成は複雑です。
スワップが無効な場合、kubeletのエビクションしきい値をノードのメモリ容量より少し低く設定することは合理的です。 その理由は、ノードがメモリ不足になりOut Of Memory(OOM)キラーが呼び出される前にKubernetesがPodのエビクションを開始したいからです。 OOMキラーはKubernetesを認識しないため、QoS、Podの優先度、またはその他のKubernetes固有の要素を考慮しません。
スワップが有効な場合、状況はより複雑です。
Linuxでは、vm.min_free_kbytesパラメーターがカーネルがメモリの積極的な回収(ページのスワップアウトを含む)を開始するメモリしきい値を定義します。
kubeletのエビクションしきい値が、カーネルがメモリ回収を開始する前にエビクションが行われるように設定されている場合、ノードのメモリ圧迫時にワークロードがスワップアウトできなくなる可能性があります。
一方、エビクションしきい値を高く設定しすぎると、ノードがメモリ不足になりOOMキラーが呼び出される可能性があり、これも理想的ではありません。
これに対処するため、kubeletのエビクションしきい値をvm.min_free_kbytesの値よりわずかに低く設定することが推奨されます。
この方法により、kubeletがPodのエビクションを開始する前にノードがスワップを開始でき、ワークロードが未使用データをスワップアウトしてエビクションを防止できます。
一方、わずかに低いだけなので、ノードがメモリ不足になる前にkubeletがPodのエビクションを開始し、OOMキラーを回避できます。
vm.min_free_kbytesの値は、ノード上で以下のコマンドを実行することで確認できます:
cat /proc/sys/vm/min_free_kbytes
未使用のスワップスペース
LimitedSwapの動作では、Podが利用できるスワップの量は、ノードの合計メモリに対するメモリリクエストの割合に基づいて自動的に決定されます(詳細については、以下のセクションを参照してください)。
この設計により、通常、Kubernetesワークロードに対して制限されたままとなるスワップの一部が存在します。 たとえば、Kubernetes 1.36はGuaranteed QoSクラスのPodに対してスワップの使用を許可していないため、Guaranteed Podのメモリリクエストに比例するスワップの量は、Kubernetesワークロードによって使用されずに残ります。
この動作は、多くのPodがスワップの対象外である場合にリスクを伴います。 一方で、これはKubernetesの管理範囲外のプロセス(システムデーモンやkubelet自体など)が使用できる、システム予約量のスワップメモリを効果的に維持します。
Kubernetesクラスターでスワップを使用するための推奨プラクティス
システムクリティカルなデーモンに対するスワップの無効化
テストフェーズやユーザーフィードバックに基づいて、システムクリティカルなデーモンやサービスのパフォーマンスが低下する可能性があることが観察されました。
これは、kubeletを含むシステムデーモンが通常よりも遅く動作する可能性があることを意味します。
この問題が発生した場合、スワップを防止するためにシステムスライスのcgroupを構成すること(つまりmemory.swap.max=0を設定すること)が推奨されます。
システムクリティカルなデーモンのI/Oレイテンシーの保護
スワップはノードのI/O負荷を増加させる可能性があります。 メモリ圧迫によりカーネルが急速にページをスワップインおよびスワップアウトする場合、I/O操作に依存するシステムクリティカルなデーモンやサービスがパフォーマンスの低下を経験する可能性があります。
これを軽減するために、systemdユーザーにはシステムスライスのI/Oレイテンシーを優先することが推奨されます。
非systemdユーザーの場合、システムデーモンとプロセス用の専用cgroupをセットアップし、同様にI/Oレイテンシーを優先することが推奨されます。
これは、システムスライスにio.latencyを設定することで実現でき、より高いI/O優先度を付与します。
詳細についてはcgroupのドキュメントを参照してください。
スワップとコントロールプレーンノード
Kubernetesプロジェクトは、スワップスペースを構成せずにコントロールプレーンノードを実行することを推奨しています。 コントロールプレーンは主にGuaranteed QoSのPodをホストするため、一般的にスワップを無効にできます。 主な懸念点は、コントロールプレーン上のクリティカルなサービスのスワップがパフォーマンスに悪影響を与える可能性があることです。
スワップ用の専用ディスクの使用
Kubernetesプロジェクトは、スワップが有効なノードを実行する場合は常に暗号化されたスワップを使用することを推奨しています。 スワップがパーティションまたはルートファイルシステム上にある場合、ワークロードがディスクへの書き込みを必要とするシステムプロセスに干渉する可能性があります。 同じディスクを共有している場合、プロセスがスワップを圧倒し、kubelet、コンテナランタイム、およびsystemdのI/Oを中断させ、他のワークロードに影響を与える可能性があります。 スワップスペースはディスク上に配置されるため、意図されたユースケースに対してディスクが十分に高速であることを確認することが重要です。 あるいは、単一のバッキングデバイスの異なるマップ領域間でI/O優先度を構成することもできます。
スワップを考慮したスケジューリング
Kubernetes 1.36は、スワップメモリの使用量を考慮してノードにPodを割り当てることをサポートしていません。
スケジューラーは通常、Pod配置のガイドとしてインフラストラクチャリソースの リクエスト を使用しますが、Podはスワップスペースをリクエストせず、memoryのみをリクエストします。
つまり、スケジューラーはスケジューリングの決定においてスワップメモリを考慮しません。
これは現在積極的に取り組んでいるものですが、まだ実装されていません。
スワップメモリの使用を意図したPod以外がスワップメモリのあるノードにスケジュールされないようにするために、管理者はスワップが利用可能なノードにtaintを設定することで、この問題から保護できます。 taintにより、スワップを許容するワークロードが負荷時にスワップのないノードに溢れ出ることが防止されます。
最適なパフォーマンスのためのストレージの選択
スワップスペースに指定されるストレージデバイスは、高いメモリ使用量時のシステム応答性を維持するために重要です。 回転式ハードディスクドライブ(HDD)は、その機械的な性質により大きなレイテンシーが発生し、深刻なパフォーマンスの低下とシステムのスラッシングを引き起こすため、このタスクには適していません。 現代のパフォーマンス要件には、ソリッドステートドライブ(SSD)などのデバイスがスワップに適した選択肢です。 低レイテンシーの電子的アクセスにより、速度低下を最小限に抑えます。
スワップの動作の詳細
LimitedSwapでスワップ制限はどのように決定されるか?
スワップメモリの設定(制限を含む)は重大な課題を提示します。 誤設定が起こりやすいだけでなく、システムレベルのプロパティであるため、誤設定は特定のワークロードではなくノード全体を危険にさらす可能性があります。 このリスクを軽減し、ノードの健全性を確保するために、制限の自動設定を備えたスワップを実装しました。
LimitedSwapでは、Burstable QoS分類に属さないPod(つまりBestEffort/Guaranteed QoSのPod)はスワップメモリの利用が禁止されています。
BestEffort QoSのPodは予測不能なメモリ消費パターンを示し、メモリ使用量に関する情報が不足しているため、安全なスワップメモリの割り当てを決定することが困難です。
逆に、Guaranteed QoSのPodは通常、ワークロードによって指定されたリソースの正確な割り当てに依存するアプリケーションに使用され、メモリがすぐに利用可能であることが前提となります。
上記のセキュリティとノードの健全性の保証を維持するため、LimitedSwapが有効な場合、これらのPodはスワップメモリの使用が許可されません。
さらに、高優先度のPodは、消費するメモリが常にRAM上に常駐し、すぐに使用可能であることを保証するために、スワップの使用が許可されていません。
スワップ制限の計算を詳しく説明する前に、以下の用語を定義する必要があります:
nodeTotalMemory: ノードで利用可能な物理メモリの合計量。totalPodsSwapAvailable: Podが使用できるノード上のスワップメモリの合計量(一部のスワップメモリはシステム使用のために予約されている場合があります)。containerMemoryRequest: コンテナのメモリリクエスト。
スワップ制限は次のように構成されます:
( containerMemoryRequest / nodeTotalMemory ) × totalPodsSwapAvailable
つまり、コンテナが使用できるスワップの量は、そのメモリリクエスト、ノードの合計物理メモリ、およびPodが使用できるノード上のスワップメモリの合計量に比例します。
Burstable QoSのPod内のコンテナの場合、メモリリクエストをメモリ制限と等しく指定することでスワップの使用をオプトアウトできることに注意する必要があります。 この方法で構成されたコンテナはスワップメモリにアクセスできません。
次の項目
- Linuxノードでのスワップの管理については、Kubernetesノードでのスワップメモリの構成を参照してください。
- Kubernetesとスワップに関するブログ記事もご覧ください。
- 背景情報については、オリジナルのKEP KEP-2400とその設計を参照してください。
3 - ノードの自動スケーリング
クラスター内でワークロードを実行するには、ノードが必要です。 クラスター内のノードは 自動スケール 可能であり、必要なキャパシティを提供しながらコストを最適化するために、動的にプロビジョニングされたり統合されたりします。 自動スケールはノードのオートスケーラーによって実行されます。
ノードのプロビジョニング
既存のノードにスケジュールできないPodがクラスター内にある場合、それらのPodを収容するために、新しいノードをクラスターに自動的に追加—プロビジョニング—できます。 これは、例えば水平ワークロードとノードの自動スケーリングを組み合わせた結果として、時間の経過とともにPodの数が変化する場合に特に役立ちます。
オートスケーラーは、ノードを裏で支えるクラウドプロバイダーのリソースを作成および削除することにより、ノードをプロビジョニングします。 一般的に、ノードを裏で支えるリソースは仮想マシンです。
プロビジョニングの主な目的は、すべてのPodをスケジュール可能にすることです。 この目的は、構成されたプロビジョニングの制限に達したり、特定のPodのセットと互換性のないプロビジョニング構成であったり、クラウドプロバイダーのキャパシティが不足していたりするなど、さまざまな制限によって常に達成可能ではありません。 プロビジョニング中には、追加の目的(たとえばプロビジョニングされたノードのコストを最小限に抑える、障害ドメイン間のノード数を調整するなど)を達成しようとすることがよくあります。
プロビジョニングするノードを決定する際のノードオートスケーラーへの2つの主な入力は、Podのスケジューリング制約とオートスケーラー構成によって課されるノード制約です。
オートスケーラーの構成には、他のノードのプロビジョニングトリガー(たとえば、設定された最小制限を下回るノードの数など)も含まれる場合があります。
備考:
プロビジョニングは、以前はCluster Autoscalerで スケールアップ として知られていました。Podのスケジューリング制約
Podは、スケジュール可能なノードの種類に制限を課すためにスケジューリング制約を表現できます。 ノードオートスケーラーは、これらの制約を考慮して、保留中のPodがプロビジョニングされたノードにスケジュールできるようにします。
最も一般的なスケジューリング制約の種類は、Podコンテナによって指定されたリソース要求です。 オートスケーラーは、プロビジョニングされたノードに要求を満たすのに十分なリソースがあることを確認します。 ただし、Podの実行開始後の実際のリソース使用量は直接考慮することはありません。 実際のワークロードのリソース使用量に基づいてノードを自動スケールするには、水平ワークロードの自動スケーリングをノードの自動スケーリングと組み合わせることができます。
その他の一般的なPodのスケジューリング制約には、ノードアフィニティ、Pod間アフィニティ、特定のストレージボリュームの要件などがあります。
オートスケーラー構成によって課されるノード制約
プロビジョニングされるノードの詳細(たとえばリソース量、特定ラベルの有無)は、オートスケーラーの構成によって異なります。 オートスケーラーは、事前定義されたノード構成のセットから選択するか、自動プロビジョニングを使用できます。
自動プロビジョニング
ノードの自動プロビジョニングは、プロビジョニング可能なノードの詳細をユーザーが完全に構成する必要のないプロビジョニングモードです。 かわりに、オートスケーラーは、対応している保留中のPodと事前に定義された制約(たとえば、最小リソース量や特定ラベルの必要性)に基づいて、ノード構成を動的に選択します。
ノードの統合
クラスターを運用する際の主な考慮事項は、スケジュール可能なすべてのPodが実行されていることを確認しながら、可能な限りクラスターのコストを低く抑えることです。 これを達成するには、Podのリソース要求がノードのリソースをできるだけ多く利用する必要があります。 この観点から、クラスター内の全体的なノードの使用率は、クラスターのコスト効率の指標として使用できます。
備考:
Podのリソース要求を正しく設定することは、ノードの使用率を最適化することと同様に、クラスター全体のコスト効率にとって重要です。 ノードの自動スケーリングを垂直ワークロードの自動スケーリングと組み合わせることで、これを実現できます。クラスター内のノードは自動的に 統合 され、全体的なノードの使用率とクラスターのコスト効率を改善できます。 統合は、クラスターから使用率の低いノードのセットを削除することで行われます。 必要に応じて、それらを置き換えるために別のノードセットをプロビジョニングできます。
プロビジョニングと同様に、統合の決定を下す際にはPodのリソース要求のみを考慮し、実際のリソース使用量は考慮しません。
統合の目的のために、ノード上でDeamonSetと静的Podのみが実行されている場合は、そのノードは 空 と見なされます。 統合中に空のノードを削除することは、空でないノードを削除するよりも簡単であり、オートスケーラーには空のノードを統合するために特別に設計された最適化が備わっていることがよくあります。
統合中に空でないノードを削除することは破壊的であり、そのノード上で実行されているPodが終了し、(たとえばDeploymentによって)再作成が必要になる可能性があります。 ただし、再作成されたすべてのPodは、クラスター内の既存のノードまたは統合の一環としてプロビジョニングされた代替ノードにスケジュールできる必要があります。 通常、統合の結果としてPodが保留中になることはありません。
備考:
オートスケーラーは、ノードのプロビジョニングまたは統合後に再作成されたPodがどのようにスケジュールされるかを予測しますが、実際のスケジューリングを制御することはありません。 そのため、統合の実行中にまったく新しいPodが出現するなどの理由で、統合の結果として一部のPodが保留中になる可能性があります。オートスケーラー構成では、さまざまなプロパティ(たとえばクラスター内のノードの最大ライフスパン)を最適化するために、他の条件(たとえばノードが作成されてからの経過時間)によって統合をトリガーすることもできます。
統合の実行方法の詳細は、特定のオートスケーラーの構成によって異なります。
備考:
統合は、以前はCluster Autoscalerで スケールダウン として知られていました。オートスケーラー
前のセクションで説明した機能は、ノードの オートスケーラー によって提供されます。 Kubernetes APIに加えて、オートスケーラーはノードをプロビジョニングおよび統合のためにクラウドプロバイダーのAPIと対話する必要があります。 つまり、サポートされている各クラウドプロバイダーと明示的に連携する必要があります。 個々のオートスケーラーのパフォーマンスと機能のセットは、連携先のクラウドプロバイダーによって異なる場合があります。
graph TD
na[Node autoscaler]
k8s[Kubernetes]
cp[Cloud Provider]
k8s --> |get Pods/Nodes|na
na --> |drain Nodes|k8s
na --> |create/remove resources backing Nodes|cp
cp --> |get resources backing Nodes|na
classDef white_on_blue fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff;
classDef blue_on_white fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5;
class na blue_on_white;
class k8s,cp white_on_blue;
オートスケーラーの実装
Cluster AutoscalerとKarpenterは、現在SIG Autoscalingがスポンサーをしている2つのノードオートスケーラーです。
クラスターユーザーの観点から、どちらのオートスケーラーも同様のノード自動スケーリング体験を提供するはずです。 どちらもスケジュールできないPodのために新しいノードをプロビジョニングし、最適に利用されなくなったノードを統合します。
さまざまなオートスケーラーがこのページで説明されているノード自動スケーリングの範囲外の機能を提供する場合もあり、それらの追加機能はオートスケーラーごとに異なる場合があります。
以下のセクションと個々のオートスケーラーにリンクされたドキュメントを参照して、どのオートスケーラーがユースケースに適しているかを判断してください。
Cluster Autoscaler
Cluster Autoscalerは、事前に構成された ノードグループ にノードを追加または削除します。 ノードグループは通常、何らかのクラウドプロバイダーのリソースグループ(最も一般的なのは仮想マシングループ)にマッピングされます。 Cluster Autoscalerの1つのインスタンスで、複数のノードグループを同時に管理できます。 プロビジョニング時には、Cluster Autoscalerは保留中のPodの要求に最も適したグループにノードを追加します。 統合時には、Cluster Autoscalerは基盤となるクラウドプロバイダーのリソースグループのサイズを単に変更するのではなく、削除する特定のノードを常に選択します。
追加のコンテキスト:
Karpenter
Karpenterは、クラスター運用者によって提供されるNodePool構成に基づいてノードを自動プロビジョニングします。 Karpenterは、自動スケーリングだけでなく、ノードのライフサイクルのあらゆる側面を処理します。 これには、特定のライフタイムに達したノードの自動更新や、新しいワーカーノードイメージがリリースされたときのノードの自動アップグレードが含まれます。 Karpenterは、個々のクラウドプロバイダーリソース(最も一般的なのは個々の仮想マシン)と直接連携し、クラウドプロバイダーのリソースグループに依存しません。
追加のコンテキスト:
実装の比較
CarpenterとCluster Autoscalerの主な違い:
- Cluster Autoscalerは、ノードの自動スケーリングに関連する機能のみを提供します。 Karpenterはより広範囲であり、ノードのライフサイクル全体を管理すること(たとえば、特定のライフタイムに達したノードを自動的に再作成したり、新しいバージョンに自動的にアップグレードしたりするなど)を目的とした機能も提供します。
- Cluster Autoscalerは、自動プロビジョニングをサポートしておらず、プロビジョニングできるノードグループは事前に構成する必要があります。 Karpeterは、自動プロビジョニングをサポートしているため、ユーザーは均質なグループを完全に構成するのではなく、プロビジョニングされるノードの制約セットを構成するだけで済みます。
- Cluster Autoscalerは、クラウドプロバイダーとの連携機能を直接提供し、Kubernetesプロジェクトの一部となっています。 Karpenterの場合、KuberentesプロジェクトはKarpenterをライブラリとして公開しており、クラウドプロバイダーはこのライブラリと連携してノードオートスケーラーを構築できます。
- Cluster Autoscalerは、小規模であまり知られていないプロバイダーを含む多数のクラウドプロバイダーとの連携機能を提供します。 Karpenterと連携できるクラウドプロバイダーは、AWSやAzureなど、より少数です。
ワークロードとノードの自動スケーリングを組み合わせる
水平ワークロードの自動スケーリング
ノードの自動スケーリングは通常、Podに応じて機能します。 つまり、スケジュールできないPodを収容するために新しいノードをプロビジョニングし、不要になったらノードを統合します。
水平ワークロードの自動スケーリングは、ワークロードのレプリカ数を自動的に調整し、レプリカ全体で望ましい平均リソース使用率を維持します。 言い換えると、アプリケーション負荷に応じて新しいPodを自動的に作成し、負荷が減少するとPodを削除します。
ノードの自動スケーリングを水平ワークロードの自動スケーリングと組み合わせて使用することで、Podの実際の平均リソース使用率に基づいてクラスター内のノードを自動スケーリングできます。
アプリケーション負荷が増加すると、そのPodの平均使用率も増加し、ワークロードの自動スケーリングによって新しいPodが作成されます。 その後、ノードの自動スケーリングは、新しいPodを収容するために新しいノードをプロビジョニングします。
アプリケーション負荷が減少すると、ワークロードの自動スケーリングによって不要なPodが削除されます。 また、ノードの自動スケーリングによって、不要になったノードが統合されるはずです。
このパターンが正しく構成されている場合、アプリケーションは必要に応じて負荷の急増に対応するためのノードキャパシティを常に保ちますが、必要ないキャパシティに対して料金を支払う必要はありません。
垂直ワークロードの自動スケーリング
ノードの自動スケーリングを使用する場合、Podのリソース要求を正しく設定することが重要です。 特定のPodの要求が低すぎると、新しいノードをプロビジョニングしても、実際にはPodの実行に役立たない可能性があります。 特定のPodの要求が高すぎると、ノードの統合を誤って妨げる可能性があります。
垂直ワークロードの自動スケーリングは、過去のリソース使用量に基づいてPodのリソース要求を自動的に調整します。
ノードの自動スケーリングと垂直ワークロードの自動スケーリングを組み合わせて使用することで、クラスター内のノードの自動スケーリング機能を維持しながら、Podのリソース要求を調整できます。
注意:
ノードの自動スケーリングを使用する場合、DaemonSetのPodに対して垂直ワークロードの自動スケーリングを設定することは推奨されていません。 オートスケーラーは、使用可能なノードリソースを予測するために、新しいノード上のDaemonSetのPodの状態を予測する必要があります。 垂直ワークロードの自動スケーリングは、これらの予測の信頼性を低下させ、誤ったスケーリングの決定につながる可能性があります。関連コンポーネント
このセクションでは、ノードの自動スケーリングに関連する機能を提供するコンポーネントについて説明します。
Descheduler
deschedulerは、カスタムポリシーに基づいてノードの統合機能を提供するコンポーネントであり、ノードとPodの最適化に関連するその他の機能(たとえば、頻繁に再起動するPodの削除)も提供します。
クラスターサイズに基づくワークロードオートスケーラー
Cluster Proportional AutoscalerとCluster Proportional Vertical Autoscalerは、クラスター内のノード数に基づいて水平または垂直ワークロードの自動スケーリングを提供します。 クラスターサイズに基づく自動スケーリングで詳細を読むことができます。
次の項目
- ワークロードレベルの自動スケーリングについて読む
4 - 証明書
クライアント証明書認証を使用する場合、easyrsaやopenssl、cfsslを用いて、手動で証明書を生成できます。
easyrsa
easyrsaを用いると、クラスターの証明書を手動で生成できます。
-
パッチを当てたバージョンのeasyrsa3をダウンロードして解凍し、初期化します。
curl -LO https://dl.k8s.io/easy-rsa/easy-rsa.tar.gz tar xzf easy-rsa.tar.gz cd easy-rsa-master/easyrsa3 ./easyrsa init-pki -
新しい認証局(CA)を生成します。
--batchは自動モードを設定し、--req-cnはCAの新しいルート証明書の共通名(CN)を指定します。./easyrsa --batch "--req-cn=${MASTER_IP}@`date +%s`" build-ca nopass -
サーバー証明書と鍵を生成します。 引数
--subject-alt-nameは、APIサーバーへのアクセスに使用できるIPおよびDNS名を設定します。MASTER_CLUSTER_IPは通常、APIサーバーとコントローラーマネージャーコンポーネントの両方で引数--service-cluster-ip-rangeとして指定されるサービスCIDRの最初のIPです。 引数--daysは、証明書の有効期限が切れるまでの日数を設定するために使われます。 以下の例は、デフォルトのDNSドメイン名としてcluster.localを使用していることを前提とします。./easyrsa --subject-alt-name="IP:${MASTER_IP},"\ "IP:${MASTER_CLUSTER_IP},"\ "DNS:kubernetes,"\ "DNS:kubernetes.default,"\ "DNS:kubernetes.default.svc,"\ "DNS:kubernetes.default.svc.cluster,"\ "DNS:kubernetes.default.svc.cluster.local" \ --days=10000 \ build-server-full server nopass -
pki/ca.crt、pki/issued/server.crt、pki/private/server.keyをディレクトリーにコピーします。 -
以下のパラメーターを、APIサーバーの開始パラメーターとして追加します。
--client-ca-file=/yourdirectory/ca.crt --tls-cert-file=/yourdirectory/server.crt --tls-private-key-file=/yourdirectory/server.key
openssl
opensslはクラスターの証明書を手動で生成できます。
-
2048ビットのca.keyを生成します。
openssl genrsa -out ca.key 2048 -
ca.keyに応じて、ca.crtを生成します。証明書の有効期間を設定するには、-daysを使用します。
openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 10000 -out ca.crt -
2048ビットのserver.keyを生成します。
openssl genrsa -out server.key 2048 -
証明書署名要求(CSR)を生成するための設定ファイルを生成します。 ファイル(例:
csr.conf)に保存する前に、かぎ括弧で囲まれた値(例:<MASTER_IP>)を必ず実際の値に置き換えてください。MASTER_CLUSTER_IPの値は、前節で説明したAPIサーバーのサービスクラスターIPであることに注意してください。 以下の例は、デフォルトのDNSドメイン名としてcluster.localを使用していることを前提とします。[ req ] default_bits = 2048 prompt = no default_md = sha256 req_extensions = req_ext distinguished_name = dn [ dn ] C = <country> ST = <state> L = <city> O = <organization> OU = <organization unit> CN = <MASTER_IP> [ req_ext ] subjectAltName = @alt_names [ alt_names ] DNS.1 = kubernetes DNS.2 = kubernetes.default DNS.3 = kubernetes.default.svc DNS.4 = kubernetes.default.svc.cluster DNS.5 = kubernetes.default.svc.cluster.local IP.1 = <MASTER_IP> IP.2 = <MASTER_CLUSTER_IP> [ v3_ext ] authorityKeyIdentifier=keyid,issuer:always basicConstraints=CA:FALSE keyUsage=keyEncipherment,dataEncipherment extendedKeyUsage=serverAuth,clientAuth subjectAltName=@alt_names -
設定ファイルに基づいて、証明書署名要求を生成します。
openssl req -new -key server.key -out server.csr -config csr.conf -
ca.key、ca.crt、server.csrを使用してサーバー証明書を生成します。
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \ -CAcreateserial -out server.crt -days 10000 \ -extensions v3_ext -extfile csr.conf -sha256 -
証明書を表示します。
openssl x509 -noout -text -in ./server.crt
最後にAPIサーバーの起動パラメーターに、同様のパラメーターを追加します。
cfssl
cfsslも証明書を生成するためのツールです。
-
以下のように、ダウンロードして解凍し、コマンドラインツールを用意します。 使用しているハードウェアアーキテクチャやcfsslのバージョンに応じて、サンプルコマンドの調整が必要な場合があります。
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssl_1.5.0_linux_amd64 -o cfssl chmod +x cfssl curl -L https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssljson_1.5.0_linux_amd64 -o cfssljson chmod +x cfssljson curl -L https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssl-certinfo_1.5.0_linux_amd64 -o cfssl-certinfo chmod +x cfssl-certinfo -
アーティファクトを保持するディレクトリーを生成し、cfsslを初期化します。
mkdir cert cd cert ../cfssl print-defaults config > config.json ../cfssl print-defaults csr > csr.json -
CAファイルを生成するためのJSON設定ファイル(例:
ca-config.json)を生成します。{ "signing": { "default": { "expiry": "8760h" }, "profiles": { "kubernetes": { "usages": [ "signing", "key encipherment", "server auth", "client auth" ], "expiry": "8760h" } } } } -
CA証明書署名要求(CSR)用のJSON設定ファイル(例:
ca-csr.json)を生成します。 かぎ括弧で囲まれた値は、必ず使用したい実際の値に置き換えてください。{ "CN": "kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names":[{ "C": "<country>", "ST": "<state>", "L": "<city>", "O": "<organization>", "OU": "<organization unit>" }] } -
CA鍵(
ca-key.pem)と証明書(ca.pem)を生成します。../cfssl gencert -initca ca-csr.json | ../cfssljson -bare ca -
APIサーバーの鍵と証明書を生成するためのJSON設定ファイル(例:
server-csr.json)を生成します。 かぎ括弧で囲まれた値は、必ず使用したい実際の値に置き換えてください。MASTER_CLUSTER_IPの値は、前節で説明したAPIサーバーのサービスクラスターIPです。 以下の例は、デフォルトのDNSドメイン名としてcluster.localを使用していることを前提とします。{ "CN": "kubernetes", "hosts": [ "127.0.0.1", "<MASTER_IP>", "<MASTER_CLUSTER_IP>", "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster", "kubernetes.default.svc.cluster.local" ], "key": { "algo": "rsa", "size": 2048 }, "names": [{ "C": "<country>", "ST": "<state>", "L": "<city>", "O": "<organization>", "OU": "<organization unit>" }] } -
APIサーバーの鍵と証明書を生成します。デフォルトでは、それぞれ
server-key.pemとserver.pemというファイルに保存されます。../cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \ --config=ca-config.json -profile=kubernetes \ server-csr.json | ../cfssljson -bare server
自己署名CA証明書の配布
クライアントノードは、自己署名CA証明書を有効だと認識しないことがあります。 プロダクション用でない場合や、会社のファイアウォールの背後で実行する場合は、自己署名CA証明書をすべてのクライアントに配布し、有効な証明書のローカルリストを更新できます。
各クライアントで、以下の操作を実行します。
sudo cp ca.crt /usr/local/share/ca-certificates/kubernetes.crt
sudo update-ca-certificates
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....
done.
証明書API
certificates.k8s.ioAPIを用いることで、こちらのドキュメントにあるように、認証に使用するx509証明書をプロビジョニングすることができます。
5 - リソースの管理
アプリケーションをデプロイし、Serviceを介して外部に公開できました。さて、どうしますか?Kubernetesは、スケーリングや更新など、アプリケーションのデプロイを管理するための多くのツールを提供します。 我々が取り上げる機能についての詳細は設定ファイルとラベルについて詳細に説明します。
リソースの設定を管理する
多くのアプリケーションではDeploymentやServiceなど複数のリソースの作成を要求します。複数のリソースの管理は、同一のファイルにひとまとめにしてグループ化すると簡単になります(YAMLファイル内で---で区切る)。
例えば:
apiVersion: v1
kind: Service
metadata:
name: my-nginx-svc
labels:
app: nginx
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
複数のリソースは単一のリソースと同様の方法で作成できます。
kubectl apply -f https://k8s.io/examples/application/nginx-app.yaml
service/my-nginx-svc created
deployment.apps/my-nginx created
リソースは、ファイル内に記述されている順番通りに作成されます。そのため、Serviceを最初に指定するのが理想です。スケジューラーがServiceに関連するPodを、Deploymentなどのコントローラーによって作成されるときに確実に拡散できるようにするためです。
kubectl applyもまた、複数の-fによる引数指定を許可しています。
kubectl apply -f https://k8s.io/examples/application/nginx/nginx-svc.yaml -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
個別のファイルに加えて、-fの引数としてディレクトリ名も指定できます:
kubectl apply -f https://k8s.io/examples/application/nginx/
kubectlは.yaml、.yml、.jsonといったサフィックスの付くファイルを読み込みます。
同じマイクロサービス、アプリケーションティアーのリソースは同一のファイルにまとめ、アプリケーションに関するファイルをグループ化するために、それらのファイルを同一のディレクトリに配備するのを推奨します。アプリケーションのティアーがDNSを通じて互いにバインドされると、アプリケーションスタックの全てのコンポーネントをひとまとめにして簡単にデプロイできます。
リソースの設定ソースとして、URLも指定できます。githubから取得した設定ファイルから直接手軽にデプロイができます:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx created
kubectlによる一括操作
kubectlが一括して実行できる操作はリソースの作成のみではありません。作成済みのリソースの削除などの他の操作を実行するために、設定ファイルからリソース名を取得することができます。
kubectl delete -f https://k8s.io/examples/application/nginx-app.yaml
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted
2つのリソースだけを削除する場合には、コマンドラインでリソース/名前というシンタックスを使うことで簡単に指定できます。
kubectl delete deployments/my-nginx services/my-nginx-svc
さらに多くのリソースに対する操作では、リソースをラベルでフィルターするために-lや--selectorを使ってセレクター(ラベルクエリ)を指定するのが簡単です:
kubectl delete deployment,services -l app=nginx
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted
kubectlは同様のシンタックスでリソース名を出力するので、$()やxargsを使ってパイプで操作するのが容易です:
kubectl get $(kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service)
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx-svc LoadBalancer 10.0.0.208 <pending> 80/TCP 0s
上記のコマンドで、最初にexamples/application/nginx/配下でリソースを作成し、-o nameという出力フォーマットにより、作成されたリソースの名前を表示します(各リソースをresource/nameという形式で表示)。そして"service"のみgrepし、kubectl getを使って表示させます。
あるディレクトリ内の複数のサブディレクトリをまたいでリソースを管理するような場合、--filename,-fフラグと合わせて--recursiveや-Rを指定することでサブディレクトリに対しても再帰的に操作が可能です。
例えば、開発環境用に必要な全てのマニフェストをリソースタイプによって整理しているproject/k8s/developmentというディレクトリがあると仮定します。
project/k8s/development
├── configmap
│ └── my-configmap.yaml
├── deployment
│ └── my-deployment.yaml
└── pvc
└── my-pvc.yaml
デフォルトでは、project/k8s/developmentにおける一括操作は、どのサブディレクトリも処理せず、ディレクトリの第1階層で処理が止まります。下記のコマンドによってこのディレクトリ配下でリソースを作成しようとすると、エラーが発生します。
kubectl apply -f project/k8s/development
error: you must provide one or more resources by argument or filename (.json|.yaml|.yml|stdin)
代わりに、下記のように--filename,-fフラグと合わせて--recursiveや-Rを指定してください:
kubectl apply -f project/k8s/development --recursive
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created
--recursiveフラグはkubectl {create,get,delete,describe,rollout}などのような--filename,-fフラグを扱うどの操作でも有効です。
また、--recursiveフラグは複数の-fフラグの引数を指定しても有効です。
kubectl apply -f project/k8s/namespaces -f project/k8s/development --recursive
namespace/development created
namespace/staging created
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created
kubectlについてさらに知りたい場合は、コマンドラインツール(kubectl)を参照してください。
ラベルを有効に使う
これまで取り上げた例では、リソースに対して最大1つのラベルを適用してきました。リソースのセットを他のセットと区別するために、複数のラベルが必要な状況があります。
例えば、異なるアプリケーション間では、異なるappラベルを使用したり、ゲストブックの例のようなマルチティアーのアプリケーションでは、各ティアーを区別する必要があります。frontendというティアーでは下記のラベルを持ちます。:
labels:
app: guestbook
tier: frontend
Redisマスターやスレーブでは異なるtierラベルを持ち、加えてroleラベルも持つことでしょう。:
labels:
app: guestbook
tier: backend
role: master
そして
labels:
app: guestbook
tier: backend
role: slave
ラベルを使用すると、ラベルで指定された任意の次元に沿ってリソースを分割できます。
kubectl apply -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml
kubectl get pods -Lapp -Ltier -Lrole
NAME READY STATUS RESTARTS AGE APP TIER ROLE
guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend <none>
guestbook-fe-ght6d 1/1 Running 0 1m guestbook frontend <none>
guestbook-fe-jpy62 1/1 Running 0 1m guestbook frontend <none>
guestbook-redis-master-5pg3b 1/1 Running 0 1m guestbook backend master
guestbook-redis-slave-2q2yf 1/1 Running 0 1m guestbook backend slave
guestbook-redis-slave-qgazl 1/1 Running 0 1m guestbook backend slave
my-nginx-divi2 1/1 Running 0 29m nginx <none> <none>
my-nginx-o0ef1 1/1 Running 0 29m nginx <none> <none>
kubectl get pods -lapp=guestbook,role=slave
NAME READY STATUS RESTARTS AGE
guestbook-redis-slave-2q2yf 1/1 Running 0 3m
guestbook-redis-slave-qgazl 1/1 Running 0 3m
Canary deployments カナリアデプロイ
複数のラベルが必要な他の状況として、異なるリリース間でのDeploymentや、同一コンポーネントの設定を区別することが挙げられます。よく知られたプラクティスとして、本番環境の実際のトラフィックを受け付けるようにするために、新しいリリースを完全にロールアウトする前に、新しいカナリア版のアプリケーションを過去のリリースと合わせてデプロイする方法があります。
例えば、異なるリリースバージョンを分けるためにtrackラベルを使用できます。
主要な安定板のリリースではtrackラベルにstableという値をつけることがあるでしょう。:
name: frontend
replicas: 3
...
labels:
app: guestbook
tier: frontend
track: stable
...
image: gb-frontend:v3
そして2つの異なるPodのセットを上書きしないようにするため、trackラベルに異なる値を持つ(例: canary)ようなguestbookフロントエンドの新しいリリースを作成できます。
name: frontend-canary
replicas: 1
...
labels:
app: guestbook
tier: frontend
track: canary
...
image: gb-frontend:v4
frontend Serviceは、トラフィックを両方のアプリケーションにリダイレクトさせるために、両方のアプリケーションに共通したラベルのサブセットを選択して両方のレプリカを扱えるようにします。:
selector:
app: guestbook
tier: frontend
安定版とカナリア版リリースで本番環境の実際のトラフィックを転送する割合を決めるため、双方のレプリカ数を変更できます(このケースでは3対1)。 最新版のリリースをしても大丈夫な場合、安定版のトラックを新しいアプリケーションにして、カナリア版を削除します。
さらに具体的な例については、tutorial of deploying Ghostを参照してください。
ラベルの更新
新しいリソースを作成する前に、既存のPodと他のリソースのラベルの変更が必要な状況があります。これはkubectl labelで実行できます。
例えば、全てのnginx Podを frontendティアーとしてラベル付けするには、下記のコマンドを実行するのみです。
kubectl label pods -l app=nginx tier=fe
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
pod/my-nginx-2035384211-u3t6x labeled
これは最初に"app=nginx"というラベルのついたPodをフィルターし、そのPodに対して"tier=fe"というラベルを追加します。 ラベル付けしたPodを確認するには、下記のコマンドを実行してください。
kubectl get pods -l app=nginx -L tier
NAME READY STATUS RESTARTS AGE TIER
my-nginx-2035384211-j5fhi 1/1 Running 0 23m fe
my-nginx-2035384211-u2c7e 1/1 Running 0 23m fe
my-nginx-2035384211-u3t6x 1/1 Running 0 23m fe
このコマンドでは"app=nginx"というラベルのついた全てのPodを出力し、Podのtierという項目も表示します(-Lまたは--label-columnsで指定)。
さらなる情報は、ラベルやkubectl labelを参照してください。
アノテーションの更新
リソースに対してアノテーションを割り当てたい状況があります。アノテーションは、ツール、ライブラリなどのAPIクライアントによって取得するための任意の非識別メタデータです。アノテーションの割り当てはkubectl annotateで可能です。例:
kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx'
kubectl get pods my-nginx-v4-9gw19 -o yaml
apiVersion: v1
kind: pod
metadata:
annotations:
description: my frontend running nginx
...
さらなる情報は、アノテーション や、kubectl annotateを参照してください。
アプリケーションのスケール
アプリケーションの負荷が増減するとき、kubectlを使って簡単にスケールできます。例えば、nginxのレプリカを3から1に減らす場合、下記を実行します:
kubectl scale deployment/my-nginx --replicas=1
deployment.apps/my-nginx scaled
実行すると、Deploymentによって管理されるPod数が1となります。
kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
my-nginx-2035384211-j5fhi 1/1 Running 0 30m
システムに対してnginxのレプリカ数を自動で選択させるには、下記のように1から3の範囲で指定します。:
kubectl autoscale deployment/my-nginx --min=1 --max=3
horizontalpodautoscaler.autoscaling/my-nginx autoscaled
実行すると、nginxのレプリカは必要に応じて自動でスケールアップ、スケールダウンします。
さらなる情報は、kubectl scale、kubectl autoscale and horizontal pod autoscalerを参照してください。
リソースの直接的アップデート
場合によっては、作成したリソースに対して処理を中断させずに更新を行う必要があります。
kubectl apply
開発者が設定するリソースをコードとして管理しバージョニングも行えるように、設定ファイルのセットをソースによって管理する方法が推奨されています。
この場合、クラスターに対して設定の変更をプッシュするためにkubectl applyを使用できます。
このコマンドは、リソース設定の過去のバージョンと、今適用した変更を比較し、差分に現れないプロパティーに対して上書き変更することなくクラスターに適用させます。
kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx configured
注意として、前回の変更適用時からの設定の変更内容を決めるため、kubectl applyはリソースに対してアノテーションを割り当てます。変更が実施されるとkubectl applyは、1つ前の設定内容と、今回変更しようとする入力内容と、現在のリソースの設定との3つの間で変更内容の差分をとります。
現在、リソースはこのアノテーションなしで作成されました。そのため、最初のkubectl paplyの実行においては、与えられた入力と、現在のリソースの設定の2つの間の差分が取られ、フォールバックします。この最初の実行の間、リソースが作成された時にプロパティーセットの削除を検知できません。この理由により、プロパティーの削除はされません。
kubectl applyの実行後の全ての呼び出しや、kubectl replaceやkubectl editなどの設定を変更する他のコマンドではアノテーションを更新します。kubectl applyした後の全ての呼び出しにおいて3-wayの差分取得によってプロパティの検知と削除を実施します。
kubectl edit
その他に、kubectl editによってリソースの更新もできます。:
kubectl edit deployment/my-nginx
このコマンドは、最初にリソースをgetし、テキストエディタでリソースを編集し、更新されたバージョンでリソースをapplyします。:
kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml
vi /tmp/nginx.yaml
# yamlファイルを編集し、ファイルを保存します。
kubectl apply -f /tmp/nginx.yaml
deployment.apps/my-nginx configured
rm /tmp/nginx.yaml
このコマンドによってより重大な変更を簡単に行えます。注意として、あなたのEDITORやKUBE_EDITORといった環境変数も指定できます。
さらなる情報は、kubectl editを参照してください。
kubectl patch
APIオブジェクトの更新にはkubectl patchを使うことができます。このコマンドはJSON patch、JSON merge patch、戦略的merge patchをサポートしています。
kubectl patchを使ったAPIオブジェクトの更新やkubectl patchを参照してください。
破壊的なアップデート
一度初期化された後、更新できないようなリソースフィールドの更新が必要な場合や、Deploymentによって作成され、壊れている状態のPodを修正するなど、再帰的な変更を即座に行いたい場合があります。このようなフィールドを変更するため、リソースの削除と再作成を行うreplace --forceを使用してください。このケースでは、シンプルに元の設定ファイルを修正するのみです。:
kubectl replace -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml --force
deployment.apps/my-nginx deleted
deployment.apps/my-nginx replaced
サービス停止なしでアプリケーションを更新する
ある時点で、前述したカナリアデプロイのシナリオにおいて、新しいイメージやイメージタグを指定することによって、デプロイされたアプリケーションを更新が必要な場合があります。kubectlではいくつかの更新操作をサポートしており、それぞれの操作が異なるシナリオに対して適用可能です。
ここでは、Deploymentを使ってアプリケーションの作成と更新についてガイドします。
まずnginxのバージョン1.14.2を稼働させていると仮定します。:
kubectl create deployment my-nginx --image=nginx:1.14.2
deployment.apps/my-nginx created
レプリカ数を3にします(新旧のリビジョンは混在します)。:
kubectl scale deployment my-nginx --current-replicas=1 --replicas=3
deployment.apps/my-nginx scaled
バージョン1.16.1に更新するには、上述したkubectlコマンドを使って.spec.template.spec.containers[0].imageの値をnginx:1.14.2からnginx:1.16.1に変更するだけでできます。
kubectl edit deployment/my-nginx
できました!Deploymentはデプロイされたnginxのアプリケーションを宣言的にプログレッシブに更新します。更新途中では、決まった数の古いレプリカのみダウンし、一定数の新しいレプリカが希望するPod数以上作成されても良いことを保証します。詳細について学ぶにはDeployment pageを参照してください。
次の項目
- アプリケーションの調査とデバッグのための
kubectlの使用方法について学んでください。 - 設定のベストプラクティスとTIPSを参照してください。
6 - クラスターのネットワーク
ネットワークはKubernetesにおける中心的な部分ですが、どのように動作するかを正確に理解することは難解な場合もあります。 Kubernetesには、4つの異なる対応すべきネットワークの問題があります:
- 高度に結合されたコンテナ間の通信: これは、Podおよび
localhost通信によって解決されます。 - Pod間の通信: 本ドキュメントの主な焦点です。
- Podからサービスへの通信: これはServiceでカバーされています。
- 外部からサービスへの通信: これはServiceでカバーされています。
Kubernetesは、言ってしまえばアプリケーション間でマシンを共有するためのものです。通常、マシンを共有するには、2つのアプリケーションが同じポートを使用しないようにする必要があります。 複数の開発者間でのポートの調整は、大規模に行うことが非常に難しく、ユーザーが制御できないクラスターレベルの問題に直面することになります。
動的ポート割り当てはシステムに多くの複雑さをもたらします。すべてのアプリケーションはポートをフラグとして受け取らなければならない、APIサーバーは設定ブロックに動的ポート番号を挿入する方法を知っていなければならない、各サービスは互いを見つける方法を知らなければならない、などです。Kubernetesはこれに対処するのではなく、別のアプローチを取ります。
Kubernetesネットワークモデルについては、こちらを参照してください。
Kubernetesネットワークモデルの実装方法
ネットワークモデルは、各ノード上のコンテナランタイムによって実装されます。最も一般的なコンテナランタイムは、Container Network Interface (CNI)プラグインを使用して、ネットワークとセキュリティ機能を管理します。CNIプラグインは、さまざまなベンダーから多数提供されています。これらの中には、ネットワークインターフェースの追加と削除という基本的な機能のみを提供するものもあれば、他のコンテナオーケストレーションシステムとの統合、複数のCNIプラグインの実行、高度なIPAM機能など、より洗練されたソリューションを提供するものもあります。
Kubernetesがサポートするネットワークアドオンの非網羅的なリストについては、このページを参照してください。
次の項目
ネットワークモデルの初期設計とその根拠、および将来の計画については、ネットワーク設計ドキュメントで詳細に説明されています。
7 - 可観測性(オブザーバビリティ)
Kubernetesにおいて、可観測性(オブザーバビリティ)とは、メトリクス、ログ、トレース(しばしば可観測性の3本柱と呼ばれる)を収集・分析し、クラスターの内部状態、パフォーマンス、健全性をより深く理解するプロセスです。
Kubernetesコントロールプレーンコンポーネントや多くのアドオンは、これらのシグナルを生成・出力します。 これらを集約・相関付けることで、クラスター全体のコントロールプレーン、アドオン、アプリケーションの統合された全体像を得ることができます。
図1は、クラスターコンポーネントが、3つの主要なシグナルタイプをどのように出力するかを示しています。
flowchart LR
A[クラスターコンポーネント] --> M[メトリクスパイプライン]
A --> L[ログパイプライン]
A --> T[トレースパイプライン]
M --> S[(ストレージと分析)]
L --> S
T --> S
S --> O[オペレーターと自動化]
図1. クラスターコンポーネントによって出力される高レベルなシグナルとそのコンシューマー。
メトリクス
Kubernetesコンポーネントは、/metricsエンドポイントからPrometheus形式でメトリクスを出力します。
以下が含まれます:
- kube-controller-manager
- kube-proxy
- kube-apiserver
- kube-scheduler
- kubelet
kubeletは、/metrics/cadvisor、/metrics/resource、/metrics/probesでもメトリクスを公開します。
また、kube-state-metricsなどのアドオンは、Kubernetesオブジェクトのステータスを追加して、これらのコントロールプレーンシグナルを充実させます。
一般的なKubernetesメトリクスパイプラインは、これらのエンドポイントを定期的にスクレイピングし、サンプルを時系列データベースに保存します(例: Prometheus)
詳細や設定オプションについては、システムメトリクスガイドを参照してください。
図2は、一般的なKubernetesメトリクスパイプラインを示しています。
flowchart LR
C[クラスターコンポーネント] --> P[Prometheusスクレイパー]
P --> TS[(時系列ストレージ)]
TS --> D[ダッシュボードとアラート]
TS --> A[自動化されたアクション]
図2. 一般的なKubernetesメトリクスパイプラインのコンポーネント。
マルチクラスターやマルチクラウドで可視性を高めるには、分散時系列データベース(例: ThanosやCortex)とPrometheusを組み合わせて使用することができます。
メトリクススクレイパーや時系列データベースについては、一般的な可観測性ツール - メトリクスツールを参照してください。
関連項目
- Kubernetesコンポーネントのシステムメトリクス
- metrics-serverによるリソース使用状況の監視
- kube-state-metricsのコンセプト
- リソースメトリクスパイプラインの概要
ログ
ログは、アプリケーション内、Kubernetesシステムコンポーネント内、および監査ログなどのセキュリティに関連するアクティビティのイベントを時系列で記録します。
コンテナランタイムは、コンテナ化されたアプリケーションの標準出力(stdout)および標準エラー出力(stderr)ストリームからの出力をキャプチャします。
ランタイムごとに実装方法は異なりますが、kubeletとの統合は CRIログ形式 を通じて標準化されており、kubeletはこれらのログをkubectl logsで取得できるようにします。

図3a. ノードレベルのログ記録アーキテクチャ。
システムコンポーネントログは、クラスターからのイベントをキャプチャし、デバッグやトラブルシューティングに役立つことがよくあります。
これらのコンポーネントは、コンテナ内で実行されるものと実行されないものの2つに分類されます。
例えば、kube-schedulerやkube-proxyは通常コンテナ内で実行されますが、kubeletやコンテナランタイムはホスト上で直接実行されます。
systemdを使用するマシンでは、kubeletとコンテナランタイムはjournaldに書き込みます。 それ以外の場合は、/var/logディレクトリの.logファイルに書き込みます。- コンテナ内で実行されるシステムコンポーネントは、デフォルトのコンテナログ記録メカニズムをバイパスして、常に
/var/logの.logファイルに書き込みます。
/var/log配下に保存されるシステムコンポーネントのログやコンテナのログは、無制限に増大しないようにログローテーションが必要です。
一部のクラスタープロビジョニングスクリプトは、デフォルトでログローテーションを設定します。
自身の環境を確認し、必要に応じて調整してください。
ログファイルの保存場所、形式、設定オプションの詳細については、システムログリファレンスを参照してください。
ほとんどのクラスターは、これらのファイルをtailして中央ログストアにエントリを転送するノードレベルのログエージェント(例: Fluent BitまたはFluentd)を実行しています。 ログアーキテクチャガイダンスでは、このようなパイプラインの設計、保持の適用、バックエンドへのログフローについて説明しています。
図3は、一般的なログ集約パイプラインを示しています。
flowchart LR
subgraph "ソース"
A[アプリケーション stdout / stderr]
B[コントロールプレーンログ]
C[監査記録]
end
A --> N[ノードログエージェント]
B --> N
C --> N
N --> L[中央ログストア]
L --> Q[ダッシュボード、アラート、SIEM]
図3. 一般的なKubernetesログパイプラインのコンポーネント。
ログエージェントと中央ログストアについては、一般的な可観測性ツール - ログツールを参照してください。
関連項目
トレース
トレースは、リクエストがKubernetesコンポーネントとアプリケーション間をどのように移動するかをキャプチャし、レイテンシー、タイミング、処理間の関係を結び付けます。 トレースを収集することで、エンドツーエンドのリクエストフローを可視化し、パフォーマンスの問題を診断し、コントロールプレーン、アドオン、またはアプリケーションのボトルネックや予期しない動作を特定できます。
Kubernetes 1.36は、組み込みのgRPCエクスポーターを介して直接、またはOpenTelemetry Collectorを通じて転送することで、OpenTelemetry Protocol(OTLP)経由でスパンをエクスポートできます。
OpenTelemetry Collectorは、コンポーネントやアプリケーションからスパンを受信し、それらを処理(例: サンプリングやリダクションの適用)して、保存と分析のためにトレーシングバックエンドに転送します。
図4は、一般的な分散トレーシングパイプラインを示しています。
flowchart LR
subgraph "ソース"
A[コントロールプレーンスパン]
B[アプリケーションスパン]
end
A --> X[OTLPエクスポーター]
B --> X
X --> COL[OpenTelemetry Collector]
COL --> TS[(トレーシングバックエンド)]
TS --> V[可視化と分析]
図4. 一般的なKubernetesトレースパイプラインのコンポーネント。
トレーシングコレクターとバックエンドについては、一般的な可観測性ツール - トレーシングツールを参照してください。
関連項目
一般的な可観測性ツール
注意: このセクションは、Kubernetesが必要とする可観測性機能を提供するサードパーティプロジェクトにリンクしています。 Kubernetesプロジェクトのメンテナーは、アルファベット順にリストされているこれらのプロジェクトに対して責任を負いません。 このリストにプロジェクトを追加するには、変更を提出する前にコンテンツガイドを読んでください。
メトリクスツール
- Cortexは、水平スケーラブルな長期Prometheusストレージを提供します。
- Grafana Mimirは、マルチテナント、水平スケーラブルなPrometheus互換ストレージを提供するGrafana Labsのプロジェクトです。
- Prometheusは、Kubernetesコンポーネントからメトリクスをスクレイピングして保存する監視システムです。
- Thanosは、グローバルクエリ、ダウンサンプリング、オブジェクトストレージサポートでPrometheusを拡張します。
ログツール
- Elasticsearchは、分散ログインデックスと検索を提供します。
- Fluent Bitは、低リソース消費でコンテナとノードのログを収集・転送します。
- Fluentdは、ログを複数の宛先にルーティング・変換します。
- Grafana Lokiは、Prometheusに触発されたラベルベース形式でログを保存します。
- OpenSearchは、Elasticsearch APIと互換性のあるオープンソースのログインデックスと検索を提供します。
トレーシングツール
- Grafana Tempoは、スケーラブルで低コストな分散トレーシングストレージを提供します。
- Jaegerは、マイクロサービスの分散トレースをキャプチャして可視化します。
- OpenTelemetry Collectorは、トレースを含むテレメトリデータを受信、処理、エクスポートします。
- Zipkinは、分散トレーシングの収集と可視化を提供します。
次の項目
- metrics-serverでリソース使用状況メトリクスを収集する方法を学ぶ
- ログ記録のタスクとチュートリアルを探索する
- 監視とトレースのタスクガイドを参照する
- コンポーネントエンドポイントと安定性について、システムメトリクスガイドを確認する
- 検証済みのサードパーティオプションについて、一般的な可観測性ツールセクションを確認する
8 - ロギングのアーキテクチャ
アプリケーションログは、アプリケーション内で何が起こっているかを理解するのに役立ちます。ログは、問題のデバッグとクラスターアクティビティの監視に特に役立ちます。最近のほとんどのアプリケーションには、何らかのロギングメカニズムがあります。同様に、コンテナエンジンはロギングをサポートするように設計されています。コンテナ化されたアプリケーションで、最も簡単で最も採用されているロギング方法は、標準出力と標準エラーストリームへの書き込みです。
ただし、コンテナエンジンまたはランタイムによって提供されるネイティブ機能は、たいていの場合、完全なロギングソリューションには十分ではありません。
たとえば、コンテナがクラッシュした場合やPodが削除された場合、またはノードが停止した場合に、アプリケーションのログにアクセスしたい場合があります。
クラスターでは、ノードやPod、またはコンテナに関係なく、ノードに個別のストレージとライフサイクルが必要です。この概念は、クラスターレベルロギング と呼ばれます。
クラスターレベルロギングのアーキテクチャでは、ログを保存、分析、およびクエリするための個別のバックエンドが必要です。Kubernetesは、ログデータ用のネイティブストレージソリューションを提供していません。代わりに、Kubernetesに統合される多くのロギングソリューションがあります。次のセクションでは、ノードでログを処理および保存する方法について説明します。
Kubernetesでの基本的なロギング
この例では、1秒に1回標準出力ストリームにテキストを書き込むコンテナを利用する、Pod specificationを使います。
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args: [/bin/sh, -c,
'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
このPodを実行するには、次のコマンドを使用します:
kubectl apply -f https://k8s.io/examples/debug/counter-pod.yaml
出力は次のようになります:
pod/counter created
ログを取得するには、以下のようにkubectl logsコマンドを使用します:
kubectl logs counter
出力は次のようになります:
0: Mon Jan 1 00:00:00 UTC 2001
1: Mon Jan 1 00:00:01 UTC 2001
2: Mon Jan 1 00:00:02 UTC 2001
...
コンテナの以前のインスタンスからログを取得するために、kubectl logs --previousを使用できます。Podに複数のコンテナがある場合は、次のように-cフラグでコマンドにコンテナ名を追加することで、アクセスするコンテナのログを指定します。
kubectl logs counter -c count
詳細については、kubectl logsドキュメントを参照してください。
ノードレベルでのロギング

コンテナエンジンは、生成された出力を処理して、コンテナ化されたアプリケーションのstdoutとstderrストリームにリダイレクトします。たとえば、Dockerコンテナエンジンは、これら2つのストリームをロギングドライバーにリダイレクトします。ロギングドライバーは、JSON形式でファイルに書き込むようにKubernetesで設定されています。
備考:
Docker JSONロギングドライバーは、各行を個別のメッセージとして扱います。Dockerロギングドライバーを使用する場合、複数行メッセージを直接サポートすることはできません。ロギングエージェントレベルあるいはそれ以上のレベルで、複数行のメッセージを処理する必要があります。デフォルトでは、コンテナが再起動すると、kubeletは1つの終了したコンテナをログとともに保持します。Podがノードから削除されると、対応する全てのコンテナが、ログとともに削除されます。
ノードレベルロギングでの重要な考慮事項は、ノードで使用可能な全てのストレージをログが消費しないように、ログローテーションを実装することです。Kubernetesはログのローテーションを担当しませんが、デプロイツールでそれに対処するソリューションを構築する必要があります。たとえば、kube-up.shスクリプトによってデプロイされたKubernetesクラスターには、1時間ごとに実行するように構成されたlogrotateツールがあります。アプリケーションのログを自動的にローテーションするようにコンテナランタイムを構築することもできます。
例として、configure-helper scriptに対応するスクリプトであるkube-up.shが、どのようにGCPでCOSイメージのロギングを構築しているかについて、詳細な情報を見つけることができます。
CRIコンテナランタイムを使用する場合、kubeletはログのローテーションとログディレクトリ構造の管理を担当します。kubeletはこの情報をCRIコンテナランタイムに送信し、ランタイムはコンテナログを指定された場所に書き込みます。2つのkubeletパラメーター、container-log-max-sizeとcontainer-log-max-filesをkubelet設定ファイルで使うことで、各ログファイルの最大サイズと各コンテナで許可されるファイルの最大数をそれぞれ設定できます。
基本的なロギングの例のように、kubectl logsを実行すると、ノード上のkubeletがリクエストを処理し、ログファイルから直接読み取ります。kubeletはログファイルの内容を返します。
備考:
外部システムがローテーションを実行した場合、またはCRIコンテナランタイムが使用されている場合は、最新のログファイルの内容のみがkubectl logsで利用可能になります。例えば、10MBのファイルがある場合、logrotateによるローテーションが実行されると、2つのファイルが存在することになります: 1つはサイズが10MBのファイルで、もう1つは空のファイルです。この例では、kubectl logsは最新のログファイルの内容、つまり空のレスポンスを返します。システムコンポーネントログ
システムコンポーネントには、コンテナ内で実行されるものとコンテナ内で実行されないものの2種類があります。例えば以下のとおりです。
- Kubernetesスケジューラーとkube-proxyはコンテナ内で実行されます。
- kubeletとコンテナランタイムはコンテナ内で実行されません。
systemdを搭載したマシンでは、kubeletとコンテナランタイムがjournaldに書き込みます。systemdが存在しない場合、kubeletとコンテナランタイムはvar/logディレクトリ内の.logファイルに書き込みます。コンテナ内のシステムコンポーネントは、デフォルトのロギングメカニズムを迂回して、常に/var/logディレクトリに書き込みます。それらはklogというロギングライブラリを使用します。これらのコンポーネントのロギングの重大性に関する規則は、development docs on loggingに記載されています。
コンテナログと同様に、/var/logディレクトリ内のシステムコンポーネントログはローテーションする必要があります。kube-up.shスクリプトによって生成されたKubernetesクラスターでは、これらのログは、logrotateツールによって毎日、またはサイズが100MBを超えた時にローテーションされるように設定されています。
クラスターレベルロギングのアーキテクチャ
Kubernetesはクラスターレベルロギングのネイティブソリューションを提供していませんが、検討可能な一般的なアプローチがいくつかあります。ここにいくつかのオプションを示します:
- 全てのノードで実行されるノードレベルのロギングエージェントを使用します。
- アプリケーションのPodにログインするための専用のサイドカーコンテナを含めます。
- アプリケーション内からバックエンドに直接ログを送信します。
ノードロギングエージェントの使用

各ノードに ノードレベルのロギングエージェント を含めることで、クラスターレベルロギングを実装できます。ロギングエージェントは、ログを公開したり、ログをバックエンドに送信したりする専用のツールです。通常、ロギングエージェントは、そのノード上の全てのアプリケーションコンテナからのログファイルを含むディレクトリにアクセスできるコンテナです。
ロギングエージェントは全てのノードで実行する必要があるため、エージェントをDaemonSetとして実行することをおすすめします。
ノードレベルのロギングは、ノードごとに1つのエージェントのみを作成し、ノードで実行されているアプリケーションに変更を加える必要はありません。
コンテナはstdoutとstderrに書き込みますが、合意された形式はありません。ノードレベルのエージェントはこれらのログを収集し、集約のために転送します。
ロギングエージェントでサイドカーコンテナを使用する
サイドカーコンテナは、次のいずれかの方法で使用できます:
- サイドカーコンテナは、アプリケーションログを自身の
stdoutにストリーミングします。 - サイドカーコンテナは、アプリケーションコンテナからログを取得するように設定されたロギングエージェントを実行します。
ストリーミングサイドカーコンテナ

サイドカーコンテナに自身のstdoutやstderrストリームへの書き込みを行わせることで、各ノードですでに実行されているkubeletとロギングエージェントを利用できます。サイドカーコンテナは、ファイル、ソケット、またはjournaldからログを読み取ります。各サイドカーコンテナは、ログを自身のstdoutまたはstderrストリームに出力します。
このアプローチにより、stdoutまたはstderrへの書き込みのサポートが不足している場合も含め、アプリケーションのさまざまな部分からいくつかのログストリームを分離できます。ログのリダイレクトの背後にあるロジックは最小限であるため、大きなオーバーヘッドにはなりません。さらに、stdoutとstderrはkubeletによって処理されるため、kubectl logsのような組み込みツールを使用できます。
たとえば、Podは単一のコンテナを実行し、コンテナは2つの異なる形式を使用して2つの異なるログファイルに書き込みます。Podの構成ファイルは次のとおりです:
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}
両方のコンポーネントをコンテナのstdoutストリームにリダイレクトできたとしても、異なる形式のログエントリを同じログストリームに書き込むことはおすすめしません。代わりに、2つのサイドカーコンテナを作成できます。各サイドカーコンテナは、共有ボリュームから特定のログファイルを追跡し、ログを自身のstdoutストリームにリダイレクトできます。
2つのサイドカーコンテナを持つPodの構成ファイルは次のとおりです:
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-log-1
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/1.log']
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-log-2
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/2.log']
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}
これで、このPodを実行するときに、次のコマンドを実行して、各ログストリームに個別にアクセスできます:
kubectl logs counter count-log-1
出力は次のようになります:
0: Mon Jan 1 00:00:00 UTC 2001
1: Mon Jan 1 00:00:01 UTC 2001
2: Mon Jan 1 00:00:02 UTC 2001
...
kubectl logs counter count-log-2
出力は次のようになります:
Mon Jan 1 00:00:00 UTC 2001 INFO 0
Mon Jan 1 00:00:01 UTC 2001 INFO 1
Mon Jan 1 00:00:02 UTC 2001 INFO 2
...
クラスターにインストールされているノードレベルのエージェントは、それ以上の設定を行わなくても、これらのログストリームを自動的に取得します。必要があれば、ソースコンテナに応じてログをパースするようにエージェントを構成できます。
CPUとメモリーの使用量が少ない(CPUの場合は数ミリコアのオーダー、メモリーの場合は数メガバイトのオーダー)にも関わらず、ログをファイルに書き込んでからstdoutにストリーミングすると、ディスクの使用量が2倍になる可能性があることに注意してください。単一のファイルに書き込むアプリケーションがある場合は、ストリーミングサイドカーコンテナアプローチを実装するのではなく、/dev/stdoutを宛先として設定することをおすすめします。
サイドカーコンテナを使用して、アプリケーション自体ではローテーションできないログファイルをローテーションすることもできます。このアプローチの例は、logrotateを定期的に実行する小さなコンテナです。しかし、stdoutとstderrを直接使い、ローテーションと保持のポリシーをkubeletに任せることをおすすめします。
ロギングエージェントを使用したサイドカーコンテナ

ノードレベルロギングのエージェントが、あなたの状況に必要なだけの柔軟性を備えていない場合は、アプリケーションで実行するように特別に構成した別のロギングエージェントを使用してサイドカーコンテナを作成できます。
備考:
サイドカーコンテナでロギングエージェントを使用すると、大量のリソースが消費される可能性があります。さらに、これらのログはkubeletによって制御されていないため、kubectl logsを使用してこれらのログにアクセスすることができません。ロギングエージェントを使用したサイドカーコンテナを実装するために使用できる、2つの構成ファイルを次に示します。最初のファイルには、fluentdを設定するためのConfigMapが含まれています。
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config
data:
fluentd.conf: |
<source>
type tail
format none
path /var/log/1.log
pos_file /var/log/1.log.pos
tag count.format1
</source>
<source>
type tail
format none
path /var/log/2.log
pos_file /var/log/2.log.pos
tag count.format2
</source>
<match **>
type google_cloud
</match>
備考:
fluentdの構成については、fluentd documentationを参照してください。2番目のファイルは、fluentdを実行しているサイドカーコンテナを持つPodを示しています。Podは、fluentdが構成データを取得できるボリュームをマウントします。
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox:1.28
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-agent
image: registry.k8s.io/fluentd-gcp:1.30
env:
- name: FLUENTD_ARGS
value: -c /etc/fluentd-config/fluentd.conf
volumeMounts:
- name: varlog
mountPath: /var/log
- name: config-volume
mountPath: /etc/fluentd-config
volumes:
- name: varlog
emptyDir: {}
- name: config-volume
configMap:
name: fluentd-config
サンプル構成では、fluentdを任意のロギングエージェントに置き換えて、アプリケーションコンテナ内の任意のソースから読み取ることができます。
アプリケーションから直接ログを公開する

すべてのアプリケーションから直接ログを公開または送信するクラスターロギングは、Kubernetesのスコープ外です。
9 - Kubernetesコントロールプレーンコンポーネントの互換性バージョン
v1.32のリリース以降、Kubernetesコントロールプレーンコンポーネントに、バージョン互換性の設定やエミュレーションのオプションを導入しました。 これにより、クラスター管理者はより細かく手順を制御できるようになり、アップグレードをより安全に行えるようにしました。
エミュレートバージョン
エミュレーションオプションは、コントロールプレーンコンポーネントの--emulated-versionフラグによって設定されます。
このオプションにより、コンポーネントはKubernetesの以前のバージョンの動作(API、機能など)をエミュレートすることができます。
使用すると、利用可能な機能はエミュレートされたバージョンと一致します:
- エミュレートするバージョン以降に導入されたバイナリバージョンの機能は利用できません。
- エミュレートするバージョン以降に削除された機能は利用可能です。
これにより、特定のKubernetesリリースのバイナリが以前のバージョンの動作を十分な忠実度でエミュレートできるようになり、他のシステムコンポーネントとの相互運用性をエミュレートされたバージョンの観点から定義することが可能になります。
--emulated-versionはbinaryVersion以下でなければなりません。
サポートされるエミュレートバージョンの範囲については、--emulated-versionフラグのヘルプメッセージを参照してください。
10 - Kubernetesオブジェクトの状態メトリクス
Kubernetes API内のKubernetesオブジェクトの状態は、メトリクスとして公開することができます。
kube-state-metricsと呼ばれるアドオンエージェントは、Kubernetes APIサーバーに接続し、クラスター内の個別オブジェクトの状態から生成されたメトリクスを含むHTTPエンドポイントを公開します。
このエージェントは、ラベルやアノテーション、起動・終了時刻、ステータス、またはオブジェクトが現在置かれているフェーズなど、オブジェクトの状態に関する様々な情報を公開します。
例えば、Pod内で実行されているコンテナはkube_pod_container_infoメトリクスを作成します。
このメトリクスには、コンテナ名、それが属するPod名、Podが実行されているネームスペース、コンテナイメージ名、イメージID、コンテナspecからのイメージ名、実行中のコンテナID、およびPod IDがラベルとして含まれています。
kube-state-metricsのエンドポイントをスクレイプすることができる外部コンポーネント(例えば、Prometheusなど)を使用することで、以下のユースケースを実現できます。
例: kube-state-metricsのメトリクスを使用したクラスター状態のクエリ
kube-state-metricsによって生成されるメトリクス系列は、クエリに使用できるため、クラスターに関する更なる洞察を得るのに役立ちます。
Prometheusまたは同じクエリ言語を使用する他のツールを使用している場合、以下のPromQLクエリは準備完了していないPodの数を返します:
count(kube_pod_status_ready{condition="false"}) by (namespace, pod)
例: kube-state-metricsに基づくアラート
kube-state-metricsから生成されるメトリクスを使用することで、クラスター内の問題に対するアラートも可能になります。
Prometheusまたは同じアラートルール言語を使用する類似のツールを使用している場合、以下のアラートは5分以上Terminating状態にあるPodが存在する際に発火します:
groups:
- name: Pod state
rules:
- alert: PodsBlockedInTerminatingState
expr: count(kube_pod_deletion_timestamp) by (namespace, pod) * count(kube_pod_status_reason{reason="NodeLost"} == 0) by (namespace, pod) > 0
for: 5m
labels:
severity: page
annotations:
summary: Pod {{$labels.namespace}}/{{$labels.pod}} blocked in Terminating state.
11 - システムログ
システムコンポーネントのログは、クラスター内で起こったイベントを記録します。このログはデバッグのために非常に役立ちます。ログのverbosityを設定すると、ログをどの程度詳細に見るのかを変更できます。ログはコンポーネント内のエラーを表示する程度の荒い粒度にすることも、イベントのステップバイステップのトレース(HTTPのアクセスログ、Podの状態の変更、コントローラーの動作、スケジューラーの決定など)を表示するような細かい粒度に設定することもできます。
klog
klogは、Kubernetesのログライブラリです。klogは、Kubernetesのシステムコンポーネント向けのログメッセージを生成します。
klogの設定に関する詳しい情報については、コマンドラインツールのリファレンスを参照してください。
klogネイティブ形式の例:
I1025 00:15:15.525108 1 httplog.go:79] GET /api/v1/namespaces/kube-system/pods/metrics-server-v0.3.1-57c75779f-9p8wg: (1.512ms) 200 [pod_nanny/v0.0.0 (linux/amd64) kubernetes/$Format 10.56.1.19:51756]
構造化ログ
警告:
構造化ログへのマイグレーションは現在進行中の作業です。このバージョンでは、すべてのログメッセージが構造化されているわけではありません。ログファイルをパースする場合、JSONではないログの行にも対処しなければなりません。
ログの形式と値のシリアライズは変更される可能性があります。
構造化ログは、ログメッセージに単一の構造を導入し、プログラムで情報の抽出ができるようにするものです。構造化ログは、僅かな労力とコストで保存・処理できます。新しいメッセージ形式は後方互換性があり、デフォルトで有効化されます。
構造化ログの形式:
<klog header> "<message>" <key1>="<value1>" <key2>="<value2>" ...
例:
I1025 00:15:15.525108 1 controller_utils.go:116] "Pod status updated" pod="kube-system/kubedns" status="ready"
JSONログ形式
警告:
JSONの出力は多数の標準のklogフラグをサポートしていません。非対応のklogフラグの一覧については、コマンドラインツールリファレンスを参照してください。
すべてのログがJSON形式で書き込むことに対応しているわけではありません(たとえば、プロセスの開始時など)。ログのパースを行おうとしている場合、JSONではないログの行に対処できるようにしてください。
フィールド名とJSONのシリアライズは変更される可能性があります。
--logging-format=jsonフラグは、ログの形式をネイティブ形式klogからJSON形式に変更します。以下は、JSONログ形式の例(pretty printしたもの)です。
{
"ts": 1580306777.04728,
"v": 4,
"msg": "Pod status updated",
"pod":{
"name": "nginx-1",
"namespace": "default"
},
"status": "ready"
}
特別な意味を持つキー:
ts- Unix時間のタイムスタンプ(必須、float)v- verbosity (必須、int、デフォルトは0)err- エラー文字列 (オプション、string)msg- メッセージ (必須、string)
現在サポートされているJSONフォーマットの一覧:
ログのサニタイズ
警告:
ログのサニタイズ大きな計算のオーバーヘッドを引き起こす可能性があるため、本番環境では有効にするべきではありません。--experimental-logging-sanitizationフラグはklogのサニタイズフィルタを有効にします。有効にすると、すべてのログの引数が機密データ(パスワード、キー、トークンなど)としてタグ付けされたフィールドについて検査され、これらのフィールドのログの記録は防止されます。
現在ログのサニタイズをサポートしているコンポーネント一覧:
- kube-controller-manager
- kube-apiserver
- kube-scheduler
- kubelet
備考:
ログのサニタイズフィルターは、ユーザーのワークロードのログが機密データを漏洩するのを防げるわけではありません。ログのverbosityレベル
-vフラグはログのverbosityを制御します。値を増やすとログに記録されるイベントの数が増えます。値を減らすとログに記録されるイベントの数が減ります。verbosityの設定を増やすと、ますます多くの深刻度の低いイベントをログに記録するようになります。verbosityの設定を0にすると、クリティカルなイベントだけをログに記録します。
ログの場所
システムコンポーネントには2種類あります。コンテナ内で実行されるコンポーネントと、コンテナ内で実行されないコンポーネントです。たとえば、次のようなコンポーネントがあります。
- Kubernetesのスケジューラーやkube-proxyはコンテナ内で実行されます。
- kubeletやDockerのようなコンテナランタイムはコンテナ内で実行されません。
systemdを使用しているマシンでは、kubeletとコンテナランタイムはjournaldに書き込みを行います。それ以外のマシンでは、/var/logディレクトリ内の.logファイルに書き込みます。コンテナ内部のシステムコンポーネントは、デフォルトのログ機構をバイパスするため、常に/var/logディレクトリ内の.logファイルに書き込みます。コンテナのログと同様に、/var/logディレクトリ内のシステムコンポーネントのログはローテートする必要があります。kube-up.shスクリプトによって作成されたKubernetesクラスターでは、ログローテーションはlogrotateツールで設定されます。logrotateツールはログを1日ごとまたはログのサイズが100MBを超えたときにローテートします。
次の項目
- Kubernetesのログのアーキテクチャについて読む。
- 構造化ログについて読む。
- ログの深刻度の慣習について読む。
12 - Kubernetesシステムコンポーネントのトレース
システムコンポーネントのトレースは、クラスター内の処理のレイテンシーと処理間の関係性を記録します。
Kubernetesコンポーネントは、gRPCエクスポーターを使用してOpenTelemetry Protocolでトレースを出力し、OpenTelemetry Collectorを使用してトレースバックエンドに収集およびルーティングできます。
トレースの収集
Kubernetesコンポーネントには、OTLPのトレースをエクスポートするための組み込みgRPCエクスポーターがあり、OpenTelemetry Collectorを使用する場合と使用しない場合の両方で利用できます。
トレースの収集とCollectorの使用に関する完全なガイドについては、OpenTelemetry Collectorの使い方を参照してください。 ただし、Kubernetesコンポーネント固有の注意点がいくつかあります。
デフォルトでは、KubernetesコンポーネントはOTLPのgRPCエクスポーターを使用して、IANA OpenTelemetryポートである4317番ポートでトレースをエクスポートします。 例えば、CollectorがKubernetesコンポーネントのサイドカーとして実行されている場合、以下のレシーバー設定でスパンを収集し、標準出力にログを出力します:
receivers:
otlp:
protocols:
grpc:
exporters:
# このエクスポーターをバックエンド用のエクスポーターに置き換えてください
exporters:
debug:
verbosity: detailed
service:
pipelines:
traces:
receivers: [otlp]
exporters: [debug]
Collectorを使用せずにバックエンドに直接トレースを出力するには、Kubernetesトレース設定ファイルのendpointフィールドに目的のトレースバックエンドアドレスを指定します。
この方法ではCollectorが不要になり、全体的な構成がシンプルになります。
認証情報を含むトレースバックエンドのヘッダー設定については、OTEL_EXPORTER_OTLP_HEADERS環境変数を使用できます。
詳細はOTLPエクスポーターの設定を参照してください。
また、Kubernetesクラスター名、名前空間、Pod名などのトレースリソース属性の設定には、OTEL_RESOURCE_ATTRIBUTES環境変数を使用できます。
詳細はOTLP Kubernetesリソースを参照してください。
コンポーネントのトレース
kube-apiserverのトレース
kube-apiserverは、受信HTTPリクエスト、およびWebhook、etcd、再入リクエストへの送信リクエストに対してスパンを生成します。 kube-apiserverは送信リクエストでW3C Trace Contextを伝播しますが、kube-apiserverは多くの場合パブリックエンドポイントであるため、受信リクエストに付加されたトレースコンテキストは使用しません。
kube-apiserverでのトレースの有効化
トレースを有効にするには、--tracing-config-file=<設定ファイルのパス>でkube-apiserverにトレース設定ファイルを提供します。
以下は、10000リクエストに1つの割合でスパンを記録し、デフォルトのOpenTelemetryエンドポイントを使用する設定の例です:
apiVersion: apiserver.config.k8s.io/v1
kind: TracingConfiguration
# default value
#endpoint: localhost:4317
samplingRatePerMillion: 100
TracingConfiguration構造体の詳細については、APIサーバー設定API (v1)を参照してください。
kubeletのトレース
More information about this feature
This is a stable feature in Kubernetes, and has been since version 1.34. It was first available in the v1.25 release.
kubeletのCRIインターフェースと認証済みHTTPサーバーは、トレーススパンを生成するように計装されています。 apiserverと同様に、エンドポイントとサンプリングレートは設定可能です。 トレースコンテキストの伝播も設定されています。 親スパンのサンプリング決定は常に尊重されます。 指定されたトレース設定のサンプリングレートは、親を持たないスパンに適用されます。 エンドポイントを設定せずに有効にした場合、デフォルトのOpenTelemetry Collectorレシーバーアドレス「localhost:4317」が設定されます。
kubeletでのトレースの有効化
トレースを有効にするには、トレース設定を適用します。 以下は、10000リクエストに1つの割合でスパンを記録し、デフォルトのOpenTelemetryエンドポイントを使用するkubelet設定のスニペット例です:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
tracing:
# default value
#endpoint: localhost:4317
samplingRatePerMillion: 100
samplingRatePerMillionを100万(1000000)に設定すると、すべてのスパンがエクスポーターに送信されます。
Kubernetes v1.36のkubeletは、ガベージコレクション、Pod同期ルーチン、およびすべてのgRPCメソッドからスパンを収集します。 kubeletはgRPCリクエストでトレースコンテキストを伝播するため、CRI-Oやcontainerdなどのトレースインストルメンテーションをサポートするコンテナランタイムは、kubeletからのトレースコンテキストに関連付けてエクスポートされたスパンを作成できます。 結果として得られるトレースには、kubeletとコンテナランタイムのスパン間の親子リンクが含まれ、ノードの問題をデバッグする際に役立つコンテキストを提供します。
スパンのエクスポートには、システム全体の設定に応じて、ネットワークとCPU側で常に小さなパフォーマンスオーバーヘッドが発生することに注意してください。
トレースが有効なクラスターでそのような問題が発生した場合は、samplingRatePerMillionを減らすか、設定を削除してトレースを完全に無効にすることで問題を軽減してください。
安定性
トレースインストルメンテーションはまだ活発に開発中であり、さまざまな形で変更される可能性があります。 これには、スパン名、付加された属性、計測対象のエンドポイントなどが含まれます。 この機能がStableに昇格するまで、トレースインストルメンテーションの後方互換性は保証されません。
次の項目
- OpenTelemetry Collectorの使い方について読む
- OTLPエクスポーターの設定について読む
13 - Kubernetesのプロキシ
このページではKubernetesと併用されるプロキシについて説明します。
プロキシ
Kubernetesを使用する際に、いくつかのプロキシを使用する場面があります。
-
- ユーザーのデスクトップ上かPod内で稼働します
- ローカルホストのアドレスからKubernetes apiserverへのプロキシを行います
- クライアントからプロキシ間ではHTTPを使用します
- プロキシからapiserverへはHTTPSを使用します
- apiserverの場所を示します
- 認証用のヘッダーを追加します
-
- apiserver内で動作する踏み台となります
- これがなければ到達不可能であるクラスターIPへ、クラスターの外部からのユーザーを接続します
- apiserverのプロセス内で稼働します
- クライアントからプロキシ間ではHTTPSを使用します(apiserverの設定により、HTTPを使用します)
- プロキシからターゲット間では利用可能な情報を使用して、プロキシによって選択されたHTTPかHTTPSのいずれかを使用します
- Node、Pod、Serviceへ到達するのに使えます
- Serviceへ到達するときは負荷分散を行います
-
- 各ノード上で稼働します
- UDP、TCP、SCTPをプロキシします
- HTTPを解釈しません
- 負荷分散機能を提供します
- Serviceへ到達させるためのみに使用されます
-
apiserverの前段にあるプロキシ/ロードバランサー:
- 実際に存在するかどうかと実装はクラスターごとに異なります(例: nginx)
- 全てのクライアントと、1つ以上のapiserverの間に位置します
- 複数のapiserverがあるときロードバランサーとして稼働します
-
外部サービス上で稼働するクラウドロードバランサー:
- いくつかのクラウドプロバイダーによって提供されます(例: AWS ELB、Google Cloud Load Balancer)
LoadBalancerというtypeのKubernetes Serviceが作成されたときに自動で作成されます- たいていのクラウドロードバランサーはUDP/TCPのみサポートしています
- SCTPのサポートはクラウドプロバイダーのロードバランサーの実装によって異なります
- ロードバランサーの実装はクラウドプロバイダーによって異なります
Kubernetesユーザーのほとんどは、最初の2つのタイプ以外に心配する必要はありません。クラスター管理者はそれ以外のタイプのロードバランサーを正しくセットアップすることを保証します。
リダイレクトの要求
プロキシはリダイレクトの機能を置き換えました。リダイレクトの使用は非推奨となります。
14 - アドオンのインストール
アドオンはKubernetesの機能を拡張するものです。
このページでは、利用可能なアドオンの一部の一覧と、それぞれのアドオンのインストール方法へのリンクを提供します。 この一覧は、すべてを網羅するものではありません。
ネットワークとネットワークポリシー
- ACIは、統合されたコンテナネットワークとネットワークセキュリティをCisco ACIを使用して提供します。
- Antreaは、L3またはL4で動作して、Open vSwitchをネットワークデータプレーンとして活用する、Kubernetes向けのネットワークとセキュリティサービスを提供します。 AntreaはSandboxレベルのCNCFプロジェクトです。
- Calicoは、ネットワーキングおよびネットワークポリシーのプロバイダーです。 Calicoは柔軟なネットワーキングオプションをサポートしており、BGPの有無を含む非オーバーレイネットワークやオーバーレイネットワークなど、状況に応じて最も効率的なオプションを選択できます。 Calicoは、ホスト、Pod、および(IstioとEnvoyを使用している場合)サービスメッシュレイヤーのアプリケーションに対して、同じエンジンを使用してネットワークポリシーを適用します。
- CanalはFlannelとCalicoをあわせたもので、ネットワークとネットワークポリシーを提供します。
- Ciliumは、eBPFベースのデータプレーンを備えたネットワーク、可観測性、およびセキュリティのソリューションです。 Ciliumは、ネイティブなルーティングまたはoverlay/encapsulationモードのいずれかを用いて複数のクラスターにまたがることができる、シンプルでフラットなL3ネットワークを提供します。 また、ネットワークのアドレス指定から切り離されたアイデンティティベースのセキュリティモデルを使用して、L3からL7のネットワークポリシーを適用することができます。 Ciliumはkube-proxyの代替として機能し、オプトインにて可観測性およびセキュリティ機能も追加で提供しています。 CiliumはGraduatedレベルのCNCFプロジェクトです。
- CNI-Genieは、KubernetesをCalico、Canal、Flannel、Weaveなど選択したCNIプラグインをシームレスに接続できるようにするプラグインです。 CNI-GenieはSandboxレベルのCNCFプロジェクトです。
- Contivは、さまざまなユースケースと豊富なポリシーフレームワーク向けに設定可能なネットワーク(BGPを使用したネイティブのL3、vxlanを使用したオーバーレイ、古典的なL2、Cisco-SDN/ACI)を提供します。 Contivプロジェクトは完全にオープンソースです。 インストーラーはkubeadmとkubeadm以外の両方をベースとしたインストールオプションがあります。
- Contrailは、Tungsten Fabricをベースにしている、オープンソースでマルチクラウドに対応したネットワーク仮想化およびポリシー管理プラットフォームです。 ContrailおよびTungsten Fabricは、Kubernetes、OpenShift、OpenStack、Mesosなどのオーケストレーションシステムと統合されており、仮想マシン、コンテナ/Pod、ベアメタルのワークロードに隔離モードを提供します。
- Flannelは、Kubernetesで使用できるオーバーレイネットワークプロバイダーです。
- Gateway APIは、SIG Networkコミュニティによって管理されているオープンソースプロジェクトで、サービスネットワーキングをモデル化するための表現力豊かで拡張可能、かつロール指向のAPIを提供します。
- Knitterは、1つのKubernetes Podで複数のネットワークインターフェースをサポートするためのプラグインです。
- Multusは、すべてのCNIプラグイン(たとえば、Calico、Cilium、Contiv、Flannel)に加えて、SRIOV、DPDK、OVS-DPDK、VPPをベースとするKubernetes上のワークロードをサポートする、複数のネットワークサポートのためのマルチプラグインです。
- OVN-Kubernetesは、Open vSwitch(OVS)プロジェクトから生まれた仮想ネットワーク実装であるOVN(Open Virtual Network)をベースとする、Kubernetesのためのネットワークプロバイダーです。 OVN-Kubernetesは、OVSベースのロードバランサーおよびネットワークポリシーの実装を含む、Kubernetes向けのオーバーレイベースのネットワーク実装を提供します。
- Nodusは、OVNベースのCNIコントローラープラグインで、クラウドネイティブベースのService function chaining(SFC)を提供します。
- NSX-T Container Plug-in(NCP)は、VMware NSX-TとKubernetesなどのコンテナオーケストレーター間のインテグレーションを提供します。 また、NSX-Tと、Pivotal Container Service(PKS)とOpenShiftなどのコンテナベースのCaaS/PaaSプラットフォームとのインテグレーションも提供します。
- Nuageは、Kubernetes Podと非Kubernetes環境間で可視化とセキュリティモニタリングを使用してポリシーベースのネットワークを提供するSDNプラットフォームです。
- Romanaは、NetworkPolicy APIもサポートするPodネットワーク向けのL3のネットワークソリューションです。
- Spiderpoolは、Kubernetes向けのアンダーレイおよびRDMAネットワークソリューションです。 Spiderpoolは、ベアメタル、仮想マシン、パブリッククラウド環境でサポートされています。
- Terwayは、AlibabaCloudのVPCおよびECSネットワーク製品をベースとしたCNIプラグインの一式です。 AlibabaCloud環境でネイティブVPCネットワーキングとネットワークポリシーを提供します。
- Weave Netは、ネットワークパーティションの両面で機能し、外部データベースを必要とせずに、ネットワークとネットワークポリシーを提供します。
サービスディスカバリ
可視化と制御
- DashboardはKubernetes向けのダッシュボードを提供するウェブインターフェースです。
- Headlampは、拡張可能なKubernetesのUIです。 クラスター内にデプロイすることや、デスクトップアプリケーションとして使用することができます。
インフラストラクチャ
- KubeVirtは仮想マシンをKubernetes上で実行するためのアドオンです。 通常、ベアメタルのクラスターで実行します。
- node problem detectorはLinuxノード上で動作し、システムの問題をEventまたはノードのConditionとして報告します。
計測
レガシーなアドオン
いくつかのアドオンは、廃止されたcluster/addonsディレクトリに掲載されています。
よくメンテナンスされたアドオンはここにリンクしてください。 PRを歓迎しています。
15 - 協調的リーダー選出
More information about this feature
To use this feature, you (or a cluster administrator) will need to enable the CoordinatedLeaderElection feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Kubernetes 1.36には、コントロールプレーンコンポーネントが 協調的リーダー選出 により、特定の戦略でリーダーを選択できるようにするベータ機能が含まれています。
これは、クラスターアップグレード中のKubernetesバージョンスキュー制約を満たすのに有用です。
現在、唯一の組み込まれたリーダー選択戦略はOldestEmulationVersionで、最も低いエミュレートバージョンを持つリーダーを優先し、次にバイナリバージョン、次に作成タイムスタンプの順で選択します。
協調的リーダー選出の有効化
APIサーバーを起動する際に、CoordinatedLeaderElectionフィーチャーゲートが有効になっており、coordination.k8s.io/v1beta1 APIグループも有効になっていることを確認してください。
これは、--feature-gates="CoordinatedLeaderElection=true"フラグと--runtime-config="coordination.k8s.io/v1beta1=true"フラグを設定することで実行できます。
コンポーネントの設定
CoordinatedLeaderElectionフィーチャーゲートを有効にし、かつcoordination.k8s.io/v1beta1 APIグループを有効にしている場合、互換性のあるコントロールプレーンコンポーネントは、必要に応じてLeaseCandidateおよびLease APIを自動的に使用してリーダーを選出します。
Kubernetes 1.36では、フィーチャーゲートとAPIグループが有効になっている場合、2つのコントロールプレーンコンポーネント(kube-controller-managerとkube-scheduler)が協調的リーダー選出を自動的に使用します。