Kubernetes Network Policy 详解与实践
Kubernetes Network Policy 详解与实践
Kubernetes 的 NetworkPolicy
是一种强大的工具,用于定义 Pod 之间的网络通信规则。本文将通过详细的解析和示例,帮助您理解如何使用 NetworkPolicy
控制 Pod 的入站(Ingress)和出站(Egress)流量。
一、引言
在 Kubernetes 集群中,NetworkPolicy
提供了一种声明式的方式来指定 Pod 间的通信规则。通过定义 NetworkPolicy
,我们可以精细地控制 Pod 的入站和出站流量,从而增强集群的安全性。
本文将分为以下几个部分:
- 基础概念:介绍
NetworkPolicy
的基本结构和关键字段。 - Ingress 和 Egress 概述:讲解入站和出站流量的概念及其管理方式。
- 示例详解:通过 9 个具体示例,详细解析
NetworkPolicy
的配置和使用方法。 - 总结:回顾关键点并提供进一步学习的建议。
二、Network Policy 基础
NetworkPolicy
资源对象定义在 networking.k8s.io/v1
API 版本中,主要包含以下关键字段:
apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 资源类型为 NetworkPolicy
metadata:
name: example-networkpolicy # 网络策略名称
namespace: default # 所属命名空间
spec:
policyTypes:
- Ingress # 定义入站流量规则
podSelector: # 目标 Pod 的选择器
matchLabels:
app: web # 匹配标签为 app: web 的 Pod
ingress: # 入站规则
- from:
- podSelector:
matchLabels:
app: db # 允许来源:标签为 app: db 的 Pod
关键字段说明:
- apiVersion:指定使用的 API 版本。
- kind:资源类型为
NetworkPolicy
。 - metadata:包含网络策略的名称和所在的命名空间。
- spec:网络策略的具体规则,包括
policyTypes
、podSelector
、ingress
和egress
等。
三、Ingress 和 Egress 概述
1. Ingress(入站流量)
Ingress
是 Kubernetes 中用于管理外部访问集群内部服务的 HTTP 和 HTTPS 路由的资源对象。它定义了路由规则,控制流量的路由,但本身不处理流量,而是依赖于 Ingress Controller
来实现流量处理。
Ingress 架构
Ingress 架构通常包括两个主要组件:
- Ingress Controller:负责监听 Ingress 规则变化并据此更新负载均衡器配置。
- Ingress 规则:定义了如何将外部流量路由到集群内部的服务。
示例
以下是一个简单的 Ingress 示例,定义了两个规则:
- 将所有
/demo
请求发送到demo-service
服务。 - 将所有其他请求发送到
main-service
服务。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: basic-ingress
spec:
rules:
- http:
paths:
- path: /demo
pathType: Prefix
backend:
service:
name: demo-service
port:
number: 80
defaultBackend:
service:
name: main-service
port:
number: 80
2. Egress(出站流量)
相对于 Ingress
,Egress
代表离开 Kubernetes 集群的流量。在 Kubernetes 中,Egress
流量通常通过 Node 的网络接口直接发送到外部网络。虽然 Ingress
有专门的控制器和规则来管理,但 Egress
流量则相对简单,通常不需要特别的控制器或规则来管理(除非有特定的安全或策略需求)。
四、示例详解
以下是 9 个具体的 NetworkPolicy
示例,详细解析其配置和使用方法。
示例 1:基于 Pod 标签的入站规则
apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
name: tomcat-access--networkpolicy # 网络策略名称
namespace: python # 所属命名空间
spec:
policyTypes:
- Ingress # 定义入站流量规则 也就是允许哪个 Pod 访问这个 Pod
podSelector: # 目标 Pod 的选择器
matchLabels:
app: python-tomcat-app1-selector # 匹配标签为 app: python-tomcat-app1-selector 的 Pod
ingress: # 入站规则
- from:
- podSelector:
matchLabels:
project: "python" # 允许来源:标签为 project: python 的 Pod
示例 1:基于 Pod 标签的入站规则
apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
name: tomcat-access--networkpolicy # 网络策略名称
namespace: python # 所属命名空间
spec:
policyTypes:
- Ingress # 定义入站流量规则
podSelector: # 目标 Pod 的选择器
matchLabels:
app: python-tomcat-app1-selector # 匹配标签为 app: python-tomcat-app1-selector 的 Pod
ingress: # 入站规则
- from:
- podSelector:
matchLabels:
project: "python" # 允许来源:标签为 project: python 的 Pod
示例 2:基于 Pod 标签和端口的入站规则
apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
name: tomcat-access--networkpolicy # 网络策略名称
namespace: python # 所属命名空间
spec:
policyTypes:
- Ingress # 定义入站流量规则
podSelector: # 目标 Pod 的选择器
matchLabels:
app: python-tomcat-app1-selector # 匹配标签为 app: python-tomcat-app1-selector 的 Pod
ingress: # 入站规则
- from:
- podSelector:
matchLabels:
project: "python" # 允许来源:标签为 project: python 的 Pod
ports:
- protocol: TCP # 指定协议:TCP
port: 8080 # 指定端口:8080
注释说明:
ports
字段限制了允许访问的协议和端口。- 在此示例中,仅允许来自标签为
project: python
的 Pod 通过 TCP 协议访问目标 Pod 的 8080 端口。
示例 3:多端口入站规则
apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
name: tomcat-access--networkpolicy # 网络策略名称
namespace: python # 所属命名空间
spec:
policyTypes:
- Ingress # 定义入站流量规则
podSelector: # 目标 Pod 的选择器
matchLabels:
app: python-tomcat-app1-selector # 匹配标签为 app: python-tomcat-app1-selector 的 Pod
ingress: # 入站规则
- from:
- podSelector: {} # 不限制来源 Pod
ports:
- protocol: TCP # 指定协议:TCP
port: 8080 # 指定端口:8080
- protocol: TCP
port: 3306 # 指定端口:3306
- protocol: TCP
port: 6379 # 指定端口:6379
注释说明:
from
中的podSelector: {}
表示不限制来源 Pod。ports
列出了多个端口和协议,允许访问的目标 Pod 的这些端口。
示例 4:不限制源 Pod 的入站规则
apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
name: tomcat-access--networkpolicy # 网络策略名称
namespace: python # 所属命名空间
spec:
policyTypes:
- Ingress # 定义入站流量规则
podSelector: # 目标 Pod 的选择器
matchLabels: {} # 匹配所有目标 Pod
ingress: # 入站规则
- from:
- podSelector: {} # 不限制来源 Pod
注释说明:
podSelector: {}
表示该规则适用于命名空间中的所有 Pod。from
中的podSelector: {}
表示不限制来源 Pod。
示例 5:基于 IP 段的入站规则
apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
name: tomcat-access--networkpolicy # 网络策略名称
namespace: python # 所属命名空间
spec:
policyTypes:
- Ingress # 定义入站流量规则
podSelector: # 目标 Pod 的选择器
matchLabels:
app: python-tomcat-app1-selector # 匹配标签为 app: python-tomcat-app1-selector 的 Pod
ingress: # 入站规则
- from:
- ipBlock:
cidr: 10.200.0.0/16 # 允许来自 10.200.0.0/16 网段的 IP 地址
注释说明:
ipBlock
定义了允许访问的 IP 地址范围。- 在此示例中,仅允许来自
10.200.0.0/16
网段的 IP 地址访问目标 Pod。
示例 6:基于 Namespace 标签的入站规则
apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
name: tomcat-access--networkpolicy # 网络策略名称
namespace: python # 所属命名空间
spec:
policyTypes:
- Ingress # 定义入站流量规则
podSelector: # 目标 Pod 的选择器
matchLabels: {} # 匹配命名空间中的所有 Pod
ingress: # 入站规则
- from:
- namespaceSelector:
matchLabels:
nsname: linux # 允许来源:标签为 nsname: linux 的 Namespace
ports:
- protocol: TCP # 指定协议:TCP
port: 8080 # 指定端口:8080
- protocol: TCP
port: 3306 # 指定端口:3306
- protocol: TCP
port: 6379 # 指定端口:6379
注释说明:
namespaceSelector
定义了允许访问的 Namespace。- 在此示例中,仅允许来自标签为
nsname: linux
的 Namespace 中的 Pod 访问目标 Pod 的指定端口。
示例 7:基于 IP 段的出站规则
apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
name: egress-access-networkpolicy # 网络策略名称
namespace: python # 所属命名空间
spec:
policyTypes:
- Egress # 定义出站流量规则
podSelector: # 目标 Pod 的选择器
matchLabels:
app: python-tomcat-app1-selector # 匹配标签为 app: python-tomcat-app1-selector 的 Pod
egress: # 出站规则
- to:
- ipBlock:
cidr: 10.200.0.0/16 # 允许访问 10.200.0.0/16 网段的 IP 地址
注释说明:
egress
定义了出站流量规则。- 在此示例中,仅允许目标 Pod 访问
10.200.0.0/16
网段的 IP 地址。
示例 8:基于 Pod 标签的出站规则
apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
name: egress-access-networkpolicy # 网络策略名称
namespace: python # 所属命名空间
spec:
policyTypes:
- Egress # 定义出站流量规则
podSelector: # 目标 Pod 的选择器
matchLabels:
app: python-nginx-selector # 匹配标签为 app: python-nginx-selector 的 Pod
egress: # 出站规则
- to:
- podSelector:
matchLabels:
app: python-tomcat-app1-selector # 允许访问:标签为 app: python-tomcat-app1-selector 的 Pod
ports:
- protocol: TCP # 指定协议:TCP
port: 8080 # 指定端口:8080
- protocol: TCP
port: 53 # 指定端口:53
- protocol: UDP
port: 53 # 指定端口:53
注释说明:
to
定义了允许访问的目标 Pod。- 在此示例中,仅允许目标 Pod 访问标签为
app: python-tomcat-app1-selector
的 Pod 的指定端口。
示例 9:基于 Namespace 标签的出站规则
apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
name: egress-access-networkpolicy # 网络策略名称
namespace: python # 所属命名空间
spec:
policyTypes:
- Egress # 定义出站流量规则
podSelector: # 目标 Pod 的选择器
matchLabels:
app: python-nginx-selector # 匹配标签为 app: python-nginx-selector 的 Pod
egress: # 出站规则
- to:
- namespaceSelector:
matchLabels:
nsname: python # 允许访问:标签为 nsname: python 的 Namespace
- namespaceSelector:
matchLabels:
nsname: linux # 允许访问:标签为 nsname: linux 的 Namespace
ports:
- protocol: TCP # 指定协议:TCP
port: 8080 # 指定端口:8080
- protocol: TCP
port: 53 # 指定端口:53
- protocol: UDP
port: 53 # 指定端口:53
注释说明:
namespaceSelector
定义了允许访问的 Namespace。- 在此示例中,仅允许目标 Pod 访问标签为
nsname: python
和nsname: linux
的 Namespace 中的 Pod 的指定端口。
五、总结
1. 核心概念回顾
- NetworkPolicy:用于定义 Pod 间通信规则的核心资源对象。
- Ingress:管理进入集群的流量,通常通过
Ingress Controller
实现。 - Egress:管理离开集群的流量,通常需要额外的安全策略。
2. 关键字段
- apiVersion 和 kind:定义资源类型和 API 版本。
- metadata:指定资源名称和命名空间。
- spec:定义具体的规则,包括
policyTypes
、podSelector
、ingress
和egress
。
3. 应用场景
- 安全性:通过限制 Pod 间的通信,防止未经授权的访问。
- 流量管理:精确控制流量的流向,优化资源利用率。
- 多租户环境:隔离不同租户的网络通信,确保数据安全。
4. 下一步学习建议
- 学习更多关于
CNI
插件的知识,了解它们如何支持NetworkPolicy
。 - 探索
Ingress Controller
的高级功能,例如 SSL/TLS 支持和负载均衡。 - 实践复杂的网络策略,结合实际业务场景进行优化。
希望本文能帮助您更好地理解和应用 Kubernetes 的 NetworkPolicy
!如果您有任何疑问或需要进一步的帮助,请随时留言交流!
如果还有其他需求,请告诉我!