1)Docker网络简介
Docker 容器内部运行应用服务,这些应用服务之间的交互依赖于大量不同的网络,这意味着 Docker 需要强大的网络功能。Docker 对于**容器之间**、**容器与外部网络**的连接均有相应的解决方案
- Docker 网络架构: 容器网络模型(CNM)的方案
- Libnetwork 是 Docker 对 CNM 的一种实现,提供了 Docker 核心网络架构的全部功能;为了实现开箱即用的效果,Docker 封装了一系列本地驱动
- Docker 网络架构的设计规范是 CNM, CNM 定义了 3 个基本要素:沙盒(Sandbox)、终端(Endpoint)和网络(Network)
- Libnetwork 实现了控制层和管理层功能,那么驱动就负责实现数据层,Docker 封装了若干内置驱动
- 第三方也可以编写 Docker 网络驱动,例如 Calico,flannel等

2)理解容器网络
2.1)容器自带网络(安装docker后默认的网络)
- 当Docker成功安装后,默认会创建3种网络,通过docker network ls进行查看,如下 ```bash [root@blog-server ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 58bc4feeec20 bridge bridge local (默认) 5ce92b51826e host host local 9b232e660bc2 none null local
- 理解Docker0每个 Docker 主机都有一个默认的单机桥接网络,**在docker安装之后,就会产生一个docker0的虚拟网桥,默认为172.17.0.0/16网段**,如下图```bash[root@blog-server ~]# ip addr1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 00:16:3e:03:0f:6d brd ff:ff:ff:ff:ff:ffinet 192.168.0.17/24 brd 192.168.0.255 scope global dynamic noprefixroute eth0valid_lft 303183090sec preferred_lft 303183090secinet6 fe80::216:3eff:fe03:f6d/64 scope linkvalid_lft forever preferred_lft forever3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group defaultlink/ether 02:42:8b:c1:66:f6 brd ff:ff:ff:ff:ff:ffinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0valid_lft forever preferred_lft foreverinet6 fe80::42:8bff:fec1:66f6/64 scope linkvalid_lft forever preferred_lft forever
"Driver": "bridge""Subnet": "172.17.0.0/16""com.docker.network.bridge.name": "docker0"[root@blog-server ~]# docker network inspect 58bc4feeec20[{"Name": "bridge","Id": "58bc4feeec20da7be6b3d2d77d02d772e99056fe6f5d1aa3ba59d7330a82e206","Created": "2020-10-30T15:48:37.561040485+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": {"5c86635ded7ccef0004f700c2c6db86b1b2279879c4a425b2110ff0728d1e95e": {"Name": "notebook_test1","EndpointID": "1fc26f4d845a3dd7b4738ea8cbfdb365afd3759cea11ebc760e14834093fc78f","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": {}}]
2.2)理解docker网络模型
None网络
场景: 对于安全性要求高且不需要联网的应用,比如生成随机码等
使用方式如下图: ```shell [root@blog-server ~]# docker run -it —network=none busybox Unable to find image ‘busybox:latest’ locally latest: Pulling from library/busybox e5d9363303dd: Pull complete Digest: sha256:c5439d7db88ab5423999530349d327b04279ad3161d7596d2126dfb5b02bfd1f Status: Downloaded newer image for busybox:latest / # ifconfig lo Link encap:Local Loopbackinet addr:127.0.0.1 Mask:255.0.0.0UP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
- host容器技术,通过Namespace隔离,其中就有net网络隔离,容器和宿主机使用不同的网络栈,如果采用host,那么容器和宿主机共享网络栈,通过-**-network=host**指定**优点: 性能、网络传输效率高,可以更方便跨主机通信**<br />**缺点: 容易造成端口冲突**```shell[root@blog-server ~]# docker run -it --network=host busybox/ # ip addr1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel qlen 1000link/ether 00:16:3e:03:0f:6d brd ff:ff:ff:ff:ff:ffinet 192.168.0.17/24 brd 192.168.0.255 scope global dynamic eth0valid_lft 303181446sec preferred_lft 303181446secinet6 fe80::216:3eff:fe03:f6d/64 scope linkvalid_lft forever preferred_lft forever3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueuelink/ether 02:42:8b:c1:66:f6 brd ff:ff:ff:ff:ff:ffinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0valid_lft forever preferred_lft foreverinet6 fe80::42:8bff:fec1:66f6/64 scope linkvalid_lft forever preferred_lft forever33: br-8b554b8f90d0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueuelink/ether 02:42:39:0b:29:68 brd ff:ff:ff:ff:ff:ffinet 172.23.0.1/16 brd 172.23.255.255 scope global br-8b554b8f90d0valid_lft forever preferred_lft foreverinet6 fe80::42:39ff:fe0b:2968/64 scope linkvalid_lft forever preferred_lft forever147: vethaefe9da@if146: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue master docker0link/ether fa:7e:db:83:18:96 brd ff:ff:ff:ff:ff:ffinet6 fe80::f87e:dbff:fe83:1896/64 scope linkvalid_lft forever preferred_lft forever
bridge
Docker安装时会创建一个命名为Docker0的linux brdige,如果启动容器不指定—network,创建的容器,默认会挂载到Docker0,如下图 ```shell yum -y install bridge-utils (安装命令)
[root@blog-xhaihua ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242488a40ae no
[root@blog-xhaihua ~]# docker run -itd busybox (启动容器) 05517c0b3839287020dcf55b5971f83a11b33cf63624e51919363b95f7b1e969
[root@blog-xhaihua ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242488a40ae no veth506039c
[root@blog-xhaihua ~]# docker exec -it 055 sh
/ # ip addr
1: lo:
<a name="4zQdp"></a>#### 2.3)用户自定义网络- 为什么要自定义网络安装docker后,默认的网络,是无法使用容器名相互ping通的,只能通过ip,自定义网络可以通过容器名互联- 自定义网络创建Docker提供三种自定义网络驱动: bridge,overlay,macvlan。```shell创建桥接网络,名为: my-net[root@blog-xhaihua ~]# docker network create --driver bridge my-net --subnet 172.22.0.0/16 --gateway 172.22.0.1cbae6791084cda285ced77da49ad0fb4b6b973208ecf46abcaa5eb855a3298de[root@blog-xhaihua ~]# docker network lsNETWORK ID NAME DRIVER SCOPE143edfe42427 blog_default bridge localb9cf8270fe55 bridge bridge localf2703670704a host host localcbae6791084c my-net bridge local9b1acb808174 none null local[root@blog-xhaihua ~]# ifconfig86: br-cbae6791084c: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group defaultlink/ether 02:42:02:dc:b2:66 brd ff:ff:ff:ff:ff:ffinet 172.22.0.1/16 brd 172.22.255.255 scope global br-cbae6791084cvalid_lft forever preferred_lft foreverinet6 fe80::42:2ff:fedc:b266/64 scope linkvalid_lft forever preferred_lft forever
- 自定义网络实战
```shell
[root@blog-xhaihua ~]# docker run -itd —name node02 —network=my-net busybox
1824961d3b4d6ec8ced68bfc1fe41a745010337302396e8f307f20fe2fd8f5e0
[root@blog-xhaihua ~]# docker run -itd —name node01 —network=my-net busybox
2e80b8c9426cd8d504987181e412c8eb6f56e3848139dfd28746c8e82872a760
[root@blog-xhaihua ~]# docker exec -it 18249 sh (进入容器)
/ # ip addr
1: lo:
mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo
93: eth0@if94:valid_lft forever preferred_lft forever
mtu 1500 qdisc noqueue link/ether 02:42:ac:16:00:02 brd ff:ff:ff:ff:ff:ff inet 172.22.0.2/16 brd 172.22.255.255 scope global eth0
/ # ping node02 (通过容器名互联) PING node02 (172.22.0.2): 56 data bytes 64 bytes from 172.22.0.2: seq=0 ttl=64 time=0.025 ms 64 bytes from 172.22.0.2: seq=1 ttl=64 time=0.063 msvalid_lft forever preferred_lft forever
<a name="iAlB4"></a>### 3)容器间通信- 通过IP通信- 通过DNS server(Docker daemon内嵌dns server)---通过容器名通信(启动容器使用--name为容器命名,比如--name=node01)<br /> 使用DNS的限制: 只能在自定义网络中使用,默认的docker0无法使用- joined容器joined容器非常特别,可以使2个或多个容器共享一个网络栈,共享网卡等信息,joined容器之间通过127.0.0.1直接通信(比如nginx+php,nginx+tomcat)```shell[root@blog-xhaihua ~]# docker run -itd --name=web1 httpd[root@blog-xhaihua ~]# docker run -itd --network=container:web1 busybox0d242204b502cd0fd6cb6cb7683c59727a4653debf58778ab2e1f4088bca1eeb
4) 容器与外部世界连接
- 容器访问外部世界 ```shell [root@blog-xhaihua ~]# iptables -t nat -vnL|grep 172.17 2 104 MASQUERADE all — * !docker0 172.17.0.0/16 0.0.0.0/0
[root@blog-xhaihua ~]# iptables -t nat -S -P PREROUTING ACCEPT -P INPUT ACCEPT -P OUTPUT ACCEPT -P POSTROUTING ACCEPT -N DOCKER -A PREROUTING -m addrtype —dst-type LOCAL -j DOCKER -A OUTPUT ! -d 127.0.0.0/8 -m addrtype —dst-type LOCAL -j DOCKER -A POSTROUTING -s 172.22.0.0/16 ! -o br-cbae6791084c -j MASQUERADE -A POSTROUTING -s 172.29.0.0/16 ! -o br-143edfe42427 -j MASQUERADE -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE -A POSTROUTING -s 172.29.0.3/32 -d 172.29.0.3/32 -p tcp -m tcp —dport 80 -j MASQUERADE -A DOCKER -i br-cbae6791084c -j RETURN -A DOCKER -i br-143edfe42427 -j RETURN -A DOCKER -i docker0 -j RETURN -A DOCKER ! -i br-143edfe42427 -p tcp -m tcp —dport 80 -j DNAT —to-destination 172.29.0.3:80
- 外部世界访问容器外部访问容器内部的服务,两种方案:1)通过端口映射 2)启动容器,使用--network=host共享宿主机网络```shell[root@blog-xhaihua ~]# docker run -d -p 82:80 httpd (-p 宿主机端口:容器端口)57b8690c12956d55ec7f02e654d3349bd1b611bb98e960a75d1c7fd19b5ce0c9[root@blog-xhaihua ~]# docker ps |grep 5757b8690c1295 httpd "httpd-foreground" 6 seconds ago Up 5 seconds 0.0.0.0:82->80/tcp charming_lovelace

跨主机通信
docker原生的overlay和macvlan,第三方的flannel、weave、calico

