大纲:

1.概述

1.1Linux的namespace+cgroup

1.2容器的网络

1.3pod的网络

插播1:Docker和容器的关系

2.Docker容器网络详解

2.1 CNM&libnetwork

2.2 单机网络---brige类型的网络

2.3 多机网络---overlay类型的网络

3.pod的网络详解

2.1 kubernetes网络概述

2.2 详解pod内的网络

2.3 详解pod间的网络

正文:

网络概述


1,Linux的namespace+cgroup
 namespace和cgroup是Linux 内核的两大特性,namespace的诞生据说就是为了支持容器技术,那么这俩特性到底干了啥呢?

- namespace:linux支持多种类型的namespace,包括Network,IPC,PID, Mount, UTC, User。创建不同类型的namespace就相当于从不同资源维度在主机上作隔离。

- cgroup:为了不让某个进程一家独大,而其他进程饿死,所以它的作用就是控制各进程分配的CPU,Memory,IO等。

- namespace+cgroup也适用进程组,即多进程运行在一个单独的ns中,此时该ns下的进程就可以交互了。

参考:https://coolshell.cn/articles/17010.html

2,容器
容器实际上是结合了namespace 和 cgroup 的一般内核进程,注意,容器就是个进程

所以,当我们使用Docker起一个容器的时候,Docker会为每一个容器创建属于他自己的namespaces,即各个维度资源都专属这个容器了,此时的容器就是一个孤岛,也可以说是一个独立VM就诞生了。当然他不是VM,网上关于二者的区别和优劣有一对资料.

更进一步,也可以将多个容器共享一个namespace,比如如果容器共享的是network 类型的namespace,那么这些容器就可以通过 localhost:[端口号]  来通信了。因为此时的两个容器从网络的角度看,和宿主机上的两个内核进程没啥区别。

在下面的详解部分会有试验来验证这个理论

3,kubernetes的pod
       根据前面的描述我们知道,多进程/多容器可以共享namespace,而k8s的pod里就是有多个容器,他的网络实现原理就是先创建一个共享namespace,然后将其他业务容器加入到该namespace中。
       k8s会自动以"合适"的方式为他们创建这个共享namespace,这正是"pause"容器的诞生。

pause容器:创建的每一个pod都会随之为其创建一个所谓的"父容器"。其主要由两个功能:

  • (主要)负责为pod创建容器共享命名空间,pod中的其他业务容器都将被加入到pause容器的namespace中
  • (可选) 负责回收其他容器产生的僵尸进程,此时pause容器可以看做是PID为1的init进程,它是所有其他容器(进程)的父进程。但在k8s1.8及以后,该功能缺省是关闭的(可通过配置开启)

水鬼子:我猜这个功能是利用了共享PID类型的Namespace吧

插播1:Docker和容器的关系
容器:我们前面说了,就是一个具有独立资源空间的Linux进程
Docker:是一个容器引擎,用来创建运行管理容器,即由它负责去和linux 内核打交道,给我们创建出来一个容器来。
容器可以被任何人创建出来,但是现在流行由Docker创建出来的,所以我们总说Docker容器,甚至提到docker就意味着说的是容器TOT

Docker容器网络详解


从范围上分:
   单机网络:none,host, bridge
   跨主机网络:overlay,macvlan,flannel等

从生成方式分:
   原生网络:none,host, bridge
   自定义网络:
      使用docker原生实现的驱动自定义的网络:bridge(自定义),overlay,macvlan,
      使用第三方驱动实现的自定义网络:flannel等

在学习网络的时候肯定遇到过关于CNM这个概念,所以首先,我们一起学习下CNM&libnetwork

CNM&libnetwork
       libnetwork是Docker团队将Docker的网络功能从Docker的核心代码中分离出来形成的一个单独的库,libnetwork通过插件的形式为Docker提供网络功能。基于代码层面再升华一下,可以将docker的网络抽象出一个模型来,就叫CNM(Container Networking Model),该模型包含三大块:

  • Sandbox:容器的网络栈,包含interface,路由表,DNS设置等,可以看做就是linux network类型的namespace本身,该有的网络方面的东西都要有,另外还包含一些用于连接各种网络的endpoint
  • Endpoint : 用来将sandbox接入到network中。典型的实现是Veth pair技术(Veth pair是Linux固有的,是一个成对的接口,用来做连接用)
  • Network : 具体的网络实现,比如是brige,VLAN等,同样它包含了很多endpoint(那一头)

