zl程序教程

您现在的位置是:首页 >  工具

当前栏目

我对 Docker 网络模型的理解

Docker网络 模型 理解
2023-09-27 14:25:57 时间
单机容器内的通信是通过 docker 自带的网桥连接互通的,如果是集群,那么做这些单机网络模型就行不通了,因为集群必然会将一个服务的多个任务需要分布到不同的机器上进行部署,因为如果把所有的任务都分配到一台机器部署了,这台服务器有故障,就会导致这个服务不能正常运行了,而且一个集群内,不同主机之间的容器是怎么进行通信的呢,这里我们就涉及到 docker 网络模型。

单机容器内的通信是通过 docker 自带的网桥连接互通的 如果是集群 那么做这些单机网络模型就行不通了 因为集群必然会将一个服务的多个任务需要分布到不同的机器上进行部署 因为如果把所有的任务都分配到一台机器部署了 这台服务器有故障 就会导致这个服务不能正常运行了 而且一个集群内 不同主机之间的容器是怎么进行通信的呢 这里我们就涉及到 docker 网络模型。


容器的端口映射


还记得 docker 单机部署时的 run -p port:port 吗 这样做的目的是将 docker 容器内的端口映射到宿主机的端口上 以便能够通过外网 ip 访问到 docker 容器 这时我们就想 如果我们把所有容器的接口都暴露在宿主机中 通过访问外网 ip 来达到容器间通信 这不是万事大吉了吗


但是在集群中如果这样暴露容器的端口 是有问题的 如果其中一个容器监听了宿主机 8080 端口 那么其他容器只能映射到其它端口了 因为端口并不能被共享 而且映射到宿主机的端口上 意味着容器也就暴露到外网了 如果要限制访问 那么就需要做一些安全配置。


单机网络模型


在介绍跨主机网络模型前 先来看看单机网络模型 在安装 docker 之后 docker 就会有 4 种网络模型 分别是


host 模式 使用 --net host 指定。container 模式 使用 --net container:NAME_or_ID 指定。none 模式 使用 --net none 指定。bridge 模式 使用 --net bridge 指定 默认设置。


但这四种网络模式都仅限于单机 其中 bridge 网络模型是 docker 的默认单机网络模型 它会将一个主机上的 docker 容器连接到一个虚拟网桥上 这个虚拟桥名称为 docker0 如下图

640.png

brige


单机中的容器之间就可以通过 docker0 互相通信了 但是如果容器被分布在不同主机上 在没有跨主机网络模型前 只能通过映射端口的形式来通信了。


640.png

brige


如上图 net1 和 net2 都代表一台主机中的 docker0 网络 在同主机下的容器通过 docker0 网络互相通信 但是在不同主机中却又是隔离的。


跨主机网络模型


docker 1.9 版本之后 加入了一个默认的 overlay 的网络模型 它是 docker swarm 内置的跨主机通信方案 这是一个基于 vxlan 协议的网络实现 其作用是虚拟出一个子网 让处于不同主机的容器能透明地使用这个子网。所以跨主机的容器通信就变成了在同一个子网下的容器通信 看上去就像是同一主机下的 bridge 网络通信。


关于详细的 vxlan 协议原理 请移步 vxlan 协议原理简介


在 swarm 管理节点发布的服务想要监听端口 只需要在 像 docker run 一样在后缀加 -p 8080:8080 就可以了 如下

$ docker service create --replicas 2 -p 8080:8080 --name hello \

chenghuizhang/helloword:0.0.2


但是跟 docker run 的 -p 又有本质的区别 实际上面那条命令并没有将 8080 端口直接暴露出去 而是将 8080 端口托付给 docker 的 overlay 网络模型中了。

640.png

docker ps


如上图可知 hello 服务的两个实例都在同一台服务器 都是 8080 端口 且没有映射到宿主机的端口上。


查看 docker 默认网络

$ docker network ls

640.png

docker network


其中 ingress 为 docker 默认的 overlay 网络。

查看 ingress 网络信息

