文章目录
在docker网络的顶层设计层面,包含了三个核心部分


。Sandbox(沙盒):提供了独立的容器虚拟网络栈,包括端口套接字、IP路由表、防火墙、DNS配置。 它的核心作用在于将容器网络与宿主机网络隔离开,形成了完整的独立的容器网络环境。
。Network:定义了Docker内部的虚拟子网,用于形成容器之间的网络联通。
。Endpoint,提供虚拟的网路接口,看上去和你在宿主机上的网络接口是一样的。它负责创建连接,并将容器独立的网络沙盒连接到Network中。 每个容器所在的 Sandbox至少包含两个 Endpoints,一个gwbridge用于访问外部网络,另一个br0用于容器间网络互通。
前文介绍了docker容器基础的网络模型,其中重要的是我们知道了驱动程序分为原生内置,以及第三方实现驱动。实际上我们后面学习docker网络,就是在学习这些驱动面向用户的使用方法。docker内置了驱动:在 Linux 上包括 Bridge、Overlay 以及 Macvlan。并由此衍生出若干的网络模式: bridge(默认)、host、container复用模式、none、用户自定义模式(bridge、overlay、macvlan)。
我们本节就说明一下 bridge、host、container复用模式、none这几种基础的网络模式。
安装完 Docker,宿主机默认会创建三个网络,分别是bridge网络,host网络,none网络,可以使用docker network ls命令查看。
# docker network ls
NETWORK ID NAME DRIVER SCOPE
cc425782673c bridge bridge local
a5b5700dedb4 host host local
fca0cfbdc8f2 none null local
并且在docker安装时会创建一个名称为docker0的linux网络接口,在不通过--network参数特殊指定的情况下,该宿主机上所有新创建的容器都会连接到docker0网络接口上面。docker0网络接口可以在宿主机上用ifconfig命令查看到。
bridge网络模式是默认的网络模式,我们通过下面几个步骤,来理解以下bridge网络模式工作原理
docker run -it --name test centos /bin/bash。因为使用-it参数,此时我们的命令行窗口正在与容器进行交互。执行ip addr命令,发现容器内部有两个网络接口一个是eth0(注意39这个数字,下文用到),一个是lo(本地回环接口-127.0.0.1)。# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> //此处省略若干不重要信息
39: eth0@if40: <BROADCAST,MULTICAST,UP,LOWER_UP> //此处省略若干不重要信息
第二步:测试容器连接宿主机外网: ping 192.168.1.111能够ping通,我的容器宿主机ip是192.168.1.111,证明容器与宿主机之间的网络是通的。
第三步:查看宿主机网络接口 :另外开一个宿主机访问终端,在宿主机上使用ifconfig命令,我们会看到这样两个网络接口:docker0,veth<随机串>(如:veth1d3961b)这样2个网络接口。其中docker0是docker安装的时候创建的,veth1d3961b是容器启动的时候创建的。
我们可以猜想一定是上面提到的这些网络接口存在网络连接,才会让容器与宿主机之间存在网络联通。我们使用下面的命令验证一下(都在宿主机上执行)。
# ethtool -S veth1d3961b
NIC statistics:
peer_ifindex: 39
上面的命令说明veth1d3961b相当于一根虚拟网线,一端连接到容器内部的39号网络接口eth0。再看下面的命令,veth1d3961b的另一端连接的是docker0。
# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242f757aefd no veth1d3961b
如果brctl命令不存在,使用
yum install bridge-utils安装

结合上面的这张图,再去理解一下上面的操作。
使用下面的命令行创建的容器,使用none网络模式,即:默认没有网络配置,不具有网卡、IP、路由信息。
docker run -it --net=none --name test1 centos /bin/bash
这种模式一般又被称为“隔离模式”,常被用于在容器内完成CPU密集型任务,计算完成后将结果保留到磁盘上。在此过程中,不与外界进行网络连接,从网络层面(断开)保证计算执行过程的安全性。

docker0和宿主机的网络命名空间都不变,只是与容器的网络命名空间没有任何连接。容器之间也没有网络连接。
使用下面的命令行创建的容器,使用host网络模式。
docker run -it --net=host --name test2 centos /bin/bash
在这种模式下,容器不会获得独立的Network Namespace,与宿主机操作系统共用一个Network Namespace。即:容器不会虚拟自己的网卡,不会配置自己的IP。宿主机的IP就是容器的IP,容器的端口就是宿主机的端口,所以同一个宿主机下的多个容器不能暴漏同一个端口。

显而易见的是这种网络模式简单,没有那么多的网络接口及数据转发,所以它是性能相对比较好的网络模式。
使用下面的命令行创建的容器使用container复用模式,添加 --net="container:name or id"启动参数可以复制一个已经存在的容器的网络配置, 被复制的容器与复制容器两者的网络完全相同。
docker run -it --name test3 centos /bin/bash;
docker run -it --net="container:test3" --name test4 centos /bin/bash;
docker run -it --net=host --name test5 centos /bin/bash;
docker run -it --net="container:test5" --name test6 centos /bin/bash;
bridge模式还支持自定义,如下所示:在宿主机范围内定义了一个名称为zimug-bridge的网络,网络模式是bridge。
docker network create --driver bridge zimug-bridge
自定义完成之后,可以通过命令查看该网络,如下所示:
# docker network ls
NETWORK ID NAME DRIVER SCOPE
cc425782673c bridge bridge local
a5b5700dedb4 host host local
fca0cfbdc8f2 none null local
27c745cc28a4 zimug-bridge bridge local
我们通过下面的2个命令,新建2个容器都加入zimug-bridge网络
docker run -it --network=zimug-bridge --name test5 centos /bin/bash;
docker run -it --network=zimug-bridge --name test6 centos /bin/bash;
由下图可见,test5容器被分配的ip是172.19.0.2

由下图可见,test6容器被分配的ip是172.19.0.3

从test5(172.19.0.2)到test6(172.19.0.3)的网络ping得通,反之亦然!网络环境可以由下图表示

这个图是不是和上文中(《二、bridge网络模式(默认)》)的图有点像,是的,唯一区别就是将docker0换成了我们自建的网络zimug-bridge,其他的没任何区别。
面试常被问道得问题总结一下,谈一下docker基础网络模式及network namespace隔离性。
| 网络模式 | 简介 |
|---|---|
| bridge | 容器具有独立的network namespace,会将容器连接到docker0虚拟网桥,并配置IP地址,默认模式。 |
| host | 容器没有独立的network namespace,和宿主机共用网络。 |
| none | 容器具有独立的network namespace,与宿主机网络隔离,但并没有对其进行任何网络设置。 |
| container | 容器和某一个已存在的容器共享network namespace。 |
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin