一. 实践说明

首先我们先创建一组资源,包括一个deployment和一个service

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
name: nginx
spec:
selector:
matchLabels:
name: nginx1
replicas: 1
template:
metadata:
labels:
name: nginx1
spec:
nodeName: meizu
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
name: nginx1
spec:
ports:
- port: 4432
targetPort: 80
selector:
name: nginx1

可以看到,我们在指定的node上面创建了一个nginx deployment,并且创建一个服务指向这个pod.然后我们再在其他节点上启动一个pod,在该pod中访问这个service.

src pod  ->  service   ->  backend  pod

172.30.83.9  ->  10.254.40.119:4432  ->  172.30.20.2:80

下面的所有操作都是nginx 服务所在的pod所运行的node上执行的

二. 物理网卡

1.监听nginx pod/src pod 地址

sudo tcpdump -i  enp4s0 ‘dst 172.30.20.9’

sudo tcpdump -i  enp4s0 'src 172.30.83.9'

都没有输出

2. 监听service 地址

sudo tcpdump  -i  enp4s0 ‘dst 10.254.40.119’

没有输出

3.src pod所在的node的物理地址是10.167.226.38,我们现在监听从这个节点发出的所有的到本地8472端口的udp报文,注意8472端口是flannel所监听的端口

sudo tcpdump  -i enp4s0 'src 10.167.226.38 and port 8472 and udp'
看到如下输出:

::22.220286 IP xiaomi. > meizu.otv: OTV, flags [I] (0x08), overlay , instance
IP 172.30.83.0. > 172.30.20.2.http: Flags [S], seq , win , options [mss ,sackOK,TS val ecr ,nop,wscale ], length
::22.221179 IP xiaomi. > meizu.otv: OTV, flags [I] (0x08), overlay , instance
IP 172.30.83.0. > 172.30.20.2.http: Flags [.], ack , win , options [nop,nop,TS val ecr ], length
::22.221383 IP xiaomi. > meizu.otv: OTV, flags [I] (0x08), overlay , instance
IP 172.30.83.0. > 172.30.20.2.http: Flags [P.], seq :, ack , win , options [nop,nop,TS val ecr ], length : HTTP: GET / HTTP/1.1
::22.221933 IP xiaomi. > meizu.otv: OTV, flags [I] (0x08), overlay , instance
IP 172.30.83.0. > 172.30.20.2.http: Flags [.], ack , win , options [nop,nop,TS val ecr ], length
::22.221949 IP xiaomi. > meizu.otv: OTV, flags [I] (0x08), overlay , instance
IP 172.30.83.0. > 172.30.20.2.http: Flags [.], ack , win , options [nop,nop,TS val ecr ], length
::22.222347 IP xiaomi. > meizu.otv: OTV, flags [I] (0x08), overlay , instance
IP 172.30.83.0. > 172.30.20.2.http: Flags [F.], seq , ack , win , options [nop,nop,TS val ecr ], length

我们可以看到在物理网卡上,报文的源地址是物理机的ip,目标地址是目标pod所在的物理机的ip。

报文体中定义的源地址是172.30.83.0,这是源pod所在主机的flannel.1网卡的地址,目标地址是172.30.20.2,这个地址是nginx pod所在的地址

4. 再看看tcp协议的输出

sudo tcpdump  -i enp4s0 'src 10.167.226.38 and port 8472 and tcp'

没有输出,由此可见,flannel之间的通信是通过udp完成的,而不是tcp。

总结:在物理网卡上,所有的通信都是通过源地址和目标地址所在的主机的物理地址进行通信的,这些报文封装了从管理源pod的docker网卡地址到目的nginx pod地址的flannel报文

三. Flannel 网卡

执行下面的指令,其中172.30.83.0是源pod所在的node的flannel网卡地址

