0%

podman_network

Podman之网络

Podman提供了网络能力,但是不同于Docker自己实现完整的网络机制;而是通过CNI机制来实现的,类似于CRI接口的CNI使用方式。基于CNI机制,通过管理和操作CNI的网络配置文件来实现网络的管理能力。

网络子命令

网络子命令,提供了网络的管理能力,主要包括网络的创建、删除、查看等。虽然叫网络的创建、删除等,其实只是对CNI网络配置文件的管理;对应于网络配置文件的创建、删除以及查看等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ podman network --help
Manage networks

Description:
Manage networks

Usage:
podman network [command]

Available Commands:
create network create
inspect network inspect
ls network list
rm network rm

基本流程

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
2
3
4
5
6
7
8
9
10
11
// NcList describes a generic map
type NcList map[string]interface{}

// NewNcList creates a generic map of values with string
// keys and adds in version and network name
func NewNcList(name, version string) NcList {
n := NcList{}
n["cniVersion"] = version
n["name"] = name
return n
}

由于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]