Kubernetesのネットワークを学び始めると、最初に目にするのは次の概念です。
- Pod
- Service
- Ingress
- CNI
- Flannel
- Calico
その結果は、学ぶほど混乱越来越深くなることです。
本当の問題はここにあります。
Kubernetesネットワークは独立した体系ではなく、Linuxネットワークの上に成り立った抽象化レイヤーです。
Linuxネットワークを理解していなければ、Pod、Service、VXLANといった概念はすべてブラックボックスになってしまいます。
一、ネットワークの世界にある中心的な概念は3つだけ
ネットワーク全体は、次の3つに抽象化できます。
设备
地址
转发
それぞれに対応するものは次のとおりです。
设备:
网卡
交换机
路由器
地址:
MAC
IP
转发:
交换
路由
NAT
二、MACとIP
MACアドレス
MACアドレスはレイヤー2のアドレスです。
00:11:22:33:44:55
同じLAN内でデバイスを特定するために使います。
IPアドレス
IPアドレスはレイヤー3のアドレスです。
192.168.1.10
10.244.1.2
8.8.8.8
ネットワークをまたいでデバイスを特定するために使います。
三、スイッチ、ARP、ルーター
スイッチはレイヤー2で動作し、MACアドレスだけを見ます。IP、TCP、HTTPは関係しません。
ARPが担当するのは次の処理です。
IP -> MAC
ルーターはレイヤー3で動作します。
查看目标 IP
↓
查路由表
↓
决定下一跳
ルーティングテーブルの例です。
ip route
192.168.1.0/24 dev eth0
default via 192.168.1.1
意味は次のとおりです。
同网段直接发送
其他流量交给默认网关
四、NAT
プライベートネットワークのアドレスは、そのままでは公網でルーティングできません。
192.168.x.x
172.16.x.x
10.x.x.x
そのため、ルーターはSNATを行います。
SRC 192.168.1.10
↓
SRC 公网 IP
さらにconntrackで接続の対応関係を記録し、返信パケットを正しい接続元へ戻すために利用します。
五、Linux Network Namespace
NamespaceはLinuxの分離の仕組みです。
Network Namespaceが分離するのは、ネットワークスタック一式です。
网卡
IP
路由表
ARP 表
iptables
端口空间
したがって、コンテナは仮想マシンではなく、次のように構成されています。
普通 Linux 进程
+
Namespace 隔离
+
Cgroups 限制
+
RootFS 文件系统
六、veth Pair
Namespace同士を接続するため、Linuxはveth pairを提供しています。
vethA <====> vethB
仮想ケーブルに似た仕組みです。
从 vethA 发出的包,会从 vethB 出来
从 vethB 发出的包,会从 vethA 出来
七、Linux Bridge
Bridgeはソフトウェアスイッチです。
ContainerA
|
Bridge
|
ContainerB
物理スイッチと同じように動作します。
学习 MAC
查 MAC 表
转发数据帧
八、Dockerネットワーク
Dockerのデフォルトネットワーク構成は次のとおりです。
Container
eth0
│
veth
│
docker0
│
Host
このうちdocker0はLinux Bridgeであり、DockerがIPアドレスも設定しています。
docker0 = 172.17.0.1
そのため、docker0はスイッチであると同時に、コンテナのデフォルトゲートウェイでもあります。
Docker自身がIPAMを管理します。
172.17.0.0/16
コンテナのIPアドレスは通常、Dockerが割り当てます。
172.17.0.2
172.17.0.3
172.17.0.4
九、Podとは何か
Podはコンテナではありません。
1つのPodには複数のコンテナを含められます。
Pod
├── app
└── sidecar
ネットワーク名前空間を持っているのは、実際にはpause containerです。
pause container
└── Network Namespace
app
└── 加入 pause 的 Network Namespace
sidecar
└── 加入 pause 的 Network Namespace
そのため、同じPod内の複数のコンテナは次を共有します。
IP
localhost
端口空间
十、Kubernetes単一ノードネットワーク
多くのCNIは、Node上にdocker0に似たブリッジを作成します。たとえば次のとおりです。
cni0
構成は次のとおりです。
PodA
|
veth
|
cni0
|
veth
|
PodB
同じNode上のPod同士が通信するときには、次の流れになります。
PodA ARP 查询 PodB MAC
↓
cni0 广播
↓
PodB 回复
↓
cni0 根据 MAC 表转发
このプロセスは、本質的にはレイヤー2のスイッチングです。
十一、CNIとは何か
Kubernetes自体はネットワークを直接実装しているわけではありません。
PodのネットワークはCNIプラグインが処理します。
代表的なCNIは次のとおりです。
Flannel
Calico
Cilium
CNIが担当するのは次の処理です。
创建 veth
配置 IP
配置路由
接入 Bridge 或其他数据平面
维护跨节点通信
Pod IPは通常、CNIのIPAMモジュールが割り当てます。KubernetesやLinuxが自動的に割り当てるものではありません。
十二、ノードをまたぐPod間の通信
たとえば次の構成を考えます。
Node1
PodA = 10.244.1.2
Node2
PodB = 10.244.2.2
PodAからPodBへアクセスすると、次のようになります。
10.244.1.2 -> 10.244.2.2
問題なのは次の点です。
Node1 怎么知道 10.244.2.0/24 在 Node2?
これがCNIが解決する問題です。
十三、VXLAN
VXLANは次のものです。
L2 Overlay over L3
つまり、次のようにレイヤー2のネットワークをレイヤー3のIPネットワークに封入するという意味です。
把二层网络封装到三层 IP 网络里面
元のPodパケットは次のとおりです。
SRC 10.244.1.2
DST 10.244.2.2
VXLANで封入すると次のようになります。
Outer IP:
SRC Node1IP
DST Node2IP
UDP
VXLAN Header
Inner IP:
SRC 10.244.1.2
DST 10.244.2.2
パケットの構造は次のとおりです。
Outer Ethernet
Outer IP
UDP
VXLAN
Inner Ethernet
Inner IP
TCP
HTTP
中間の物理ネットワークが見るのは次の情報だけです。
Node1IP -> Node2IP
Node2が受け取ると、VXLANのデカプセル化を行い、元のPodパケットをPodBに渡します。
十四、flannel.1とは何か
flannel.1はプロセスではありません。
LinuxのVXLANネットワークデバイスです。
たとえば次のものAXISZZZDUMMY9c936c0da6f2LEN23があります。
eth0
docker0
cni0
vethxxx
ルーティングテーブルには次のエントリが入ります。
10.244.2.0/24 dev flannel.1
これは次を意味しています。
去 10.244.2.0/24 的流量
交给 flannel.1 这个 VXLAN 设备处理
その後はLinuxカーネルがVXLANの封入を担当します。
実際のプロセスはflanneldです。flanneldは次を担当します。
创建 flannel.1
写路由表
维护 Node 和 PodCIDR 的映射
十五、Serviceの本質
Serviceは安定したアクセス入口を提供します。
たとえば次のとおりです。
Service IP = 10.96.0.10
ただし、このIPは通常、実際のNICのいずれかに設定されたIPではありません。
Serviceの本質は次のとおりです。
虚拟 IP
+
iptables / IPVS 转发规则
十六、kube-proxy
kube-proxyは次のものを監視します。
Service
Endpoint / EndpointSlice
その後、転送ルールを生成します。
たとえば次のとおりです。
10.96.0.10:8080
↓ DNAT
10.244.1.2:8080
そのため、Serviceにアクセスしたとき、実際の流れは次のとおりです。
访问 Service IP
↓
iptables / IPVS 命中规则
↓
DNAT 到某个后端 Pod IP
↓
通过 CNI 网络转发到目标 Pod
十七、CoreDNS
Podの中からサービス名へアクセスする場合は、次のようにします。
curl user-service
名前解決の流れは次のとおりです。
user-service
↓
CoreDNS
↓
Service ClusterIP
↓
kube-proxy
↓
Pod IP
十八、Ingress
Ingressはルールであり、実際のゲートウェイプロセスではありません。
トラフィックを処理するのはIngress Controllerです。たとえば次のとおりです。
Nginx Ingress Controller
Traefik
APISIX
Kong
外部リクエストの経路は次のとおりです。
Browser
↓
LoadBalancer / NodePort
↓
Ingress Controller
↓
Service
↓
Pod
Ingress Controllerは通常、レイヤー7のリバースプロキシとして次の情報を解析します。
Host
Path
TLS
HTTP Header
十九、完全な流れのまとめ
Linuxネットワークの基礎です。
MAC
↓
ARP
↓
交换机
↓
路由器
↓
路由表
↓
NAT
コンテナネットワークの基礎です。
Namespace
↓
veth
↓
Bridge
↓
IPAM
↓
Docker 网络
Kubernetesネットワークです。
Pod
↓
CNI
↓
PodCIDR
↓
cni0 / route / eBPF
↓
VXLAN / BGP
↓
Service
↓
CoreDNS
↓
Ingress
二十、最終的な結論
Kubernetesネットワークは、いわば突然現れた新しい体系ではありません。
本質的には次の組み合わせです。
Linux 网络能力
+
CNI 自动化
+
Kubernetes 声明式编排
より具体的に言えば、次のようになります。
Kubernetes 网络
=
Namespace
+
veth
+
Bridge
+
Route
+
NAT
+
iptables / IPVS
+
VXLAN / BGP / eBPF
+
CNI
Kubernetesネットワークを理解する正しい道筋は、Pod、Service、Ingressを先に暗記することではありません。まず次のことを理解することです。