一句话:sandbox代表容器,network代表容器外的网络驱动形成的网络,endpoint连接了二者

另外,CMN还提供了2个可插拔的接口,让用户可以自己实现驱动然后接入该接口,支持驱动有两类:网络驱动和IPAM驱动,看看这俩类驱动干什么的?

  • Network Drivers: 即真正的网络实现,可以为Docker Engine或其他类型的集群网络同时提供多种驱动,但是每一个具体的网络只能实例化一个网络驱动。细分为本地网络驱动和远端网络驱动:

          - 本地网络驱动:对应前面说到的原生网络
          - 远端网络驱动:对应前面说的自定义网络

    IPAM Drivers — 构建docker网络的时候,每个docker容器如果不手动指定的话是会被分配ip地址的,这个分配的任务就是由该驱动完成的,同样的,Docker Engine还是给我们提供了缺省的实现。

整个的原理模型图如下,参见官网:

参考:https://success.docker.com/article/networking
(一定要好好看看这篇文章,我英文不行看了整整2天,很有收获)

好了,收,开始真正进入docker网络的学习,我们挑2个代表性的网络一起研究下

单机网络---brige类型的网络

原理如下图(摘自https://success.docker.com/article/networking):

接下来听我慢慢道来,我们先按照步骤走一遍,然后再细抠里面的原理

实操:在主机上起两个docker容器,使用缺省网络即bridge网络,容器要使用有操作系统的镜像,要不不方便验证

1)进入任一个容器内
     sh-4.2# ip addr
     13: eth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
             inet 172.17.0.3/16 scope global eth0

  附:容器中可能缺少诸多命令,可以在启动后安装如下工具:
  yum install net-tools
  yum install iputils
  yum install iproute *

2)在宿主机上查看接口信息:

   [root@centos network-scripts]# ip addr
: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue state UP group default
inet 172.17.0.1/ scope global docker0
: vetha470484@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue master docker0 state UP group default
: veth25dfcae@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue master docker0 state UP group default

3) 在host上查看docker缺省会创建的三个网络

 [root@centos ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
451a2ff68c71 bridge bridge local
7bd661f0c17f host host local
6c9bb2d42d95 none null local

4)再看下支撑网络背后的驱动,即这个叫“bridge”的bridge类型网络使用的驱动:一个名叫docker0的bridge(网桥)。网桥上挂两个interface:veth25dfcae, vetha470484

  [root@centos network-scripts]# brctl show
bridge name bridge id STP enabled interfaces
docker0 .0242dee689ea no veth25dfcae
vetha470484

附:可能缺少命令,可以在启动后安装如下工具:

# yum install bridge-utils

#ln -s /var/run/docker/netns/ /var/run/netns     ---用来在host上查看所有的namespace,缺省情况下ip netns show显示的是/var/run/netns中的内容,但是Docker启动后会清除

解析】

看容器(Sandbox), 接口的number是13的那个,他名字是eth0, 然后他@if14,这个就是endpoint,那么这个if14是谁?

看主机,有个网桥叫做docker0,有两个interface 他们的master是docker0,并且这两个interface的number分别是14,16,并且分别@if13和@if15,是的,if13正是容器中的接口,同理if14也是另一个容器中的接口,也就是说在host上的veth接口(NO.14)和容器中的eth接口(NO.13)正是一对veth pair,至此Endpoint作为容器和nework的连接的任务达成了。而docker0正是名叫bridge的Network的驱动。

最后,看一下路由吧
容器1:

sh-4.2# ip route
default via 172.17.0.1 dev eth0
172.17.0.0/ dev eth0 proto kernel scope link src 172.17.0.3

表示:目的是172.17的流量交给eth0出去,然后交给网关172.17.0.1,也就是docker0

宿主机:

[root@centos ~]# ip route
default via 192.168.12.2 dev ens33 proto dhcp metric
172.17.0.0/ dev docker0 proto kernel scope link src 172.17.0.1
192.168.12.0/ dev ens33 proto kernel scope link src 192.168.12.132 metric

