热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Kubernetes网络策略NetworkPolicy

1、概述Kubernetes要求集群中所有Pod,无论是节点内还是跨节点,都可以直接通信。默认情况下,集群中所有Pod之间、Pod与节点

1、 概述

Kubernetes要求集群中所有Pod,无论是节点内还是跨节点,都可以直接通信。默认情况下,集群中所有Pod之间、Pod与节点之间可以互通。网络主要解决两个问题,一个是连通性,实体之间能够通过网络互通。另一个是隔离性,出于安全、限制网络流量的目的,又要控制实体之间的连通性。网络策略(NetworkPolicy)用来实现隔离性,只有匹配规则的流量才能进入Pod,同理只有匹配规则的流量才可以离开Pod。NetworkPolicy 资源使用标签选择Pod,并定义选定Pod所允许的通信规则。

但请注意,kubernetes支持的用以实现Pod网络的network plugin有很多种,并不是全部都支持Network Policy,为kubernetes选择network plugin时需要考虑到这点,是否需要隔离?可用network plugin及是否支持Network Policy请参考这里(支持网络策略的 CNI 网络插件有很多,包括 Calico、Cilium、Kube-router、Romana 和 Weave Net 等,但是flannel不支持)。

2、NetworkPolicy 资源

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: test-network-policynamespace: default
spec:# 必须设置此参数podSelector:matchLabels:role: db# 假设配置文件中没设置此参数,资源成功后会自动带着policyTypes->Ingress参数配置policyTypes:- Ingress- Egress# ingress规则白名单列表,满足底下任意一个规则即可匹配成功(注意底下的"-"字符,同一缩进的"-"是或关系,"-"底下的所有规则是并关系)ingress:- from:- ipBlock:cidr: 172.17.0.0/16except:- 172.17.1.0/24- namespaceSelector:matchLabels:project: myproject- podSelector:matchLabels:role: frontendports:- protocol: TCPport: 6379# egress规则白名单列表egress:- to:- ipBlock:cidr: 10.0.0.0/24ports:- protocol: TCPport: 5978 

说明:

  • spec: NetworkPolicy 规约中包含了在一个命名空间中定义特定网络策略所需的所有信息
  • podSelector: 每个 NetworkPolicy 都包括一个 podSelector ,它对该策略所应用的一组 Pod进行选择。示例中的策略选择带有 "role=db" 标签的 Pod。空的 podSelector 选择命名空间下的所有 Pod。
  • policyTypes: 每个 NetworkPolicy 都包含一个 policyTypes 列表,其中包含 Ingress 或 Egress 或两者兼具。policyTypes 字段表示给定的策略是否应用于进入所选 Pod 的入口流量或者来自所选 Pod的出口流量,或两者兼有。如果 NetworkPolicy 未指定 policyTypes 则默认情况下始终设置 Ingress(假设创建networkPolicy资源实例时没有指定policyTypes,创建完成后查看资源详细信息会发现给自动带上Ingress信息),如果NetworkPolicy 有任何出口规则的话则设置 Egress,不设置Egress的话表示对于所选择Pod出口不做任何限制。
  • ingress: 每个 NetworkPolicy 可包含一个 ingress 规则的白名单列表。每个规则都允许同时匹配 from 和ports 部分的流量。示例策略中包含一条简单的规则: 它匹配一个单一的端口,来自三个来源中的一个, 第一个通过 ipBlock指定,第二个通过namespaceSelector 指定,第三个通过 podSelector 指定。
  • egress: 每个 NetworkPolicy 可包含一个 egress 规则的白名单列表。每个规则都允许匹配 to 和 port部分的流量。该示例策略包含一条规则,该规则将单个端口上的流量匹配到 10.0.0.0/24 中的任何目的地。

所以,该网络策略示例:

  1、隔离 “default” 命名空间下 “role=db” 的 Pod (如果它们不是已经被隔离的话)。

  2、(Ingress 规则)允许以下 Pod 连接到 “default” 命名空间下的带有 “role=db” 标签的所有 Pod 的6379 TCP 端口:

    • “default” 命名空间下任意带有 “role=frontend” 标签的 Pod
    • 带有 “project=myproject” 标签的任意命名空间中的 Pod
    • IP 地址范围为 172.17.0.0–172.17.0.255 和 172.17.2.0–172.17.255.255(即,除了172.17.1.0/24 之外的所有 172.17.0.0/16)

  3、(Egress 规则)允许从带有 “role=db” 标签的命名空间下的任何 Pod 到 CIDR 10.0.0.0/24 下 5978TCP 端口的连接。

