ASP.NET Core on K8S深入学习(11)K8S网络知多少
本篇已加入《.NET Core on K8S学习实践系列文章索引》,可以点击查看更多容器化技术相关系列文章。
一、Kubernetes网络模型
我们都知道Kubernetes作为容器编排引擎,它有一个强大又复杂的网络模型,也牵引出了Pod网络、Service网络、ClusterIP、NodePort、Ingress等多个概念。这里我们采用杨波老师(架构师杨波)模仿TCP/IP协议栈总结的一个K8S网络模型图来看看K8S的四个抽象层次,从而了解一下K8S的网络。本小节的文字主要引用自杨波老师关于K8S网络模型的文章及CloudMan的《每天5分钟玩转Kubernetes》一书。

K8S网络层次模型图 (From 波波老师)
根据上图模型中展示的四个层次,从0到3,除了第0层,每一层都是构建于前一层之上。
(1)第0层:节点主机互通互联
主要保证K8S节点(物理或虚拟机)之间能够正常IP寻址和互通的网络,这个一般由底层(公有云或数据中心)网络基础设施支持,这里我们无需过多关心。
(2)第1层:Pod虚拟机互联
在一个Pod中可以运行一个或多个容器,且Pod中所有容器使用同一个网络namespace,即相同的IP和端口空间,可以直接用localhost通信,而且还可以共享存储(本质是通过将Volume挂载到Pod中的每个容器)。

Pod网络模型图 (From 波波老师)
(3)第2层:服务发现和负载均衡
在K8S集群中,Pod的IP并不是固定的,可能会频繁地销毁和创建实例,为了解决此问题,Service提供了访问Pod的抽象层。即无论后端Pod如何变化,Service都作为稳定的前端对外提供服务。此外,Service还提供了高可用和负载均衡的功能,它负责将请求转发给正确的Pod。

Service网络模型图 (From 波波老师)
(4)第3层:外部流量接入
K8s的Service网络只是一个集群内部网络,集群外部是无法直接访问的。为此,想要将应用暴露出去让公网能够访问,K8S提供了两种方式:
① NodePort:使Service通过Cluster节点的静态端口对外提供服务,外部可以通过 NodeIP:NodePort 来访问Service。

Node Port方式示意图 (From 波波老师)
② LoadBalancer:使Service利用Cloud Provider提供的Load Balancer对外提供服务,Cloud Provider负责将Load Balancer的流量导向Service。目前支持的Cloud Provider包括AWS、Azure、阿里云、腾讯云等。

Load Balancer方式示意图 (From 波波老师)
More:关于K8S网络的更多基本原理与讲解,强力推荐阅读波波老师的以下文章:
- Kubernetes网络三部曲-Pod网络(From 杨波老师)
- Kubernetes网络三部曲-Service网络(From 杨波老师)
- Kubernetes网络三部曲-外部接入网络(From 杨波老师)
二、传说中的CNI规范
为了保证网络方案的标准化、扩展性和灵活性,K8S采用了CNI(Container Networking Interface)规范。CNI是一个Pod网络集成标准,简化了K8S和不同Pod网络实现技术的集成。CNI最大的优点就是支持多种容器runtime,而不仅仅是Docker。目前已经有多种支持K8S的网络方案,包括 Flannel、Calico、Canal等,它们都实现了CNI规范,因此无论我们选择哪种具体方案,它们的网络模型都是一致的。

CNI模型图
More:关于CNI的更多基本原理与讲解,推荐阅读陈Sir的文章《K8S网络详解:CNI与CNI网络模型》
三、Network Policy
3.1 关于Network Policy
Network Policy是K8S的一种资源,它使K8S可以通过Label选择Pod,并指定其他Pod或外界如何与这些Pod通信。换句话说,当Pod被定义了Network Policy时,只有Policy允许的流量才能访问Pod(默认情况下,任何来源的流量都可以访问Pod,是没有限制的)即帮助K8S实现更为精细的流量控制,实现租户隔离机制。
But,并不是所有K8S网络方案都支持Network Policy,比如Flannel就不支持,而Calico是支持的。
3.2 Network Policy实践
3.2.1 部署Canal
想要部署Canal,需要切换网络方案,这里我们使用最简单粗暴的方式:重建当前K8S集群
kubeadm reset # 在每个节点上执行一次
然后,重新对Master节点进行初始化:
kubeadm init \
--apiserver-advertise-address=192.168.2.100 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.13.3 \
--service-cidr=10.1.0.0/ \
--pod-network-cidr=10.244.0.0/
在两个Node节点上执行以下命令重新加入集群:(注意这里的token请填写你的Master节点初始化后的输出结果)
kubeadm join 192.168.2.100: --token ekqxk2.iiu5wx5bbnbdtxsw --discovery-token-ca-cert-hash \
sha256:c50bb83d04f64f4a714b745f04682b27768c1298f331e697419451f3550f2d05
最后,通过以下命令部署Canal:(参考自K8S官方文档)
kubectl apply -f https://docs.projectcalico.org/v3.8/manifests/canal.yaml
此时,再次令验证的集群结果如下:
(1)集群节点状态

