Docker之网络
1. 端口映射
-P 宿主机会随便产生一个端口映射容器内部的端口
-p 自定义宿主机的端口映射容器内部的端口
Local_Port:Container_Port
Local_IP:Local_Port:Container_Port
Local_IP::Container_Port 与-P相似
Local_Port:Container_Port/[tcp/udp]
2. 端口暴露
1. 在dockerfile使用EXPOSE命令
2. docker运行时指定--expose
3. 容器互联
1. 两个容器使用一个自定义的网络
1. 创建两个容器
docker run -itd --name=container1 busybox
docker run -itd --name=container2 busybox
2. 创建自定义网络
docker network create -d bridge --subnet 172.25.0.0/16 demo_net
3. 将容器连接到自定义网络
docker network connect demo_net container1
docker network connect demo_net container2
4. 启动第三个容器
docker run --network=demo_net -itd --name=container3 busybox
4. Docker的网络模式
docker network ls 查看docker网络
docker network inspect [bridge|host|none|自定义网桥名称]
1. bridge
默认网络模式,使用docker0作为网桥。默认创建的容器也是加入到这个网络中。
2. host
容器不会获得一个独立的network namespace,而是与宿主机公用一个。
容器内可以看到宿主机的网卡信息
3. none
获取独立的network namespace,但不为容器进行任何网络配置。
4. container
与指定的容器使用同一个network namespace,网卡配置也都是相同的。
5. 自定义
与bridge网络一样。
5. bridge网络
当启动docker时,会自动生成一个名为docker0的Linux bridge(网桥)。bridge可以看成是一个软件交换机,负责对挂载在它上面的接口进行包转发。

每个容器使用bridge模式启动时,Docker都会为容器创建一对虚拟网络接口(veth pair)设备,这对设备一端在容器的Network NameSpace,另一端在docker0。
6. host网络
在启动容器时使用--network host指定为本机网络,则容器将与宿主机共享网络栈,此时容器会使用主机的IP以及其他网络配置。
使用host网络时,对容器做端口映射将会无效, 容器会忽略 -p 所指定的端口,而直接在宿主机网络层面开启对应端口。例如,容器中如果开放了80端口,那么此时宿主机也将开放同样端口。
host网络相比bridge网络具有更高的性能,同时在容器有大量端口要开放的时候 ,也会省事很多。但同时也增加了不安全性,此时可在容器内对主机的网络栈进行操作,所以并不推荐使用。
docker run -itd --net=host nginx:alpine
7. none网络
none网络会禁用容器的网络栈,使得容器与外部隔离。在启动时通过 --network none 实现。此时,容器除lo外,将不再有其他网卡,完全与外部网络隔离。
8. container模式
这个模式表示与另一个运行中的容器共享一个network namespace,共享意味着拥有相同的网络视图
1. 启动一个容器
docker run -itd --name nginx nginx:alpine
2. 再启动一个容器,使用上面容器的网络
docker run --net=container:nginx -it nginx:alpine
8. 自定义网络
1. 创建网络桥
docker network create -d bridge --subnet "172.16.0.0/16" --gateway "172.16.0.1" mybr0
2. 查看是否有网络
docker network ls
3. 查看网络详细信息
docker network inspect mybr0
4. 创建容器
docker run -it -d --name mynginx-v1 --network mybr0 -p 81:80 mynginx:v1
5. 删除网桥
docker network rm mybr0
9. 容器内部与外部网络互通访问
安装docker时,默认会启用Linux的包转发功能,如下:
$ sudo sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
1. 容器内部访问外部网络
查看宿主机iptables的nat表上面的POSTROUTING链规则,可看到一条转发规则
iptables -L -n -v -t nat POSTROUTING
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
该规则的作用是当docker0收到来自容器网段(172.17.0.0/16)的网络包时,将其交给MASQUERADE处理。MASQUERADE与传统的SNAT相似,会将网络包的源IP替换为网卡IP,这样可以保证容器的网络包能够正常外出。
2. 外部网络访问容器内部
我们开放了80端口,那么会在iptables规则里,加一条DNAT规则
1198K 69M DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.11:80
该规则将访问到主机80端口的网络包,转发到容器地址(172.17.0.2)的80端口,以此实现外部网络对容器的访问。
10. 容器的整体网络架构

11. 修改docker0桥的网段地址
1. 停止docker服务
2. 修改/etc/docker/daemon.json文件的内容
{"insecure-registries": ["172.16.20.215:5000"],
"bip": "192.168.110.1/24"
}
3. 启动docker服务,可以看到docker0的IP地址已经修改。
12. 远程连接docker服务
1. 停止docker服务
2. 修改/etc/docker/daemon.json文件的内容
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"hosts": ["tcp:0.0.0.0:2375","unix:///var/run/docker.sock"]
}
3. 启动docker服务
4. 客户端连接的时候,需要指定docker -H 192.168.1.100:2375 ps
13. 查看单个容器的IP地址
docker inspect 容器名称或容器ID | grep IPAddress | grep [1-9] | awk '{print $2}' | sort|uniq | awk -F '"' '{print $2}'
docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称或容器ID
14. 查看所有容器的IP地址
1. 获取所有容器名称及其IP地址
docker inspect -f '{{.Name}} - {{.NetworkSettings.IPAddress }}' $(docker ps -aq)
2. 如果是docker-compose启动的容器,使用下面的命令查看
docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
docker inspect --format='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)

浙公网安备 33010602011771号