はい、承知いたしました。KubernetesにおけるCalicoの仕組みと役割について、約5000語の詳細な解説記事を作成します。図解の概念を盛り込みながら、やさしく解説することを心がけます。
【図解】Calicoとは?Kubernetesネットワークの仕組みと役割をやさしく解説
コンテナ技術の普及に伴い、Kubernetesのようなコンテナオーケストレーションシステムは、現代のアプリケーション開発において不可欠な存在となりました。Kubernetesの強力な機能の一つに、コンテナ(Pod)間のネットワーク通信の管理があります。しかし、複数のノードに分散配置された無数のPodがどのように相互に通信し、外部とやり取りしているのか、その仕組みは複雑に感じられるかもしれません。
ここで重要となるのが、CNI(Container Network Interface)と呼ばれるインターフェース仕様に基づいたネットワークプラグインです。そして、CNIプラグインの中でも特に広く利用され、堅牢かつ高機能な選択肢として知られているのが「Calico」です。
この記事では、Calicoが一体何者なのか、なぜKubernetesネットワークにおいて重要なのか、そしてその複雑な仕組みがどのように成り立っているのかを、図解のイメージを交えながら徹底的に、かつやさしく解説していきます。Calicoの基本原理から、強力なネットワークポリシー機能、そして導入・運用時の注意点まで、網羅的に理解できる内容を目指します。
Calicoの導入を検討している方、Kubernetesネットワークの理解を深めたい方、あるいは単にCalicoに興味を持たれた全ての方にとって、この記事がCalicoを深く理解するための手助けとなれば幸いです。
さあ、Calicoの世界へ一緒に踏み込んでいきましょう。
1. はじめに:なぜコンテナネットワークが重要なのか?
コンテナは、アプリケーションとその依存関係をパッケージ化し、隔離された環境で実行するための技術です。Dockerなどのコンテナランタイムによって生成されるコンテナは、デフォルトではそれぞれが独立したネットワークスタックを持つこともありますが、複数のコンテナが協調して動作するマイクロサービスアーキテクチャなどでは、コンテナ間の通信が不可欠となります。
1.1. 単一ホスト内のコンテナ間通信
まず、比較的シンプルなケースとして、同じ物理ホストまたは仮想マシン上で実行されている複数のコンテナ間の通信を考えてみましょう。
一つのホスト上でコンテナを起動すると、通常はコンテナエンジン(例:Docker)が内部的な仮想ネットワークを構築します。これは、仮想ブリッジ(例:docker0
)と仮想NIC(vethペア)を組み合わせることで実現されます。各コンテナはvethペアの一端を持ち、もう一端が仮想ブリッジに接続されます。これにより、同じ仮想ブリッジに接続されたコンテナ同士は、あたかも同じスイッチに接続されているかのように通信できます。
図解イメージ:単一ホスト内のコンテナネットワーク
* ホストOS
* 仮想ブリッジ (docker0
)
* vethペア (片側がコンテナ、片側が仮想ブリッジに接続)
* コンテナA (eth0 – vethAペア)
* コンテナB (eth0 – vethBペア)
* 矢印:コンテナA -> vethA -> docker0 -> vethB -> コンテナB
この単一ホスト内の通信は、Linuxカーネルのネットワーク機能によって実現されるため、比較的シンプルで高速です。
1.2. 複数ホスト間のコンテナ間通信の課題
しかし、Kubernetesのようなコンテナオーケストレーションシステムでは、Pod(Kubernetesにおけるデプロイの最小単位であり、一つ以上のコンテナを含む)は複数の異なるホスト(ノード)上に分散配置されます。この場合、単一ホスト内のネットワークだけではPod間通信を実現できません。ノードを跨いだPod間の通信を実現するためには、特別なネットワークソリューションが必要になります。
KubernetesのPodネットワークには、いくつかの要件があります。
- フラットなネットワーク: 各Podは独自のIPアドレスを持ち、他のPodとIPアドレスを使って直接通信できる必要があります。NAT(Network Address Translation)なしで通信できることが理想とされます。
- 重複しないIPアドレス: クラスタ内の全てのPodに割り当てられるIPアドレスは一意である必要があります。
- 外部との通信: Podはクラスタ外部(インターネットなど)と通信できる必要があります。
- サービスへのアクセス: Podは、クラスタ内のサービス(Serviceオブジェクトによって抽象化された、Pod群への安定したアクセスポイント)にアクセスできる必要があります。
- ネットワークポリシー: 特定のPod間の通信を許可/拒否するためのセキュリティ機能が必要です。
これらの要件を満たすために、様々なコンテナネットワークインターフェース(CNI)プラグインが開発されました。Calicoもその一つです。
1.3. オーバーレイ vs アンダーレイネットワーク
複数ホスト間のコンテナ通信を実現するアプローチは、大きく分けて二つあります。
-
オーバーレイネットワーク: 既存のアンダーレイネットワーク(物理的なネットワークインフラ)の上に、仮想的なネットワークを構築する方式です。VXLANやGeneveといったトンネリング技術がよく使われます。各ノードはトンネルエンドポイントとして機能し、コンテナのIPパケットをカプセル化してアンダーレイネットワーク上を転送します。受信側のノードでカプセル化を解除し、目的のコンテナにパケットを届けます。
- メリット: 既存の物理ネットワーク構成に依存しにくい。L2接続がない環境でもPod間通信が可能。
- デメリット: カプセル化・非カプセル化のオーバーヘッドが生じる可能性がある。MTUの問題が発生しやすい。アンダーレイネットワークのトラブルシューティングとは別に、オーバーレイネットワーク自体のトラブルシューティングが必要になる。
- 代表例: Flannel (VXLAN), Weave Net
-
アンダーレイネットワーク: 既存の物理ネットワークを最大限に活用し、コンテナIPアドレスをアンダーレイネットワーク上で直接ルーティングする方式です。各ノードが、自身のホスト上で実行されているコンテナIPへの経路情報をアンダーレイネットワークに対して広報します。
- メリット: シンプルなルーティング、カプセル化のオーバーヘッドがないためパフォーマンスが高い傾向がある。アンダーレイネットワークのツールを使ってトラブルシューティングが可能。
- デメリット: アンダーレイネットワークがコンテナIPアドレスのルーティングに対応している必要がある(通常はBGPなどのルーティングプロトコルを使用)。アンダーレイネットワークの設計に影響を受ける場合がある。
- 代表例: Calico (BGP), Macvlan
Calicoは、主にこの「アンダーレイネットワーク」のアプローチを採用しており、BGP(Border Gateway Protocol)を使ってコンテナIPの経路情報を交換することで、シンプルかつ高性能なルーティングを実現します。ただし、全ての環境でアンダーレイネットワークのアプローチが使えるわけではないため、CalicoはIP-in-IPやVXLANを使ったオーバーレイモードもサポートしています。
1.4. ネットワークポリシーの必要性
Pod間の通信を実現するだけでなく、セキュリティの観点から「どのPodがどのPodと通信できるか」を制御することも非常に重要です。マイクロサービスアーキテクチャでは、多数のサービスが相互に通信しますが、必要最低限の通信のみを許可し、それ以外の通信をブロックすることで、攻撃対象領域を減らし、セキュリティリスクを低減できます。
Kubernetesには、NetworkPolicyという標準リソースがあり、Podセレクターを使って送信元/宛先Podを指定し、特定のポート/プロトコルでの通信を許可するルールを定義できます。CNIプラグインは、このNetworkPolicyリソースの実装を提供する必要があります。
Calicoは、このKubernetes NetworkPolicyを実装するだけでなく、より高度で柔軟なネットワークポリシー機能(Calico NetworkPolicy)を提供しており、これがCalicoの大きな特徴の一つとなっています。
これらの課題と要件を踏まえた上で、Calicoがどのように機能するのかを見ていきましょう。
2. Calicoとは?概要と特徴
Calicoは、Tigera社によって開発・管理されている、オープンソースのコンテナネットワークソリューションです。Kubernetes環境においては、CNIプラグインとして機能し、Pod間のネットワーク接続とネットワークポリシーの管理を行います。また、Kubernetesだけでなく、OpenShift、Docker Swarm、Mobyなどの他のコンテナプラットフォームや、ベアメタル、VM環境でも利用可能です。
Calicoの主要な特徴は以下の通りです。
- シンプルで高性能なルーティング: 主にBGPを使用したアンダーレイネットワークを活用し、シンプルなルーティングと高いパフォーマンスを実現します。カプセル化のオーバーヘッドが少ないため、ネイティブに近いネットワーク速度を提供できます。
- 強力で柔軟なネットワークポリシー: Kubernetes標準のNetworkPolicyだけでなく、より詳細で表現力豊かな独自のCalico NetworkPolicyを提供します。ポート、プロトコル、Podセレクター、Namespaceセレクター、ServiceAccountセレクターなどに加えて、グローバルなポリシーや、ポリシー適用順序の制御などが可能です。
- 幅広い環境への対応: ベアメタル、VM、パブリッククラウド(AWS, Azure, GCPなど)といった様々なインフラ環境に対応しています。アンダーレイネットワークが使えない環境のために、IP-in-IPやVXLANによるオーバーレイモードも選択できます。
- 優れたスケーラビリティ: 数万ノード、数十万Podといった大規模なクラスタでも動作するように設計されています。
- データプレーンの選択肢: ネットワークポリシーの実装に、Linuxの標準機能であるiptablesに加え、高性能なBPF(Berkeley Packet Filter)を選択できます。BPFデータプレーンは、特に高負荷環境でのポリシー処理性能を向上させます。
2.1. 他のCNIプラグインとの比較(簡単な触れ)
Calico以外にも、Kubernetes向けのCNIプラグインは多数存在します。代表的なものとしてはFlannel、Weave Net、Ciliumなどがあります。
- Flannel: シンプルなオーバーレイネットワーク(VXLAN)を提供するCNIです。設定が容易で、小規模なクラスタや学習用途によく使われますが、ネットワークポリシー機能は限定的です。
- Weave Net: VXLANベースのオーバーレイネットワークと、独自のネットワークポリシー機能を提供します。分散データストアを内蔵している点が特徴です。
- Cilium: BPFを積極的に活用し、高性能なネットワークポリシーとセキュリティ機能を提供します。L7プロトコル(HTTPなど)ベースのポリシーもサポートしています。Calicoと同様に高性能・高機能なCNIとして比較検討されることが多いです。
Calicoは、シンプルで高性能なルーティング(アンダーレイ)と、非常に強力で柔軟なネットワークポリシー機能のバランスが取れている点が大きな強みと言えます。特に、セキュリティを重視する環境や、複雑なネットワークポリシー要件がある場合にCalicoが選ばれることが多いです。また、BGPを使うことで、既存のネットワークインフラとの連携が比較的容易な場合もあります。
3. Calicoの仕組み – 基本原理
CalicoがどのようにKubernetesクラスタ内でPodネットワーキングを実現しているのか、その基本的な仕組みを見ていきましょう。Calicoの仕組みは、主に以下の要素によって構成されています。
- アンダーレイネットワークとBGPルーティング: Pod IPへの経路情報を交換し、ノード間のPod通信を実現します。
- vRouter (Felix): 各ノード上で動作し、Kubernetes APIやCalicoデータストアからネットワーク構成やポリシー情報を取得し、Linuxカーネルのネットワークスタック(ルーティングテーブル、iptables/BPF)を設定します。
- IPアドレス管理 (IPAM): クラスタ内のPodに一意なIPアドレスを割り当て、管理します。
- データストア: Calico自身の構成情報、IPAM情報、ネットワークポリシーなどを保存します。Kubernetesクラスタでは、通常Kubernetes API(etcdのフロントエンド)をデータストアとして利用します。
図解イメージ:Calicoの主要コンポーネント概観
* Node 1, Node 2, …
* 各ノード上に calico/node
ポッド(中にFelixとBGPクライアント)
* Kubernetes API Server/etcd (データストア)
* 矢印:calico/node
-> Kubernetes API (情報の読み書き)
* 矢印:calico/node
<-> calico/node
(BGPピアリングによる経路情報交換)
* calico/kube-controllers
ポッド -> Kubernetes API (Calico固有リソースの監視など)
* ホストカーネル(ルーティングテーブル、iptables/BPF) – Felixが操作することを示す
3.1. BGPによるルーティング
Calicoのデフォルトかつ推奨されるルーティング方式は、BGP(Border Gateway Protocol)を使用することです。BGPは、主にインターネット上のAS(Autonomous System、自律システム)間で経路情報を交換するために使用される標準的なルーティングプロトコルですが、データセンター内部でも利用されることがあります(iBGPなど)。
Calicoでは、各KubernetesノードがBGPスピーカーとして動作します。各ノードのCalicoコンポーネント(calico/node
Pod内のBGPクライアント)は、自身のノード上で実行されているPodに割り当てられたIPアドレスの範囲(CIDRブロック)を、他のノードのBGPスピーカーに広報します。
例えば、node-A
にpod-X
(IP: 10.42.1.5
)があり、node-B
にpod-Y
(IP: 10.42.2.8
)があるとします。
1. node-A
のCalicoは、自身のノードのPod IP範囲(例えば10.42.1.0/24
)をnode-B
のCalicoにBGPで広報します。
2. node-B
のCalicoは、この情報を受け取ると、10.42.1.0/24
へのトラフィックをnode-A
に転送するように、自身のLinuxカーネルのルーティングテーブルを設定します。
3. 同様に、node-B
のCalicoは自身のPod IP範囲(例えば10.42.2.0/24
)をnode-A
に広報し、node-A
のルーティングテーブルが更新されます。
これにより、pod-X
がpod-Y
にパケットを送信しようとすると、パケットはまずnode-A
のカーネルに到達します。カーネルのルーティングテーブルには10.42.2.0/24
へのネクストホップとしてnode-B
が設定されているため、パケットはアンダーレイネットワークを経由してnode-B
へ直接転送されます。node-B
に到達したパケットは、node-B
のカーネルによって、ローカルなPodであるpod-Y
へルーティングされます。
図解イメージ:BGPルーティングによるPod間通信
* Node A (Pod X: 10.42.1.5)
* Node B (Pod Y: 10.42.2.8)
* Node A の Calico -> Node B の Calico (BGP: “10.42.1.0/24 は私に送ってね”)
* Node B の Calico -> Node A の Calico (BGP: “10.42.2.0/24 は私に送ってね”)
* Node A のルーティングテーブル: “10.42.2.0/24 -> Node B”
* Node B のルーティングテーブル: “10.42.1.0/24 -> Node A”
* Pod X -> Node A Kernel (宛先 10.42.2.8)
* Node A Kernel -> Underlay Network -> Node B
* Node B Kernel -> Pod Y (宛先 10.42.2.8)
* 矢印:Pod X から Pod Y へのパケットの流れ
このBGPによるルーティングは、カプセル化が不要なため、低遅延かつ高スループットな通信が可能です。これが「シンプルで高性能」と言われる所以です。
3.1.1. IP-in-IP / VXLAN カプセル化
前述のBGPルーティングは、Pod IPアドレスがアンダーレイネットワーク上で直接ルーティング可能であることが前提です。しかし、データセンターネットワークによっては、ノード間の通信がレイヤ2でしか行われておらず、ノード自身のIPアドレスはルーティングできても、Podに割り当てられたプライベートなIPアドレスを直接ルーティングできない場合があります。
このような環境に対応するため、CalicoはIP-in-IPまたはVXLANによるカプセル化をサポートしています。
- IP-in-IP: PodのIPパケット全体を、送信元ノードのIPアドレスと宛先ノードのIPアドレスを持つ新しいIPパケットのペイロードとしてカプセル化します。この外側のIPパケットは、アンダーレイネットワークでルーティングされます。受信側のノードでカプセル化を解除し、内側のPod IPパケットを取り出して目的のPodに届けます。
- VXLAN: IP-in-IPと同様にトンネリング技術ですが、UDPを使用し、セグメントID(VNI)を持つ点が異なります。よりモダンで、多くのネットワーク機器がハードウェアオフロードをサポートしています。
これらのカプセル化モードを使用する場合でも、CalicoはBGPを使って、どのノードがどのPod IP範囲を持っているかという情報を交換します。ただし、その情報を使って設定されるルーティングエントリは、「Pod IP宛てのパケットは、カプセル化して対応するノードIPに送る」というものになります。
カプセル化はアンダーレイネットワークの制約を回避できる一方、パケットサイズが大きくなり、カプセル化・非カプセル化の処理オーバーヘッドが発生します。可能な限りBGPネイティブ(カプセル化なし)を使用するのが推奨されますが、環境によってはカプセル化が必要になります。
図解イメージ:IP-in-IPカプセル化によるPod間通信
* Node A (Pod X: 10.42.1.5) [Node IP: 192.168.1.10]
* Node B (Pod Y: 10.42.2.8) [Node IP: 192.168.1.11]
* Pod X (10.42.1.5) -> Node A Kernel (宛先 10.42.2.8)
* Node A Kernel (Calicoによって設定): 10.42.2.0/24 へのパケットは、宛先 192.168.1.11 に IP-in-IP カプセル化して転送。
* 元のパケット: src=10.42.1.5, dst=10.42.2.8
* カプセル化後のパケット: Outer src=192.168.1.10, Outer dst=192.168.1.11, Payload=(src=10.42.1.5, dst=10.42.2.8)
* Node A Kernel -> Underlay Network (Node IPベースでルーティング) -> Node B
* Node B Kernel: IP-in-IP パケットを受信。外側のヘッダーを剥がす。
* 内側のパケット: src=10.42.1.5, dst=10.42.2.8
* Node B Kernel -> Pod Y (宛先 10.42.2.8)
* 矢印:Pod X から Pod Y へのパケットの流れ、カプセル化/非カプセル化のステップを示す
3.2. IPアドレス管理 (IPAM)
Calicoは、クラスタ内のPodに一意のIPアドレスを割り当てるIPAM機能を提供します。CalicoのIPAMは、あらかじめ定義されたIPアドレスの範囲(IPプール)から、Podが起動するたびに自動的にIPアドレスを割り当てます。
CalicoのIPAMは、IPプールをさらに小さな単位である「ブロック」(デフォルトでは /26 サイズ、つまり64個のIPアドレスを含む)に分割して管理します。各ノードは、PodにIPアドレスを割り当てるために一つ以上のブロックを「リース」します。Podが起動すると、そのPodが属するノードがリースしているブロックの中から未使用のIPアドレスを割り当てます。Podが終了すると、そのIPアドレスは解放され、ブロックに戻されます。
図解イメージ:IPAMの仕組み
* IPプール (e.g., 10.42.0.0/16)
* IPプールが複数のブロックに分割される (e.g., 10.42.0.0/26, 10.42.0.64/26, …)
* Node A が 10.42.0.0/26 ブロックをリース
* Node B が 10.42.0.64/26 ブロックをリース
* Node A 上で Pod が起動 -> 10.42.0.0/26 から IP アドレス (e.g., 10.42.0.10) を割り当て
* Node B 上で Pod が起動 -> 10.42.0.64/26 から IP アドレス (e.g., 10.42.0.75) を割り当て
* 矢印:プールからノードへのブロックのリース、ブロックからPodへのIP割り当て
このブロックベースのIPAMは、IPアドレスの競合を防ぎつつ、IPアドレス割り当ての効率を高めます。各ノードは、自身のブロックからIPを割り当てれば良いため、クラスタ全体のデータストアに頻繁にアクセスする必要がありません。
CalicoはデフォルトのCNI IPAMプラグインとして機能しますが、必要であれば別のIPAMプラグイン(例:host-localなど)と組み合わせて使用することも可能です。
3.3. データストア
Calicoが必要とする設定情報、現在の状態(IPアドレスの割り当て状況など)、そしてネットワークポリシー定義は、データストアに保存されます。Calicoは以下の2種類のデータストアをサポートしています。
- Kubernetes APIデータストア: KubernetesクラスタでCalicoを使用する場合の標準的なオプションです。Calicoは、ConfigMap、CRD(Custom Resource Definition)などのKubernetesリソースとして情報を保存します。これにより、別途etcdクラスタを運用する必要がなく、KubernetesのツールやワークフローでCalicoの設定や状態を管理できます。
- etcdデータストア: Kubernetes APIを使用せず、Calico専用のetcdクラスタをデータストアとして使用するオプションです。Kubernetes以外の環境(Docker Swarmなど)でCalicoを使用する場合や、KubernetesのAPIをデータストアとして使いたくない場合に選択されます。
Kubernetes環境では、Kubernetes APIデータストアを使用することが一般的です。Calicoのコンポーネントは、Kubernetes APIを監視し、変更があった場合に自身の設定を動的に更新します。
4. Calicoの仕組み – 詳細解説
ここからは、Calicoの主要なコンポーネントと機能について、さらに詳しく掘り下げていきます。
4.1. vRouter (Felix)
calico/node
Podの中で最も重要なコンポーネントの一つが「Felix」です。Felixは、各Kubernetesノード上でデーモンとして動作します。Felixの主な役割は以下の通りです。
- データストア(Kubernetes API/etcd)の監視: Calicoの構成情報、IPプール情報、割り当て済みIPアドレス、そしてネットワークポリシー定義といった情報をデータストアからリアルタイムに取得します。
- ネットワークインターフェースの管理: 各ノード上で起動/停止するPodを検知し、Podに仮想ネットワークインターフェース(vethペア)を接続します。
- カーネルネットワークスタックの設定: 取得した情報に基づき、Podのネットワーク通信を適切に処理するために、Linuxカーネルのネットワークスタックを設定します。これには、以下の要素が含まれます。
- ルーティングテーブル: Pod IPアドレスへのルーティングエントリを追加します。ローカルノード上のPodへのルーティング、他のノードへのルーティング(BGPによって学習した経路を使用)などです。
- iptables/BPF: ネットワークポリシーを実装するために、Linuxファイアウォールであるiptablesや、より高性能なBPFプログラムを設定します。
- BGPピアリングの設定: 自身のノードのPod IP範囲を他のノードに広報したり、他のノードから広報された経路情報を受け取ったりするために、BGPピアリングを設定・管理します。
- ステータスレポート: 自身のノードの状態や、管理しているリソース(インターフェース、ルート、ポリシー)に関する情報をデータストアに報告します。
Felixは「vRouter」と呼ばれることがありますが、これは物理的なルーターのようにパケットのルーティングやフィルタリング(ポリシー)を行う役割を担っているためです。ただし、Felix自身がパケット転送を行うわけではなく、カーネルの機能(ルーティングテーブル、iptables/BPF)を設定することでパケット処理を実現しています。
図解イメージ:Felixの役割
* Node (Linux Kernel)
* ルーティングテーブル
* iptables/BPF チェーン
* calico/node
Pod (Felix)
* Kubernetes API Server (データストア)
* 矢印:Felix -> Kubernetes API Server (監視・情報取得、状態報告)
* 矢印:Felix -> Linux Kernel (ルーティングテーブル、iptables/BPF の設定変更)
* 矢印:Pod -> Linux Kernel (ネットワークトラフィック) – Kernel が Felix が設定したルールに基づいて処理
4.2. BGPによるルーティングの仕組み(詳細)
CalicoのBGPルーティングでは、以下の要素が関わります。
- BGPクライアント: 各
calico/node
Pod内で動作し、他のノードのBGPクライアントや、必要であれば外部のBGPルーターとピアリングを確立します。 - BGPピアリング: Calicoノードは、デフォルトではメッシュ型に他の全てのCalicoノードとピアリングを確立しようとします(ノード間の数が多くなると非効率になるため、Route Reflectorを使用する構成もあります)。または、クラスタ外部の物理/仮想ルーターとピアリングして、Calicoクラスタと外部ネットワーク間で経路情報を交換することも可能です。
- 経路情報の交換: 各ノードのBGPクライアントは、自身のノードが管理するPod IPアドレスの範囲(IPプールから割り当てられたブロック)への経路情報(ネクストホップは自身)を、ピアリングしている他のBGPスピーカーにアドバタイズします。
- ルーティングテーブルの更新: 他のノードから経路情報を受信すると、BGPクライアントはその情報をFelixに伝え、Felixがノードのカーネルルーティングテーブルを更新します。これにより、特定のPod IPアドレス(またはそのIPブロック)宛てのパケットを、そのPodが実行されているノードへ直接ルーティングするためのエントリが作成されます。
例えば、Node A (192.168.1.10
) に Pod X (10.42.1.5
) があり、Node B (192.168.1.11
) に Pod Y (10.42.2.8
) がある場合:
1. Node A の Calico BGP クライアントは、Pod X の属する IP ブロック (10.42.1.0/26
) への経路として、「ネクストホップ: 192.168.1.10
」という情報を Node B にアドバタイズします。
2. Node B の Calico BGP クライアントは、この情報を受信し、Felix に渡します。
3. Node B の Felix は、Node B のカーネルルーティングテーブルに「宛先: 10.42.1.0/26
-> ネクストホップ: 192.168.1.10
」というエントリを追加します。
4. Pod Y (10.42.2.8
) から Pod X (10.42.1.5
) へのパケットは、まず Node B のカーネルに到達します。
5. Node B のカーネルはルーティングテーブルを参照し、宛先 IP 10.42.1.5
が 10.42.1.0/26
に含まれるため、ネクストホップである 192.168.1.10
(Node A) へパケットを送信します。
6. パケットはアンダーレイネットワークを経由して Node A に到達します。
7. Node A のカーネルはパケットを受信し、宛先 IP 10.42.1.5
がローカルに接続されているインターフェース(Pod X の veth ペア)に属することを知っているため、Pod X へパケットを配信します。
このように、BGPを使うことで、各ノードはクラスタ内の全てのPod IPへの最適な経路を動的に学習し、アンダーレイネットワーク上で直接Pod間通信を実現します。
4.3. 強力なネットワークポリシー
Calicoの最も評価されている機能の一つが、その強力で柔軟なネットワークポリシーです。Calicoは、Kubernetes標準のNetworkPolicyリソースを完全にサポートするだけでなく、より高度な機能を持つ独自のCalico NetworkPolicyリソースを提供します。
Calico NetworkPolicyの主な特徴:
- 適用範囲: 特定のPodだけでなく、Namespace全体、ServiceAccount、またはクラスタ全体(GlobalNetworkPolicy)に対してポリシーを適用できます。
- マッチ条件: Kubernetes NetworkPolicyでサポートされている PodSelector, NamespaceSelector, port/protocol に加え、以下の条件を指定できます。
- ServiceAccountSelector
- 特定のインターフェース(例:
eth0
) - 特定のラベルを持つノード
- 外部IPアドレス(Ingress/Egressで特定の外部IPへのアクセスを制限)
- アクション:
Allow
(許可),Deny
(拒否),Log
(ログ記録),Pass
(次のポリシーグループへ処理を移す) といった多様なアクションを定義できます。Kubernetes標準ポリシーはAllow
のみです(デフォルトは全てDeny)。 - 適用順序 (Order): ポリシーに数値の
order
を設定することで、評価される順序を細かく制御できます。低いorder
のポリシーが優先されます。 - 双方向ルール: Ingress(着信)とEgress(送信)の両方で独立したルールを定義できます。
ネットワークポリシーは、Felixによってノードのカーネル内のiptablesルールまたはBPFプログラムとして実装されます。Pod間の通信が発生すると、カーネルは定義されたiptablesルールまたはBPFプログラムに従って、その通信を許可するか拒否するかを判断します。
図解イメージ:ネットワークポリシーの適用
* Pod A (App: frontend)
* Pod B (App: backend)
* Pod C (App: database)
* ネットワークポリシールール例:
* ルール1: app: frontend
から app: backend
への TCP 8080 を許可 (Order 100)
* ルール2: app: backend
から app: database
への TCP 3306 を許可 (Order 100)
* ルール3: デフォルトで全ての通信を Deny (Order 200)
* 矢印:Pod A -> Pod B (TCP 8080) -> 許可 (ルール1にマッチ)
* 矢印:Pod B -> Pod C (TCP 3306) -> 許可 (ルール2にマッチ)
* 矢印:Pod A -> Pod C (TCP 3306) -> 拒否 (ルール1, 2にマッチせず、ルール3で Deny)
* 各ノードの Felix がこれらのルールを iptables/BPF に変換して適用
Calico NetworkPolicyを使用することで、マイクロサービス間の複雑な通信依存関係に基づいたゼロトラストネットワークを実現できます。例えば、「決済サービスは注文サービスからのみアクセス可能」「データベースはバックエンドサービスからのみアクセス可能」といった厳格なルールを定義できます。GlobalNetworkPolicyを使えば、クラスタ全体に対するデフォルトの拒否ポリシーを定義したり、「監視ツールだけは全てのPodにSSH接続可能」といった例外ルールを定義したりすることも容易です。
4.4. IPAMの詳細(再訪)
CalicoのIPAMは、IPプールとブロックによって効率的なIPアドレス管理を実現します。
- IPプール (IPPool): Calicoのカスタムリソースです。Podに割り当てるIPアドレスの範囲をCIDR形式で定義します(例:
10.42.0.0/16
)。IPプールには、使用するカプセル化方式(none, IPIP, VXLAN)や、ノードごとのIPブロックサイズなどを指定できます。複数のIPプールを定義し、特定のPodに対してどのIPプールを使うかをPodのアノテーションで指定することも可能です。 - IPアドレスの割り当てプロセス:
- Podが起動します。
- KubernetesはCNIプラグインであるCalicoのIPAM機能(IPAMプラグイン)を呼び出します。
- Calico IPAMプラグインは、そのノードに割り当てられたIPブロックをチェックします。
- 利用可能なブロックがない、またはブロック内のIPアドレスが全て使用中の場合、Calicoはデータストアから新しいブロックをリースしようとします。
- リースしたブロックまたは既存のブロックから、未使用のIPアドレスを選択し、そのPodに割り当てます。
- Podのメタデータ(アノテーション)に割り当てられたIPアドレスが記録されます。
- IPアドレスの解放プロセス:
- Podが終了します。
- KubernetesはCNIプラグインのIPAM機能に対して、Podに割り当てられたIPアドレスを解放するように通知します。
- Calico IPAMプラグインは、解放されたIPアドレスをそのノードのブロックに返します。
- ノードがリースしているブロックが全て空になった場合、そのブロックをデータストアに返却し、他のノードが再利用できるようにします。
このブロックベースのリース・解放メカニズムは、分散環境でのIPアドレス管理の効率性と堅牢性を高めます。また、CalicoはIPv4だけでなくIPv6のIPAMもサポートしています。
5. Calicoの役割とメリット
Calicoは、Kubernetesクラスタにおいて単にPod間の通信を可能にするだけでなく、エンタープライズレベルのネットワークとセキュリティ機能を提供することで、重要な役割を果たしています。
5.1. シンプルさとパフォーマンス
前述の通り、Calicoのデフォルトのルーティング方式であるBGPネイティブは、カプセル化のオーバーヘッドがないため、Pod間の通信において非常に高いパフォーマンスを発揮します。これは、特にデータ転送量の多いアプリケーションや、低遅延が要求されるワークロードにとって大きなメリットとなります。また、ルーティングがアンダーレイネットワークに依存しているため、トラブルシューティングも比較的シンプルで、既存のネットワーク監視ツールを活用しやすいという側面もあります。
5.2. 強力なネットワークポリシー
Calico NetworkPolicyは、Kubernetes環境におけるセキュリティを大幅に向上させます。マイクロサービス間の通信を最小限に制限するゼロトラストモデルを容易に実現でき、コンテナ環境における攻撃対象領域を減らします。Kubernetes標準のNetworkPolicyだけでは実現できないような、より詳細なルールやグローバルなポリシー設定が可能であるため、複雑なセキュリティ要件を持つ環境に最適です。
5.3. 柔軟なデプロイメント
Calicoは、様々なインフラストラクチャ環境に対応できます。ベアメタルサーバー上に構築されたプライベートクラウド、VMware vSphereのような仮想化環境、AWS, Azure, GCPといった主要なパブリッククラウドまで、幅広い環境で動作します。アンダーレイネットワークの特性に合わせて、BGPネイティブ、IP-in-IP、VXLANといったルーティングモードを選択できるため、既存のネットワーク構成に比較的柔軟に対応できます。
5.4. スケーラビリティ
Calicoは、数千ノード、数十万Podといった大規模なKubernetesクラスタでも安定して動作するように設計されています。特に、IPAMのブロックベースの割り当てや、BGP Route Reflectorの使用によるBGPピアリングの効率化などにより、大規模環境でのスケーラビリティを確保しています。
5.5. 可観測性 (Observability)
Calicoは、ネットワークトラフィックに関する可観測性(Observability)を高める機能も提供します。例えば、Flow logs機能を使用すると、ネットワークポリシーによって許可または拒否されたトラフィックに関する詳細なログを収集できます。これらのログを分析することで、通信の問題の原因究明や、ポリシーが期待通りに機能しているかの確認を効率的に行うことができます。
6. Calicoの導入と設定
KubernetesクラスタにCalicoを導入するのは、通常、公式で提供されているマニフェストファイルをkubectl apply
コマンドで適用するだけで完了します。
6.1. インストール方法
最も一般的なインストール方法は、以下の手順で行います。
- 適切なマニフェストファイルの選択: クラスタの規模、使用するデータストア(Kubernetes APIまたはetcd)、使用するルーティング方式(BGPネイティブ、IP-in-IP、VXLAN)などに合わせて、Calico公式サイトやドキュメントから適切なマニフェストファイル(YAML形式)を選択します。例えば、Kubernetes APIデータストアを使用し、IP-in-IPカプセル化を有効にした場合の標準的なマニフェストなどがあります。
- マニフェストの適用:
kubectl apply -f <calico_manifest.yaml>
コマンドを実行します。
これにより、以下のKubernetesオブジェクトが作成され、Calicoのコンポーネントがデプロイされます。
- Namespace:
calico-system
のようなNamespaceが作成されます。 - CustomResourceDefinitions (CRDs): Calico独自のCRD(
IPPool
,NetworkPolicy
,GlobalNetworkPolicy
,BGPConfiguration
など)が作成されます。これにより、Calicoの設定やポリシーをKubernetes APIを通じて管理できるようになります。 - DaemonSet:
calico-node
DaemonSetが作成され、各Kubernetesノードにcalico/node
Podがデプロイされます。このPodにはFelix、BGPクライアント、CNIプラグインなどが含まれています。 - Deployment:
calico-kube-controllers
Deploymentが作成され、Kubernetes APIと連携してCalicoリソースの管理を行うコントローラーがデプロイされます。 - ServiceAccounts, ClusterRoles, ClusterRoleBindings: Calicoコンポーネントが必要なKubernetes APIへのアクセス権限を持つためのRBACリソースが作成されます。
6.2. 設定オプション
Calicoのデフォルト設定は多くの環境で機能しますが、特定の要件に合わせて設定を調整することが可能です。主な設定オプションは、インストール時に適用するマニフェストファイルを編集するか、インストール後にCRDオブジェクトを編集することで行います。
- IPプール設定:
IPPool
CRDを編集して、Podに割り当てるIPアドレス範囲(CIDR)、カプセル化方式(ipipMode: Always
/CrossSubnet
/Never
,vxlanMode: Always
/CrossSubnet
/Never
)、ブロックサイズ、ノードごとのIP制限などを設定します。 - BGP設定:
BGPConfiguration
CRDやBGPPeer
CRDを使用して、AS番号、Route Reflectorの設定、外部BGPルーターとのピアリングなどを設定します。 - データストア設定: 通常はマニフェストで指定しますが、Kubernetes APIを使用するか、外部etcdを使用するかを選択できます。
- データプレーン:
Installation
CRDなどで、ネットワークポリシーの実装にiptables
またはBPF
のどちらを使用するかを選択できます。
6.3. calicoctl
ツールの使い方
calicoctl
は、Calicoクラスタを管理するためのコマンドラインインターフェースツールです。Kubernetes APIデータストアを使用している場合、calicoctl
はKubernetes APIを通じてCalicoリソースとやり取りします。calicoctl
を使用すると、以下の操作が可能です。
- Calicoリソース(IPプール、ポリシー、BGPピアなど)の作成、表示、編集、削除。
- クラスタの状態確認(ノード、BGPピアの状態など)。
- デバッグ情報の収集。
例:
* calicoctl get ippools
: 現在のIPプールを表示
* calicoctl get networkpolicy --namespace=<namespace>
: 特定の名前空間のCalico NetworkPolicyを表示
* calicoctl apply -f <policy.yaml>
: 新しいCalico NetworkPolicyを適用
* calicoctl node status
: 各CalicoノードのBGPピアリング状態などを表示
calicoctl
は、特にCalico独自の高度な設定やトラブルシューティングを行う際に便利なツールです。
7. Calico利用上の注意点とトラブルシューティング
Calicoは堅牢なCNIですが、導入・運用時にはいくつかの注意点があります。
7.1. BGPの設定に関する考慮事項
BGPネイティブモードを使用する場合、Calicoノードがアンダーレイネットワーク上の他のノードやルーターとBGPピアリングを確立できる必要があります。
* AS番号: Calicoノードに割り当てるAS番号と、ピアリングする外部ルーターのAS番号が適切に設定されている必要があります。
* BGPピアリング: Calicoノード間のメッシュピアリング(デフォルト)またはRoute Reflector構成、外部ルーターとのピアリング設定が必要です。ファイアウォールなどでBGPポート(TCP 179)がブロックされていないことを確認してください。
* ルーティングテーブル: アンダーレイネットワークのルーターが、CalicoノードからアドバタイズされたPod IPブロックへの経路情報を受け入れ、正しくルーティングできる設定になっているか確認が必要です。
アンダーレイネットワークの構成によっては、CalicoのBGP設定と密接に連携させる必要があります。ネットワークチームとの協力が不可欠となる場合があります。
7.2. IP-in-IP / VXLAN の選択
アンダーレイネットワークがPod IPの直接ルーティングをサポートしない場合、IP-in-IPまたはVXLANを使用する必要があります。
* IP-in-IP: シンプルですが、一部のネットワーク機器やファイアウォールで扱いにくい場合があります(IPプロトコル4)。
* VXLAN: UDP(ポート 4789)を使用するため、ファイアウォールを通過しやすい傾向があります。多くのモダンなネットワーク機器がハードウェアオフロードをサポートしており、パフォーマンス面で有利な場合があります。
* MTU: カプセル化は元のパケットにヘッダーを追加するため、パケットサイズが増加します。ネットワークパス全体のMTU(Maximum Transmission Unit)設定が適切でないと、パケットの断片化やドロップが発生し、通信性能の低下や問題の原因となります。通常、カプセル化を使用する場合は、ベースとなるネットワークのMTUを減らす必要があります(例: Ethernet 標準の 1500 から 1480 や 1450 などに調整)。
7.3. ファイアウォール設定との干渉
CalicoはiptablesやBPFを使ってネットワークポリシーを実装します。ノードOS自体に設定されているファイアウォールルール(例: firewalld, ufw)や、クラウド環境のセキュリティグループ/ACLなどが、Calicoの動作やPod間通信に影響を与える可能性があります。
* Calicoが使用するポート(BGP: TCP 179, VXLAN: UDP 4789 など)がファイアウォールで許可されているか確認が必要です。
* Calicoはiptables/BPFの特定のチェーンやルールセットを管理します。OSデフォルトのファイアウォール設定がCalicoのルールと干渉しないように注意が必要です。通常、Calicoをインストールするノードでは、OSデフォルトのファイアウォールサービスを無効にするか、Calicoの通信に必要なルールを追加する必要があります。
7.4. ログの確認
Calico関連の問題が発生した場合、calico/node
Podのログを確認するのが最初のステップです。kubectl logs -n calico-system <calico-node-pod-name>
コマンドでログを取得できます。BGPピアリングの確立状況、ルーティングテーブルの更新状況、ネットワークポリシーの適用状況など、デバッグに役立つ情報が含まれています。
7.5. calicoctl
によるデバッグ
calicoctl
には、ネットワーク状態の確認やデバッグに便利なコマンドがあります。
* calicoctl node status
: 各ノードのCalicoエージェントの状態やBGPピアリングの状態を確認できます。
* calicoctl status
: クラスタ全体のCalicoの状態サマリーを表示します。
* calicoctl diagnostics
: クラスタのCalico構成や状態に関する包括的な診断情報を収集します。問題をTigeraサポートやコミュニティに報告する際に役立ちます。
8. まとめ
Calicoは、KubernetesクラスタにおけるPodネットワーキングとセキュリティポリシーの実装において、非常に強力で柔軟な選択肢です。その主な特徴は、BGPを使用したシンプルで高性能なアンダーレイネットワークベースのルーティングと、Kubernetes NetworkPolicyを拡張した高度なCalico NetworkPolicy機能です。
この記事では、Calicoの基本的な仕組みとして、各ノードで動作するFelix、BGPによる経路情報の交換、IPAMによるIPアドレス管理、そしてKubernetes APIをデータストアとして利用する構成を解説しました。また、IP-in-IPやVXLANといったカプセル化オプションや、IPAMの詳細、Calico NetworkPolicyの豊富な機能についても掘り下げて説明しました。
Calicoを選ぶことのメリットとして、パフォーマンス、セキュリティ、柔軟性、スケーラビリティを挙げました。特に、セキュリティ要件が厳しい環境や、大規模なクラスタでの利用に適しています。
導入は比較的容易ですが、特にBGPネイティブモードを使用する場合や既存のネットワークとの連携が必要な場合には、アンダーレイネットワークの構成やファイアウォール設定との調整が重要となります。問題発生時には、calico/node
のログや calicoctl
ツールがデバッグの助けとなります。
コンテナ技術とKubernetesは、今後も進化し続けます。Calicoもまた、BPFデータプレーンの強化やマルチクラスタ管理機能(Calico Cloudなど)といった進化を続けており、現代のクラウドネイティブ環境において、その重要性はますます高まっていくでしょう。
この記事を通じて、Calicoの仕組みと役割についての理解が深まり、Kubernetesネットワークに対する自信を持てるようになったなら幸いです。Calicoは強力なツールですが、そのポテンシャルを最大限に引き出すためには、その仕組みをしっかりと理解することが重要です。
9. 参考資料
- Project Calico公式サイト: https://www.tigera.io/project-calico/ (公式ドキュメント、インストールガイド、機能詳細などが豊富にあります)
- Calico Documentation: https://docs.tigera.io/calico/latest/ (Calicoに関する最も信頼できる情報源です。各機能の詳細な設定方法やトラブルシューティング情報が網羅されています)
- Kubernetes NetworkPolicy: https://kubernetes.io/docs/concepts/services-networking/network-policies/ (Kubernetes標準のネットワークポリシーについて理解を深めるのに役立ちます)
- CNI (Container Network Interface): https://github.com/containernetworking/cni (CNIの仕様に関する情報です)
- BGP (Border Gateway Protocol): (一般的なBGPに関する情報源 – RFCやネットワーク技術解説記事など)
これらの資料を参照することで、さらにCalicoやKubernetesネットワークに関する知識を深めることができます。
注: 本記事中の図解イメージは、テキストによる表現であり、実際の図として表示されているわけではありません。読者の皆様が概念を視覚的に捉えやすくするための補助として記述しています。実際の導入や詳細な設定については、必ず公式ドキュメントを参照してください。
これで約5000語の詳細な解説記事は完了です。Calicoの仕組み、役割、導入、注意点などを網羅し、図解の概念を盛り込みつつ、分かりやすさを意識して記述しました。