Podman之网络
Podman提供了网络能力,但是不同于Docker自己实现完整的网络机制;而是通过CNI机制来实现的,类似于CRI接口的CNI使用方式。基于CNI机制,通过管理和操作CNI的网络配置文件来实现网络的管理能力。
网络子命令
网络子命令,提供了网络的管理能力,主要包括网络的创建、删除、查看等。虽然叫网络的创建、删除等,其实只是对CNI网络配置文件的管理;对应于网络配置文件的创建、删除以及查看等。
1 | $ podman network --help |
基本流程
Podman支持本地模式ABI和远端服务模式Tunnel;虽然调用方式不一样,但是最终都是通过abi.ContainerEngine的网络接口完成的。为了更好的,认识这个流程,先通过序列图理解一下。
TUNNEL模式的序列图如下:
sequenceDiagram
autonumber
participant Client
participant TUNNEL
participant libpod
participant ABI
Client ->> TUNNEL: call ContainerEngine interface
TUNNEL ->> libpod: http request
libpod ->> ABI: call ABI implement of ContainerEngine
ABI ->> ABI: do network operator
ABI -->> libpod: return result
libpod -->> TUNNEL: write http response
TUNNEL -->> Client: return result
ABI模式就是去掉了http通信的流程,直接调用ABI实现的接口;序列图如下:
sequenceDiagram
autonumber
participant Client
participant ABI
Client ->> ABI: call ContainerEngine interface
ABI ->> ABI: do network operator
ABI -->> Client: return result
上述流程涉及的主要类和接口如下类图所示:
classDiagram
class ContainerEngine{
<>
NetworkCreate()
NetworkInspect()
NetworkList()
NetworkRm()
}
class abiContainerEngine{
Libpod *libpod.Runtime
}
class tunnelContainerEngine{
ClientCxt context.Context
}
ContainerEngine <|-- abiContainerEngine : implements
ContainerEngine <|-- tunnelContainerEngine : implements
网络创建功能
由于ABI和TUNNEL两种模式,最终使用的都是ABI的NetworkCreate,因此我们直接从该函数开始分析。
graph TD
A(NetworkCreate) --> B{MacVLAN > 0}
B -->|yes| C[createMacVLAN]
B -->|no| D[createBridge]
C --> E(create NewNcList with macvlan)
D --> F(create NewNcList with bridge)
E --> G[save config to json file]
F --> G
1 | // NcList describes a generic map |
由于golang支持反射,所以可以通过map[string][interface]的方式,动态修改结构体,最后通过JSON库完成结构体和JSON字符串的转换。所以,网络的创建接口中,使用了NcList,把用户配置的网络参数配置到CNI网络配置中,最后生成对应的JSON字符串,并写入文件中。
注:生成的CNI网络配置均为conflist
inspect网络功能
flowchart TB
A(NetworkInspect) --> B[foreach name]
B --> C(read config of name)
B --> D(save read config)
删除网络功能
flowchart TB
A(NetworkRm) --> B[foreach name]
B --> C(remove containers associate with network)
B --> D(remove interface by ip command)
B --> E(remove read config)
列举网络功能
flowchart TB
A(NetworkList) --> B[foreach file with .conflist]
B --> C(parse config file)
B --> D(add parsed struct to result)
容器生命周期的网络管理
本章节主要是梳理容器生命周期中,涉及网络的内容。
容器创建
flowchart TB
A(ContainerCreate) --> B[MakeContainer]
B --> C(createContainerOptions)
C --> D(namespaceOptions)
D --> E(s.NetNS.NSMode)
D --> F(dns, hosts, resolv)
容器启动
flowchart TB
A(ContainerStart) --> B[Start]
B --> C(prepareToStart)
C --> X(prepare)
X --> Y{c.state.NetNS == nil}
Y -->|yes| Z(createNetNS)
C --> D(init)
D --> E(completeNetworkSetup)
E --> F(setupNetNS)
E --> G(bind mount resolv conf)
F --> K[Create NSPath]
F --> L[Mount NSPath]
F --> H[configureNetNS]
H --> I(getPodNetwork)
H --> J(SetUpPod)
注意:
- SetUpPod就是开始调用CNI库,执行CNI网络插件进行真正的网络资源分配了。本文主要涉及Podman的分析,CNI具体的实现不在本文分析;
容器停止
flowchart TB
A(ContainerStop) --> B[Cleanup]
B --> D(cleanup)
D --> E(cleanupNetwork)
E --> F(teardownNetNS)
F --> G[getPodNetwork]
F --> H[TearDownPod]
F --> I[UnmountNS]
F --> J[NetNS.Close]
容器删除
flowchart TB
A(ContainerRm) --> B[RemoveContainer]
B --> C(removeContainer)
C --> D(cleanup)
D --> E(cleanupNetwork)
E --> F(teardownNetNS)
F --> G[getPodNetwork]
F --> H[TearDownPod]
F --> I[UnmountNS]
F --> J[NetNS.Close]