设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

Docker网络配置

2014-7-8 09:00| 发布者: joejoe0332| 查看: 29733| 评论: 0|原作者: oscfox, 徐继开, 地狱星星, --zxp, 无若, 昊翔, 繁华的落尽|来自: oschina

摘要: 当docker启动时,它会在宿主机器上创建一个名为docker0的虚拟网络接口。它会从RFC 1918定义的私有地址中随机选择一个主机不用的地址和子网掩码,并将它分配给docker0。例如当我启动docker几分钟后它选择了172.17.42. ...


Docker 如何使容器连接到网络

  docker是正在发展中的,并会持续提升网络配置的逻辑。当前命令行是很难满足docker新建容器时所需要的网络配置。

让我们回顾一些基础知识。


  通讯的时候使用网际协议(IP),一个机器需要访问至少一个网络接口用来发送和接收包,路由表定义了通过接口可达IP地址范围。网络接口不一定非是物理设备。实际上,在每一个Linux机器(和每个Docker容器内部)的lo回环接口都是有效的而且完全是虚拟的——Linux内核简单地拷贝回环(数据)包,直接从发送者的内存放入接收者的内存。


  Docker使用特殊的虚拟接口让容器在主机间通讯——成对的虚拟接口被叫做“peers”,它被链接到主机内核的内部,因此(数据)包能在他们之间传输。他们简单创建,待会儿我们将会看到。


  Docker配置容器的步骤是:


1.创建一对虚拟接口

2.在主Docker主机内部给它一个唯一的名称,比如veth65f9,绑定它到docker0或者Docker使用的任何网桥上

3.让其他的接口翻墙进入新的容器(已经提供了lo接口),在容器的独立和唯一网络接口命名空间内,重新命名它为更漂亮的名字eth0,名称不要和其他的物理接口冲突。

4.在网桥的网络地址访问内给容器的eth0一个新的IP地址,设置它的缺省路由为Docker主机在网桥上拥有的IP地址。

这些步骤结束后,容器将立即拥有一个eth0(虚拟)网卡,并会发现它自己可以和其他的容器以及互联网通讯。


  你可以使用 --net= 这个选项来执行 docker run 启动一个容器,这个选项有一下可选参数。


  • --net=bridge— 默认选项,用网桥的方式来连接docker容器。

  • --net=host— 高数docker跳过配置容器的独立网络栈。本质上来说,这个参数告诉docker不去打包容器的网络层。当然,docker 容器的进程仍然被限制在它自己独有的文件系统、进程列表以及其他资源中。一个快速命令 ip addr 将像你展示docker的网络,它是建立在docker 宿主主机上的,有完整的权限去访问宿主主机的网络接口。注意这不意味着docker容器可以去重新配置宿主主机的网络栈,重新配置是需要 --privaleged=true 这个选项参数的,但是这个选项参数会让docker容器打开大量的端口以及其他的系统的超级管理权限的进程。这也会允许容器去访问宿主主机的网络服务,比如 D-bus。这会使docker容器里的进程有有权限去做一些意想不到的事,比如重启你的宿主主机。所以要谨慎使用这个选项参数。

  • --net=container:NAME_or_ID— 告诉docker让这个新建的容器使用已有容器的网络配置。这个新建的容器将配置新的自己的文件系统和进程列表以及其他资源限制,但是将共享这个指定的容器的网络IP地址以及端口号,使得这两个容器可以通过 loopback接口相互访问。

  • --net=none— 告诉docker为新建的容器建立一个网络栈,但不对这个网络栈进行任何配置,在这个文档的最后将介绍如何让你去建立自定义的网络配置。


去了解以下这一步是非常必要的,如果你在建立容器的时候使用 --net=none  这个选项参数。以下是一些命令去去配置自定义网络,就好像你让docker完全去自己配置一样。

# At one shell, start a container and# leave its shell idle and running$ sudo docker run -i -t --rm --net=none base /bin/bash
root@63f36fc01b5f:/#

