ノードとコントロールプレーン間の通信

本ドキュメントは、APIサーバーとKubernetesクラスター間の通信経路をまとめたものです。 その目的は、信頼できないネットワーク上(またはクラウドプロバイダー上の完全なパブリックIP)でクラスターが実行できるよう、ユーザーがインストールをカスタマイズしてネットワーク構成を強固にできるようにすることです。

ノードからコントロールプレーンへの通信

Kubernetesには「ハブアンドスポーク」というAPIパターンがあります。ノード(またはノードが実行するPod)からのすべてのAPIの使用は、APIサーバーで終了します。他のコントロールプレーンコンポーネントは、どれもリモートサービスを公開するようには設計されていません。APIサーバーは、1つ以上の形式のクライアント認証が有効になっている状態で、セキュアなHTTPSポート(通常は443)でリモート接続をリッスンするように設定されています。 特に匿名リクエストサービスアカウントトークンが許可されている場合は、1つ以上の認可形式を有効にする必要があります。

ノードは、有効なクライアント認証情報とともに、APIサーバーに安全に接続できるように、クラスターのパブリックルート証明書でプロビジョニングされる必要があります。適切なやり方は、kubeletに提供されるクライアント認証情報が、クライアント証明書の形式であることです。kubeletクライアント証明書の自動プロビジョニングについては、kubelet TLSブートストラップを参照してください。

APIサーバーに接続したいPodは、サービスアカウントを利用することで、安全に接続することができます。これにより、Podのインスタンス化時に、Kubernetesはパブリックルート証明書と有効なBearerトークンを自動的にPodに挿入します。 kubernetesサービス(デフォルトの名前空間)は、APIサーバー上のHTTPSエンドポイントに(kube-proxy経由で)リダイレクトされる仮想IPアドレスで構成されます。

また、コントロールプレーンのコンポーネントは、セキュアなポートを介してAPIサーバーとも通信します。

その結果、ノードやノード上で動作するPodからコントロールプレーンへの接続は、デフォルトでセキュアであり、信頼されていないネットワークやパブリックネットワークを介して実行することができます。

コントロールプレーンからノードへの通信

コントロールプレーン(APIサーバー)からノードへの主要な通信経路は2つあります。 1つ目は、APIサーバーからクラスター内の各ノードで実行されるkubeletプロセスへの通信経路です。 2つ目は、APIサーバーの プロキシー 機能を介した、APIサーバーから任意のノード、Pod、またはサービスへの通信経路です。

APIサーバーからkubeletへの通信

APIサーバーからkubeletへの接続は、以下の目的で使用されます:

  • Podのログの取得。
  • 実行中のPodへのアタッチ(通常はkubectlを使用)。
  • kubeletのポート転送機能の提供。

これらの接続は、kubeletのHTTPSエンドポイントで終了します。デフォルトでは、APIサーバーはkubeletのサービング証明書を検証しないため、接続は中間者攻撃の対象となり、信頼されていないネットワークやパブリックネットワークを介して実行するのは安全ではありません

この接続を検証するには、--kubelet-certificate-authorityフラグを使用して、kubeletのサービング証明書を検証するために使用するルート証明書バンドルを、APIサーバーに提供します。

それができない場合は、信頼できないネットワークやパブリックネットワークを介した接続を回避するため、必要に応じてAPIサーバーとkubeletの間でSSHトンネルを使用します。

最後に、kubelet APIを保護するために、Kubelet認証/認可を有効にする必要があります。

APIサーバーからノード、Pod、サービスへの通信

APIサーバーからノード、Pod、またはサービスへの接続は、デフォルトで平文のHTTP接続になるため、認証も暗号化もされません。API URL内のノード、Pod、サービス名にhttps:を付けることで、セキュアなHTTPS接続を介して実行できますが、HTTPSエンドポイントから提供された証明書を検証したり、クライアント認証情報を提供したりすることはありません。そのため、接続の暗号化はされますが、完全性の保証はありません。これらの接続を、信頼されていないネットワークやパブリックネットワークを介して実行するのは、現在のところ安全ではありません

SSHトンネル

Kubernetesは、コントロールプレーンからノードへの通信経路を保護するために、SSHトンネルをサポートしています。この構成では、APIサーバーがクラスター内の各ノードへのSSHトンネルを開始(ポート22でリッスンしているSSHサーバーに接続)し、kubelet、ノード、Pod、またはサービス宛てのすべてのトラフィックをトンネル経由で渡します。 このトンネルにより、ノードが稼働するネットワークの外部にトラフィックが公開されないようになります。

Konnectivityサービス

FEATURE STATE: Kubernetes v1.18 [beta]

SSHトンネルの代替として、Konnectivityサービスは、コントロールプレーンからクラスターへの通信に、TCPレベルのプロキシーを提供します。Konnectivityサービスは、コントロールプレーンネットワークのKonnectivityサーバーと、ノードネットワークのKonnectivityエージェントの、2つの部分で構成されています。 Konnectivityエージェントは、Konnectivityサーバーへの接続を開始し、ネットワーク接続を維持します。 Konnectivityサービスを有効にすると、コントロールプレーンからノードへのトラフィックは、すべてこの接続を経由するようになります。

Konnectivityサービスのセットアップに従って、クラスターにKonnectivityサービスをセットアップしてください。