一、四种网络模式
bridge模式:使用–-network bridge指定,默认使用docker0;
host模式:使用–-network host指定;
none模式:使用–-network none指定;
container模式:使用–-network container:NAMEorID指定。
1、bridge——网络通信
bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上(docker0)。
两个容器的进程可以通过lo网卡设备通信。 (ip不共享,但是两容器可以通过网络进行通信,可以ping)
a、创建自定义网络(网桥)
选取了172.18.0.0网段,也可以指定其他任意空闲的网段
1.docker network create --subnet=172.18.0.0/16 shadownet
2.docker network create --driver bridge my-net (随机分配一个子网和ip)
注:shadown为自定义网桥的名字,可自己任意取名。
b、在你自定义的网段选取任意IP地址作为你要启动的container的静态IP地址
docker run -d --net shadownet --ip = 172.18.0.0 //一个ip只能被一个容器使用
2、host模式
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
3、none模式
在none模式下,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。 也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
4、container——网络共享(公用ip)
这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。 新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。 同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。
二、相关命令
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 ls 查看网络
docker network inspect my-net 查看网络源数据
docker network rm mynet 删除网络
三、容器间的网络互连
1、自定义bridge网络
docker network create mynet
同个自定义network下,ip不同,可以互ping。也就是容器处于同一个局域网下。
如果使用的是 user-defined 网络(自定义的network),我们借助 docker daemon 内嵌的 DNS server,容器间可以直接通过“容器名”通信。
注意:默认的 bridge 网络(docker0)下,容器是无法使用容器名互通的。
docker run -itd --network=test --name alpine1 alpine:latest /bin/sh
docker run -it --network=test --name alpine2 alpine:latest /bin/sh
在alpine2中,ping alpine1是可以直接ping通的。
ifconfig查看ip也是不一样的。
2、link连接容器
docker run -d --name db -e MYSQL_ROOT_PASSWORD=server mysql
docker run -d --name web --link db:aliasdb nginx
link机制和/etc/hosts:使用了link机制后,可以通过指定的名字来和目标容器通信,这其实是通过给/etc/hosts中加入名称和IP的解析关系来实现的。
可以进入web容器内部查看/etc/hosts,可以发现多了一行:172.17.0.8 aliasdb c1a7c7f091eb db,这样不用知道对方ip,可以通过别名进行通信;也不用担心容器重启后ip会改变;
3、container模式共享网络(共享ip)
也就相当于同一个主机中的多个进程了,需要考虑端口冲突的问题;
共享网络下,如何访问其他容器的服务?
直接127.0.0.1+port就行了。
docker run -itd --network=test --name alpine1 alpine:latest /bin/sh
docker run -it --network=container:alpine1 --name alpine2 alpine:latest /bin/sh
在alpine2中,查看ip可以发现两个容器的ip是相同的。
四、其他
1、关于网络配置
在安装docker时,会自动创建一个默认的bridge网络docker0。
docker run 的时候,没有指定network的话,使用的就是docker0
在宿主机ifconfig,就可以看到docker0,和自己create的network
eth0,eth1,eth2……代表网卡一,网卡二,网卡三…… lo代表127.0.0.1,即localhost
inet addr用来表示网卡的IP地址
两个容器在同个自定义网络下,会从这个网关下各自拿到分配的ip,此时两个容器的网络是互通的;
使用默认网络(docker0),还是这样分配的,但是容器的网络就不互通了;
2、用户定义网络中的网桥与默认网络中的网桥之间的差异
- 连接到同一个自定义网桥的容器会自动将所有端口相互暴露,而不会向外界显示任何端口。 如果使用默认网络(docker0),则需要--link或拿到容器ip才能相互通信;
- 在同一个桥接网络上,容器可以通过容器名称或别名相互解析。(DNS服务)
- 在容器的生命周期中,可以动态地将其与用户定义的网络连接或断开连接。
3、如何给容器指定一个固定 IP 地址,而不是每次重启容器 IP 地址都会变?
docker network create -d bridge --subnet 172.25.0.0/16 my-net docker run --network=my-net --ip=172.25.3.3 -itd --name=my-container busybox
4、一个容器多个网络
如果两个容器一开始运行时处于不同的 user-defined 网络,可以通过 docker network connect 命令添加另一个容器的网络;
5、docker0网桥配置的修改
问题起因:内网172.0....无法访问,原来是因为和docker0的网段冲突了
sudo vim /etc/docker/daemon.json
在daemon.json下追加以下配置
{
"bip": "10.125.0.1/16" //这个是自定义的
}
执行以下命令重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker.service
使用ifconfig查看docker0网卡配置信息,如inet为10.125.0.1即为配置成功
172.17都会和172服务器冲突,不管是docker0还是自己创建的network。
也就是说我在本机访问172.17是直接访问docker0,而不是访问172服务器,所以会产生172无法访问的现象