写在前面学习K8s,学到这里,整理记忆,本文用于理解K8s网络中Calico网路方案的原理优缺点内容包括:常见的容器跨主机通信方案简介Caliao实现Container跨主机通信简述Calico多个主机通信的实战Demo。没有涉及K8s,通过Docker实现博文部分理论来自《基于Kubernetes的容器云平台实战》,看的PDF,书很不错,感兴趣小伙伴可以支持作者一波。Demo部分操作使用了ansible,但是不影响阅读 户外依然大雨滂沱,只是这回彷彿不仅命运一人独自哭泣,不晓得由来,窗外的雨水似乎渗上我心头,有些寒冻,有些缩麻,还有些苦涩。城市万家灯火,橘黄街灯与家户里的温暖流洩,我总觉得这时候的我,最脆弱。《UnserLebenUnserTraum》跨主机Docker网络通信 常见的跨主机通信方案主要有以下几种: 形式 描述 Host模式 容器直接使用宿主机的网络,这样天生就可以支持跨主机通信。这种方式虽然可以解决跨主机通信问题,但应用场景很有限,容易出现端口冲突,也无法做到隔离网络环境,一个容器崩溃很可能引起整个宿主机的崩溃。 端口绑定 通过绑定容器端口到宿主机端口,跨主机通信时使用主机IP端口的方式访问容器中的服务。显然,这种方式仅能支持网络栈的4层及以上的应用,并且容器与宿主机紧耦合,很难灵活地处理问题,可扩展性不佳。 定义容器网络 使用OpenvSwitch或Flannel等第三方SDN工具,为容器构建可以跨主机通信的网络环境。这类方案一般要求各个主机上的Dockero网桥的cidr不同,以避免出现IP冲突的问题,限制容器在宿主机上可获取的IP范围。并且在容器需要对集群外提供服务时,需要比较复杂的配置,对部署实施人员的网络技能要求比较高。 容器网络发展到现在,形成了两大阵营:Docker的CNM;Google,Coreos,Kuberenetes主导的CNI CNM和CNI是网络规范或者网络体系,并不是网络实现因此并不关心容器网络的实现方式(Flannel或者Calico等),CNM和CNI关心的只是网络管理。 网络类型 描述 CNM(ContainerNetworkModel) CNM的优势在于原生,容器网络和Docker容器,生命周期结合紧密;缺点是被Docker绑架。支持CNM网络规范的容器网络实现包括:DockerSwarmoverlay,MacvlanIPnetworkdrivers,Calico,Contiv,Weave等。 CNI(ContainerNetworkInterface) CNI的优势是兼容其他容器技术(如rkt)及上层编排系统(KubernetesMesos),而且社区活跃势头迅猛;缺点是非Docker原生。支持CNI网络规范的容器网络实现包括:Kubernetes、Weave,Macvlan,Calico,Flannel,Contiv。MesosCNI等。 但从网络实现角度,又可分为: 网络实现角度 描述 隧道方案 隧道方案在laas层的网络中应用也比较多,它的主要缺点是随着节点规模的增长复杂度会提升,而且出了网络问题后跟踪起来比较麻烦,大规模集群情况下这是需要考虑的一个问题 路由方案 一般是基于3层或者2层实现网络隔离和跨主机容器互通的,出了问题也很容易排查出来。 Calico:基于BGP协议的路由方案,支持很细致的ACL控制,对混合云亲和度比较高。 Macvlan:从逻辑和Kernel层来看,是隔离性和性能最优的方案。基于二层隔离,所以需要一层路由器支持,大多数云服务商不支持,所以混合云上比较难以实现。calico通信过程 Calico把每个操作系统的协议栈当作一个路由器,认为所有的容器是连在这个路由器上的网络终端,在路由器之间运行标准的路由协议BGP,然后让它们自己去学习这个网络拓扑该如何转发。 Calico方案其实是一个纯三层的方案,也就是说让每台机器的协议栈的三层去确保两个容器、跨主机容器之间的三层连通性。其网络模型如图所示。 网络模型 对于控制平面,其每个Calico节点上会运行两个主要的程序 程序 描述 一个是Felix 它会监听etcd,并从etcd获取事件,如该节点新增容器或者增加IP地址等。当在这个节点上创建出一个容器,并将其网卡、IP,MAC都设置好后,Felix在内核的路由表里面写一条数据,注明这个IP应该配置到这张网卡。 一个标准的路由程序 ,它会从内核里面获取哪一些IP的路由发生了变化,然后通过标准BGP的路由协议扩散到整个其他宿主机上,通知外界这个IP在这里。 由于Calico是一种纯三层(网络层)的实现,因此可以避免与二层方案相关的数据包封装的操作,中间没有任何的NAT,没有任何的Overlay,所以它的转发效率可能是所有方案中最高的。因为它的包直接走原生TCPIP的协议栈,它的隔离也因为这个栈而变得好做。因为TCPIP的协议栈提供了一整套的防火墙规则,所以它可以通过iptables的规则达到比较复杂的隔离逻辑。Calico实现方案 拓扑模式 环境准备 这里我们通过calico来进行跨主机容器网络通信过程演示, ansible网络测试〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmping192。168。26。101SUCCESS{ansiblefacts:{discoveredinterpreterpython:usrbinpython},changed:false,ping:pong}192。168。26。102SUCCESS{ansiblefacts:{discoveredinterpreterpython:usrbinpython},changed:false,ping:pong}192。168。26。100SUCCESS{ansiblefacts:{discoveredinterpreterpython:usrbinpython},changed:false,ping:pong}〔rootvms81。liruilongs。github。io〕〔ansible〕 etcd集群测试,这里我们已经搭建好一个etcd集群,etcdctlmemberlist查看集群列表〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshellaetcdctlmemberlist192。168。26。102CHANGEDrc06f2038a018db1103,started,etcd100,http:192。168。26。100:2380,http:192。168。26。100:2379,http:localhost:2379bd330576bb637f25,started,etcd101,http:192。168。26。101:2380,http:192。168。26。101:2379,http:localhost:2379fbd8a96cbf1c004d,started,etcd102,http:192。168。26。102:2380,http:192。168。26。100:2379,http:localhost:2379192。168。26。101CHANGEDrc06f2038a018db1103,started,etcd100,http:192。168。26。100:2380,http:192。168。26。100:2379,http:localhost:2379bd330576bb637f25,started,etcd101,http:192。168。26。101:2380,http:192。168。26。101:2379,http:localhost:2379fbd8a96cbf1c004d,started,etcd102,http:192。168。26。102:2380,http:192。168。26。100:2379,http:localhost:2379192。168。26。100CHANGEDrc06f2038a018db1103,started,etcd100,http:192。168。26。100:2380,http:192。168。26。100:2379,http:localhost:2379bd330576bb637f25,started,etcd101,http:192。168。26。101:2380,http:192。168。26。101:2379,http:localhost:2379fbd8a96cbf1c004d,started,etcd102,http:192。168。26。102:2380,http:192。168。26。100:2379,http:localhost:2379〔rootvms81。liruilongs。github。io〕〔ansible〕 docker安装启动,修改数据存储位置〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshellayumyinstalldockerce〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshellasystemctlenabledockernow〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshellasystemctlstatusdocker192。168。26。100CHANGEDrc0docker。serviceDockerApplicationContainerEngineLoaded:loaded(usrlibsystemdsystemdocker。service;enabled;vendorpreset:disabled)Active:active(running)sinceSat2022010120:27:17CST;10minagoDocs:https:docs。docker。com。。。 修改docker启动参数:数据存储位置clusterstore〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshellacatusrlibsystemdsystemdocker。servicegrepcontainerd。sock192。168。26。100CHANGEDrc0ExecStartusrbindockerdHfd:containerdruncontainerdcontainerd。sock192。168。26。102CHANGEDrc0ExecStartusrbindockerdHfd:containerdruncontainerdcontainerd。sock192。168。26。101CHANGEDrc0ExecStartusrbindockerdHfd:containerdruncontainerdcontainerd。sock 这里我们直接使用SED来修改〔rootvms81。liruilongs。github。io〕〔ansible〕ansible192。168。26。100mshellasediscontainerd。sockcontainerd。sockclusterstoreetcd:192。168。26。100:2379usrlibsystemdsystemdocker。service192。168。26。100CHANGEDrc0〔rootvms81。liruilongs。github。io〕〔ansible〕ansible192。168。26。101mshellasediscontainerd。sockcontainerd。sockclusterstoreetcd:192。168。26。101:2379usrlibsystemdsystemdocker。service192。168。26。101CHANGEDrc0〔rootvms81。liruilongs。github。io〕〔ansible〕ansible192。168。26。102mshellasediscontainerd。sockcontainerd。sockclusterstoreetcd:192。168。26。102:2379usrlibsystemdsystemdocker。service192。168。26。102CHANGEDrc0〔rootvms81。liruilongs。github。io〕〔ansible〕 刷新Service文件,重启docker〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshellasystemctldaemonreload;systemctlrestartdocker192。168。26。100CHANGEDrc0192。168。26。102CHANGEDrc0192。168。26。101CHANGEDrc0〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshellasystemctlstatusdocker搭建Calico网络 然后我们需要创建calico配置文件,这里我们通过ansilbe的方式 使用file模块新建文件夹mkdiretccalico〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmfileapathetccalicostatedirectoryforceyes 使用template模块创建配置文件新建模板,这里使用到j2模板,魔法变量〔rootvms81。liruilongs。github。io〕〔ansible〕catcalicoctl。j2apiVersion:v1kind:calicoApiConfigmetadata:spec:datastoreType:etcdv2etcdEndpoints:http:{{inventoryhostname}}:2379〔rootvms81。liruilongs。github。io〕〔ansible〕 calico集群创建配置文件〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmtemplateasrccalicoctl。j2destetccalicocalicoctl。cfgforceyes 核对创建的配置文件〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshellacatetccalicocalicoctl。cfg192。168。26。100CHANGEDrc0apiVersion:v1kind:calicoApiConfigmetadata:spec:datastoreType:etcdv2etcdEndpoints:http:192。168。26。100:2379192。168。26。102CHANGEDrc0apiVersion:v1kind:calicoApiConfigmetadata:spec:datastoreType:etcdv2etcdEndpoints:http:192。168。26。102:2379192。168。26。101CHANGEDrc0apiVersion:v1kind:calicoApiConfigmetadata:spec:datastoreType:etcdv2etcdEndpoints:http:192。168。26。101:2379 Calico相关镜像导入〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmcopyasrcrootcaliconodev2。tardestroot〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshelladockerloadirootcaliconodev2。tar192。168。26。100CHANGEDrc0Loadedimage:quay。iocaliconode:v2。6。12192。168。26。102CHANGEDrc0Loadedimage:quay。iocaliconode:v2。6。12192。168。26。101CHANGEDrc0Loadedimage:quay。iocaliconode:v2。6。12〔rootvms81。liruilongs。github。io〕〔ansible〕 镜像查看〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshelladockerimages192。168。26。102CHANGEDrc0REPOSITORYTAGIMAGEIDCREATEDSIZEquay。iocaliconodev2。6。12401cc3e56a1a3yearsago281MB192。168。26。100CHANGEDrc0REPOSITORYTAGIMAGEIDCREATEDSIZEquay。iocaliconodev2。6。12401cc3e56a1a3yearsago281MB192。168。26。101CHANGEDrc0REPOSITORYTAGIMAGEIDCREATEDSIZEquay。iocaliconodev2。6。12401cc3e56a1a3yearsago281MB〔rootvms81。liruilongs。github。io〕〔ansible〕 calicoctl工具导入〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmcopyasrcrootcalicoctldestbinmodex 开始建立caliconode信息:每个主机上都部署了CalicoNode作为虚拟路由器〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshellacalicoctlnoderunnodeimagequay。iocaliconode:v2。6。12cetccalicocalicoctl。cfg 查看node状态,通过Calico将宿主机组织成任意的拓扑集群 〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshellacalicoctlnodestatus192。168。26。102CHANGEDrc0Calicoprocessisrunning。IPv4BGPstatusPEERADDRESSPEERTYPESTATESINCEINFO192。168。26。100nodetonodemeshup14:46:35Established192。168。26。101nodetonodemeshup14:46:34EstablishedIPv6BGPstatusNoIPv6peersfound。192。168。26。101CHANGEDrc0Calicoprocessisrunning。IPv4BGPstatusPEERADDRESSPEERTYPESTATESINCEINFO192。168。26。100nodetonodemeshup14:46:31Established192。168。26。102nodetonodemeshup14:46:34EstablishedIPv6BGPstatusNoIPv6peersfound。192。168。26。100CHANGEDrc0Calicoprocessisrunning。IPv4BGPstatusPEERADDRESSPEERTYPESTATESINCEINFO192。168。26。101nodetonodemeshup14:46:31Established192。168。26。102nodetonodemeshup14:46:35EstablishedIPv6BGPstatusNoIPv6peersfound。〔rootvms81。liruilongs。github。io〕〔ansible〕 当集群中的容器需要与外界通信时,就可以通过BGP协议将网关物理路由器加入到集群中,使外界可以直接访问容器IP,而不需要做任何NAT之类的复杂操作。通过Calico网络实现跨主机通信 在某一个Node上创建一个docker内部calico网络〔rootvms81。liruilongs。github。io〕〔ansible〕ansible192。168。26。100mshelladockernetworkcreatedrivercalicoipamdrivercalicoipamcalnet1192。168。26。100CHANGEDrc058121f89bcddec441770aa207ef662d09e4413625b0827ce4d8f601fb10650d0 会发现这个内网网络变成的一个全局的网络,在所有节点可见,58121f89bcdd〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshelladockernetworklist192。168。26。100CHANGEDrc0NETWORKIDNAMEDRIVERSCOPEcaa87ba3dd86bridgebridgelocal58121f89bcddcalnet1calicoglobal1d63e3ad385fhosthostlocaladc94f172d5fnonenulllocal192。168。26。102CHANGEDrc0NETWORKIDNAMEDRIVERSCOPEcc37d3c66e2fbridgebridgelocal58121f89bcddcalnet1calicoglobal3b138015d4abhosthostlocal7481614a7084nonenulllocal192。168。26。101CHANGEDrc0NETWORKIDNAMEDRIVERSCOPEd0cb224ed111bridgebridgelocal58121f89bcddcalnet1calicoglobal106e1c9fb3d3hosthostlocalf983021e2a02nonenulllocal〔rootvms81。liruilongs。github。io〕〔ansible〕 查看节点中的网卡信息,这个时候没有容器运行,所以没有caliao网卡〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshellaipa192。168。26。102CHANGEDrc01:lo:LOOPBACK,UP,LOWERUPmtu65536qdiscnoqueuestateUNKNOWNqlen1linkloopback00:00:00:00:00:00brd00:00:00:00:00:00inet127。0。0。18scopehostlovalidlftforeverpreferredlftforeverinet6::1128scopehostvalidlftforeverpreferredlftforever2:ens32:BROADCAST,MULTICAST,UP,LOWERUPmtu1500qdiscpfifofaststateUPqlen1000linkether00:0c:29:0f:98:f1brdff:ff:ff:ff:ff:ffinet192。168。26。10224brd192。168。26。255scopeglobalens32validlftforeverpreferredlftforeverinet6fe80::20c:29ff:fe0f:98f164scopelinkvalidlftforeverpreferredlftforever3:docker0:NOCARRIER,BROADCAST,MULTICAST,UPmtu1500qdiscnoqueuestateDOWNlinkether02:42:c3:28:19:78brdff:ff:ff:ff:ff:ffinet172。17。0。116brd172。17。255。255scopeglobaldocker0validlftforeverpreferredlftforever192。168。26。100CHANGEDrc01:lo:LOOPBACK,UP,LOWERUPmtu65536qdiscnoqueuestateUNKNOWNqlen1linkloopback00:00:00:00:00:00brd00:00:00:00:00:00inet127。0。0。18scopehostlovalidlftforeverpreferredlftforeverinet6::1128scopehostvalidlftforeverpreferredlftforever2:ens32:BROADCAST,MULTICAST,UP,LOWERUPmtu1500qdiscpfifofaststateUPqlen1000linkether00:0c:29:8c:e8:1abrdff:ff:ff:ff:ff:ffinet192。168。26。10024brd192。168。26。255scopeglobalens32validlftforeverpreferredlftforeverinet6fe80::20c:29ff:fe8c:e81a64scopelinkvalidlftforeverpreferredlftforever3:docker0:NOCARRIER,BROADCAST,MULTICAST,UPmtu1500qdiscnoqueuestateDOWNlinkether02:42:f7:1a:2e:30brdff:ff:ff:ff:ff:ffinet172。17。0。116brd172。17。255。255scopeglobaldocker0validlftforeverpreferredlftforever192。168。26。101CHANGEDrc01:lo:LOOPBACK,UP,LOWERUPmtu65536qdiscnoqueuestateUNKNOWNqlen1linkloopback00:00:00:00:00:00brd00:00:00:00:00:00inet127。0。0。18scopehostlovalidlftforeverpreferredlftforeverinet6::1128scopehostvalidlftforeverpreferredlftforever2:ens32:BROADCAST,MULTICAST,UP,LOWERUPmtu1500qdiscpfifofaststateUPqlen1000linkether00:0c:29:3b:6e:efbrdff:ff:ff:ff:ff:ffinet192。168。26。10124brd192。168。26。255scopeglobalens32validlftforeverpreferredlftforeverinet6fe80::20c:29ff:fe3b:6eef64scopelinkvalidlftforeverpreferredlftforever3:docker0:NOCARRIER,BROADCAST,MULTICAST,UPmtu1500qdiscnoqueuestateDOWNlinkether02:42:70:a7:4e:7ebrdff:ff:ff:ff:ff:ffinet172。17。0。116brd172。17。255。255scopeglobaldocker0validlftforeverpreferredlftforever〔rootvms81。liruilongs。github。io〕〔ansible〕 每个节点运行一个容器〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshelladockerrunname{{inventoryhostname}}itdnetcalnet1restartalwaysbusybox192。168。26。101CHANGEDrc0cf2ff4b65e6343fa6e9afba6e75376b97ac47ea59c35f3c492bb7051c15627f0192。168。26。100CHANGEDrc0065724c073ded04d6df41d295be3cd5585f8683664fd42a3953dc8067195c58e192。168。26。102CHANGEDrc082e4d6dfde5a6e51f9a4d4f86909678a42e8d1e2d9bfa6edd9cc258b37dfc2db 查看容器节点信息〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshelladockerps192。168。26。102CHANGEDrc0CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES82e4d6dfde5abusyboxshAboutaminuteagoUpAboutaminute192。168。26。102c2d2ab904d6dquay。iocaliconode:v2。6。12startrunit2hoursagoUp2hourscaliconode192。168。26。100CHANGEDrc0CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES065724c073debusyboxshAboutaminuteagoUpAboutaminute192。168。26。100f0b150a924d9quay。iocaliconode:v2。6。12startrunit2hoursagoUp2hourscaliconode192。168。26。101CHANGEDrc0CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMEScf2ff4b65e63busyboxshAboutaminuteagoUpAboutaminute192。168。26。1010e4e6f005797quay。iocaliconode:v2。6。12startrunit2hoursagoUp2hourscaliconode〔rootvms81。liruilongs。github。io〕〔ansible〕 查看每个容器的内部网卡和IP〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshelladockerexecit{{inventoryhostname}}ipagrepcali0A4192。168。26。100CHANGEDrc04:cali0if5:BROADCAST,MULTICAST,UP,LOWERUP,MDOWNmtu1500qdiscnoqueuelinketheree:ee:ee:ee:ee:eebrdff:ff:ff:ff:ff:ffinet192。168。239。12832scopeglobalcali0validlftforeverpreferredlftforever192。168。26。102CHANGEDrc04:cali0if5:BROADCAST,MULTICAST,UP,LOWERUP,MDOWNmtu1500qdiscnoqueuelinketheree:ee:ee:ee:ee:eebrdff:ff:ff:ff:ff:ffinet192。168。63。6432scopeglobalcali0validlftforeverpreferredlftforever192。168。26。101CHANGEDrc04:cali0if5:BROADCAST,MULTICAST,UP,LOWERUP,MDOWNmtu1500qdiscnoqueuelinketheree:ee:ee:ee:ee:eebrdff:ff:ff:ff:ff:ffinet192。168。198。032scopeglobalcali0validlftforeverpreferredlftforever〔rootvms81。liruilongs。github。io〕〔ansible〕 查看容器内的路由关系,即所有的出口都是通过cali0网卡来实现的〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshelladockerexecit{{inventoryhostname}}iproutegrepcali0192。168。26。101CHANGEDrc0defaultvia169。254。1。1devcali0169。254。1。1devcali0scopelink192。168。26。102CHANGEDrc0defaultvia169。254。1。1devcali0169。254。1。1devcali0scopelink192。168。26。100CHANGEDrc0defaultvia169。254。1。1devcali0169。254。1。1devcali0scopelink 每创建一个容器,则会在物理机上创建一张虚拟网卡出来,对应容器中的网卡,从这里可以看到容器里的虚拟网卡cali0和物理机的cali6f956c2ada9是vethpair关系。 关于vethpair小伙伴可以百度下,这里简单描述,作用很简单,就是要把从一个networknamespace发出的数据包转发到另一个namespace。veth设备是成对的,一个是container之中,另一个在container之外(宿主机),即在真实机器上能看到的。VETH设备总是成对出现,送到一端请求发送的数据总是从另一端以请求接受的形式出现。创建并配置正确后,向其一端输入数据,VETH会改变数据的方向并将其送入内核网络子系统,完成数据的注入,而在另一端则能读到此数据。(Namespace,其中往veth设备上任意一端上RX到的数据,都会在另一端上以TX的方式发送出去)veth工作在L2数据链路层,vethpair设备在转发数据包过程中并不串改数据包内容。 更多小伙伴可以参考:https:blog。csdn。netsld880311articledetails77650937〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshellaipagrepA4cali192。168。26。102CHANGEDrc05:cali6f956c2ada9if4:BROADCAST,MULTICAST,UP,LOWERUPmtu1500qdiscnoqueuestateUPlinkether6a:65:54:1a:19:e6brdff:ff:ff:ff:ff:fflinknetnsid0inet6fe80::6865:54ff:fe1a:19e664scopelinkvalidlftforeverpreferredlftforever192。168。26。100CHANGEDrc05:cali0b7f49da20aif4:BROADCAST,MULTICAST,UP,LOWERUPmtu1500qdiscnoqueuestateUPlinkether9e:da:0e:cc:b3:7ebrdff:ff:ff:ff:ff:fflinknetnsid0inet6fe80::9cda:eff:fecc:b37e64scopelinkvalidlftforeverpreferredlftforever192。168。26。101CHANGEDrc05:calib6f7ddae7e3if4:BROADCAST,MULTICAST,UP,LOWERUPmtu1500qdiscnoqueuestateUPlinkether1e:e6:16:ae:f0:91brdff:ff:ff:ff:ff:fflinknetnsid0inet6fe80::1ce6:16ff:feae:f09164scopelinkvalidlftforeverpreferredlftforever〔rootvms81。liruilongs。github。io〕〔ansible〕 查看宿主机路由关系〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshellaiproute192。168。26。101CHANGEDrc0defaultvia192。168。26。2devens32169。254。0。016devens32scopelinkmetric1002172。17。0。016devdocker0protokernelscopelinksrc172。17。0。1192。168。26。024devens32protokernelscopelinksrc192。168。26。101192。168。63。6426via192。168。26。102devens32protobirdblackhole192。168。198。026protobird192。168。198。1devcali2f9e2c68badscopelink192。168。239。12826via192。168。26。100devens32protobird192。168。26。100CHANGEDrc0defaultvia192。168。26。2devens32169。254。0。016devens32scopelinkmetric1002172。17。0。016devdocker0protokernelscopelinksrc172。17。0。1192。168。26。024devens32protokernelscopelinksrc192。168。26。100192。168。63。6426via192。168。26。102devens32protobird192。168。198。026via192。168。26。101devens32protobird192。168。239。128devcali0b7f49da20ascopelinkblackhole192。168。239。12826protobird192。168。26。102CHANGEDrc0defaultvia192。168。26。2devens32169。254。0。016devens32scopelinkmetric1002172。17。0。016devdocker0protokernelscopelinksrc172。17。0。1192。168。26。024devens32protokernelscopelinksrc192。168。26。102192。168。63。64devcali6f956c2ada9scopelinkblackhole192。168。63。6426protobird192。168。198。026via192。168。26。101devens32protobird192。168。239。12826via192。168。26。100devens32protobird〔rootvms81。liruilongs。github。io〕〔ansible〕 我们那其中一台机器来看:192。168。26。100宿主机来讲 192。168。239。128devcali0b7f49da20ascopelink 进去:本机到目的地址到容器IP(192。168。239。128)的数据包都从cali6f956c2ada9(新产生的虚拟网卡)走。 192。168。63。6426via192。168。26。102devens32protobird 192。168。198。026via192。168。26。101devens32protobird 出来:本机目的地址到容器IP(192。168。63。6426)容器IP(192。168。198。026)网段的数据包都从ens32发到其他的两个宿主机上去。 每台主机都知道不同的容器在哪台主机上,所以会动态的设置路由。 〔rootvms81。liruilongs。github。io〕〔ansible〕ansibleetcdmshellarouten192。168。26。101CHANGEDrc0KernelIProutingtableDestinationGatewayGenmaskFlagsMetricRefUseIface0。0。0。0192。168。26。20。0。0。0UG000ens32169。254。0。00。0。0。0255。255。0。0U100200ens32172。17。0。00。0。0。0255。255。0。0U000docker0192。168。26。00。0。0。0255。255。255。0U000ens32192。168。63。64192。168。26。102255。255。255。192UG000ens32192。168。198。00。0。0。0255。255。255。192U000192。168。198。10。0。0。0255。255。255。255UH000cali2f9e2c68bad192。168。239。128192。168。26。100255。255。255。192UG000ens32192。168。26。100CHANGEDrc0KernelIProutingtableDestinationGatewayGenmaskFlagsMetricRefUseIface0。0。0。0192。168。26。20。0。0。0UG000ens32169。254。0。00。0。0。0255。255。0。0U100200ens32172。17。0。00。0。0。0255。255。0。0U000docker0192。168。26。00。0。0。0255。255。255。0U000ens32192。168。63。64192。168。26。102255。255。255。192UG000ens32192。168。198。0192。168。26。101255。255。255。192UG000ens32192。168。239。1280。0。0。0255。255。255。255UH000cali0b7f49da20a192。168。239。1280。0。0。0255。255。255。192U000192。168。26。102CHANGEDrc0KernelIProutingtableDestinationGatewayGenmaskFlagsMetricRefUseIface0。0。0。0192。168。26。20。0。0。0UG000ens32169。254。0。00。0。0。0255。255。0。0U100200ens32172。17。0。00。0。0。0255。255。0。0U000docker0192。168。26。00。0。0。0255。255。255。0U000ens32192。168。63。640。0。0。0255。255。255。255UH000cali6f956c2ada9192。168。63。640。0。0。0255。255。255。192U000192。168。198。0192。168。26。101255。255。255。192UG000ens32192。168。239。128192。168。26。100255。255。255。192UG000ens32〔rootvms81。liruilongs。github。io〕〔ansible〕 简单测试一下:192。168。26。100宿主机上的容器(192。168。239。128)去ping192。168。63。64(192。168。26。100上的容器),实现跨主机互通。〔rootvms100。liruilongs。github。io〕〔〕dockerexecit192。168。26。100binshlsbindevetchomeprocrootsystmpusrvaripa1:lo:LOOPBACK,UP,LOWERUPmtu65536qdiscnoqueueqlen1linkloopback00:00:00:00:00:00brd00:00:00:00:00:00inet127。0。0。18scopehostlovalidlftforeverpreferredlftforever4:cali0if5:BROADCAST,MULTICAST,UP,LOWERUP,MDOWNmtu1500qdiscnoqueuelinketheree:ee:ee:ee:ee:eebrdff:ff:ff:ff:ff:ffinet192。168。239。12832scopeglobalcali0validlftforeverpreferredlftforeverping192。168。63。64PING192。168。63。64(192。168。63。64):56databytes64bytesfrom192。168。63。64:seq0ttl62time18。519ms64bytesfrom192。168。63。64:seq1ttl62time0。950ms64bytesfrom192。168。63。64:seq2ttl62time1。086ms64bytesfrom192。168。63。64:seq3ttl62time0。846ms64bytesfrom192。168。63。64:seq4ttl62time0。840ms64bytesfrom192。168。63。64:seq5ttl62time1。151ms64bytesfrom192。168。63。64:seq6ttl62time0。888msC192。168。63。64pingstatistics7packetstransmitted,7packetsreceived,0packetlossroundtripminavgmax0。8403。46818。519ms 在K8s集群的中,有一个容器,就会生成一个calico网卡〔rootvms81。liruilongs。github。io〕〔ansible〕ipa1:lo:LOOPBACK,UP,LOWERUPmtu65536qdiscnoqueuestateUNKNOWNqlen1linkloopback00:00:00:00:00:00brd00:00:00:00:00:00inet127。0。0。18scopehostlovalidlftforeverpreferredlftforeverinet6::1128scopehostvalidlftforeverpreferredlftforever2:ens32:BROADCAST,MULTICAST,UP,LOWERUPmtu1500qdiscpfifofaststateUPqlen1000linkether00:0c:29:ad:e3:93brdff:ff:ff:ff:ff:ffinet192。168。26。8124brd192。168。26。255scopeglobalens32validlftforeverpreferredlftforeverinet6fe80::20c:29ff:fead:e39364scopelinkvalidlftforeverpreferredlftforever3:docker0:NOCARRIER,BROADCAST,MULTICAST,UPmtu1500qdiscnoqueuestateDOWNlinkether02:42:0a:9e:7d:44brdff:ff:ff:ff:ff:ffinet172。17。0。116brd172。17。255。255scopeglobaldocker0validlftforeverpreferredlftforever4:tunl0NONE:NOARP,UP,LOWERUPmtu1480qdiscnoqueuestateUNKNOWNqlen1linkipip0。0。0。0brd0。0。0。0inet10。244。88。6432scopeglobaltunl0validlftforeverpreferredlftforever5:cali12cf25006b5if4:BROADCAST,MULTICAST,UP,LOWERUPmtu1480qdiscnoqueuestateUPlinketheree:ee:ee:ee:ee:eebrdff:ff:ff:ff:ff:fflinknetnsid0inet6fe80::ecee:eeff:feee:eeee64scopelinkvalidlftforeverpreferredlftforever6:cali5a282a7bbb0if4:BROADCAST,MULTICAST,UP,LOWERUPmtu1480qdiscnoqueuestateUPlinketheree:ee:ee:ee:ee:eebrdff:ff:ff:ff:ff:fflinknetnsid1inet6fe80::ecee:eeff:feee:eeee64scopelinkvalidlftforeverpreferredlftforever7:calicb34164ec79if4:BROADCAST,MULTICAST,UP,LOWERUPmtu1480qdiscnoqueuestateUPlinketheree:ee:ee:ee:ee:eebrdff:ff:ff:ff:ff:fflinknetnsid2inet6fe80::ecee:eeff:feee:eeee64scopelinkvalidlftforeverpreferredlftforever〔rootvms81。liruilongs。github。io〕〔ansible〕