(2)Pod状态

3.2.2 部署测试应用
这里通过一个httpd应用来演示Network Policy,该应用的yaml定义如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd
spec:
replicas:
selector:
matchLabels:
name: networkpolicy-demo
template:
metadata:
labels:
name: networkpolicy-demo
spec:
containers:
- name: httpd
image: httpd:latest
ports:
- containerPort:
imagePullPolicy: IfNotPresent --- kind: Service
apiVersion: v1
metadata:
name: httpd-svc
spec:
type: NodePort
ports:
- protocol: TCP
nodePort:
port:
targetPort:
selector:
name: networkpolicy-demo
通过kubectl将其部署到K8S集群:
kubectl apply -f httpd-demo.yaml
这时候三个httpd Pod已经成功Running:

由于定义的是NodePort方式暴露服务,这里我们在集群外部访问Service看看:

由于当前并没有创建任何Network Policy,这里我们可以通过创建一个Pod应用(我们熟悉的busybox)来验证一下是否可以在K8S集群内部随意访问该httpd应用:
kubectl run busybox --rm -it --image=busybox /bin/sh


从上图可以知道,它可以正常访问到Service,也可以正常ping到Pod节点。
3.2.3 测试Network Policy有效性
现在我们创建一个Network Policy,其配置文件yaml如下:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: access-httpd
spec:
podSelector:
matchLabels:
name: networkpolicy-demo
ingress:
- from:
- podSelector:
matchLabels:
access: "true"
ports:
- protocol: TCP
port:
该Network Policy定义了如下规则:
(1)应用于所有 label 为 name : networkpolicy-demo 的Pod,这里即刚刚创建的三个httpd pod。
(2)ingress中定义了只有 label 为 access : "true" 的Pod才能访问应用。
(3)即使通过Policy也只能访问80端口
通过kubectl将其应用到K8S集群中:
kubectl apply -f networkpolicy.yaml
下面再次在busybox pod中验证Network Policy的有效性:


从上图中可以看到,已经无法再成功访问Service,也无法再ping通三个Pod节点。
这个时候,集群外也无法再通过NodePort访问到Service:

如果想要让测试Pod(busybox)能访问到应用了Network Policy的httpd应用,我们可以对busybox pod加一个label就可以:
kubectl run busybox --rm -it --image=busybox --labels="access=true" /bin/sh
运行后的验证结果如下,可以访问到Service,但Ping却被禁止:

但是,此时集群节点(k8s-master与两个node)与集群仍然无法访问到应用了Network Policy的httpd应用,如果想要让它们也访问到,则需要修改Network Policy做一个类似于开防火墙白名单的操作(注意下面的ipBlock配置):
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: access-httpd
spec:
podSelector:
matchLabels:
name: networkpolicy-demo
ingress:
- from:
- podSelector:
matchLabels:
access: "true"
- ipBlock:
cidr: 192.168.2.0/
ports:
- protocol: TCP
port:
再次应用到K8S集群后,再来通过集群外部的访问者浏览器试试:

