手当たり次第に書くんだ

飽きっぽいのは本能

OpenShift を知ると Kubernetes が分かるのは半分正解 – IP アドレス設計から見る製品と Kubernetes の境界

OpenShift を学ぶことで、Kubernetes への理解が深まることは間違いありません。認証、ネットワーク、ストレージ、監視、Operator、ノード管理、アップグレードなどが統合されており、Kubernetes を実際の業務基盤として成立させるために何が必要なのかが見えるためです。

一方で、OpenShift を知ることと、Kubernetes そのものを知ることは同じではありません。OpenShift では、多くの技術選択と設計判断が Red Hat によって済ませられています。そのため、利用者が内部アーキテクチャを細かく知らなくても、一定水準の基盤を構築・運用できます。これは製品として当然の価値ですが、OpenShift の標準構成を Kubernetes 本体の仕様と誤認する原因にもなります。

この違いは、IP アドレス設計を見ると分かりやすくなります。

参考
書籍
参考書籍

Kubernetes 完全ガイド 第 2 版

Kubernetes のリソース、ネットワーク、運用観点を体系的に確認したい場合の参考書籍です。価格や在庫はリンク先で確認してください。

Amazon で見る

このリンクは Amazon アソシエイトリンクです。

Kubernetes 本体には製品固有の予約 CIDR がない

Kubernetes クラスターでは、主に Node ネットワーク、Pod CIDR、Service CIDR、外部ネットワークを扱います。Kubernetes 本体が要求しているのは、Node、Pod、Service に対して重複しないアドレス範囲を割り当て、それぞれの役割に応じて整合性を保つことです。

アドレス空間主な用途主に関係する要素
Node ネットワークKubernetes ノード自身の通信kubelet、API Server、CNI、クラウドコントローラー
Pod CIDRPod に割り当てる IP アドレスCNI、IPAM、ノードごとの Pod 配置
Service CIDRClusterIP などの仮想 IP アドレスAPI Server、kube-proxy または代替実装
外部ネットワーク利用者、既存システム、外部ロードバランサーとの通信Ingress、Gateway、LoadBalancer、ルーティング

重要なのは、Kubernetes 本体が特定のプライベートアドレスを内部利用として固定的に予約しているわけではないことです。kubeadm では Service CIDR の例として 10.96.0.0/12 がよく使われますが、この範囲は Kubernetes に固定された予約アドレスではありません。構築時に別の CIDR を指定できます。

Pod CIDR についても同様です。たとえば、Pod CIDR に 10.193.0.0/21、Service CIDR に 10.201.0.0/21、Node ネットワークに 172.17.32.0/24 を使う、といった設計は可能です。必要なサイズと既存ネットワークとの重複を考慮し、設計者がアドレスを選択できます。

したがって、ネイティブ Kubernetes には OpenShift のような「この CIDR は製品内部で使うため避ける」という製品標準の内部サブネット制約がない、という理解はおおむね正しいと言えます。ただし、それは Kubernetes にネットワーク上の制約がないという意味ではありません。

Kubernetes 本体が持つのはアドレスの種類と整合性に関する制約

Kubernetes の制約は、特定のアドレス範囲よりも、各 CIDR の役割と関係にあります。Pod CIDR をノード単位に分割する構成では、クラスター全体の Pod CIDR と、ノードへ割り当てるプレフィックス長から、収容可能なノード数と 1 ノードあたりの Pod アドレス数が決まります。

Cluster Pod CIDRノード単位分割数1 ブロックのアドレス数
10.193.0.0/21/248256
10.193.0.0/21/2516128
10.193.0.0/21/263264

Pod CIDR の設計では、クラスター全体のノード数と 1 ノードあたりの Pod 数を同時に考える必要があります。小さすぎる CIDR を選ぶと、ノード追加や Pod 増加の余地がなくなります。大きすぎる CIDR を選ぶと、既存ネットワークや他クラスターとの重複管理が難しくなります。

Service CIDR も、単なる任意の仮想アドレスではありません。Service IP は単一のホストが直接応答する IP アドレスではなく、kube-proxy や代替実装がノード上でパケットを捕捉し、適切なバックエンドへ転送します。そのため、Service CIDR と既存ネットワークが重複すると、外部ネットワークへ送るつもりの通信が、ノード上で Kubernetes Service 向けの通信として処理される可能性があります。

また、構築後に Service CIDR を変更する作業は、API Server だけで完結しません。Kubernetes では ServiceCIDR リソースが導入されていますが、ServiceCIDR の cidrs は immutable とされており、既存 Service、kube-proxy または代替実装、DNS、kubernetes.default Service なども含めて考える必要があります。ネイティブ Kubernetes ではアドレスを選べますが、後から容易に変更できるとは限りません。