表示:目的是172.17的流量从docker0出去,
           缺省的交给ens33接口给网关192.168.12.2(因为我的宿主机是个虚拟机,所以还是个小网ip),也就是说如果访问的是同网段(如加入同一网络的其他容器)则交给网桥docker0内部转发,否则走向世界

另外:详细的可以 看一下bridge网络,可以网络中有两个容器,ip,mac都有

[root@centos ~]# docker network inspect bridge
{
"Name": "bridge",
"Driver": "bridge",
"IPAM": { //负责给容器分配ip地址
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
}, "Containers": {
"9161f717c07ac32f96b1ede19d21a56a63f17fb69a63627f66704f5cec01ca27": {
"Name": "server.1.oeep0sn0121wrvrw3aunmf9ww",
"EndpointID": "5083992493b0a69fedb2adc02fe9c0aa61e59b068e16dd9371ec27e28d7d088c",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",""
},
"fb67b65aa43619779d0d4f9d2005815aea90586f0aba295436431f688239562b": {
"Name": "fervent_ritchie",
"EndpointID": "e402fa0f99f60199c8ba50263173ef3bc14ca75dbb597d2cbcd813dd4f8706f7",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
}
},

插播:bridge的原理
在容器技术中,bridge扮演了一个非常重要的角色,懂得bridge的原理可以很好的定位网络问题,这里就不展开讨论,在我的[爬坑]系列有讲述,你只需要记住:不要把bridge想复杂,bridge是一个桥作为master,可以往桥上挂很多类型及个数的interface接口,当桥上有一个接口接收到数据后,只要不是给桥所在的宿主机本身,则桥会内部转发,数据会从其余接口同步冒出来

】:
1,容器连接外网--OK

sh-4.2# ping www.baidu.com
PING www.a.shifen.com (115.239.210.27) () bytes of data.
bytes from 115.239.210.27 (115.239.210.27): icmp_seq= ttl= time=5.38 ms

注:这里面要说明一下,从容器发外网的egress流量之所以能顺利得到应答,是因为它在出去的时候经过了iptables的NAT表,就是这里:

# iptables -t nat -L
...
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/ anywhere
MASQUERADE all -- 172.18.0.0/ anywhere

这里如果对iptables的原理不是很清楚的,推荐这位大牛的博客:
http://www.zsythink.net/archives/1199/

2,容器连接另一个容器--OK

sh-4.2# ping 172.17.0.2 -c
PING 172.17.0.2 (172.17.0.2) () bytes of data.
bytes from 172.17.0.2: icmp_seq= ttl= time=95.9 ms

3,容器如果想要被外网可以访问的到,需要在起容器的时候指定--publish/-p,即在host上找一个port与容器映射,这个host将代表容器对外打交道,这里就不展开了,网上资料很多,上面贴出的链接中也有讲解。

单机网络---overlay类型的网络

上一个章节我们没有细说容器和linux的namespace之间的关系,因为在overlay类型的网络中,大量使用了linux的namespace技术,所以我们再展开讲。

overlay这个词不是docker家的,一直以来就有overlay类型的网络,意/译为"覆盖"型网络,其中VxLan技术就可以认为是一种overlay类型网络的实现,而在docker的overlay网络,使用的正是Vxlan技术。所以我们再跑偏一下,讲讲VxLAN

https://www.cnblogs.com/shuiguizi/p/10923841.html

水鬼子:简言之,可以暂时这么理解,宿主机上有一个叫做VTEP的组件。它的ip就是宿主机的ip,负责和其他宿主机连通形成隧道。这样宿主机上的VM就可以利用该隧道和其他host上的VM沟通了,然后还并不感知该隧道的存在。也许这么说并不严谨,但是有助于对overlay网络的理解。

另外,为了学习vxlan网络以及容器对vxlan网络的应用,我做了大量的实验,遇到了很多很多的坑,需要的可以参考:.[爬坑系列]之VXLan网络实现

oK,再“收”,回到docker 网络

前情提要:
我们也可以直接使用docker 提供的overlay驱动创建overlay网络,然后创建容器加入到该网络,但如果是Docker Engine 1.12之前,还需要一个k-v类型的存储介质。Docker Engine 1.12之后的由于集成了一个叫做“网络控制平面(control plane)”的功能,则不需要额外的存储介质了。在这里为了更好的理解,我们选择前者,大致的步骤如下:

操作】
1,安装启动etcd,安装方法
2,在一个host上创建overlay类型的网络,并创建容器使用该网络
3,在另一个容器上也可以看到该网络,然后也加入这个网络

root@master ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
731d1b63b387        ov_net2             overlay             global

分别在两个节点上创建两个docker 容器
master:
docker run -ti -d --network=ov_net2 --name=centos21 centos:wxy /bin/sh

minion:
docker run -d --name nginx --network=ov_net2 nginx22

注:更详细的步骤网上很多,另外想要看我自己搭建的过程中遇到的坑等,请参见【爬坑系列】之docker的overlay网络配置

这里我只想展示overlay网络的深层实现,包括和namespace,vxlan的关系等

【解析】

1)看一下namespace以及配置
ln -s /var/run/docker/netns/ /var/run/netns