[wlh@meizu ~]$ sudo tcpdump  -i flannel. 'host 172.30.83.0 and tcp'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on flannel., link-type EN10MB (Ethernet), capture size bytes
::43.362239 IP 172.30.83.0. > 172.30.20.2.http: Flags [S], seq , win , options [mss ,sackOK,TS val ecr ,nop,wscale ], length
::43.363702 IP 172.30.20.2.http > 172.30.83.0.: Flags [S.], seq , ack , win , options [mss ,sackOK,TS val ecr ,nop,wscale ], length
::43.364106 IP 172.30.83.0. > 172.30.20.2.http: Flags [.], ack , win , options [nop,nop,TS val ecr ], length
::43.364180 IP 172.30.83.0. > 172.30.20.2.http: Flags [P.], seq :, ack , win , options [nop,nop,TS val ecr ], length : HTTP: GET / HTTP/1.1
::43.364218 IP 172.30.20.2.http > 172.30.83.0.: Flags [.], ack , win , options [nop,nop,TS val ecr ], length
::43.364482 IP 172.30.20.2.http > 172.30.83.0.: Flags [P.], seq :, ack , win , options [nop,nop,TS val ecr ], length : HTTP: HTTP/1.1 OK
::43.364608 IP 172.30.20.2.http > 172.30.83.0.: Flags [FP.], seq :, ack , win , options [nop,nop,TS val ecr ], length : HTTP
::43.364868 IP 172.30.83.0. > 172.30.20.2.http: Flags [.], ack , win , options [nop,nop,TS val ecr ], length
::43.364888 IP 172.30.83.0. > 172.30.20.2.http: Flags [.], ack , win , options [nop,nop,TS val ecr ], length
::43.365226 IP 172.30.83.0. > 172.30.20.2.http: Flags [F.], seq , ack , win , options [nop,nop,TS val ecr ], length
::43.365271 IP 172.30.20.2.http > 172.30.83.0.: Flags [.], ack , win , options [nop,nop,TS val ecr ], length

可以看到物理层的报文被解封装后提交给了flannel.1网卡,它处理的报文就是从源pod所在的node的flannel.1网卡地址到目标pod的地址的通信

四. Docker0网卡

其中172.30.83.0是源pod所在的主机的flannel.1网卡的地址

 [wlh@meizu ~]$ sudo tcpdump  -i docker0 'host 172.30.83.0 and tcp'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on docker0, link-type EN10MB (Ethernet), capture size bytes
::00.681066 IP 172.30.83.0. > 172.30.20.2.http: Flags [S], seq , win , options [mss ,sackOK,TS val ecr ,nop,wscale ], length
::00.681110 IP 172.30.20.2.http > 172.30.83.0.: Flags [S.], seq , ack , win , options [mss ,sackOK,TS val ecr ,nop,wscale ], length
::00.681548 IP 172.30.83.0. > 172.30.20.2.http: Flags [.], ack , win , options [nop,nop,TS val ecr ], length
::00.681560 IP 172.30.83.0. > 172.30.20.2.http: Flags [P.], seq :, ack , win , options [nop,nop,TS val ecr ], length : HTTP: GET / HTTP/1.1
::00.681608 IP 172.30.20.2.http > 172.30.83.0.: Flags [.], ack , win , options [nop,nop,TS val ecr ], length
::00.681773 IP 172.30.20.2.http > 172.30.83.0.: Flags [P.], seq :, ack , win , options [nop,nop,TS val ecr ], length : HTTP: HTTP/1.1 OK
::00.681853 IP 172.30.20.2.http > 172.30.83.0.: Flags [FP.], seq :, ack , win , options [nop,nop,TS val ecr ], length : HTTP
::00.682018 IP 172.30.83.0. > 172.30.20.2.http: Flags [.], ack , win , options [nop,nop,TS val ecr ], length
::00.682031 IP 172.30.83.0. > 172.30.20.2.http: Flags [.], ack , win , options [nop,nop,TS val ecr ], length
::00.682504 IP 172.30.83.0. > 172.30.20.2.http: Flags [F.], seq , ack , win , options [nop,nop,TS val ecr ], length
::00.682523 IP 172.30.20.2.http > 172.30.83.0.: Flags [.], ack , win , options [nop,nop,TS val ecr ], length

我们可以看到这里的通信是以tcp协议进行并且所有的通信和flannel类似,也是在源主机的flannel网卡地址和目标pod地址之间进行的。

五 容器网卡

容器网卡的输出和前面的比较类似这里不再赘述。

六总结

下面总结一下整个过程

  1. 首先容器内的进程发送一个访问service的请求,这个被交给容器内网卡进行处理,容器内网卡将请求发送给veth pair的另一端。此时请求是从src pod ip-> service ip。
  2. 然后根据NAT表的设置, 目的地址被转化为backend pod 的ip,这个请求再传送给docker0网卡。此时请求是 src pod ip -> backend pod ip
  3. docker0 网卡收到请求后直接将请求发出去,请求根据路由表(route -n)被传送给flannel.1网卡。此时请求是flanne.1 ip -> backend pod ip
  4. flannel.1网卡将请求发送给flanneld进程进行处理,该进程读取etcd的配置,给请求封装上一个udp协议头,然后发出去, 该报文是 source node ip -> dst node ip
  5. 本地网卡收到这个请求后将报文从物理网络上发出去,到达远程主机。

flannel.1

