可以再找一些资料补充一下知识:(也没必要太全,毕竟不是运维)
1 Docker 网络端口映射
在启动容器的时候,可以配置容器的端口映射方式。一种是随机端口映射,一种是指定端口映射。
# 随机端口映射
docker run -d -P microweb python app.py
# 指定端口映射
# 将主机的 8123 端口与容器的 80 端口绑定
docker run -d -p 8123:80 microweb python app.pydocker port 命令可以让我们快捷地查看端口的绑定情况。
docker port microweb 80 # 127.0.0.1:81232 Docker 网络模式
Docker 网络模式有四种:bridge、host、none、container。
- bridge 模式:为每一个容器分配、设置 IP 等,并将容器连接到一个
docker0。属于虚拟网桥,默认配置。 - host 模式:容器将不会虚拟出自己的网卡、配置自己的 IP,而是使用宿主机的 IP 和端口。
- none 模式:容器有独立的 network namespace,但并没有对其进行任何网络设置,如分配 veth pair 和网络链接、IP 等。
- container 模式:新创建的容器不会创建自己的网卡和配置自己的 IP,而是和一个指定的容器共享 IP 、端口范围等。
在启动容器的时候可以指定 Docker 网络模式。
# 默认就是 bridge 模式
docker run -d -p 8081:8080 billygoo/tomcat8-jdk8
docker run -d -p 8081:8080 --network billygoo/tomcat8-jdk8
# host 模式,此时配置端口映射会 warning
docker run -d --network=host billygoo/tomcat8-jdk8
# none 模式
docker run -d --network=none billygoo/tomcat8-jdk8
# container 模式
docker run -d --network=container:NAME_OR_ID billygoo/tomcat8-jdk83 查看 Docker 网络命令
3.1 查看网络模式
docker network ls
---
NETWORK ID NAME DRIVER SCOPE
a097979797 bridge bridge local
lkasjdfljl host host local
sjaklfajas none null local3.2 查看网络信息
docker inspect a097979797
---
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "10.11.0.0/16",
"Gateway": "10.11.0.1"
}
]
},3.3 删除网络
docker network rm 网络名字3.4 查看网络命令
docker network --help
---
docker network COMMAND
Commands:
connect: connect a container to a network
create: create a network
disconnect: disconnect a container to a network
inspect: display detailed info on one or more networks
ls: list networks
prune: remove all unused networks
rm: remove one or more networks4 了解 Docker 网络模式
Docker 网络模式的用处
- 容器间的互联和通信以及端口映射
- 容器 IP 变动时候可以通过服务名直接网络通信而不受到影响
Docker 容器 IP 地址分配
- 创建 docker1、docker2,通过 docker network inspect 观察两个的网络 IPAddress。
- 关闭 docker2,创建 docker3,再次观察 docker3 的网络 IPAddress,发现和原 docker2 的地址是一样的。


Docker 不启动,默认的网络情况:

在 CentOS7 的安装过程中如果有选择相关虚拟化的的服务安装系统后,启动网卡时会发现有一个以网桥连接的私网地址的 virbr0 网卡(virbr0 网卡:它还有一个固定的默认 IP 地址 192.168.122.1),是做虚拟机网桥的使用的,其作用是为连接其上的虚机网卡提供 NAT 访问外网的功能。
Docker 启动后,网络情况:
会产生一个名为 docker0 的虚拟网桥。

5 bridge 模式
Docker 服务默认会创建一个 Docker 容器网桥(其上有一个 docker0 内部接口),该桥接网络的名称为 docker0。Docker 容器上会有名为 eth0 的网卡接口与网桥上的 veth 接口进行一一匹配,从而彼此联通。
它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。Docker 默认指定了 docker0 接口的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信。
-
Docker 使用 Linux 桥接,在宿主机虚拟一个 Docker 容器网桥(docker0),Docker 启动一个容器时会根据 Docker 网桥的网段分配给容器一个 IP 地址,称为 Container-IP,同时 Docker 网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。
-
docker run 的时候,没有指定 network 的话默认使用的网桥模式就是 bridge,使用的就是 docker0。在宿主机 ifconfig,就可以看到 docker0 和自己 create 的 network(后面讲)eth0,eth1,eth2……代表网卡一,网卡二,网卡三……,lo 代表 127.0.0.1,即 localhost,inet addr 用来表示网卡的 IP 地址
-
网桥 docker0 创建一对对等虚拟设备接口一个叫 veth,另一个叫 eth0,成对匹配。
- 整个宿主机的网桥模式都是 docker0,类似一个交换机有一堆接口,每个接口叫 veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫 veth pair);
- 每个容器实例内部也有一块网卡,每个接口叫 eth0;
- docker0 上面的每个 veth 匹配某个容器实例内部的 eth0,两两配对,一一匹配。
通过上述,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一个网络下,会从这个网关下各自拿到分配的 ip,此时两个容器的网络是互通的。