//一个容器创建完了,就多了两个namespace
[root@master ~]# ip netns    
a740da7c2043 (id: 9)
1-731d1b63b3 (id: 8)

第一个namespace:其实就是docker容器本身,它有两个接口,都是veth pair类型,对应的兄弟接口分别位于另一个namespace和系统namespace

root@master ~]# ip netns exec a740da7c2043 ip addr
: eth0@if45: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue state UP group default
link/ether ::0a::: brd ff:ff:ff:ff:ff:ff link-netnsid
inet 10.0.1.2/ scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80:::aff:fe00:/ scope link
valid_lft forever preferred_lft forever
: eth1@if47: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue state UP group default
link/ether ::ac::: brd ff:ff:ff:ff:ff:ff link-netnsid
inet 172.18.0.4/ scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80:::acff:fe12:/ scope link
valid_lft forever preferred_lft forever

第二个namespace:他的作用是专门用来做vxlan转发的,核心是一个bro桥,桥上有两个接口,一个与容器(第一个ns )相连,另一个vxlan1接口充当 vxlan网络的vtep

[root@master ~]# ip netns exec -731d1b63b3 ip addr
: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue state UP group default
link/ether ::::: brd ff:ff:ff:ff:ff:ff
inet 10.0.1.1/ scope global br0
valid_lft forever preferred_lft forever
inet6 fe80::842a:a1ff:fec8:da3b/ scope link
valid_lft forever preferred_lft forever
: vxlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue master br0 state UNKNOWN group default
link/ether ::::: brd ff:ff:ff:ff:ff:ff link-netnsid
inet6 fe80:::57ff:fe62:/ scope link
valid_lft forever preferred_lft forever
: veth2@if44: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue master br0 state UP group default
link/ether ae:a1::8c:c2:0a brd ff:ff:ff:ff:ff:ff link-netnsid
inet6 fe80::aca1:58ff:fe8c:c20a/ scope link
valid_lft forever preferred_lft forever

结论:docker的overlay网络 = 2namespace + vxlan

kubernetes之pod网络详解


一,kubernetes网络概述

我们说的k8s网络就是集群网络,因为k8s是用于集群的,单机网络没什么意义。一个集群的网络,主要涉及一下4个方面的通信

1,pod中的容器之间的通信:
   这个在前面的章节我们已经说了,pod中容器都是共享网络空间的,所以就如一台机器上的应用一般,使用localhost:port就可以通信,也当然需要容器们自己保证大家别端口冲突了。

2,pod-to-pod的通信
   首先k8s给每一个pod都分配ip了,具体他们之间怎么通信取决于具体的网络实施,这个不是k8s做的,但是k8s做了要求,也叫网络模型,具体要求如下:
   1)一个节点上的pod可以和所有节点上的所有pod通信,且不需要NAT
   2)节点上的agent(比如系统daemons:kubelet)可以和该节点上的所有pod通信
   3)如果pod是运行与host的网络中,则要求pod同样可以和节点上的其他pod通信

3,pod和service的通信,这个详见service的定义
4,外网和serice的通信,同样相近service的定义
注:3,4的实现就是service的实现,建议仔仔细细研究官方文档就可以搞清楚了,有时间我会将这部分也整理下分享出来。那部分总结一句话就是:iptables的运用

