关于 Docker 系列其他文章的传送门
《 简单了解 Linux 容器是什么 以及 Docker 常用命令操作说明 》
《 Docker 中 4 种网络模型的概念和实现 》 您当前所在位置
《 关于 Docker 中镜像与存储卷的概念和详细使用方法 》
《 使用 Dockerfile 定制镜像 搭建 php 站点 》
《 使用 Harbor 创建本地 Docker 仓库 》
Docker 网络
虚拟网络分类
首先,回顾一下虚拟化中的四种网络类型。
类型
描述
隔离桥
内部网络完全封闭,只能内部通信
仅主机桥
在隔离的基础上,仅能和宿主机通信
路由桥
内网主机可以通过路由把报文转发出去,但是如果外部没有对应的路由,报文是回不来的
NAT 桥
内网主机报文通过 NAT 桥上的网关地址转发出去,回来时再通过 连接追踪 机制转发给内网主机
这篇《 一篇文章讲解什么是虚拟化和 kvm 的使用方法 》 详细描述了各种网络模型的实现方法
Docker 中的网络分类
Docker 中也有四种网络,但是 Docker 中的网络使用了 Linux Bridge 和 namespace 机制,类似于虚拟化中的网络,但又不完全一样
这里说明 Docker 的网络分类和使用方法
类型
描述
桥网络
类似虚拟机中的网桥,默认是 docker(NAT)
共享桥网络
将 6 种名称空间内的 UTS、IPC、Network 共享,但是其他 3 个依然独立,也称之为 联盟式网络,这样在共享桥内的网络就像在同一台主机运行一样,但是 Mount、User 和 PID 依然独立
共享宿主机网络
容器直接使用宿主机的根网络名称空间,宿主机能看到网络信息,容器内也都可以看到
none 网络
无网络,就好像没有网卡的计算机设备
这张图展现了 4 种 Docker 网络的区别 :
四种网络的使用方法
第 1 种 桥网络
创建容器 node1 并指定使用
1 2 3 4 5 6 7 8 9 docker container run --name node1 --rm -it --network bridge centos:7 # --rm 停止即删除 # 指定网络使用 bridge,也是默认 # 查看 ip 等信息,可以看到 ip 地址为 172.17.0.2/16 [root@aec511c03380 /] ip a show eth0 63: eth0@if64: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
第 2 种 共享桥网络
再创建一个容器 node2,并指定使用 node1 的网络
1 2 3 4 5 6 7 8 9 docker container run --name node2 --rm -it --network container:node1 centos:7 # 这里把网络指向了第一个容器的网络 # 查看 node2 的 ip 等信息,发现不仅 ip 地址和 node1 一样,连 mac 和主机名都一样。但是文件、进程等都是隔离的 [root@aec511c03380 /] ip a show eth0 63: eth0@if64: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
第 3 种 共享宿主机网络
创建一个 node3,并指定使用宿主机的命名空间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 docker container run --name node3 --rm -it --network host centos:7 # 这里指定网络类型为 host # 查看 node3 的 ip 等信息,发现所有网卡、主机名等信息都和宿主机一毛一样了,但是文件、进程依旧都是隔离的 [root@docker /] ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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 inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br-ex state UP group default qlen 1000 link/ether 00:0c:29:cf:e7:f6 brd ff:ff:ff:ff:ff:ff 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:22:ce:de:82 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:22ff:fece:de82/64 scope link valid_lft forever preferred_lft forever 36: br-ex: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 00:0c:29:cf:e7:f6 brd ff:ff:ff:ff:ff:ff inet 192.168.50.11/24 brd 192.168.50.255 scope global noprefixroute br-ex valid_lft forever preferred_lft forever inet6 fe80::b052:84ff:fe4c:df5c/64 scope link valid_lft forever preferred_lft forever 64: veth98cb889@if63: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 3e:f0:a6:03:15:27 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::3cf0:a6ff:fe03:1527/64 scope link valid_lft forever preferred_lft forever
第 4 种 none 网络
也就等于设备没有网卡
1 2 3 4 5 6 7 8 9 docker container run --name node3 --rm -it --network none centos:7 # 指定网络为 none # 查看 ip 等信息发现,只有一个回环地址 [root@d98998a4e071 /] ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
注入网络类信息
常用的网络注入选项,建议使用 docker network --help 查看帮助信息
容器类命令中的网络参数
1 2 3 4 5 6 7 8 docker container: ###### 容器类命令 ###### run # 创建+启动 -h # 指定容器的主机名 = --hostname --add-host # 注入解析到 hosts 文件 --dns # 注入 dns 地址 --dns-search # 注入搜索域 -p # 定制对外暴露的方式 (DNAT)
1. 创建容器
1 2 3 4 5 6 docker run --name node1 -it \ -h node1.template.com \ # 注入主机名为 node1 --add-host www.template.com:192.168.1.1 \ # 注入一条解析到 /etc/hosts 下 --dns 114.114.114.114 \ # 指定 dns 服务器 ip --dns-search template.com \ # 指定 dns 搜索域 centos # 使用 centos 镜像
2. 查看
可以看到主机名已经注入了 node1,再查看 hosts 信息,也已经有了我们指定的解析 "192.168.1.1 www.template.com"
1 2 3 4 [root@node1 /] cat /etc/hosts 127.0.0.1 localhost 192.168.1.1 www.template.com 172.17.0.2 node1.template.com node1
查看 DNS 信息,看到指定的 search 和 nameserver 都应设置成功了。
1 2 3 [root@node1 /] cat /etc/resolv.conf search template.com nameserver 114.114.114.114
常用的网络类注入就搞定了,简单吧!
创建 Docker 网络
如果不想使用默认的网络,也可以自己创建 Docker 网络。
网络类参数
1 2 3 4 5 6 7 8 9 10 docker network: ###### 网络类选项 ###### ls # 显示当前的网络信息 create # 创建网络 -d # 驱动 默认 bridge --subnet # 指定子网,默认第一个地址是网关 --gateway # 指定网关 --ip-range # 设定 ip 地址范围 connect # 把指定的网络(接口)连接到容器 disconnet # 从容器拆除指定的网络(接口)
1.创建网络
1 2 3 4 5 6 docker network create \ # 创建一个叫 mybr0 的网络 -d bridge \ # 指定网络类型为 bridge --subnet 10.10.0.0/16 \ # 指定子网范围 --gateway 10.10.10.1 \ # 指定网关,默认为可用地址的第一个 --ip-range 10.10.50.0/24 \ # 设定 ip 范围,默认为全部可用 ip 地址 mybr0 # 网络名字为 mybr0
2.启动一个容器
指定使用刚才创建的 mybr0 网络
1 docker container run --name node1 --rm -it --network mybr0 centos
3.查看
进入容器查看获取到的 ip,就是刚才创建的 mybr0 中的地址
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@0fe7b88ec7ff /] ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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 172: eth0@if173: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:0a:0a:32:00 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.10.50.0/16 brd 10.10.255.255 scope global eth0 valid_lft forever preferred_lft forever [root@0fe7b88ec7ff /] ip route default via 10.10.10.1 dev eth0 10.10.0.0/16 dev eth0 proto kernel scope link src 10.10.50.0
如果想给容器添加一个网络(接口),可以这样使用 :
1 2 docker network connect mybr0 node1 # 给容器添加一个 mybr0 网络 (接口) docker network disconnect mybr0 node1 # 将 mybr0 网络 (接口) 从容器拆除
开放入站通信
如果容器内部运行了一个服务,想要对外开放,可以把端口映射到宿主机上,方法是在启动容器时,加入 -p 选项指定映射方式
-p 选项的使用格式 :
(1). -p <containerPort> 将容器的指定端口,映射至主机所有地址的一个动态端口
(2). -p <hostPort>:<containerPort> 将容器的指定端口,映射至主机的指定端口
1 docker run -p 10080:80 nginx
(3). -p <ip>::<containerPort> 将容器指定的端口,映射至主机指定的动态端口
1 docker run -p 192.168.50.11::80 nginx
(4). -p <ip>:<hostPort>:<containerPort> 将容器的指定端口,映射至主机指定的 ip 和指定的端口
1 docker run -p 192.168.50.11:10080:80 nginx
查看指定容器的端口映射关系:
1 2 3 4 docker port <CONTAINER_NAME> ~ ] docker port nginx 80/tcp -> 0.0.0.0:80