3、 选择器 to 和 from 的行为

可以在 ingress from 部分或 egress to 部分中指定四种选择器:

3.1 podSelector

这将在与 NetworkPolicy 相同的命名空间中选择特定的 Pod,应将其允许作为入口源或出口目的地。

3.2 namespaceSelector

这将选择特定的命名空间,应将所有 Pod 用作其输入源或输出目的地。

3.3 namespaceSelector 和 podSelector

一个指定 namespaceSelector 和 podSelector的 to/from 条目选择特定命名空间中的特定 Pod。注意使用正确的 YAML 语法(注意底下的"-"字符,同一缩进的"-"是或关系,"-"底下的所有规则是并关系,3.3表示的选择器是"-"底下的规则需要全部匹配),这项策略:

...ingress:- from:- namespaceSelector:matchLabels:user: alicepodSelector:matchLabels:role: client...

在 from 数组中仅包含一个元素,只允许来自标有 role=client 的 Pod 且该 Pod 所在的命名空间中标有 user=alice 的连接。但是 这项 策略:

...ingress:- from:- namespaceSelector:matchLabels:user: alice- podSelector:matchLabels:role: client...

在 from 数组中包含两个元素,允许来自本地命名空间中标有 role=client 的 Pod 的连接,或 来自任何命名空间中标有 user = alice 的任何 Pod 的连接。
这两种定义方式的区别,请你一定要分清楚。

3.4 ipBlock

这将选择特定的 IP CIDR 范围以用作入口源或出口目的地。 这些应该是群集外部 IP,因为 Pod IP 存在时间短暂的且随机产生。
群集的入口和出口机制通常需要重写数据包的源 IP 或目标 IP。在发生这种情况的情况下,不确定在 NetworkPolicy 处理之前还是之后发生,并且对于网络插件,云提供商,Service 实现等的不同组合,其行为可能会有所不同。

在进入的情况下,这意味着在某些情况下,您可以根据实际的原始源 IP 过滤传入的数据包,而在其他情况下,NetworkPolicy 所作用的 源IP 则可能是 LoadBalancer 或 Pod 的节点等。

对于出口,这意味着从 Pod 到被重写为集群外部 IP 的 Service IP 的连接可能会或可能不会受到基于 ipBlock 的策略的约束。

4. 默认策略

默认情况下,如果命名空间中不存在任何策略,则所有进出该命名空间中的 Pod 的流量都被允许。以下示例使您可以更改该命名空间中的默认行为。

4.1 默认拒绝所有入口流量

您可以通过创建选择所有容器但不允许任何进入这些容器的入口流量的 NetworkPolicy 来为命名空间创建 “default” 隔离策略。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: default-deny-ingress
spec:podSelector: {}policyTypes:- Ingress

这样可以确保即使容器没有选择其他任何 NetworkPolicy,也仍然可以被隔离。由于policyTypes中没有配置Egress,所以此策略不会更改默认的出口隔离行为。

4.2 默认允许所有入口流量

如果要允许所有流量进入某个命名空间中的所有 Pod(即使添加了导致某些 Pod 被视为“隔离”的策略),则可以创建一个策略来明确允许该命名空间中的所有流量。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: allow-all-ingress
spec:podSelector: {}ingress:- {}policyTypes:- Ingress

4.3 默认拒绝所有出口流量

您可以通过创建选择所有容器但不允许来自这些容器的任何出口流量的 NetworkPolicy 来为命名空间创建 “default” egress 隔离策略。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: default-deny-egress
spec:podSelector: {}policyTypes:- Egress

4.4 默认允许所有出口流量

如果要允许来自命名空间中所有 Pod 的所有流量(即使添加了导致某些 Pod 被视为“隔离”的策略),则可以创建一个策略,该策略明确允许该命名空间中的所有出口流量。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: allow-all-egress
spec:podSelector: {}egress:- {}policyTypes:- Egress

4.5 默认拒绝所有入口和所有出口流量