另外,在进行k8s网络验证之前,需要进行k8s本地环境安装,为了更好的研究我走了一条非常复杂的安装之路:本地编译源码生成二进制,在打包镜像,最后通过三种途径安装了master节点和node节点:yum自动安装,二进制安装,镜像安装,想起来都是泪,想参考的见【爬坑系列】之kubernetes环境搭建:二进制安装与镜像安装

二,详解pod内的通信
1,一个例子模拟pod的通信
模拟k8的行为,首先创建pause容器,然后创建centos容器和nginx容器都加入到pause容器的网络中,然后在centos容器中访问localhost:80,于是访问到了nginx容器。具体如下:
docker run -d --name pause docker.io/ist0ne/pause-amd64

docker run -d --name nginx --net=container:pause --ipc=container:pause --pid=container:pause nginx

docker run -d -ti --name centos --net=container:pause --ipc=container:pause --pid=container:pause centos /bin/sh
sh-4.2# curl localhost:80  ---访问nginx
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

2,实际的k8s的:

创建一个有俩容器的pod,一个是centos操作系统,一个是nginx,在centos中访问localhost:80可以访问到nginx服务

//创建pod的yaml文件,该pod中有两个容器
# vi centos-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-2c
labels:
app: centos
spec:
containers:
- name: centos-container
image: centos:wxy
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10; done"]
- name: nginx-container
image: nginx
//登录pod默认登录到centos-container这个容器,刚好
# kubectl exec -ti myapp-2c /bin/sh
Defaulting container name to centos-container.
Use 'kubectl describe pod/myapp-2c -n default' to see all of the containers in this pod.
sh-4.2# curl localhost:
<!DOCTYPE html>
...
<h1>Welcome to nginx!</h1>
//看看容器的情况:一个pause容器领着领养俩业务容器
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
edf722104aa6 nginx "nginx -g 'daemon ..." minutes ago Up minutes k8s_nginx-container.570a1191_myapp-2c_default_0461d9cd--11e9-a770-5254006bdf04_702066eb
6e5e2c96bd90 centos:wxy "/bin/sh -c 'while..." minutes ago Up minutes k8s_centos-container.e8c7257b_myapp-2c_default_0461d9cd--11e9-a770-5254006bdf04_d950aeda
044e4c09f0e9 docker.io/ist0ne/pause-amd64 "/pause" minutes ago Up minutes k8s_POD.68b7dd1e_myapp-2c_default_0461d9cd--11e9-a770-5254006bdf04_00db96a2

二:详解pod之间的通信
这个是k8s集群网络的核心,前面说了,取决于具体的网络实施。

  水鬼子:如果你刚接触k8s,不知道你是否会对这里感到迷惑,第三方实现是什么鬼?pod之间的通信不是k8s自己做的么?难道要额外安装啥软件?
      是的需要额外安装,在这里我们就以etcd + flunnel为例来讲解。

概述

集群中的各个node,首先一定是连通的,然后基于底层网络之上的flannel其实就是一个overlay网络。说到overlay,如果你看了前面Docker网络的章节,一定大概知道是怎么回事了。flannel网络有多种实现方式,目前支持的有:udp(默认),host-gw,VxLAN(是不是很熟悉?)。实际上pod之间的网络要比docker的还简单。

原理详解:

1,为什么需要etcd
        etcd是一个key-value形式的存储系统,可以往里写各种类型的数据。我们需要做的就是首先约定好一个key,以这个key向etcd中写入网络配置参数;然后在安装flannel的时候配置FLANNEL_ETCD_PREFIX参数为此key。
        k8s集群中的每个节点上都有安装flanneld作为网络代理,它通过读取etcd知道当前的网络配置信息,为pod分配ip后,再将当前的网络状况比如本节点分得的subnet和对应的public ip等信息再写入etcd中。这种网络管理模式就是所谓的network planes,用我的话说,大家也没什么上下级关系,都是处在同一平级,所以叫"网络平面"。

2,网络拓扑和转发原理

所谓flannel的安装,最主要是在每个节点上安装flanneld,这个"代理"一样的角色会做什么呢?