# At another shell, learn the container process ID
# and create its namespace entry in /var/run/netns/# for the "ip netns" command we will be using below$ sudo docker inspect -f '{{.State.Pid}}' 63f36fc01b5f2778$ pid=2778$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid# Check the bridge's IP address and netmask$ ip addr show docker021: docker0: ...inet 172.17.42.1/16 scope global docker0...# Create a pair of "peer" interfaces A and B,# bind the A end to the bridge, and bring it up$ sudo ip link add A type veth peer name B
$ sudo brctl addif docker0 A
$ sudo ip link set A up# Place B inside the container's network namespace,# rename to eth0, and activate it with a free IP$ sudo ip link set B netns $pid
$ sudo ip netns exec $pid ip link set dev B name eth0
$ sudo ip netns exec $pid ip link set eth0 up
$ sudo ip netns exec $pid ip addr add 172.17.42.99/16 dev eth0
$ sudo ip netns exec $pid ip route add default via 172.17.42.1

到这一步你的容器应该可以正常运行网络操作了。

当你最后退出shell以及清理掉这个容器的时候,这个容器的虚拟网络 eth0 将在网络接口A 被清除后被消除,也会自动在网桥 docker0 上销毁。所以不用你执行其他的命令,所有的东西将被清理。当然,是几乎所有的东西:

# Clean up dangling symlinks in /var/run/netnsfind -L /var/run/netns -type l -delete

  还要注意上面的脚本使用了现代的ip命令行替代旧的弃用的封装,类似ipconfig和route,这些老的命令行还是会一直呆在我们的容器内部工作。如果你很忙碌的话,ip addr命令行也可以只键入ip a。


  总之,注意这个ip netns exec重要的命令行,它让我们以root用户进入内部并配置一个网络命名空间。如果在容器内部运行,类似的命令行可能不会工作,因为安全容器化的部分是Docker剥离容器的处理过程,这个过程要正确地配置自己的网络。使用ip netns exec可以让我们完成配置,还避免了运行容器自身--privileged=true的危险步骤。


工具和实例

  在把自定义网络拓扑逻辑分类成下面几个部分之前,你应该关注一些外部工具盒关于配置的实例。下面就有两个例子:


  两个工具都使用网络命令并和之前见到的版本很相似,在下面章节会看到。


建立点对点连接

  缺省情况下, Docker通过docker0将所有的容器添加到虚拟子网中。你能够按照Building your own bridge中的方法创建你自己的桥让容器连接到不同的虚拟子网。启动容器时使用命令docker run --net=none,然后使用shell命令添加容器到你自己的桥,方法见How Docker networks a container


  但是有时你想让两个特别的容器能够直接通讯,不用绑定到主机的以太网桥上。


  解决方案是简单的。创建一对对等接口,将他们放到容器中,并将其配置为经典的点对点链接。两个容器就能够直接通讯了(当然要告诉每个容器对方的IP地址)。您可能会调整在上一节的指示去这样的事情:


# Start up two containers in two terminal windows$ sudo docker run -i -t --rm --net=none base /bin/bash
root@1f1f4c1f931a:/#

$ sudo docker run -i -t --rm --net=none base /bin/bash
root@12e343489d2f:/#

# Learn the container process IDs
# and create their namespace entries

$ sudo docker inspect -f '{{.State.Pid}}' 1f1f4c1f931a
2989
$ sudo docker inspect -f '{{.State.Pid}}' 12e343489d2f
3004
$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/2989/ns/net /var/run/netns/2989$ sudo ln -s /proc/3004/ns/net /var/run/netns/3004# Create the "peer" interfaces and hand them out$ sudo ip link add A type veth peer name B

$ sudo ip link set A netns 2989$ sudo ip netns exec 2989 ip addr add 10.1.1.1/32 dev A
$ sudo ip netns exec 2989 ip link set A up
$ sudo ip netns exec 2989 ip route add 10.1.1.2/32 dev A

$ sudo ip link set B netns 3004$ sudo ip netns exec 3004 ip addr add 10.1.1.2/32 dev B
$ sudo ip netns exec 3004 ip link set B up
$ sudo ip netns exec 3004 ip route add 10.1.1.1/32 dev B


  两个容器应该可以相互ping通以确定连接成功。点对点链接不依赖于子网或子网掩码,但是ip route需要确认一些其他的单一IP地址是连接到了特定的网络接口。


  请注意点对点链接可以安全的和其他类型的网络连接混合使用。如果你想用点对点链接替换容器的正常网络连接,启动的时候,不需要带参数--net=none。


  在Docker主机和容器之间创建点对点链接是这个模板最终的排列方式,它允许主机和有单一IP地址的容器通讯。除非你有很特别的网络需求,让你尝试使用这样的解决方案,正如我们前面探讨的,使用--icc=false锁定跨容器的通讯是更好的方案。


酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部