実際の制約は CNI を選択した時点で具体化する

Kubernetes 本体だけでは、ノードをまたぐ Pod 間通信は完成しません。実際のクラスターでは、Calico、Cilium、OVN-Kubernetes、クラウドプロバイダーの CNI など、何らかのネットワーク実装を選択します。

稼働している Kubernetes のネットワーク構成は、Kubernetes 本体に CNI、IPAM、Service 転送実装、Ingress または Gateway、LoadBalancer 実装、Underlay ネットワークを組み合わせたものです。Kubernetes 本体に製品固有の予約 CIDR がなくても、選択した CNI や IPAM が内部ネットワークやプレフィックスに関する制約を持つことはあります。

ここで、OpenShift の OVN-Kubernetes と Calico の違いが分かりやすい例になります。

OpenShift では OVN-Kubernetes の内部構造にもアドレスが必要になる

OpenShift では、OVN-Kubernetes が標準のネットワークプロバイダーとして組み込まれています。OVN-Kubernetes は、単に Pod へ IP アドレスを割り当てるだけではありません。OVN 上に論理スイッチ、論理ルーター、ゲートウェイルーターなどを構成し、クラスター内の通信を実現します。

その内部トポロジーにも IP アドレスが必要です。OpenShift Container Platform 4.20 のドキュメントでは、OVN-Kubernetes の内部 IP アドレスサブネットとして Join subnet、Transit subnet、Masquerade subnet が説明されています。

内部サブネット主な役割IPv4 デフォルト値
Join subnetゲートウェイルーターと分散ルーターの接続100.64.0.0/16
Transit subnetノードやゾーンをまたぐ東西通信100.88.0.0/16
Masquerade subnetHairpin 通信などにおけるアドレス衝突の回避169.254.0.0/17

これらは Pod CIDR や Service CIDR とは別の、OVN-Kubernetes 内部の論理ネットワークで使用するアドレスです。クラスター内の他の CIDR だけでなく、接続する既存インフラとも重複させてはいけません。

なお、これらの値は完全に変更不能な予約アドレスではありません。OpenShift では、既存ネットワークとの重複を避けるため、Join、Transit、Masquerade の内部サブネットを変更できます。固定されているのは必ずしもデフォルト CIDR そのものではなく、OVN-Kubernetes のアーキテクチャ上、これらの内部ネットワークが必要になることです。

Calico の制約は内部ネットワーク予約より IPAM の分割単位に現れる

Calico では、OpenShift の OVN-Kubernetes と同じ形の Join subnet や Transit subnet が標準で必要になるわけではありません。Calico IPAM では、Pod へ割り当てるアドレス範囲を IPPool として定義し、IPPool を allocation block へ分割してノードへ割り当てます。

項目意味
IPv4 IPPool10.193.0.0/21Pod に使用する IPv4 アドレス範囲
IPv4 blockSize/26Calico IPAM がノードへ割り当てる IPv4 ブロック単位
IPv6 IPPoolfd00:10:193::/64Pod に使用する IPv6 アドレス範囲
IPv6 blockSize/122Calico IPAM がノードへ割り当てる IPv6 ブロック単位

Calico のデフォルト block size は、IPv4 が /26、IPv6 が /122 です。どちらも 64 アドレス分のブロックになります。ノード上のワークロードへアドレスをまとめて割り当てることで、ホスト間や BGP ピアへ広告する経路数を抑える構造です。

アドレスファミリーblockSize の許容範囲デフォルト
IPv4/20 から /32/26
IPv6/116 から /128/122

ここで注意したいのは、Calico の /122 がノード上の IPv6 LAN プレフィックスを意味するわけではないことです。これは Calico IPAM が Pod アドレスを管理し、経路を集約するための内部的な割り当て単位です。

また、IPPool 全体の CIDR は、少なくとも一つの allocation block を収容できる大きさでなければなりません。デフォルトの blockSize: 122 を使う場合、/124 の IPv6 IPPool は /122 ブロックを収容できないため成立しません。Calico IPPool は IPv4 の 169.254.0.0/16、IPv6 の fe80::/10 とも重複できません。これも制約ですが、OpenShift における大規模な内部論理ネットワーク用 CIDR とは性質が異なります。

同じ CIDR 制約でも発生理由が異なる

OpenShift と Calico を単純に比較すると、どちらにも CIDR やプレフィックスの制約があります。しかし、その理由は同じではありません。

