docker网络管理

本文最后更新于:2023年12月5日 晚上

docker 网络支持 5 种网络模式:none、bridge、host、container、network-net

创建新容器时,docker run命令可以指定网络模式:

docker run --network <mode>

# mode:默认是bridge
none
bridge
host
container:容器名或容器ID
自定义网络名称

bridge 模式

默认模式,容器连接到一个虚拟网桥与外界通信,通过 SNAT 访问外网,通过 DNAT 可以让容器被外部主机访问,所以此模式也称为 NAT 模式

此模式会启动宿主机的 ip_forward 功能

bridge 模式特点:

  • 网络资源隔离:不同主机的容器之间无法直接通信
  • 因为 NAT 转换,所以性能较低
  • 端口管理繁琐,每个容器必须手动指定唯一的端口,容易产生端口冲突

修改默认的 bridge 模式网络配置:

方法一:修改 docker.service

# docker0默认ip为172.17.0.1/16,修改为10.100.0.1/24
root@Z510:~# vim /usr/lib/systemd/system/docker.service
...
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --bip=10.100.0.1/24
...

方法二:修改 daemon.json,推荐这种方法

root@Z510:~# vim /etc/docker/daemon.json
# hosts 指定docker守护进程侦听的地址,默认/var/run/docker.sock
"hosts": ["tcp://0.0.0.0:2375", "fd://"],
"bip": "192.168.100.100/24", # docker0网卡的IP
"fixed-cidr": "192.168.100.128/26", # 分配给容器的IP范围
"fixed-cidr-v6": "2001:db8::/64",
"mtu": 1500,
"default-gateway": "192.168.100.200", # 网关必须和bip在同一个网段
"default-gateway-v6": "2001:db8:abcd::89",
"dns": [ "1.1.1.1", "8.8.8.8"]

host 模式

容器和宿主机之间网络不隔离(其他资源隔离),容器不创建自己的虚拟网卡,而是使用宿主机的网卡和 IP 地址,因此在容器里面查看到的 IP 信息就是宿主机的信息,访问容器的时候直接使用宿主机 IP+容器端口即可

此模式由于直接使用宿主机的网络无需转换,网络性能最高,但是各容器内使用的端口不能相同,适用于运行容器端口比较固定的业务

host 网络模式特点:

  • 共享宿主机网络
  • 网络性能无损耗
  • 网络故障排除相对简单
  • 各容器网络无隔离
  • 网络资源无法分别统计
  • 端口管理困难: 容易产生端口冲突
  • 不支持端口映射

范例:

docker run -d --network host --name web1 nginx-centos7-base:1.6.1

none 模式

容器不会进行任何网络配置,没有网卡、没有 IP 也没有路由,因此默认无法与外界通信,需要手动添加网卡配置 IP 等,所以极少使用

containter 模式

指定一个已经存在的容器(选择与其通信频繁的容器),共享其网络,因此这个容器的端口不能和被指定容器的端口冲突

这种模式也较少使用

自定义网络模式

# docker network --help
Usage: docker network COMMAND

Commands:
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

自定义网络内的容器可以直接通过容器进行相互的访问

可以使用自定义网络模式,实现不同集群应用的独立网络管理,而互补影响,而且在一个网络内,可以直接利用容器名称相互访问,非常便利

创建自定义网络:

# docker network create --help
Usage: docker network create [OPTIONS] NETWORK

Options:
      --attachable           Enable manual container attachment
      --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
      --config-from string   The network from which copying the configuration
      --config-only          Create a configuration only network
  -d, --driver string        Driver to manage the Network (default "bridge")
      --gateway strings      IPv4 or IPv6 Gateway for the master subnet
      --ingress              Create swarm routing-mesh network
      --internal             Restrict external access to the network
      --ip-range strings     Allocate container ip from a sub-range
      --ipam-driver string   IP Address Management Driver (default "default")
      --ipam-opt map         Set IPAM driver specific options (default map[])
      --ipv6                 Enable IPv6 networking
      --label list           Set metadata on a network
  -o, --opt map              Set driver specific options (default map[])
      --scope string         Control the network's scope
      --subnet strings       Subnet in CIDR format that represents a network segment
docker network create -d <mode> --subnet <CIDR> --gateway <网关> <自定义网络名称>

#注意mode不支持host和none

容器间通信

禁止同宿主机的不同容器间通信

docker.service

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --icc=false

daemon.json

"icc": false

容器名称互联

前文中,自定义网络模式,可以实现容器名称互联,如果是默认模式,想要实现这个功能,需要在创建容器时,使用–link 选项

范例:实现 a1 和 a2 容器名称互联

# 1. 创建容器a1
root@Z510:~# docker container run -it --name a1  alpine:latest
/ # hostname -i
172.17.0.2
# 2. 创建容器a2
root@Z510:~# docker container run -it --name a2 --link a1 alpine:latest
/ # hostname -i
172.17.0.3
/ # cat /etc/hosts
...
172.17.0.2 a1 6079167b0ed1
172.17.0.3 b4e8abef6893
/ # ping a1        # a2可以ping通a1
PING a1 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.191 ms
...
# 3. 修改容器a1的hosts
/ # vi /etc/hosts
# 添加如下行
172.17.0.3      a2 b4e8abef6893
/ # ping a2        # a1可以ping通a2
PING a2 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.135 ms
...

同宿主机之间不同网络的容器通信

同一个宿主机,创建两个容器,一个使用自定义网络,一个使用默认的 bridge 模式,默认这两个容器是无法通信的,如果想要实现通信,有两种方式:修改 iptables 规则 和 通过docker network connect实现

本笔记只记录第二种方式:

# docker network connect --help
Usage: docker network connect [OPTIONS] NETWORK CONTAINER

Options:
      --alias strings           Add network-scoped alias for the container
      --driver-opt strings      driver options for the network
      --ip string               IPv4 address (e.g., 172.30.100.104)
      --ip6 string              IPv6 address (e.g., 2001:db8::33)
      --link list               Add link to another container
      --link-local-ip strings   Add a link-local address for the container

范例:默认 docker0 中的容器为 test1,自定义网络 test-net 中的容器为 test2

# 1. 创建网络和容器,过程略...
# 2. 让默认网络中容器test1可以连通自定义网络test-net的容器test2
docker network connect test-net test1
ip a # 可以看到新增一个网卡,ip和test-net同网段
# 3. 让自定义网络中容器test2可以连通默认网络的容器test1
docker network connect bridge test2
ip a # 可以看到新增一个网卡,ip和docker0同网段

docker 容器创建后,必不可少的要和其它主机或容器进行网络通信

docker 的网络模式和 KVM 很相似

docker 网络连接模式

跨宿主机的容器之间网络通信

四种方法:

  1. 桥接
  2. NAT
  3. Open vSwitch
  4. weave

生产中,以上四种都不用,而是通过 k8s 实现,如果真的用到了,再回来复习课件

案例:docker & LVS 实现网络架构高可用

整体规划图:

过程略..


docker网络管理
http://blog.lujinkai.cn/运维/Docker/4.docker网络管理/
作者
像方便面一样的男子
发布于
2021年1月8日
更新于
2023年12月5日
许可协议