CNM、Libnetwork和驱动

CNM容器网络模型

Docker的网络构架源自一种叫做容器网络模型(CNM)的方案,该方案是开源的并且支持插接式连接。
CNM中规定了Docker网络的基础构成要素:沙盒(Sandbox)、终端(Endpoint)和网络(Network)。
沙盒,是一个独立的网络栈。其中包括以太网接口、端口、路由表及DNS配置。
终端,就是虚拟网络接口。就像普通网络接口一样,终端的主要职责是创建连接。在CNM中,终端是负责将沙盒连接到网络。
网络,是802.1.d 网桥的软件实现。因此,网络就是需要交互的终端的集合,并且终端之间相互独立。

Libnetwork

Libnetwork是Docker对CNM的一种实现,提供了Docker核心网络架构的全部功能。不通的驱动可以通过插拔式的方式接入Libnetwork来提供定制化的网络拓扑。
Libnetwork通过Go语言编写,并实现了CNM中列举的核心组件。Libnetwork是从deamon中拆分出来的外部类库。
Libnetwork实现了CNM中规定的全部3个组件,此外它还实现了本地服务发现(Service Discovery)、基于Ingress的容器负载均衡,以及网络控制层和管理层功能。

驱动

如果说Libnetwork实现了控制层和管理层功能,那么驱动就负责实现数据层。比如,网络连续性和隔离型是由驱动来处理的,驱动层实际创建网络对象也是如此。
Docker封装了若干内置驱动,通常被称作原生驱动或本地驱动。在Linux上包括Bridge、Overlay以及Macvlan。
第三方也可以编写Docker网络驱动,这些驱动称为远程驱动。每个驱动都负责其上所有网络资源的创建和管理。
为了满足复杂且不固定的环境需求,Libnetwork支持同时激活多个网络驱动。这意味着Docker环境可以支持一个庞大的异构网络。

单机桥接网络

单机桥接网络只能在单个Docker节点上运行,并且只能与所在Docker主机上的容器进行连接。
桥接表示这是802.1.d桥接的一种实现(二层交换机)。
每个Docker主机都有一个默认的单机桥接网络。在Linux上网络名称名为bridge,在Windows上名为nat。除非通过命令行创建容器时指定参数--network,否则默认情况下,新创建的容器都会连接到该网络。

Docker网络命令

docker network ls

列出当前主机上的网络

docker network inspect <网络名称>

显示网络的详细信息

示例输出:

[root@localhost ~]# docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "141c791e674798ac0027623c2d2c564bcfe8b6aa88ed7e66fed7636d95918649",
        "Created": "2020-07-25T09:06:00.876062816-04:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "94b4e0f51663da4bc34b577c2c6395e6d7ef03314fa4dbfeb46ef768e940d9aa": {
                "Name": "nginx",
                "EndpointID": "a9ca9e4dd8badaf077804b8f9e60ecd1361fc65a5008c8584076bc4b2c821928",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

在Linux主机上,Docker网络由Bridge驱动创建,而Bridge底层是基于Linux内核中的Linux Bridge技术,Bridge是高效而且稳定的。
默认的bridge网络被映射到内核中名为docker0的Linux网桥。

#Linux系统中的docker0网桥
[root@localhost ~]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:c6ff:fe6c:869d  prefixlen 64  scopeid 0x20<link>
        ether 02:42:c6:6c:86:9d  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5  bytes 446 (446.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

创建新的单机桥接网络

docker network create -d bridge <网络名称>
#创建新桥接网络命令
#-d 选择驱动

创建了新的网络后,Linux主机内核中还会创建一个新的Linux网桥。

将容器接入网络

docker run -d --name nginx --network <网络名称> <镜像名称>
#将容器连接到网络,通过docker network inspect 查看网络信息,可以看到连接的容器列表。

桥接网络中的容器只能与位于相同网络中的容器进行通信。但是可以使用端口映射(Port Mapping)来绕开这个限制。
端口映射将容器的某个端口映射到Docker主机的端口上,仍和发送到该端口上的流量都会转发到容器。但是这种方法比较笨重并且不能扩展。

多机覆盖网络

覆盖网络适用于多机环境。它允许单个网络包含多个主机,这样不同主机上的容器间就可以在链路层实现通信。覆盖网络是理想的容器间通信方式,支持完全容器化的应用,并且具备良好的伸缩性。
Docker为覆盖网络提供本地驱动。这使得创建覆盖网络非常简单,只需要在docker network create 命令中添加--d overlay参数。

Macvlan驱动

Macvlan驱动可以为容器提供MAC和IP地址,且因为无需端口映射或者额外桥接,可以通过主机接口(或者子接口)访问容器接口,性能优异。
但是Macvlan需要将主机网卡设置为混杂模式,这在大部分公有云上是不允许的。对于公司内部的数据中心网络来说Macvlan是很棒的。但是在公有云上并不可行。

用于故障排除的容器和服务日志

服务日志

journalctl -u docker.service
#查看daemon日志

通过编辑daemon配置文件(daemon.json)将debug设置为true,并同时设置log-level为下面的某个值.
- debug:最详细的日志级别
- info:默认值,次详细日志级别
- warn: 第三详细日志级别
- error:第四详细日志级别
- fatal:最粗略日志级别
修改完配置文后,需要重启Docker。

容器日志

docker logs
#查看单独容器日志

docker service logs
查看Swarm服务日志

服务发现

作为核心网络架构,Libnetwork还提供服务发现(Service Discovery)功能,允许容器和Swarm服务通过名称互相定位。唯一的要求就是需要处于同一网络当中。

---待完善---

标签: Docker

添加新评论