K8S-NetworkPolicy
一、概述
在Kubernetes中,NetworkPolicy是一项关键功能,它允许开发者定义和控制Pod之间的网络通信。本文将深入研究Kubernetes中的NetworkPolicy,详细介绍其原理、用途,并通过实际示例演示如何使用NetworkPolicy来确保集群中的网络安全。
1、什么是NetworkPolicy?
NetworkPolicy是Kubernetes中用于定义Pod之间网络通信规则的资源对象。通过NetworkPolicy,开发者可以控制哪些Pod可以与另外哪些Pod通信,以及使用何种方式进行通信。这种细粒度的网络控制有助于提高集群的安全性,防止未经授权的访问和通信。
2、NetworkPolicy的基本原理
NetworkPolicy的工作原理基于以下几个核心概念:
-
Pod选择器(PodSelector)& namespaceSelector:NetworkPolicy使用标签选择器来选择特定的Pod。通过标签,可以将网络策略应用于特定的Pod群体。
-
Ingress规则:定义了允许从其他Pod进入被选中Pod的规则,包括允许的协议、端口范围等。
-
Egress规则:定义了允许被选中Pod访问其他Pod或外部网络的规则。
-
Peer Pod:NetworkPolicy中的规则是基于Peer Pod(对等Pod)的。通过选择Peer Pod,可以精确定义通信策略。
二、NetworkPolicy资源清单
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: default spec: podSelector: matchLabels: app: backend #选择带有 app=backend 标签的 Pod 作为目标 Pod ingress: #入站 - from: - podSelector: matchLabels: app: frontend # 允许带有 app=frontend 标签的 Pod 访问目标 Pod - ipBlock: cidr: 192.168.1.0/24 # 允许来自 192.168.1.0/24 网段的流量访问目标 Pod ports: - protocol: TCP port: 8080 # 只允许访问目标 Pod 的 8080 端口 egress: #出站 - to: - podSelector: matchLabels: app: database # 允许目标 Pod 访问带有 app=database 标签的 Pod ports: - protocol: TCP port: 3306 #目标 Pod 访问其他 Pod 时只允许使用 3306 端口
三、NetworkPolicy的示例
示例一:不允许相同Namespace下的Pod通信
【注意】提前给命名空间设置labels
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-same-namespace
namespace: default # 改成你要限制的命名空间
spec:
# 作用于命名空间内所有 Pod
podSelector: {}
# 拒绝所有入站流量
policyTypes:
- Ingress
# 入站规则为空 = 拒绝所有入站
ingress: []
####禁止default命令空间一切访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: full-isolation
namespace: default # 改成你要隔离的命名空间
spec:
# 匹配命名空间下所有 Pod
podSelector: {}
# 同时控制 入站 + 出站 流量(核心!缺一不可)
policyTypes:
- Ingress
- Egress
# 1. 拒绝所有入站流量(任何Pod都不能访问我)
ingress: []
# 2. 拒绝所有出站流量(我不能访问任何Pod)
egress: []
示例二:限制外部访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-external-traffic
spec:
podSelector:
matchLabels:
app: sensitive-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector: {}
egress:
- to:
- podSelector: {}
#######允许本命名空间的pod之间的访问,及与default命名空间下的访问,但不允许对其他网络的访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-external-traffic
namespace: network1
spec:
podSelector:
matchLabels:
app: nignx
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector: {}
egress:
- to:
- podSelector: {}
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: default
在这个示例中,我们创建了一个名为"deny-external-traffic"的NetworkPolicy,限制了标签为app: sensitive-app的Pod的Ingress和Egress。该策略允许Pod之间的通信,但不允许访问任何外部网络。
示例三:指定端口范围
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-specific-ports spec: podSelector: matchLabels: app: frontend ingress: - ports: - protocol: TCP port: 80 - protocol: UDP port: 53
在这个示例中,我们创建了一个名为"allow-specific-ports"的NetworkPolicy,指定了标签为app: frontend的Pod的Ingress规则。该规则允许从其他Pod进入的流量,其中包括TCP端口80和UDP端口53。
四、限制其他命名空间中的pod访问podSelector匹配到的pod
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-external-traffic namespace: myns1 spec: podSelector: matchLabels: app: alpine policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: project: myns1
五、只访问外部网络和同命名空间下的pod
现在有如下需求: 使用networkpolicy实现在myns1命名空间下的所有label为app: alpine的pod可以与myns1命名空间中的其他pod和外部互联网通信,不能与其他命名空间中的任何pod通信。请编写资源清单文件。
【注意】 pod访问带有svc的pod时,可以通过svcFQDN访问。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: alpine-communication-policy
namespace: myns1 # 策略仅作用于 myns1 命名空间
spec:
podSelector:
matchLabels:
app: alpine # 目标 Pod:myns1 中所有标签为 app: alpine 的 Pod
policyTypes:
- Ingress # 控制入站流量
- Egress # 控制出站流量
# ------------------------------
# 入站规则:仅允许 myns1 内 Pod 访问
# ------------------------------
ingress:
- from:
- podSelector: {} # 匹配 myns1 命名空间内的所有 Pod(无标签过滤)
# 无端口限制(允许所有端口),如需限制端口可添加 ports 字段
# ------------------------------
# 出站规则:允许访问 myns1 内 Pod 和外部互联网,拒绝其他命名空间
# ------------------------------
egress:
# 规则 1:允许访问 myns1 命名空间内的所有 Pod(包括自身)
- to:
- podSelector: {} # 匹配当前命名空间(myns1)的所有 Pod
# 规则 2:允许访问外部互联网(非集群内部 IP)
- to:
- ipBlock:
cidr: 0.0.0.0/0 # 允许所有 IPv4 地址(需排除集群内部 CIDR)
except:
# 重要:替换为集群实际的 Pod CIDR 和 Service CIDR
- 10.244.0.0/16 # 示例:calico 默认 Pod CIDR(需根据集群调整)
- 10.96.0.0/12 # 示例:Kubernetes Service 默认 CIDR(需根据集群调整)
# 规则 3:允许 DNS 解析(关键!否则无法访问外部域名)
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system # kube-dns 所在命名空间
podSelector:
matchLabels:
k8s-app: kube-dns # kube-dns Pod 标签(可能因集群不同而变化)
ports:
- protocol: UDP
port: 53 # DNS UDP 端口
- protocol: TCP
port: 53 # DNS TCP 端口(用于长查询)
四、NetworkPolicy的高级用法(了解)
除了基本的示例外,NetworkPolicy还支持一些高级用法,如网络策略的继承、Peer Pod选择器的高级匹配等。以下是一些高级用法的示例:
1、网络策略的继承
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: parent-policy spec: podSelector: matchLabels: role: parent ingress: - from: - podSelector: matchLabels: role: child --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: child-policy spec: podSelector: matchLabels: role: child policyTypes: - Ingress - Egress
在这个示例中,我们创建了两个NetworkPolicy。"parent-policy"用于选择标签为role: parent的Pod,并定义了一个Ingress规则,允许来自标签为role: child的Pod的通信。"child-policy"选择标签为role: child的Pod,并定义了Ingress和Egress规则。这样,"child-policy"继承了"parent-policy"的规则。
2、高级Peer Pod选择器匹配
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: advanced-selector-matching
spec:
podSelector:
matchLabels:
app: backend
ingress:
- from:
- podSelector:
matchExpressions:
- {key: role, operator: In, values: [frontend, middleware]}
在这个示例中,我们通过matchExpressions定义了更复杂的Peer Pod选择器匹配条件。该规则选择标签为app: backend的Pod,并定义了一个Ingress规则,允许来自标签为role为frontend或middleware的Pod的通信。
更多推荐


所有评论(0)