您可以为命名空间创建 “default” 策略,以通过在该命名空间中创建以下 NetworkPolicy 来阻止所有入站和出站流量。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: default-deny-all
spec:podSelector: {}policyTypes:- Ingress- Egress

5、NetworkPolicy原理

在具体实现上,凡是支持 NetworkPolicy 的 CNI 网络插件,都维护着一个 NetworkPolicy Controller,通过控制循环的方式对 NetworkPolicy 对象的增删改查做出响应,然后在宿主机上完成 iptables 规则的配置工作。

在 Kubernetes 生态里,目前已经实现了 NetworkPolicy 的网络插件包括 Calico、Weave 和 kube-router 等多个项目,但是并不包括 Flannel 项目。所以说,如果想要在使用 Flannel 的同时还使用 NetworkPolicy 的话,你就需要再额外安装一个网络插件,比如 Calico 项目,来负责执行 NetworkPolicy。(安装 Flannel + Calico 的流程可以参考这个文档)

那么,这些网络插件,又是如何根据 NetworkPolicy 对 Pod 进行隔离的呢?

接下来,以三层网络插件为例(比如 Calico),来为你分析一下这部分的原理。NetworkPolicy 对象示例如下所示:

apiVersion: extensions/v1beta1
kind: NetworkPolicy
metadata:name: test-network-policynamespace: default
spec:podSelector:matchLabels:role: dbingress:- from:- namespaceSelector:matchLabels:project: myproject- podSelector:matchLabels:role: frontendports:- protocol: tcpport: 6379

可以看到,我们指定的 ingress“白名单”,是任何 Namespace 里,携带 project=myproject 标签的 Namespace 里的 Pod;以及 default Namespace 里,携带了 role=frontend 标签的 Pod。允许被访问的端口是:6379。

而被隔离的对象,是default命名空间下所有携带了 role=db 标签的 Pod。

那么这个时候,Kubernetes 的网络插件就会使用这个 NetworkPolicy 的定义,在宿主机上生成 iptables 规则。这个过程,我可以通过如下所示的一段 Go 语言风格的伪代码来为你描述:

for dstIP := range 所有被networkpolicy.spec.podSelector选中的Pod的IP地址for srcIP := range 所有被ingress.from.podSelector选中的Pod的IP地址for port, protocol := range ingress.ports {iptables -A KUBE-NWPLCY-CHAIN -s $srcIP -d $dstIP -p $protocol -m $protocol --dport $port -j ACCEPT }}
}

可以看到,这是一条最基本的、通过匹配条件决定下一步动作的 iptables 规则。这条规则的名字是 KUBE-NWPLCY-CHAIN,含义是:当 IP 包的源地址是 srcIP、目的地址是 dstIP、协议是 protocol、目的端口是 port 的时候,就允许它通过(ACCEPT)。

而正如这段伪代码所示,匹配这条规则所需的这四个参数,都是从 NetworkPolicy 对象里读取出来的。

可以看到,Kubernetes 网络插件对 Pod 进行隔离,其实是靠在宿主机上生成 NetworkPolicy 对应的 iptable 规则来实现的。

此外,在设置好上述“隔离”规则之后,网络插件还需要想办法,将所有对被隔离 Pod 的访问请求,都转发到上述 KUBE-NWPLCY-CHAIN 规则上去进行匹配。并且,如果匹配不通过,这个请求应该被“拒绝”。

在 CNI 网络插件中,上述需求可以通过设置两组 iptables 规则来实现。

第一组规则,负责“拦截”对被隔离 Pod 的访问请求。生成这一组规则的伪代码,如下所示:

for pod := range 该Node上的所有Pod {if pod是networkpolicy.spec.podSelector选中的 {iptables -A FORWARD -d $podIP -m physdev --physdev-is-bridged -j KUBE-POD-SPECIFIC-FW-CHAINiptables -A FORWARD -d $podIP -j KUBE-POD-SPECIFIC-FW-CHAIN...}
}

其中,第一条 FORWARD 链“拦截”的是一种特殊情况:它对应的是同一台宿主机上容器之间经过 CNI 网桥进行通信的流入数据包。其中,--physdev-is-bridged 的意思就是,这个 FORWARD 链匹配的是,通过本机上的网桥设备,发往目的地址是 podIP 的 IP 包。

而第二条 FORWARD 链“拦截”的则是最普遍的情况,即:容器跨主通信。这时候,流入容器的数据包都是经过路由转发(FORWARD 检查点)来的。