対象制約の主な理由
Kubernetes の Pod CIDRPod 数とノード数を収容するため
Kubernetes の Service CIDRService の仮想 IP を管理するため
Calico の block sizeIPAM と経路集約の単位を定めるため
OVN-Kubernetes の Join subnet論理ルーター間を接続するため
OVN-Kubernetes の Transit subnetノードやゾーンをまたぐ転送のため
OVN-Kubernetes の Masquerade subnetNAT や Hairpin 通信の処理に使うため

Calico では、主として Pod アドレスをどの単位でノードへ割り当て、どの単位で経路として扱うかが制約になります。OVN-Kubernetes では、Pod アドレスとは別に、内部の論理ネットワークを成立させるためのアドレス空間が必要になります。どちらが優れているという話ではなく、採用しているネットワークアーキテクチャが異なるため、制約の現れ方も異なります。

ネイティブ Kubernetes には制約がないのではなく、制約を選択できる

ネイティブ Kubernetes について、自由度が高いと表現されることがあります。これは間違いではありませんが、何でも自由に設計できるというより、CNI、IPAM、Service 実装、Ingress、LoadBalancer、ストレージなどを自分たちで選択できるという意味です。

選択した構成には、それぞれ固有の制約があります。Kubernetes と Calico、Kubernetes と Cilium、Kubernetes と OVN-Kubernetes、Kubernetes とクラウド CNI は、同じ Kubernetes API を利用していても、必要な CIDR、Pod IP の払い出し方法、経路広告、カプセル化、NAT、Underlay との関係が異なります。

観点ネイティブ KubernetesOpenShift
CNI の選択設計者が選択する製品標準がある
内部 CIDR選択した実装に依存する製品仕様として明示される
デフォルト値インストーラーや構成ごとに異なる製品として統一される
設計責任利用組織が広く負う製品側が大部分を引き受ける
変更方法構成に応じて利用者が設計するOperator や製品手順に従う
サポート境界自分たちで定義するベンダーのサポート条件がある

ネイティブ Kubernetes には制約がないのではありません。どの制約を持つ構成を採用するかを、設計者が選択しているのです。OpenShift では、その選択の大部分を Red Hat が済ませ、検証し、製品仕様として提供しています。

OpenShift を知ると Kubernetes が分かるのはなぜ半分なのか

OpenShift を知ることで、Kubernetes を業務基盤として運用するために必要な要素を理解できます。一方で、OpenShift では多くの設計判断が製品内部に隠蔽されています。

通常の構築や運用では、Join subnet がなぜ必要なのか、OVN の論理ルーターがどのように接続されているのか、Operator がどのリソースを監視し、どの状態へ収束させているのかを詳しく知らなくても利用できます。これは欠点ではなく、製品の価値です。

しかし、既存ネットワークとのアドレス重複、特殊なルーティング、CNF、Multus、SR-IOV、DPDK、性能問題、障害解析などに踏み込むと、抽象化の下にあるアーキテクチャが表面化します。このとき、OpenShift の操作方法だけを知っていても十分ではありません。

必要なのは、Kubernetes 本体の仕様なのか、CNI のアーキテクチャに由来するのか、OpenShift 独自の統合や Operator による制御なのか、Linux、OVS、OVN など下位レイヤーの挙動なのか、製品上変更可能なのか、技術的には可能でもサポート対象外なのかを分けて考えることです。

OpenShift を知ると、完成された Kubernetes 基盤がどのようなものか分かります。一方、ネイティブ Kubernetes を設計・構築すると、その完成品を成立させるために、どのような選択と統合作業が必要なのかが分かります。

まとめ

Kubernetes 本体には、OpenShift の OVN-Kubernetes が使用するような製品標準の内部サブネットは基本的にありません。Kubernetes 本体が定義しているのは、Pod、Service、Node に必要なアドレス空間と、それらを重複させないこと、さらにクラスター規模に応じた CIDR サイズや分割に関する条件です。

実際の制約は、CNI を選択した段階で具体化します。Calico では、IPPool と allocation block の関係、block size、経路集約といった IPAM 上の制約として現れます。OVN-Kubernetes では、Join、Transit、Masquerade といった内部論理ネットワーク用のアドレス空間として現れます。

OpenShift は Kubernetes に無意味な制約を追加しているのではありません。Kubernetes を一つの製品として成立させるために、ネットワークアーキテクチャを選択し、その結果として生じる制約を製品仕様として明示しています。

この意味で、「OpenShift を知ると Kubernetes が分かる」という説明は半分正解です。より正確には、OpenShift を知ることで、Kubernetes を製品として成立させる一つの設計回答が分かる、と表現するのが適切だと考えます。

参考資料

関連記事

OpenShift を知ると Kubernetes が分かるのは半分正解 – IP アドレス設計から見る製品と Kubernetes の境界

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る