Docker学习(11) Docker 网络

Docker学习(11) Docker 网络

  • Docker网络体系的基本原理:容器网络模型、以及Libnetwork

Docker网络简介

  • Docker的网络架构源自一个叫做容器网络模型(CNM)
  • Libnetwork是Docker对CNM的一种实现,提供了Docker核心网络架构的全部功能。
  • 为了实现开箱即用的效果,Docker封装了一系列的本地驱动,包括:
      1. 单机桥接网络(Single-Host Brige Network)
      2. 多机覆盖网络(Multi-Host Overlay)
  • Libnetwork提供了本地服务发现和容器的负载均衡解决方案。

Docker网络——详解

基础理论

  • Docker的网络架构主要由3个部分过程:CNM、Libnetwork和驱动

CNM

  • CNM是docker网络的设计标准:规定了Docker网络架构的基础组成要素。
  • 具体内容:https://github.com/docker/libnetwork
  • CNM定义了三个基本要素:沙盒(Sandbox)、终端(Endpoint)和网络(network)
    • 沙盒:独立的网络桟,包括以太网的接口、端口、路由表以及NDS配置。
    • 终端:虚拟网络接口,和普通网络接口一样,主要负责创建网络,在CNM中,主要是将沙盒连接到网络
    • 网络:是802.1d网桥的软件实现,网络就是需要交互终端的集合,并且终端直接相互集合。
  • docker环境中最小的调度单位是容器。

Libnetwork

  • Libnetwork是CNM的具体实现,通过Go语言编写的,实现了CNM列出的核心组件。
  • Libnetwork实现了CNM定义的3个组件。还实现了本地发现功能,基于Ingress的容器负载均衡,以及网络控制层和管理层的功能。

驱动

  • 通过实现特定网络拓扑的方式来拓扑该模型的能力。

  • 驱动负责实现了网络的数据层。

  • Docker封装了内置驱动,包括bridge,Overlay以及macvlan

单机桥接网络

  • 单机:该网络只在单个docker主机中运行,并且只能在docker主机内的容器进行连接。
  • 桥接:802.1d桥接的一种实现。
  • linux Docker创建网络时采用的是内置的桥接驱动。默认的单机桥接网络时bridge
  • 查看docker主机默认的网络
lhf@lhf-virtual-machine:~$ docker network ls
NETWORK ID          NAME                             DRIVER              SCOPE
3c6fd32ed9fb        bridge                           bridge              local
8b95e29168fa        counter-app-master_counter-net   bridge              local
682a75797ba4        host                             host                local
596066e2fd78        none                             null                local

  • 查看docker网络的详细信息
lhf@lhf-virtual-machine:~$ docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "3c6fd32ed9fbe215b5ee34a773ba14703ea7d0a295a3b54cd01906c3c2b749b6",
        "Created": "2019-11-08T21:51:18.740007297+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "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": {}
    }
]

  • docker网络由bridge驱动创建的。bridge底层基于linux内核 linux bridge技术。
  • 查看bridge网络
lhf@lhf-virtual-machine:~$ ip link show docker0
4: docker0:  mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether 02:42:03:5f:82:17 brd ff:ff:ff:ff:ff:ff

  • 默认的“bridge”网络映射到内核中为“docker0”的linux网桥
lhf@lhf-virtual-machine:~$ docker network inspect bridge | grep bridge.name
            "com.docker.network.bridge.name": "docker0",
  • 创建一个新的单机桥接网络,名为“localnet”
lhf@lhf-virtual-machine:~$ docker network create -d bridge localnet
2b5ed819e9331ffa5c109f5f81dc6080f18e78cee7fc8ad05df9455247c01a0b
lhf@lhf-virtual-machine:~$ docker network ls | grep localnet
2b5ed819e933        localnet                         bridge              local

  • 通过使用brctl工具查看系统中的linux网桥。
lhf@lhf-virtual-machine:~$ brctl show
bridge name bridge id       STP enabled interfaces
br-2b5ed819e933     8000.02421d8b6570   no      
br-8b95e29168fa     8000.024223c21723   no      
docker0     8000.0242035f8217   no  
  • 创建一个新的容器,并接入新建网络localnet中
$ docker container run -d --name c1 \
> --network c1 \
> alpine sleep 1d

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
f8bf6041757a        alpine              "sleep 1d"          46 seconds ago      Up 43 seconds                           c1


  • 查看详细输出
