Member-only story
図解でわかるKubernetesのネットワーキング【第3回】
今回は、Kubernetes Networkingについてのシリーズの第3回目です。まだパート1とパート2を読んでいない方は、まずそちらの記事をお読みください。
Cluster dynamics
Kubernetesや一般的な分散システムは常に変化するダイナミックな性質を持っているため、ポッド(およびその結果としてのIP)は常に変化しています。その理由は、必要なローリングアップデートやスケーリングイベントから、予測できないポッドやノードのクラッシュまで多岐にわたります。このため、PodのIPは、通信に直接使用するには信頼性に欠けます。
Kubernetes Servicesを入力します。Kubernetes Servicesは、エンドポイントとしてのPod IP群(ラベルセレクタで識別)を持つ仮想IPです。これらは仮想ロードバランサーとして機能し、バックエンドのPod IPが変更されてもIPは同じままです。
バーチャルIPの実装は、iptables(最近のバージョンではIPVSを使用するオプションがありますが、それはまた別の議論になります)のルールで、Kubernetesのコンポーネントであるkube-proxyによって管理されています。この名前は今では誤解を招く恐れがあります。v1.0以前はプロキシとして動作していましたが、カーネルスペースとユーザースペースの間で常にコピーを行うため、かなりのリソースを消費し、速度も低下しました。今では、Kubernetesの他の多くのコントローラと同様、単なるコントローラであり、apiサーバのエンドポイントの変更を監視し、それに応じてiptablesのルールを更新します。
このiptablesのルールにより、サービスIP宛のパケットは必ずDNAT化(DNAT=Destination Network Address Translation)され、宛先IPがサービスIPから、iptablesがランダムに選んだエンドポイント(ポッドIP)に変更されます。これにより、負荷がバックエンドのポッドに均等に分散されるようになっています。
このDNATが発生すると、この情報はLinuxの接続トラッキングテーブルであるconntrackに格納されます(iptablesが行った5-tuple translations(protocol, srcIP, srcPort, dstIP, dstPort)が格納されます)。これは、応答が戻ってきたときに、DNATを解除する、つまりソースIPをPod IPからService IPに変更するためです。こうなっているため、クライアントは、舞台裏でパケットフローがどのように処理されているかを知ることはできません。
そのため、Kubernetesのサービスを利用することで、(ポートをエンドポイントにリマップできるので)競合することなく同じポートを使用することができます。これにより、サービスの発見が非常に簡単になります。内部D…