不难看到,这些规则最后都跳转(即:-j)到了名叫 KUBE-POD-SPECIFIC-FW-CHAIN 的规则上。它正是网络插件为 NetworkPolicy 设置的第二组规则。

而这个 KUBE-POD-SPECIFIC-FW-CHAIN 的作用,就是做出“允许”或者“拒绝”的判断。这部分功能的实现,可以简单描述为下面这样的 iptables 规则:

iptables -A KUBE-POD-SPECIFIC-FW-CHAIN -j KUBE-NWPLCY-CHAIN
iptables -A KUBE-POD-SPECIFIC-FW-CHAIN -j REJECT --reject-with icmp-port-unreachable

可以看到,首先在第一条规则里,我们会把 IP 包转交给前面定义的 KUBE-NWPLCY-CHAIN 规则去进行匹配。按照我们之前的讲述,如果匹配成功,那么 IP 包就会被“允许通过”。而如果匹配失败,IP 包就会来到第二条规则上。可以看到,它是一条 REJECT 规则。通过这条规则,不满足 NetworkPolicy 定义的请求就会被拒绝掉,从而实现了对该容器的“隔离”。

以上,就是 CNI 网络插件实现 NetworkPolicy 的基本方法了。

参考:k8s networkpolicy网络策略详解_ghostwritten的博客-CSDN博客_networkpolicy

参考:网络策略 | Kubernetes

转载至https://www.likecs.com/show-305777962.html


推荐阅读
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • Gitlab接入公司内部单点登录的安装和配置教程
    本文介绍了如何将公司内部的Gitlab系统接入单点登录服务,并提供了安装和配置的详细教程。通过使用oauth2协议,将原有的各子系统的独立登录统一迁移至单点登录。文章包括Gitlab的安装环境、版本号、编辑配置文件的步骤,并解决了在迁移过程中可能遇到的问题。 ... [详细]
  • 使用R包提供的数据是学习数据科学工具的好方法,但是在某个时候,您希望停止学习,开始使用自己的数据。在本章中,您将学习如何将纯文本矩形文件读入r。在这里,我们只讨论数据导入的皮毛,但 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 有没有一种方法可以在不继承UIAlertController的子类或不涉及UIAlertActions的情况下 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 本文整理了315道Python基础题目及答案,帮助读者检验学习成果。文章介绍了学习Python的途径、Python与其他编程语言的对比、解释型和编译型编程语言的简述、Python解释器的种类和特点、位和字节的关系、以及至少5个PEP8规范。对于想要检验自己学习成果的读者,这些题目将是一个不错的选择。请注意,答案在视频中,本文不提供答案。 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
  • 本文介绍了利用ARMA模型对平稳非白噪声序列进行建模的步骤及代码实现。首先对观察值序列进行样本自相关系数和样本偏自相关系数的计算,然后根据这些系数的性质选择适当的ARMA模型进行拟合,并估计模型中的位置参数。接着进行模型的有效性检验,如果不通过则重新选择模型再拟合,如果通过则进行模型优化。最后利用拟合模型预测序列的未来走势。文章还介绍了绘制时序图、平稳性检验、白噪声检验、确定ARMA阶数和预测未来走势的代码实现。 ... [详细]
  • 引号快捷键_首选项和设置——自定义快捷键
    3.3自定义快捷键(CustomizingHotkeys)ChemDraw快捷键由一个XML文件定义,我们可以根据自己的需要, ... [详细]
  • 云原生SRE
    序言年底了,没有分手的朋友的赶紧分了,所谓新年新气象,年年不重样。去留无意,望看风卷残云。。。运维不会消失,但 ... [详细]
  • k8shelm官网:https:helm.sh点击charts:https:artifacthub.iopackagessearch?sortrelevance&page11.1h ... [详细]
  • 初始化_SQL Server 2017 AlwaysOn AG 自动初始化
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了SQLServer2017AlwaysOnAG自动初始化相关的知识,希望对你有一定的参考价值。 ... [详细]
  • KVM配置调整
    一内存CPU调整1.1增大虚拟机内存[root@k8s-01~]#virshshutdownvm01-centos7域vm01-centos7被关闭[root@k8s-01~]#v ... [详细]
author-avatar
黑旦儿
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有