Docker精华问答 | 如何让一个容器连接两个网络?

640?wx_fmt=png

如今Docker的使用已经非常普遍,特别在一线互联网公司。使用Docker技术可以帮助企业快速水平扩展服务,从而到达弹性部署业务的能力。在云服务概念兴起之后,Docker的使用场景和范围进一步发展。今天,就让我们来看看关于Docker的深度问答。


640?wx_fmt=gif1

Q:vethxxxx 这种虚拟网卡和容器的对应关系从哪里看? 

 

A:使用如下命令:

$ docker network ls640?wx_fmt=png

注意这里的 br-56f04389b8f0 以及 br-094fcb269385,br- 后面的是上面的网络id,由此可以看出 veth 和 Docker 网络的对应关系,而容器都是连接到了某个Docker网络上的,从而就有了容器和 veth 的对应关系。对于某个网络出现了多个veth 的情况,可以观察veth22996d2@if11 后面的 if11 这部分,和容器内的 ip addr 的结果,一般奇-偶是一对。

 

640?wx_fmt=gif2

Q:如何让一个容器连接两个网络? 

 

A:如果是使用 docker run,那很不幸,一次只可以连接一个网络,因为 docker run 的 --network 参数只可以出现一次(如果出现多次,最后的会覆盖之前的)。不过容器运行后,可以用命令 docker network connect 连接多个网络。假设我们创建了两个网络:640?wx_fmt=png

640?wx_fmt=gif3

Q:Docker 多宿主网络怎么配置

 

A:Docker 跨节点容器网络互联,最通用的是使用 overlay 网络。

一代 Swarm 已经不再使用,它要求使用 overlay 网络前先准备好分布式键值库,比如 etcd, consul 或 zookeeper。然后在每个节点的 Docker 引擎中,配置 --cluster-store 和 --cluster-advertise 参数。这样才可以互连。可以参考我写的 LNMP 容器互联例子中的 run1.sh 这个脚本,这个脚本是利用 docker-machine自动建立 Swarm 并且配置好 overlay 的脚本,可以分析其流程。

现在都在使用二代 Swarm,也就是 Docker Swarm Mode,非常简单,只要 docker swarm init 建立集群,其它节点 docker swarm join 加入集群后,集群内的服务就自动建立了 overlay 网络互联能力。

需要注意的是,如果是多网卡环境,无论是 docker swarm init 还是 docker swarm join,都不要忘记使用参数 --advertise-addr 指定宣告地址,否则自动选择的地址很可能不是你期望的,从而导致集群互联失败。格式为 --advertise-addr <地址>:<端口>,地址可以是 IP 地址,也可以是网卡接口,比如 eth0。端口默认为 2377,如果不改动可以忽略。

此外,这是供服务使用的 overlay,因此所有 docker service create 的服务容器可以使用该网络,而 docker run 不可以使用该网络,除非明确该网络为 --attachable。

 

640?wx_fmt=gif4

Q:明明 docker network ls 中看到了建立的 overlay 网络,怎么docker run 还说网络不存在啊? 

 

A:如果在 docker network ls 中看到了如下的 overlay 网络:640?wx_fmt=png

报错说mynet 网络找不到。其实如果仔细观察,会看到这个名为mynet 的网络,驱动是 overlay没有错,但它的Scope 是swarm。这个意思是说这个网络是在二代Swarm环境中建立的overlay网络,因此只可以由Swarm环境下的服务容器才可以使用。而docker run所运行的只是零散的容器,并非Service,因此自然在零散容器所能使用的网络中,不存在叫mynet网络。

docker run可以使用的overlay网络是Scope为global的overlay网络,也就是使用外置键值库所建立的overlay网络,比如一代Swarm的overlay网络。这点在 1.13 后稍有变化。如果是 1.13 以后的系统,会看到这样的信息:640?wx_fmt=png

 

640?wx_fmt=gif5

Q:容器怎么取宿主机 IP 啊? 

 

A:单机环境 

如果是单机环境,很简单,不必琢磨怎么突破命名空间限制,直接用环境变量送进去即可。640?wx_fmt=png

然后容器内直接读取 HOST_IP 环境变量即可。

集群环境 

集群环境相对比较复杂,docker service create 中的 -e 以及 --env-file是在服务创建时指定、读取环境变量内容,而不是运行时,因此对于每个节点都是一样的。而且目前不存在 dockerd -e 选项,所以直接使用这些选项达不到我们想要的效果。不过有变通的办法,可以在宿主上建立一个 /etc/variables 文件(名字随意,这里用这个文件举例)。其内容为:640?wx_fmt=png

其中 1.2.3.4 是这个节点的宿主 IP,因此每个节点的 /etc/variables 的内容不同。

而在启动服务时,指定挂载这个服务端本地文件:

docker service create --name app \

--mount type=bind,source=/etc/variables,target=/etc/variables:ro \

myapp

由于 --mount 是发生于容器运行时,因此所加载的是所运行的服务器的 /etc/variables,里面所包含的也是该服务器的 IP 地址。在 myapp 这个镜像的入口脚本加入加载该环境变量文件的命令:640?wx_fmt=png

这样app这个服务容器就会拥有 HOST_IP 环境变量,其值为所运行的宿主 IP。

 

640?wx_fmt=png

小伙伴们冲鸭,后台留言区等着你!

关于Docker,今天你学到了什么?还有哪些不懂的?除此还对哪些话题感兴趣?快来留言区打卡啦!留言方式:打开第XX天,答:……

同时欢迎大家搜集更多问题,投稿给我们!风里雨里留言区里等你~

 

福利

1、扫描添加小编微信,备注“姓名+公司职位”,加入【云计算学习交流群】,和志同道合的朋友们共同打卡学习!

 

640?wx_fmt=jpeg

2、公众号后台回复:白皮书,获取IDC最新数据白皮书整理资料!

 

推荐阅读:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值