ASP.NET Core on K8S深入学习(11)K8S网络知多少

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 本文简单介绍了Kubernetes的4层网络模型、CNI 容器网络接口规范 以及 Network Policy,并通过改造K8S集群的网络配置从Flannel到Canal来验证Network Policy的有效性。

本篇已加入《.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网络的更多基本原理与讲解,强力推荐阅读波波老师的以下文章:

二、传说中的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/16 \
--pod-network-cidr=10.244.0.0/16

  在两个Node节点上执行以下命令重新加入集群:(注意这里的token请填写你的Master节点初始化后的输出结果)

kubeadm join 192.168.2.100:6443 --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: 3
  selector:
    matchLabels:
      name: networkpolicy-demo
  template:
    metadata:
      labels:
        name: networkpolicy-demo
    spec:
      containers:
      - name: httpd
        image: httpd:latest
        ports:
        - containerPort: 80
        imagePullPolicy: IfNotPresent

---

kind: Service
apiVersion: v1
metadata:
  name: httpd-svc
spec:
  type: NodePort
  ports:
    - protocol: TCP
      nodePort: 31000
      port: 8080
      targetPort: 80
  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: 80

  该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/24
    ports:
    - protocol: TCP
      port: 80

  再次应用到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网络模型

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
28天前
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:<https://github.com/khellang/Scrutor>
46 5
|
2月前
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
49 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
1月前
|
开发框架 缓存 .NET
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
29 3
|
13天前
|
开发框架 算法 中间件
ASP.NET Core 中的速率限制中间件
在ASP.NET Core中,速率限制中间件用于控制客户端请求速率,防止服务器过载并提高安全性。通过`AddRateLimiter`注册服务,并配置不同策略如固定窗口、滑动窗口、令牌桶和并发限制。这些策略可在全局、控制器或动作级别应用,支持自定义响应处理。使用中间件`UseRateLimiter`启用限流功能,并可通过属性禁用特定控制器或动作的限流。这有助于有效保护API免受滥用和过载。 欢迎关注我的公众号:Net分享 (239字符)
31 0
|
3月前
|
开发框架 JavaScript 前端开发
一个适用于 ASP.NET Core 的轻量级插件框架
一个适用于 ASP.NET Core 的轻量级插件框架
|
24天前
|
SQL 安全 网络安全
网络安全与信息安全:知识分享####
【10月更文挑战第21天】 随着数字化时代的快速发展,网络安全和信息安全已成为个人和企业不可忽视的关键问题。本文将探讨网络安全漏洞、加密技术以及安全意识的重要性,并提供一些实用的建议,帮助读者提高自身的网络安全防护能力。 ####
62 17
|
1月前
|
存储 SQL 安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将介绍网络安全的重要性,分析常见的网络安全漏洞及其危害,探讨加密技术在保障网络安全中的作用,并强调提高安全意识的必要性。通过本文的学习,读者将了解网络安全的基本概念和应对策略,提升个人和组织的网络安全防护能力。
|
1月前
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将从网络安全漏洞、加密技术和安全意识三个方面进行探讨,旨在提高读者对网络安全的认识和防范能力。通过分析常见的网络安全漏洞,介绍加密技术的基本原理和应用,以及强调安全意识的重要性,帮助读者更好地保护自己的网络信息安全。
51 10
|
1月前
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
在数字化时代,网络安全和信息安全已成为我们生活中不可或缺的一部分。本文将介绍网络安全漏洞、加密技术和安全意识等方面的内容,并提供一些实用的代码示例。通过阅读本文,您将了解到如何保护自己的网络安全,以及如何提高自己的信息安全意识。
61 10
|
1月前
|
存储 监控 安全
云计算与网络安全:云服务、网络安全、信息安全等技术领域的融合与挑战
本文将探讨云计算与网络安全之间的关系,以及它们在云服务、网络安全和信息安全等技术领域中的融合与挑战。我们将分析云计算的优势和风险,以及如何通过网络安全措施来保护数据和应用程序。我们还将讨论如何确保云服务的可用性和可靠性,以及如何处理网络攻击和数据泄露等问题。最后,我们将提供一些关于如何在云计算环境中实现网络安全的建议和最佳实践。