1)Docker网络简介

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

六、Docker网络 - 图1

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
  1. - 理解Docker0
  2. 每个 Docker 主机都有一个默认的单机桥接网络,**在docker安装之后,就会产生一个docker0的虚拟网桥,默认为172.17.0.0/16网段**,如下图
  3. ```bash
  4. [root@blog-server ~]# ip addr
  5. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  6. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  7. inet 127.0.0.1/8 scope host lo
  8. valid_lft forever preferred_lft forever
  9. inet6 ::1/128 scope host
  10. valid_lft forever preferred_lft forever
  11. 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
  12. link/ether 00:16:3e:03:0f:6d brd ff:ff:ff:ff:ff:ff
  13. inet 192.168.0.17/24 brd 192.168.0.255 scope global dynamic noprefixroute eth0
  14. valid_lft 303183090sec preferred_lft 303183090sec
  15. inet6 fe80::216:3eff:fe03:f6d/64 scope link
  16. valid_lft forever preferred_lft forever
  17. 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
  18. link/ether 02:42:8b:c1:66:f6 brd ff:ff:ff:ff:ff:ff
  19. inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
  20. valid_lft forever preferred_lft forever
  21. inet6 fe80::42:8bff:fec1:66f6/64 scope link
  22. valid_lft forever preferred_lft forever
  1. "Driver": "bridge"
  2. "Subnet": "172.17.0.0/16"
  3. "com.docker.network.bridge.name": "docker0"
  4. [root@blog-server ~]# docker network inspect 58bc4feeec20
  5. [
  6. {
  7. "Name": "bridge",
  8. "Id": "58bc4feeec20da7be6b3d2d77d02d772e99056fe6f5d1aa3ba59d7330a82e206",
  9. "Created": "2020-10-30T15:48:37.561040485+08:00",
  10. "Scope": "local",
  11. "Driver": "bridge",
  12. "EnableIPv6": false,
  13. "IPAM": {
  14. "Driver": "default",
  15. "Options": null,
  16. "Config": [
  17. {
  18. "Subnet": "172.17.0.0/16",
  19. "Gateway": "172.17.0.1"
  20. }
  21. ]
  22. },
  23. "Internal": false,
  24. "Attachable": false,
  25. "Ingress": false,
  26. "ConfigFrom": {
  27. "Network": ""
  28. },
  29. "ConfigOnly": false,
  30. "Containers": {
  31. "5c86635ded7ccef0004f700c2c6db86b1b2279879c4a425b2110ff0728d1e95e": {
  32. "Name": "notebook_test1",
  33. "EndpointID": "1fc26f4d845a3dd7b4738ea8cbfdb365afd3759cea11ebc760e14834093fc78f",
  34. "MacAddress": "02:42:ac:11:00:02",
  35. "IPv4Address": "172.17.0.2/16",
  36. "IPv6Address": ""
  37. }
  38. },
  39. "Options": {
  40. "com.docker.network.bridge.default_bridge": "true",
  41. "com.docker.network.bridge.enable_icc": "true",
  42. "com.docker.network.bridge.enable_ip_masquerade": "true",
  43. "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
  44. "com.docker.network.bridge.name": "docker0",
  45. "com.docker.network.driver.mtu": "1500"
  46. },
  47. "Labels": {}
  48. }
  49. ]

六、Docker网络 - 图2
六、Docker网络 - 图3

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 Loopback

    1. inet addr:127.0.0.1 Mask:255.0.0.0
    2. UP LOOPBACK RUNNING MTU:65536 Metric:1
    3. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    4. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    5. collisions:0 txqueuelen:1000
    6. RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
  1. - host
  2. 容器技术,通过Namespace隔离,其中就有net网络隔离,容器和宿主机使用不同的网络栈,如果采用host,那么容器和宿主机共享网络栈,通过-**-network=host**指定
  3. **优点: 性能、网络传输效率高,可以更方便跨主机通信**<br />**缺点: 容易造成端口冲突**
  4. ```shell
  5. [root@blog-server ~]# docker run -it --network=host busybox
  6. / # ip addr
  7. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
  8. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  9. inet 127.0.0.1/8 scope host lo
  10. valid_lft forever preferred_lft forever
  11. inet6 ::1/128 scope host
  12. valid_lft forever preferred_lft forever
  13. 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel qlen 1000
  14. link/ether 00:16:3e:03:0f:6d brd ff:ff:ff:ff:ff:ff
  15. inet 192.168.0.17/24 brd 192.168.0.255 scope global dynamic eth0
  16. valid_lft 303181446sec preferred_lft 303181446sec
  17. inet6 fe80::216:3eff:fe03:f6d/64 scope link
  18. valid_lft forever preferred_lft forever
  19. 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
  20. link/ether 02:42:8b:c1:66:f6 brd ff:ff:ff:ff:ff:ff
  21. inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
  22. valid_lft forever preferred_lft forever
  23. inet6 fe80::42:8bff:fec1:66f6/64 scope link
  24. valid_lft forever preferred_lft forever
  25. 33: br-8b554b8f90d0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
  26. link/ether 02:42:39:0b:29:68 brd ff:ff:ff:ff:ff:ff
  27. inet 172.23.0.1/16 brd 172.23.255.255 scope global br-8b554b8f90d0
  28. valid_lft forever preferred_lft forever
  29. inet6 fe80::42:39ff:fe0b:2968/64 scope link
  30. valid_lft forever preferred_lft forever
  31. 147: vethaefe9da@if146: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue master docker0
  32. link/ether fa:7e:db:83:18:96 brd ff:ff:ff:ff:ff:ff
  33. inet6 fe80::f87e:dbff:fe83:1896/64 scope link
  34. valid_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: 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 valid_lft forever preferred_lft forever 84: eth0@if85: mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever

  1. <a name="4zQdp"></a>
  2. #### 2.3)用户自定义网络
  3. - 为什么要自定义网络
  4. 安装docker后,默认的网络,是无法使用容器名相互ping通的,只能通过ip,自定义网络可以通过容器名互联
  5. - 自定义网络创建
  6. Docker提供三种自定义网络驱动: bridge,overlay,macvlan。
  7. ```shell
  8. 创建桥接网络,名为: my-net
  9. [root@blog-xhaihua ~]# docker network create --driver bridge my-net --subnet 172.22.0.0/16 --gateway 172.22.0.1
  10. cbae6791084cda285ced77da49ad0fb4b6b973208ecf46abcaa5eb855a3298de
  11. [root@blog-xhaihua ~]# docker network ls
  12. NETWORK ID NAME DRIVER SCOPE
  13. 143edfe42427 blog_default bridge local
  14. b9cf8270fe55 bridge bridge local
  15. f2703670704a host host local
  16. cbae6791084c my-net bridge local
  17. 9b1acb808174 none null local
  18. [root@blog-xhaihua ~]# ifconfig
  19. 86: br-cbae6791084c: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
  20. link/ether 02:42:02:dc:b2:66 brd ff:ff:ff:ff:ff:ff
  21. inet 172.22.0.1/16 brd 172.22.255.255 scope global br-cbae6791084c
  22. valid_lft forever preferred_lft forever
  23. inet6 fe80::42:2ff:fedc:b266/64 scope link
  24. valid_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
    1. valid_lft forever preferred_lft forever
    93: eth0@if94: 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
    1. valid_lft forever preferred_lft forever
    / # 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 ms
  1. <a name="iAlB4"></a>
  2. ### 3)容器间通信
  3. - 通过IP通信
  4. - 通过DNS server(Docker daemon内嵌dns server)---通过容器名通信
  5. (启动容器使用--name为容器命名,比如--name=node01)<br /> 使用DNS的限制: 只能在自定义网络中使用,默认的docker0无法使用
  6. - joined容器
  7. joined容器非常特别,可以使2个或多个容器共享一个网络栈,共享网卡等信息,joined容器之间通过127.0.0.1直接通信(比如nginx+php,nginx+tomcat)
  8. ```shell
  9. [root@blog-xhaihua ~]# docker run -itd --name=web1 httpd
  10. [root@blog-xhaihua ~]# docker run -itd --network=container:web1 busybox
  11. 0d242204b502cd0fd6cb6cb7683c59727a4653debf58778ab2e1f4088bca1eeb

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. 外部访问容器内部的服务,两种方案:1)通过端口映射 2)启动容器,使用--network=host共享宿主机网络
  3. ```shell
  4. [root@blog-xhaihua ~]# docker run -d -p 82:80 httpd (-p 宿主机端口:容器端口)
  5. 57b8690c12956d55ec7f02e654d3349bd1b611bb98e960a75d1c7fd19b5ce0c9
  6. [root@blog-xhaihua ~]# docker ps |grep 57
  7. 57b8690c1295 httpd "httpd-foreground" 6 seconds ago Up 5 seconds 0.0.0.0:82->80/tcp charming_lovelace

image.png

  • 跨主机通信


    docker原生的overlay和macvlan,第三方的flannel、weave、calico