验证 bridge 模式 - 容器 eth0 与主机 veth
docker run -d -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8
6 host 模式
容器将不会虚拟出自己的网卡、配置自己的 IP,而是使用宿主机的 IP 和端口,不再需要额外进行 NAT 转换。

# 创建容器 正确示例
docker run -d --network host --name tomcat83 billygoo/tomcat8-jdk8
# 创建容器 错误示例
# 由于使用 host 模式,所有不会进行端口映射。此时会提示 warning。
docker run -d -p 8083:8080 --network host --name tomcat83 billygoo/tomcat8-jdk8
# 访问容器 tomcat83
http://宿主机IP:8080/// 查看网络信息,发现 Gateway 和 IPAddress 均为空了
docker inspect tomcat83 | tail -n 20
---
"Networks":{
"host": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "ae13c04d76263af4ed36cef3f63a945d...",
"EndpointID": "bbdb4ba60381326b6224d3f9dbcd567...",
"Gateway": "",
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "",
"DriverOpts": null
}
}7 none 模式
在 none 模式下,并不为 Docker 容器进行任何网络配置。
也就是说,这个 Docker 容器没有网卡、IP、路由等信息,只有一个 lo。
lo 就是 127.0.0.1 表示本地回环。
需要我们自己为 Docker 容器添加网卡、配置 IP 等。
# none 模式创建方式
docker run -d -p 8084:8080 --network none --name tomcat84 billygoo/tomcat8-jdk88 container 模式
新建的容器和已经存在的一个容器共享一个网络 ip 配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。

# 创建容器 alpine1
docker run -it --name alpine1 alpine /bin/sh
# 创建容器 alpine2,网络依托于 alpine1
docker run -it --network container:alpine1 --name alpine2 alpine /bin/sh
# 进入容器内部后,查看网络,可以看到两者使用同一个 eth0
ip addr
# 当关闭容器 alpine1 后,alpine2 上的网络就没有 eth0 了
ip addr需要注意的是,使用 container 模式时,避免端口冲突。
# tomcat86和tomcat85公用同一个ip同一个端口,导致端口冲突
docker run -d -p 8085:8080 --name tomcat85 billygoo/tomcat8-jdk8
docker run -d -p 8086:8080 --network container:tomcat85 --name tomcat86 billygoo/tomcat8-jdk89 自定义网络
在之前,使用服务名进行 ping 会失败。Docker 自定义服务就是可以使得,同一个 network 下,容器之间可以通过服务名 (name) 而不是仅仅通过 IP 进行通信。多个容器的服务规划,就采用自定义网络服务,使得他们在同一个 network 下,避免了只能通过 IP 来通信、容器重启使得 IP 变更无法通信的情况。
自定义桥接网络,自定义网络默认使用的是桥接网络 bridge。
自定义网络本身就维护好了主机名和 ip 的对应关系(ip 和域名都能通)。
# 创建自定义 network
docker network create temp_network
# 创建容器加入自定义的 network
docker run -d -p 8081:8080 --network temp_network --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --network temp_network --name tomcat82 billygoo/tomcat8-jdk8
# 进入容器后,可以互相使用服务名进行 ping
ping tomcat82
ping tomcat81自定义网络下,可以使用 docker network inspect 网络名称 来查看当前子网下有哪些容器。通过下面可以看到,网络中已经建立起来了,容器名与 IP 的映射关系。
root@KitDevVps:~# docker network inspect mynet
[
...
"Containers": {
"2a26067838f1724347ef50a1b8988a50603715e514fb288ab86401571dc70173": {
"Name": "centos02",
"EndpointID": "83e59d8f388561cb006564de55bb1c76278ab54b0e87f1f7e671a9962efe3608",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"43f47db12bf4a8be9ea6172a89a44c530a23b29de49bf2a5ef95a88308675025": {
"Name": "centos01",
"EndpointID": "b0a1f17acc6a4c835952ae4e764c7f7e26a90fc3ce28be97cf9bb8c2ee0c10a4",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
]Docker 自定义网络中,还可以自定义子网、网关。docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet。具体参数可以通过 docker network create -h 进行查看。
Docker 自定义网络中,不同网桥/bridge 下的容器,无法通过 ip 进行 ping 通。通过 dockers network connect 另一个网桥名称 当前网桥的容器 命令,可以在当前容器下创建一个新的虚拟网卡,从而能 ping 通过。Site Unreachable (感觉自定义网络这里还是有些模糊)