$ docker network inspect  localnet --format
"ConfigOnly": false,
        "Containers": {
            "f8bf6041757a51afc6b56d35a84a8370037d207230101c0df6fc565da1d68741": {
                "Name": "c1",
                "EndpointID": "7016a80031330e87c3073c1cd148a5bbef6aa39738cd84bcdfe1657cf19f214e",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

$ brctl show
bridge name bridge id       STP enabled interfaces
br-2b5ed819e933     8000.02421d8b6570   no      veth53c5236
br-8b95e29168fa     8000.024223c21723   no      
docker0     8000.0242035f8217   no      
  • 查看到c1网络已经接入到veth53c5236
  • 如果在相同的网络接入新的容器c2的话,是可以ping通c1的

  • 创建一个c2容器

$ docker container run -it --name c2 \
> --network localnet \
> alpine sh
/ # ping c1
PING c1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.296 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.143 ms
^C
--- c1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.143/0.219/0.296 ms
/ # 

  • 新容器都指定了docker的DNS服务。,所有相同网络的容器可以解析到其他容器的名称。

端口映射

  • 端口映射:将某个容器的端口映射到docker主机的端口上。
  • 将容器运行一个web'服务80映射到docker主机 5000
$ docker container run -d --name web \
> --network localnet \
> --publish 5000:80 \
> nginx

  • 确认端口映射
$ docker port web
80/tcp -> 0.0.0.0:5000

  • 通过web查看服务


    15.png

多机覆盖网络

  • 覆盖网络适用于多机环境,允许单个网络包含多个主机。不同主机的容器可以通过链路层实现通信。
  • docker主机为覆盖网络提供了本地驱动,在创建网络时docker network create 时添加参数 --d overlay

接入现有网络

  • 将容器化的应用接入到外部系统以及物理网络功能。比如:
    • 容器化的应用于运行的物理网络和VLAN上未容器化的部分进行通信。
    • docker 的内置驱动(Macvlan),为容器提供mac和IP地址

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

  • 容器间网络连接问题,检查daemon日志和容器日志

  • 在linux上,daemon日志存放位置取决于当前系统使用的初始化方式。

    • 如果是systemd,日志会存储在Journald,通过journalctl -u docker.service查看

    • 如果不是systemd,需要查看如下存放位置

      • Ubuntu系统:upstart:/var/log/upstart/docker.log
      • RHEl系统:systems:/var/log/messages
      • Debian系统: /var/log/daemon.log
    • 可以设置daemon日志的详细程度。通过编辑daemon的配置文件(daemon.json),将debug改为true,设置log-level为某个值:

      • debug:最详细的日志
      • info:默认值,仅次于最详细日志
      • warn:第三详细日志级别
      • error:第四详细日志级别
      • fatal;最粗略的日志级别
  • 查看单个容器日志
$ docker container logs web
172.18.0.1 - - [08/Nov/2019:16:15:38 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:70.0) Gecko/20100101 Firefox/70.0" "-"

服务发现

  • 服务发现(Service Discovery)允许容器和Swarm服务通过名称相互定位,需要在同一个网络中。

  • 底层实现是利用Docker内置的DNS功能,为每个容器提供DNS解析。上述例子c2可以ping通c1

  • 具体过程分析

    1. ping c2 命令调用本地DNS解释器,尝试将c2解析成具体的IP地址,每个docker都有本地的DNS解释器。
    2. 如果本地DNS解释器在本地缓存没有c2相对应的IP地址的映射关系。本地DNS会想dockerDNS发起一个递归查询。
    3. Docker DNS服务器器记录了全部容器的容器名和IP地址的映射关系。
    4. Docker DNS服务器会返回给“c2”相对应的IP地址给c1的本地DNS解释器,
    5. ping 命令返回给c2对应的IP地址。

Ingress网络

  • Swarm支持两种服务发布模式。
    • Ingress模式:保证swarm服务中任意节点都可以访问该服务(默认的模式)
    • Host模式:只能通过运行服务副本的节点来访问。

docker网络——命令

  • docker network ls :列出运行在本地的docker主机的全部网络
  • docker network create :创建新的docker网络。默认采用的是bridge 加-d参数指定(网络类型)
  • docker network inspect:提供docker网络的详细配置信息。
  • docker network prune:删除docker主机上全部未使用的网络。
  • docker network rm :删除docker主机上指定的网络

你可能感兴趣的:(Docker学习(11) Docker 网络)