$ docker network inspect ingress
[

 Name : ingress ,

 Id : x58u3pdo4z4qooriloi82l58k ,

 Created : 2018-08-15T12:54:22.080771222 08:00 ,

 Scope : swarm ,

 Driver : overlay ,

 EnableIPv6 : false,

 IPAM : {

 Driver : default ,

 Options : null,

 Config : [

 Subnet : 10.255.0.0/16 ,

 Gateway : 10.255.0.1 

 Internal : false,

 Attachable : false,

 Containers : {

 aef3e18d73b1db723aab0f162600a805aa7c50b5f51ec31d82d80b7eb3438c08 : {

 Name : hello.1.tzk61cn6d0jjat2w4mu5x8bbf ,

 EndpointID : 40e9352419b4eccea739be3a6ab7e6327ee28a2220ce185750f028d74e2e05c8 ,

 MacAddress : 02:42:0a:ff:00:05 ,

 IPv4Address : 10.255.0.5/16 ,

 IPv6Address : 

 ef4a7f16567d3b51d0dff629b3b6252f50d06ec77a24b36dcd8d40b6ab9afc2d : {

 Name : hello.2.lcvumjyd19tymzankbjwita1w ,

 EndpointID : d5b9a2e41654097337d6f22b139e1501b253e260d2ac3ac52e8eaf491a70340d ,

 MacAddress : 02:42:0a:ff:00:06 ,

 IPv4Address : 10.255.0.6/16 ,

 IPv6Address : 

 ingress-sbox : {

 Name : ingress-endpoint ,

 EndpointID : b610f32940e6066751a6c7b8d87f11874077f779a00d28855d8d3329d15783e9 ,

 MacAddress : 02:42:0a:ff:00:03 ,

 IPv4Address : 10.255.0.3/16 ,

 IPv6Address : 

 Options : {

 com.docker.network.driver.overlay.vxlanid_list : 4096 

 Labels : {},

 Peers : [

 Name : VM_0_10_centos-8ef37c047944 ,

 IP : 172.16.0.10 

]


由于 orverlay 网络模型是基于 vxlan 协议的网络实现 所以根据上面的网络信息可知 它是要在三层网络中虚拟出二层网络 即跨网段建立虚拟子网 也就是把 docker 要发送的信息先发送到虚拟子网地址 10.255.0.1 再由虚拟子网包装为宿主机的真实网网址  172.16.0.10 这样做的好处就是不会公开暴露容器的端口 让这些事情交给  overlay 网络驱动去做就行了 而且在同一台服务器 不会引起端口冲突 最重要的一点是可以实现集群容器间的负载均衡。


640.png


正如它的名字一样 在所有容器的上面一层 覆盖了一层网络 该网络可以使在集群中的容器像本地通信一样 所以 orverlay 网络模型也称之为覆盖网络。


构建自定义 overlay 网络集群


新建网络驱动
$ docker network create -d overlay mynet

-d 指定 mynet 网络驱动为 overlay 类型。


创建 etcd 服务
$ docker service create \

--name etcd \

--replicas 1 \

--network mynet \

-p 2379:2379


创建 mysql 服务
$ docker service create \

--name mysql-galera \

--replicas 3 \

--network mynet \

-p 3306:3306


创建 hello 应用服务
$ docker service create \

--name hello chenghuizhang/helloword:0.0.2 \

--replicas 2 \

--network mynet \

-p 8080:8080


到这里 我们已经构建了一个名为 mynet 的网络集群了 集群网络模型如下 640.png

swarm 集群的内部会为容器的各个节点之间负责负载均衡的管理 无需我们去操心了 如上如图三台服务器 无论我们访问的哪台服务器 都可以访问到 docker 各个可用节点中 比如访问 172.16.1.11:8080 也可以通过 swarm 集群的负载均衡转发到 172.16.1.12:8080。



利用Docker挂载Nginx-rtmp(服务器直播流分发)+FFmpeg(推流)+Vue.js结合Video.js(播放器流播放)来实现实时网络直播 众所周知,在视频直播领域,有不同的商家提供各种的商业解决方案,其中比较靠谱的服务商有阿里云直播,腾讯云直播,以及又拍云和网易云的有偿直播服务,服务包括软硬件设备,摄像机,编码器,流媒体服务器等。但是其高昂的费用以及较高的准入门槛让许多个人和小型企业望而却步,本文要讲解的是如何使用nginx-rtmp搭建直播服务器,配合FFmpeg推流,在网页端vue.js作为载体利用video.js作为流播放器,打造一套可用的在线视频直播方案。
docker安装后导致的网络问题 在uat环境中某台机子上安装了docker后,发现公司的办公网络到这条uat的机子就ping不通了,测试环境的网络也ping不通uat了。
后端进阶 微信公众号「后端进阶」作者,技术博客(https://objcoding.com/)博主,Seata Committer,GitHub ID:objcoding。