1)首先去etcd那里读取配置。根据配置为自己分配一个subnet,并将其与public ip(在安装flannel时指定的ip,如果没有指定则缺省是host上的eth0的地址)的对应关系再存入etcd中,这样其他节点上的flannel也就共享这些信息了。

2)创建虚拟网卡flannel0并分配一个该子网段ip,还会添加一条路由:所有到其他pod的数据都从flanel0出去;

3))将网段信息写入/run/flannel/subnet.env中,这是一个用于刷新Docker环境变量相关的的文件:/run/flannel/docker。所以这时候重启一下Docker,docker0就有了一个该子网段的ip。

 [坑]这里要注意,我不知道别的版本,反正我目前安装的版本,如果flannel重启并重新给自己分配了subnet,那么此时一定记得重启Docker,否则docker0的ip和flannel0的ip不一致,进而导致数据无法正确转发。

最后,数据如何转发的呢?数据从容器出来,经过veth pair到达网桥docker0,根据路由再转发给flannel0,进而数据由flannel的backend(udp或者host-gw或者vxlan)转发给目的pod所在的backend上,最后由目的host上的backend上送至目的pod的容器中。具体如下:

//etcd中存放着flannel网络配置信息:地址空间,缺省backend类型
 #etcdctl get /k8s/network/config
 {"Network": "10.0.0.0/16"}

//flannel启动后,它会偷偷改变Docker的环境变量
 #vi /usr/lib/systemd/system/flanneld.service
 ...
 ExecStartPost=/usr/libexec/flannel/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
 ...

//于是docker在启动的时候就有了约束,其中bip决定了网桥docker0的IP
 # systemctl status docker.service
 ...
 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current ... --bip=10.0.42.1/24 --ip-masq=true --mtu=1472
 ...

//集群中两个节点,分别给自己分配了子网,也都存在了etcd中,包括到达子网络的public ip
# etcdctl ls /k8s/network/subnets
/k8s/network/subnets/10.0.58.0-
/k8s/network/subnets/10.0.42.0- # etcdctl get /k8s/network/subnets/10.0.42.0-
{"PublicIP":"188.x.x.113"}

//veth pair把数据容器里导出来到达网桥docker0,再经过路由表到达flannel0,最后交给backend
# ip addr
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1472 qdisc noqueue state UP group default
link/ether 02:42:ad:d6:96:b7 brd ff:ff:ff:ff:ff:ff
inet 10.0.42.1/24 scope global docker0
valid_lft forever preferred_lft forever

...
36: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state UNKNOWN group default qlen 500
link/none
inet 10.0.42.0/16 scope global flannel0
valid_lft forever preferred_lft forever
40: veth9b5a76f@if48: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1472 qdisc noqueue master docker0 state UP group default
link/ether da:e4:3e:d3:cb:f9 brd ff:ff:ff:ff:ff:ff link-netnsid 3

# ip route
default via 172.21.0.1 dev eth0
10.0.0.0/16 dev flannel0 proto kernel scope link src 10.0.42.0
10.0.42.0/24 dev docker0 proto kernel scope link src 10.0.42.1

3,详解flannel的三种backend

参考博客:

http://www.360doc.com/content/16/0629/16/17572791_571683078.shtml

我觉得他讲的很明了了

实操

1,创建l两个pod,为了让他们能够分别调度到两个节点上,我还为node打了标签,并为pod配置了nodeSelector,例如

# cat centos.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-centos
labels:
app: centos
spec:
containers:
- name: nginx-container
image: centos:wxy
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10; done"]
nodeSelector:
node: master
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-centos / Running 16h
myapp-nginx / Running 83s

2,验证连通性:在一个pod里访问另一个pod

1)看一下nginx的ip
# kubectl get pods myapp-nginx -oyaml |grep podIP
  podIP: 10.0.58.3

2)在centos中访问一下nginx
[root@master ~]# kubectl exec -ti myapp-centos /bin/sh
sh-4.2# curl http://10.0.58.3:80
...
<h1>Welcome to nginx!</h1>

 

==============================END===================================================

