# Flannel

flannel通过建立overlay网络实现了容器的跨节点通讯，请求包由flanneld进行vxlan封包发送和解包。网络传输方式如下图所示：

![](https://3697521973-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LK_1OIKdb2LfhqtvPC_%2F-M1_CuflbnIs0loXwBPc%2F-M1_J9ojAfUFyVSgKChD%2Fimage.png?alt=media\&token=b935f641-bdbd-4155-8fe6-56c75a260816)

原图[链接](https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbnN1YmdyYXBoIGhvc3QwXG5wb2QwIC0tPiB2ZXRoMCh2ZXRoMCAxNzIuMTcuMTAuMi8yNClcbnBvZDEgLS0-IHZldGgxKHZldGgxIDE3Mi4xNy4xMC4zLzI0KVxudmV0aDAgLS0-IGhvc3QwX2RvY2tlcjAoZG9ja2VyMCAxNzIuMTcuMTAuMS8yNClcbnZldGgxIC0tPiBob3N0MF9kb2NrZXIwXG5ob3N0MF9kb2NrZXIwIC0tPiBob3N0MF9mbGFubmVsMChmbGFubmVsMCAxNzIuMTcuMTAuMC8xNilcbmhvc3QwX2ZsYW5uZWwwIC0tPiBob3N0MF9mbGFubmVsZChmbGFubmVsZClcbmhvc3QwX2ZsYW5uZWxkIC0tPiBob3N0MF9ldGgwKGV0aDAgMTkyLjE2OC4xLjEvMjQpXG5lbmRcblxuc3ViZ3JhcGggaG9zdDFcbnBvZDIgLS0-IHZldGgyKHZldGgyIDE3Mi4xNy4yMC4yLzI0KVxucG9kMyAtLT4gdmV0aDModmV0aDMgMTcyLjE3LjIwLjMvMjQpXG52ZXRoMiAtLT4gaG9zdDFfZG9ja2VyMChkb2NrZXIwIDE3Mi4xNy4yMC4xLzI0KVxudmV0aDMgLS0-IGhvc3QxX2RvY2tlcjBcbmhvc3QxX2RvY2tlcjAgLS0-IGhvc3QxX2ZsYW5uZWwwKGZsYW5uZWwwIDE3Mi4xNy4yMC4wLzE2KVxuaG9zdDFfZmxhbm5lbDAgLS0-IGhvc3QxX2ZsYW5uZWxkKGZsYW5uZWxkKVxuaG9zdDFfZmxhbm5lbGQgLS0-IGhvc3QxX2V0aDAoZXRoMCAxOTIuMTY4LjEuMi8yNClcbmVuZFxuXG5ob3N0MF9ldGgwIC0tPiBzd2l0Y2goc3dpdGNoIDE5Mi4xNjguMS4wLzI0KVxuaG9zdDFfZXRoMCAtLT4gc3dpdGNoIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0)

## 工作流程

### 网络初始化

1. 在etcd中为flannel分配pod地址段（如：172.17.0.0/16）；
2. 为flanneld配置etcd的访问地址，启动flanneld服务；
3. flanneld获取到当前节点对应的pod子地址段（如：172.17.10.0/24），将该子地址段设置到docker服务的启动参数中并启动docker服务；
4. docker以设定的容器网段初始化docker0网桥；
5. flanneld创建flannel0网桥，一端接到docker0网桥上，另一端接到flanneld进程上；
6. 在pod创建时docker为其分配一个节点子网段的地址，并且以flannel0网桥的地址作为默认路由；
7. flanneld从etcd同步每个pod的地址信息在内存中生成路由表。

### 容器跨节点通讯

1. pod依据默认路由将请求包从veth通过docker0网桥发送到对端的flannel0网桥上；
2. 发送到flannel0网桥上的请求会由用户态的flanneld进程抓取并进行vxlan封包；
3. flanneld根据内存中的路由表获取到目的pod所在的节点地址，将请求包发送到目的节点上；
4. 目的节点的flanneld从物理接口上获取到请求包后进行解包，获得pod的目标地址并发送到对应的pod上。