可以看到,已经可以正常访问啦!
四、小结
本文简单介绍了Kubernetes的4层网络模型、CNI 容器网络接口规范 以及 Network Policy,并通过改造K8S集群的网络配置从Flannel到Canal来验证Network Policy的有效性。对于Kubernetes的网络模型的原理与介绍,强烈推荐阅读杨波老师的《Kubernetes网络三部曲》,它的传送门位于下方的参考资料列表中。最后,希望能够对初学者的你有所帮助!
参考资料
(1)CloudMan,《每天5分钟玩转Kubernetes》
(2)李振良,《一天入门Kubernets教程》
(3)马哥(马永亮),《Kubernetes快速入门》
(4)Liang,《K8S CNI网络最强对比》
(5)杨波,《K8S网络三部曲》
(6)陈Sir,《K8S网络详解:CNI与CNI网络模型》
ASP.NET Core on K8S深入学习(11)K8S网络知多少的更多相关文章
- ASP.NET Core 借助 Helm 部署应用至K8S
前言 玩K8S也有一段时间了,借助云服务提供商的K8S控制台,已经可以很方便的快速部署应用至K8S.通过简单的点击,可以一次性帮忙创建K8S 对象:Deployment.Service.Ingress ...
- 【笔记目录2】【jessetalk 】ASP.NET Core快速入门_学习笔记汇总
当前标签: ASP.NET Core快速入门 共2页: 上一页 1 2 任务27:Middleware管道介绍 GASA 2019-02-12 20:07 阅读:15 评论:0 任务26:dotne ...
- ASP.NET Core快速入门(第4章:ASP.NET Core HTTP介绍)--学习笔记
课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务22:课程介绍 1.HTTP 处理过程 2.WebHost 的配置与启动 ...
- ASP.NET Core依赖注入系统学习教程:关于服务注册使用到的方法
在.NET Core的依赖注入框架中,服务注册的信息将会被封装成ServiceDescriptor对象,而这些对象都会存储在IServiceCollection接口类型表示的集合中,另外,IServi ...
- ASP.NET Core MVC 源码学习:Routing 路由
前言 最近打算抽时间看一下 ASP.NET Core MVC 的源码,特此把自己学习到的内容记录下来,也算是做个笔记吧. 路由作为 MVC 的基本部分,所以在学习 MVC 的其他源码之前还是先学习一下 ...
- ASP.NET Core MVC 源码学习:MVC 启动流程详解
前言 在 上一篇 文章中,我们学习了 ASP.NET Core MVC 的路由模块,那么在本篇文章中,主要是对 ASP.NET Core MVC 启动流程的一个学习. ASP.NET Core 是新一 ...
- ASP.NET Core MVC 源码学习:详解 Action 的激活
前言 在 上一篇 文章中,我们已经学习了 ASP.NET Core MVC 的启动流程,那么 MVC 在启动了之后,当请求到达过来的时候,它是怎么样处理的呢? 又是怎么样把我们的请求准确的传达到我们的 ...
- ASP.NET Core MVC 源码学习:详解 Action 的匹配
前言 在 上一篇 文章中,我们已经学习了 ASP.NET Core MVC 的启动流程,那么 MVC 在启动了之后,当请求到达过来的时候,它是怎么样处理的呢? 又是怎么样把我们的请求准确的传达到我们的 ...
- ASP.NET Core MVC的基础学习笔记
最近由于“武汉肺炎”疫情在家办公,也没闲着,最近学习了一下asp.net core mvc的一些网页开发的的基础知识,话不多说直接上教程! 一.创建Web应用程序 1)创建新项目--->找到 “ ...
- ASP.NET Core快速入门_学习笔记汇总
第2章 配置管理 任务12:Bind读取配置到C#实例 任务13:在Core Mvc中使用Options 任务14:配置的热更新 任务15:配置框架设计浅析 第3章 依赖注入 任务16:介绍- 任务1 ...
随机推荐
- 2019年12月4日Linux开发手记
OK,经过昨天对V4L2工作流程的学习,现在已经大体了解了V4L2的工作原理,现在开始对V4L2的API的学习,目标:1.打开摄像头 2.储存图像 3.关闭摄像头,API网址:Linux Media ...
- GO 单例模式
wiki百科: 单例模式,也叫单子模式,是一种常用的软件设计模式.在应用这个模式时,单例对象的类必须保证只有一个实例存在.许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为.比 ...
- Nginx源码构建
1.上传或下载nginx软件包,并解压 rz 2.搭建nginx安装环境 yum install gcc-c++ zlib-devel pcre-devel openssl-devel automak ...
- 虚拟机中linux操作系统raid5(5块磁盘,3块做raid,2块做备份)配置流程及损坏磁盘的移除
1.打开所要用的虚拟机,点击编辑虚拟机设置,点击硬盘,添加 2.一直点击下一步不做修改,直到最后完成 3.按照以上步骤添加5块磁盘 4.点击开启虚拟机,输入用户名root密码登录进去 5.进入虚拟机后 ...
- 小白的springboot之路(六)、跨域解决方案CORS
0-前言 前后端分离.分布式集群,经常都会涉及到跨域访问,而浏览器基于同源策略,正常情况下是不能跨域的,这就需要我们解决跨域访问问题:spring boot解决跨域也比较简单: 1-CORS跨域解决方 ...
- Solr搜索引擎【索引管理】
一.索引存储 当文档提交到索引之后,directory目录组件会将它们写入到持久化存储器.Solr的目录组件具有以下重要特点: 1.隐藏持久存储的读写细节,例如,将文档写入到磁盘或通过JDBC在数据库 ...
- 鲲鹏性能优化十板斧——鲲鹏处理器NUMA简介与性能调优五步法
TaiShan特战队六月底成立,至今百日有余,恰逢1024程序员节,遂整理此文,献礼致敬!希望能为广大在鲲鹏处理器上开发软件.性能调优的程序员们,提供一点帮助.从今天开始,将陆续推出性能调优专题文章. ...
- iNeuOS 工业互联网 从网关到云端一体化解决方案。教你如何做PPT。
iNeuOS 专注打造云端操作系统,提供全新解决方案 (凑够150字) 核心组件包括:边缘网关(iNeuLink).设备容器(iNeuKernel).视图建模(iNeuView).机器 ...
- 开放下载 | 《Knative 云原生应用开发指南》开启云原生时代 Serverless 之门
点击下载<Knative 云原生应用开发指南> 自 2018 年 Knative 项目开源后,就得到了广大开发者的密切关注.Knative 在 Kubernetes 之上提供了一套完整的应 ...
- [TimLinux] docker CentOS7入门——服务(2)
1. 服务含义 分布式应用中,应用的不同部分即称为“服务”,视频网站是一个分布式应用,包含有:数据的存储,视频的转码,前端展示等部分,对应的这些部分即称为相应的服务.docker平台中,定义.运行和扩 ...