深入解读docker网络与kubernetes网络的更多相关文章

  1. 【华为云技术分享】跟唐老师学习云网络 : Kubernetes网络实现

    当今K8s独霸天下之时,咱们站在更高的角度,好好的看看K8s网络是以什么理念构筑的.以及一个容器集群的好保姆,是如何分别照顾 南北流量和东西流量的. 一.简单介绍下Kubernetes 略..容器集群 ...

  2. 【好书分享】容器网络到kubernetes网络

    Nginx 公司的 Michael Hausenblas 发布了一本关于 docker 和 kubernetes 中的容器网络的小册子.这份资料一共 72 页,是大家由浅入深的了解 Docker 和 ...

  3. [翻译] 一个kubernetes网络简明教程[Part 1]

    一个kubernetes网络简明教程[Part 1] 翻译: icebug 所有我学到的关于kubernetes网络的事情 你可能已经在kubernetes集群当中跑了一堆服务并且正在享受其带来的好处 ...

  4. Kubernetes网络的4种解决方案

    一.Kubernetes + Flannel Kubernetes的网络模型假定了所有Pod都在一个可以直接连通的扁平的网络空间中,这在GCE(Google Compute Engine)里面是现成的 ...

  5. kubernetes网络原理

    1.1. 基础原则 每个Pod都拥有一个独立的IP地址,而且假定所有Pod都在一个可以直接连通的.扁平的网络空间中,不管是否运行在同一Node上都可以通过Pod的IP来访问. k8s中Pod的IP是最 ...

  6. 从零开始入门 K8s | Kubernetes 网络概念及策略控制

    作者 | 阿里巴巴高级技术专家  叶磊 一.Kubernetes 基本网络模型 本文来介绍一下 Kubernetes 对网络模型的一些想法.大家知道 Kubernetes 对于网络具体实现方案,没有什 ...

  7. kubernetes网络之Flannel

    简介 Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址. 在默认的Dock ...

  8. Kubernetes网络之Flannel工作原理

    目录 1.Docker网络模式 1.1 bridge网络的构建过程 1.2 外部访问 2.Kubernetes网络模式 2.1 同一个Pod中容器之间的通信 2.2 不同Pod中容器之间的通信 2.3 ...

  9. 超长干货丨Kubernetes网络快速入门完全指南

    Kubernetes网络一直是一个非常复杂的主题.本文将介绍Kubernetes实际如何创建网络以及如何为Kubernetes集群设置网络. 本文不包括如何设置Kubernetes集群.这篇文章中的所 ...

随机推荐

  1. Jenkins系列之-—07 集成JIRA

    一.Jenkins Jira插件安装&配置 1. 安装插件,主要安装如下插件: Jira Issue Updater 该插件用于更新JIRA ISSUES 的工作流状态或增加备注 JIRA p ...

  2. Allegro改动shape网络节点

    使用Allegro时改动shape的网络节点方法: ①选择shape->Select Shape or Void/Cavity ②选择要改动的shape ③点击(...)改动网络节点的名字 ④改 ...

  3. mybatis 简单项目步骤

    mybatis.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configura ...

  4. oracle spm使用1

    oracle11g new feature SPM 有助于保持sql的语句特性,仅仅同意运行性能提高的运行计划. 它不同于stored outlines, spm在于稳定sql性能,而store ou ...

  5. JRE、JDK、JVM区别和联系

    首先说Java编程语言,它是一门高级编程语言,具体由谁何时创建的,读者可以到网上查找相关资料,这里就不再赘述.那么,谈到Java就不得不谈谈JVM.JRE和JDK三者间的区别和联系. JVM:英文全称 ...

  6. html-基本form元素---ShinePans

    <html> <meta http-equiv="content-type" content="text/html;charset=UTF-8" ...

  7. python -- day 11 考试题

    1. 文件t1.txt里面的内容为:(6分) 1,alex,22,13651054608,IT 2,wusir,23,13304320533,Tearcher 3,taibai,18,13332353 ...

  8. 1507: [NOI2003]Editor

    1507: [NOI2003]Editor Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 3535  Solved: 1435 [Submit][St ...

  9. 获取Android设备无线和以太网MAC地址

    package com.raycloud.wolf.blogformac; import android.net.wifi.WifiManager; import android.support.v7 ...

  10. 有关定时器setTimeout()、setInterval()详解

    JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成. setTimeout() setTimeout函数用 ...