k8s 网络模型解析之实践的更多相关文章

  1. k8s 网络模型解析之原理

    今天研究了一下k8s的网络模型,该解析基于flannel vxlan+ kubeproxy iptables 模式. 一.Docker 首先分析一下Docker层面的网络模型,我们知道容器是基于内核的 ...

  2. k8s 网络模型

    一.前言 k8s对Pods之间如何进行组网通信提出了要求,k8s对集群的网络有以下要求: 所有的Pods之间可以在不使用NAT网络地址转换的情况下相互通信 所有的Nodes之间可以在不使用NAT网络地 ...

  3. Tengine HTTPS原理解析、实践与调试【转】

    本文邀请阿里云CDN HTTPS技术专家金九,分享Tengine的一些HTTPS实践经验.内容主要有四个方面:HTTPS趋势.HTTPS基础.HTTPS实践.HTTPS调试. 一.HTTPS趋势 这一 ...

  4. k8s loadbalancer与ingress实践

    k8s可以通过三种方式将集群内服务暴露到外网,分别是NodePort.LoadBalancer.Ingress,其中NodePort作为基础通信形式我们在<k8s网络模型与集群通信>中进行 ...

  5. [转帖]我花了10个小时,写出了这篇K8S架构解析

    我花了10个小时,写出了这篇K8S架构解析 https://www.toutiao.com/i6759071724785893891/   每个微服务通过 Docker 进行发布,随着业务的发展,系统 ...

  6. k8s网络模型与集群通信

    在k8s中,我们的应用会以pod的形式被调度到各个node节点上,在设计集群如何处理容器之间的网络时是一个不小的挑战,今天我们会从pod(应用)通信来展开关于k8s网络的讨论. 小作文包含如下内容: ...

  7. 从零开始入门 K8s | etcd 性能优化实践

    作者 | 陈星宇(宇慕)  阿里云基础技术中台技术专家 本文整理自<CNCF x Alibaba 云原生技术公开课>第 17 讲. 导读:etcd 是容器云平台用于存储关键元信息的组件.阿 ...

  8. ELK:收集k8s容器日志最佳实践

    简介 关于日志收集这个主题,这已经是第三篇了,为什么一再研究这个课题,因为这个课题实在太重要,而当今优秀的开源解决方案还不是很明朗: 就docker微服务化而言,研发有需求标准输出,也有需求文件输出, ...

  9. 一文看懂 K8s 日志系统设计和实践

    上一篇中我们介绍了为什么需要一个日志系统.为什么云原生下的日志系统如此重要以及云原生下日志系统的建设难点,相信DevOps.SRE.运维等同学看了是深有体会的.本篇文章单刀直入,会直接跟大家分享一下如 ...

随机推荐

  1. Python&Selenium&Unittest&BeautifuReport 自动化测试并生成HTML自动化测试报告

    一.摘要 本篇博文将介绍如何借助BeautifulReport和HTML模版,生成HTML测试报告的BeautifulReport 源码Clone地址为 https://github.com/Test ...

  2. 2018多校第九场 HDU 6416 (DP+前缀和优化)

    转自:https://blog.csdn.net/CatDsy/article/details/81876341 #include <bits/stdc++.h> using namesp ...

  3. Java项目出现的问题--实际项目01

    1   从Excel中导入指纹图谱数据异常 在导入指纹图谱时对Excel的规范是有限制的,有时候报空指针异常是因为虽然有些地方看起来没有内容但是可能有空格键:解决方法是新建一个Excel表,把要用到的 ...

  4. demo(一) react-native-router-flux

    react-native init AwesomeProject cd AwesomeProject 安装模块 npm i react-native-router-flux --save

  5. @Test 测试

    package com.自定义.mall.admin.system; import java.util.List; import java.util.Map; import javax.annotat ...

  6. BZOJ 2100: [Usaco2010 Dec]Apple Delivery spfa

    由于是无向图,所以可以枚举两个终点,跑两次最短路来更新答案. #include <queue> #include <cstdio> #include <cstring&g ...

  7. hdu 6021 MG loves string (一道容斥原理神题)(转)

    MG loves string    Accepts: 30    Submissions: 67  Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  8. [python之ipython] jupyter notebook在云端服务器上开启,本地访问

    本地ssh到云端: ssh username@xxx.xxx.xxx.xxx -L127.0.0.1:7777:127.0.0.1:8888 把云端的8888端口映射到本地的7777端口 云端运行指令 ...

  9. windows 安装python2.7

    下载:https://www.python.org/downloads/release/python-2716/ 安装即可. 设置环境变量 进入C:\Python27,修改python.exe 为py ...

  10. 为vue3.0学点typescript, 解读高级类型

    知识点摘要 本节课主要关键词为: 自动类型推断 / 类型断言 / 类型别名(type) / 映射类型(Pick/Record等...) / 条件类型(extends) / 类型推断(infer) 自动 ...