一、 Docker默认的网络通信
1. Docker安装后默认的网络设置
Docker服务安装完成之后,默认在每个宿主机会生成一个名称为docker0的网卡其IP地址都是172.17.0.1/16
2. 创建容器后的网络配置
每次新建容器后:
- 宿主机多了一个虚拟网卡,和容器的网卡组合成一个网卡,比如: 137: veth8ca6d43@if136,而在容器内的网卡名为136,可以看出和宿主机的网卡之间的关联
- 容器会自动获取一个172.17.0.0/16网段的随机地址,默认从172.17.0.2开始,第二次容器为172.17.0.3,以此类推
- 容器获取的地址并不固定,每次容器重启,可能会发生地址变化
3. 容器间的通信
默认情况下,同一个宿主机的不同容器之间可以相互通信
4. 修改默认网络设置
新建容器默认使用docker0的网络配置,可以修改默认指向自定义的网桥网络
例: 用自定义的网桥代替默认的docker0
- 新建网桥
[root@localhost ~]# brctl addbr docker1
[root@localhost ~]# brctl show //显示所有网桥的信息
bridge name bridge id STP enabled interfaces
docker0 8000.024202703cc2 no
docker1 8000.000000000000 no
virbr0 8000.52540005857c yes virbr0-nic
[root@localhost ~]# ip a a 192.168.1.1/24 dev docker1 //给网桥设置地址 adress add
[root@localhost ~]# ip a
138: docker1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether aa:e0:3e:4c:9e:cd brd ff:ff:ff:ff:ff:ff
inet 192.168.1.1/24 scope global docker1
valid_lft forever preferred_lft forever
- 让容器使用docker1 网桥
`修改service 文件`
[root@localhost ~]# vim /usr/lib/systemd/system/docker.service
13 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -b docker1
//在启动命令行加入 -b docker1
- 重启服务
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# docker run -it centos:7.9 //进入容器
[root@13dddf5a694d /]# ifconfig
bash: ifconfig: command not found
[root@13dddf5a694d /]# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.2 13dddf5a694d
- 可以看网桥
[root@localhost ~]# docker run -d nginx
b1fff2e22fbe402596a3495feaa40eccb84c278f50b1c4ae64497b1f3d3ec3b2
[root@localhost ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.024202703cc2 no
docker1 8000.262a9ea12ee2 no vethdc13d7c
virbr0 8000.52540005857c yes virbr0-nic
5. 修改docker 0默认的网段
[root@localhost ~]#vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -bip 192.168.2.1/24
//在启动命令行加入 -b docker1
[root@localhost ~]#systemctl daemon-reload
[root@localhost ~]#systemctl restart docker
二、 容器名称互联
1. 介绍
新建容器时,docker会自动分配容器名称,容器ID和IP地址,导致容器名称,容器ID和IP都不固定,那么如何区分不同的容器,实现和确定目标容器的通信呢?
解决方案是给容器起个固定的名称,容器之间通过固定名称实现确定目标的通信。
2. 实现
docker run 创建容器,可使用--link选项实现容器名称的引用
docker run --name <容器名称> //先创建指定名称的容器
docker run --link <目标通信的容器ID或容器名称> //再创建容器时引用上面容器的名称
例:
- 先建立一个带有名字的容器
[root@localhost _data]# docker run -it --name c1 centos:7.9 bash
- 再建立第二个容器 和第一个连接
[root@localhost ~]# docker run -it --name c2 --link c1 centos:7.9 bash
[root@7aa539347616 /]# ping c1
PING c1 (172.17.0.2) 56(84) bytes of data.
64 bytes from c1 (172.17.0.2): icmp_seq=1 ttl=64 time=0.102 ms
64 bytes from c1 (172.17.0.2): icmp_seq=2 ttl=64 time=0.082 ms
64 bytes from c1 (172.17.0.2): icmp_seq=3 ttl=64 time=0.142 ms
三、 docker网络连接模式
Docker支持5种网络模式:
- brige :网桥模式 默认的模式,nat 地址转换
- host :容器和真机共享网络,直连
- none :没有网络只有一块回环网卡
- container :容器和容器共享网络,两个容器共用一块网卡
- network-name :自定义模式
使用
docker network ls命令查看默认的网络模式
1. 指定网络模式
默认新建的容器使用Bridge模式,创建容器时,docker run 命令使用以下选项指定网络模式
docker run --network <mode>
docker run --net=<mode>
<mode>: 可是以下值
none
bridge
host
container:<容器名或容器ID>
<自定义网络名称>
2. brige模式
本模式是docker的默认模式,即不指定任何模式就是bridge模式,也是使用比较多的模式,此模式创建的容器会为每一个容器分配自己的网络IP等信息,并将容器连接到一个虚拟网桥与外界通信。
可以和外部网络之间进行通信,通过SNAT访问外网,使用DNAT可以让容器被外部主机访问,所以此模式也称为NAT模式。
bridge网络模式特点:
- 网络资源隔离:不同宿主机的容器无法直接通信,各自使用独立网络
- 无需手动配置:容器默认自动获取172.17.0.0/16的IP地址,此地址可以修改
- 可访问外网:利用宿主机的物理网卡,SNAT连接外网
- 外部主机无法直接访问容器:可以通过配置DNAT接受外网的访问
- 低性能较低:因为通过NAT,网络转换带来更多的损耗
- 端口管理繁琐:每个容器必须手动指定唯一的端口,容器产生端口冲容
⭐使用此模式一定要net.ipv4.ip_forward
修改默认的bridge模式网络配置
[root@localhost ~]#vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"], //指定了Docker镜像的镜像加速地址,Docker将会从这个镜像地址加速器下载镜像
"bip": "192.168.100.100/24", //指定了Docker守护进程使用的网桥的IP地址和子网掩码
"fixed-cidr": "192.168.100.128/26", //用于配置Docker守护进程的固定CIDR地址,指定了Docker守护进程的固定CIDR地址范围
"default-gateway": "192.168.100.200" //指定了Docker守护进程使用的默认网关地址。容器将使用这个默认网关来访问外部网络
}
//注意每一行结尾加,逗号 最后一行不用加
3. host模式
如果指定host模式启动容器,那么新创建的容器不会创建自己的虚拟网卡,而是直接使用宿主机的网卡和IP地址,因此在容器里面查看到的IP信息就是宿主机的信息,访问容器的时候直接使用 宿主机IP+容器端口 即可,不过容器内除网络以外的其它资源,如: 文件系统、系统进程等 仍然和宿主机保持隔离。
此模式由于直接使用宿主机的网络无需转换,网络性能最高,但是各容器内使用的端口不能相同,适用于运行容器端口比较固定的业务。
Host 网络模式特点:
- 使用参数 --network host 指定
- 共享宿主机网络
- 网络性能无损耗
- 网络故障排除相对简单
- 各容器网络无隔离
- 网络资源无法分别统计
- 端口管理困难:容易产生端口冲突
- 不支持端口映射
例:
docker run -d --network host --name web1 nginx
4. none模式
在使用none 模式后,Docker 容器不会进行任何网络配置,没有网卡、没有IP也没有路由,因此默认无法与外界通信,需要手动添加网卡配置IP等,所以极少使用。
none模式特点:
- 使用参数 --network none 指定
- 默认无网络功能,无法和外部通信
例:
docker run -it --network none centos:7.9
5. container模式
使用此模式创建的容器需指定和一个已经存在的容器共享一个网络,而不是和宿主机共享网,新创建的容器不会创建自己的网卡也不会配置自己的IP,而是和一个被指定的已经存在的容器共享IP和端口范围,因此这个容器的端口不能和被指定容器的端口冲突,除了网络之外的文件系统、进程信息等仍然保持相互隔离,两个容器的进程可以通过lo网卡进行通信。
Container 模式特点:
- 使用参数 –-network container:名称或ID 指定
- 与宿主机网络空间隔离
- 空器间共享网络空间
- 适合频繁的容器间的网络通信
- 直接使用对方的网络,较少使用
例:
[root@localhost ~]#docker run -d --name web1 nginx
[root@localhost ~]#docker run -d --name web2 --network container:web1 nginx