1、kubernetes 网络策略(网络隔离策略)
Network Policy 是 Kubernetes 中用于控制 Pod 之间网络通信的一种机制。它通过定义规则,限制哪些 Pod 或外部实体可以与目标 Pod 通信(基于标签、命名空间、端口等)。Network Policy 的实现依赖于 CNI(Container Network Interface)插件(如 Calico、Cilium、Weave Net 等),并非所有网络插件都支持 Network Policy。
Network Policy 提供了基于策略的网络控制,用于隔离应用并减少攻击面。它使用标签选择器模拟传统的分段网络,并通过策略控制它们之间的流量以及来自外部的流量。
Pod 有两种隔离:出口的隔离和入口的隔离,默认情况下入口和出口都是非隔离的,可以接受来自任何请求方的网络请求。所谓的隔离也就是限制流量的流入或者流出,如果一个 NetworkPolicy 的标签选择器选中了某个 Pod,则该 Pod 将变成隔离的(isolated),并将拒绝任何不被 NetworkPolicy 许可的网络连接。
Kubernetes Network Policy 的核心字段通过定义流量规则来实现 Pod 之间的网络隔离。以下是核心字段的详细解析,帮助理解其工作原理和配置方法:
一、核心字段结构
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: <policy-name>namespace <string> #NetworkPolicy是名称空间级别的资源
spec:podSelector: {} # 当前规则生效的同一名称空间中的一组目标Pod对象,必选字段;policyTypes: # 策略类型(Ingress/Egress)二者可同时存在- Ingress- Egressingress: # 入站规则(允许的流量来源)白名单如果此字段为空,则此 NetworkPolicy 不允许任何入站流量 (这种设置用来确保它所选择的 Pod 在默认情况下是被隔离的)。- from:- <rule-sources> # 流量来源(Pod、命名空间、IP段)ports: # 允许的端口和协议- protocol: TCP/UDPport: <port>egress: # 出站规则(允许的流量去向)- to:- <rule-destinations> # 流量去向(Pod、命名空间、IP段)ports:- protocol: TCP/UDPport: <port>
二、核心字段详解
1. podSelector
-
作用:选择该 Network Policy 生效的目标 Pod。
-
规则:
- 使用标签选择器匹配 Pod(如
matchLabels
或matchExpressions
)。 - 空对象
{}
:匹配当前命名空间下的所有 Pod。
- 使用标签选择器匹配 Pod(如
-
示例:
podSelector:matchLabels:app: backend # 仅作用于标签为 app=backend 的 Pod
2. policyTypes
-
作用:定义策略的类型(入站或出站)。每个 NetworkPolicy 都包含一个
policyTypes
列表,其中包含Ingress
或Egress
或两者兼具。 -
可选值:
Ingress
:控制入站流量(谁可以访问目标 Pod)。Egress
:控制出站流量(目标 Pod 可以访问谁)。
-
默认行为:
- 如果未显式指定
policyTypes
,则根据ingress
或egress
字段的存在自动推断。
- 如果未显式指定
-
示例:
policyTypes: - Ingress # 仅处理入站流量规则
3. ingress
(入站规则)
定义允许的入站流量来源,每个 NetworkPolicy 可包含一个 ingress
规则的白名单列表。 每个规则都允许同时匹配 from
和 ports
部分的流量。如果此字段为空,则此 NetworkPolicy 不允许任何入站流量 (这种设置用来确保它所选择的 Pod 在默认情况下是被隔离的)。支持多种匹配条件:
3.1 from
字段(流量来源)
-
支持类型:
-
podSelector
:匹配同一命名空间内的 Pod。podSelector 是负责选择 Pod 的标签选择算符。如果字段存在但为空值,则选择所有 Pod。- podSelector:matchLabels:role: frontend
-
namespaceSelector
:匹配指定命名空间中的 Pod。namespaceSelector 使用集群范围标签来选择特定的 Namespace。 如果此字段存在但为空值,则会选择所有名字空间。- namespaceSelector:matchLabels:env: prod
-
ipBlock
:匹配 IP 地址段(CIDR 格式)。ipBlock 针对特定 IPBlock 定义策略。如果设置了此字段,则不可以设置其他字段。IPBlock 定义一个特定的 CIDR 范围(例如
192.168.1.0/24
、2001:db8::/64
), 来自这个 IP 范围的流量来源将会被允许访问与 NetworkPolicySpec 的 podSelector 匹配的 Pod 集合。- ipBlock:cidr: 192.168.1.0/24except: # 排除部分 IP- 192.168.1.1/32
-
-
组合逻辑:
from
中的多个条件是 逻辑或(OR) 关系。- 同一
from
块内的多个条件是 逻辑与(AND) 关系。
NetworkPolicy 的
.spec.ingress.from
和.spec.egress.to
字段中,可以指定 4 种类型的标签选择器:- podSelector 选择与
NetworkPolicy
同名称空间中的 Pod 作为入方向访问控制规则的源或者出方向访问控制规则的目标 - namespaceSelector 选择某个名称空间(其中所有的Pod)作为入方向访问控制规则的源或者出方向访问控制规则的目标
- namespaceSelector 和 podSelector 在一个
to
/from
条目中同时包含namespaceSelector
和podSelector
将选中指定名称空间中的指定 Pod。此时请特别留意 YAML 的写法,如下所示:
...ingress:- from:- namespaceSelector:matchLabels:user: alicepodSelector:matchLabels:role: client...
该例子中,podSelector 前面没有
-
减号,namespaceSelector 和 podSelector 是同一个 from 元素的两个字段,将选中带user=alice
标签的名称空间中所有带role=client
标签的 Pod。但是,下面的这个 NetworkPolicy 含义是不一样的:...ingress:- from:- namespaceSelector:matchLabels:user: alice- podSelector:matchLabels:role: client...
- 后者,podSelector 前面带
-
减号,说明 namespaceSelector 和 podSelector 是 from 数组中的两个元素,他们将选中 NetworkPolicy 同名称空间中带role=client
标签的对象,以及带user=alice
标签的名称空间的所有 Pod。 - 前者是交集关系(且),后者是并集关系(或)
3.2 ports
字段
-
作用:指定允许的协议和端口。ports 是在此规则选中的 Pod 上应可访问的端口列表。此列表中的个项目使用逻辑或操作组合。如果此字段为空或缺失, 则此规则匹配所有端口(进入流量可访问任何端口)
-
规则:
-
如果未指定
ports
,则允许所有端口。 -
支持
TCP
(默认)和UDP
。 -
ingress.ports.endPort
endPort 表示如果设置了此字段,则策略应该允许 port 与 endPort 之间(包含二者)的所有端口。 如果未定义 port 或将 port 字段值为命名端口(字符串),则不可以使用 endPort。 endPort 必须等于或大于 port 值。
-
-
示例:
ports: - protocol: TCPport: 80 # 允许 TCP 80 端口 - protocol: UDPport: 53 # 允许 UDP 53 端口
4. egress
(出站规则)
定义允许的出站流量去向,egress 是应用到所选 Pod 的出站规则的列表。如果此字段为空,则此 NetworkPolicy 拒绝所有出站流量(这策略可以确保它所选中的 Pod 在默认情况下是被隔离的)语法与 ingress
类似:
4.1 to
字段(流量去向)
-
支持类型:
podSelector
、namespaceSelector
、ipBlock
(同from
)。
-
示例(允许访问外部 DNS 服务器):
egress: - to:- ipBlock:cidr: 8.8.8.8/32ports:- protocol: UDPport: 53
4.2 ports
字段
- 与
ingress
中的ports
字段规则一致。
三、关键行为规则
- 白名单机制:
- 一旦为 Pod 定义任意 Network Policy,其流量默认进入“白名单模式”。
- 未被规则明确允许的流量将被拒绝。
- 策略叠加:
- 多个 Network Policy 同时作用于同一 Pod 时,规则是 叠加生效 的(逻辑或关系)。
- 示例:若策略 A 允许来自 Pod X 的流量,策略 B 允许来自 Pod Y 的流量,则最终允许 X 和 Y。
- 命名空间隔离:
namespaceSelector
用于跨命名空间控制,但需确保目标命名空间存在且标签匹配。
- IP 段限制:
ipBlock
适用于外部 IP 或集群内非 Pod IP(如 Service ClusterIP)。
四、常见配置场景
创建测试环境
[root@master ~]# mkdir networkpolicy
创建两个名称空间
[root@master networkpolicy]# ls
[root@master networkpolicy]# kubectl create ns app
namespace/app created
[root@master networkpolicy]# kubectl create ns dev
namespace/dev created
[root@master networkpolicy]# kubectl get ns
NAME STATUS AGE
app Active 7s
dev Active 3s[root@master networkpolicy]# cat deployment-dev.yml
apiVersion: apps/v1
kind: Deployment
metadata:name: deployment-demonamespace: dev
spec:replicas: 2selector:matchLabels:app: demoapprelease: stabletemplate:metadata:labels :app: demoapprelease: stablespec:containers:- name: demoappimage: nginxports:- containerPort: 80name: http[root@master networkpolicy]# kubectl apply -f deployment-dev.yml
deployment.apps/deployment-demo created
[root@master networkpolicy]# kubectl get pod,deploy -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/deployment-demo-54668bc56b-qswzx 1/1 Running 0 7m22s 10.244.140.84 node02 <none> <none>
pod/deployment-demo-54668bc56b-xz9ht 1/1 Running 0 7m22s 10.244.186.217 node03 <none> <none>NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/deployment-demo 2/2 2 2 7m22s demoapp nginx app=demoapp,release=stable[root@master networkpolicy]# cat deployment-app.yml
apiVersion: apps/v1
kind: Deployment
metadata:name: deployment-demo-appnamespace: app
spec:replicas: 2selector:matchLabels:app: nginxrelease: latesttemplate:metadata:labels:app: nginxrelease: latestspec:containers:- name: nginximage: nginxports:- containerPort: 80name: http[root@master networkpolicy]# kubectl apply -f deployment-app.yml
deployment.apps/deployment-demo-app created
[root@master networkpolicy]# kubectl get pod,deploy -n app -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/deployment-demo-app-7c469bff9d-cdm5q 1/1 Running 0 2m39s 10.244.186.218 node03 <none> <none>
pod/deployment-demo-app-7c469bff9d-hs4v7 1/1 Running 0 2m39s 10.244.140.85 node02 <none> <none>NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/deployment-demo-app 2/2 2 2 2m39s nginx nginx app=nginx,release=latest创建service
[root@master networkpolicy]# cat deployment-dev-svc.yml
apiVersion: v1
kind: Service
metadata:name: dev-svcnamespace: dev
spec:selector:app: demoapprelease: stableports:- protocol: TCPport: 8080targetPort: 80[root@master networkpolicy]# kubectl apply -f deployment-dev-svc.yml
service/dev-svc created
[root@master networkpolicy]# kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dev-svc ClusterIP 10.108.14.28 <none> 8080/TCP 6m37s
测试在app名称空间下访问dev名称空间里面的应用
[root@master networkpolicy]# kubectl exec -it deployment-demo-app-7c469bff9d-cdm5q -n app -- /bin/bash
root@deployment-demo-app-7c469bff9d-cdm5q:/# curl -I http://10.244.140.84
HTTP/1.1 200 OK
Server: nginx/1.27.4
Date: Wed, 26 Mar 2025 08:49:50 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Wed, 05 Feb 2025 11:06:32 GMT
Connection: keep-alive
ETag: "67a34638-267"
Accept-Ranges: bytesroot@deployment-demo-app-7c469bff9d-cdm5q:/# curl -I http://10.244.186.217
HTTP/1.1 200 OK
Server: nginx/1.27.4
Date: Wed, 26 Mar 2025 08:49:59 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Wed, 05 Feb 2025 11:06:32 GMT
Connection: keep-alive
ETag: "67a34638-267"
Accept-Ranges: bytesroot@deployment-demo-app-7c469bff9d-cdm5q:/# curl -I http://dev-svc.dev.svc.cluster.local:8080
HTTP/1.1 200 OK
Server: nginx/1.27.4
Date: Wed, 26 Mar 2025 12:08:24 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Wed, 05 Feb 2025 11:06:32 GMT
Connection: keep-alive
ETag: "67a34638-267"
Accept-Ranges: bytes
在测试在dev名称空间下访问app名称空间里面的应用
[root@master networkpolicy]# kubectl exec -it deployment-demo-54668bc56b-xz9ht -n dev -- /bin/bash
root@deployment-demo-54668bc56b-xz9ht:/# curl -I http://10.244.186.218
HTTP/1.1 200 OK
Server: nginx/1.27.4
Date: Wed, 26 Mar 2025 08:52:34 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Wed, 05 Feb 2025 11:06:32 GMT
Connection: keep-alive
ETag: "67a34638-267"
Accept-Ranges: bytesroot@deployment-demo-54668bc56b-xz9ht:/# curl -I http://10.244.140.85
HTTP/1.1 200 OK
Server: nginx/1.27.4
Date: Wed, 26 Mar 2025 08:52:42 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Wed, 05 Feb 2025 11:06:32 GMT
Connection: keep-alive
ETag: "67a34638-267"
Accept-Ranges: bytes
综上默认情况下各个名称空间中的pod都是互通的。
为所有名称空间打上标签
[root@master networkpolicy]# kubectl label ns dev resource=dev
namespace/dev labeled
[root@master networkpolicy]# kubectl label ns app resource=app system=app
namespace/app labeled
[root@master networkpolicy]# kubectl get ns --show-labels | grep dev
dev Active 23m kubernetes.io/metadata.name=dev,resource=dev
[root@master networkpolicy]# kubectl get ns --show-labels | grep app
app Active 23m kubernetes.io/metadata.name=app,resource=app,system=app
场景 1:禁止所有入站流量
你可以通过创建选择所有 Pod 但不允许任何进入这些 Pod 的入站流量的 NetworkPolicy 来为名字空间创建 “dev” 隔离策略。
这确保即使没有被任何其他 NetworkPolicy 选择的 Pod 仍将被隔离以进行入口。 此策略不影响任何 Pod 的出口隔离。
[root@master networkpolicy]# cat networkpolicy-denyall-dev.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: deny-all-ingressnamespace: dev
spec:podSelector: {}policyTypes:- Ingress # 无ingress 规则,拒绝所有入站[root@master networkpolicy]# kubectl apply -f networkpolicy-denyall-dev.yml
[root@master networkpolicy]# kubectl get networkpolicy -n dev
NAME POD-SELECTOR AGE
deny-all-ingress <none> 3m22s
测试在app命令空间的pod中访问dev名称空间的资源
[root@master networkpolicy]# kubectl exec -it deployment-demo-app-7c469bff9d-cdm5q -n app -- /bin/bash
root@deployment-demo-app-7c469bff9d-cdm5q:/# curl -I http://10.244.140.84
^C
root@deployment-demo-app-7c469bff9d-cdm5q:/#
root@deployment-demo-app-7c469bff9d-cdm5q:/# curl 10.244.186.217
^C在default名称空间中的pod访问dev名称空间中的资源
[root@master networkpolicy]# kubectl exec -it nginx-deployment-6d758bfc44-gg2sw -- /bin/bash
root@nginx-deployment-6d758bfc44-gg2sw:/# curl -I http://10.244.140.84
^C
允许所有入站流量
如果你想允许一个名字空间中所有 Pod 的所有入站连接,你可以创建一个明确允许的策略。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: allow-all-ingress
spec:podSelector: {}policyTypes:- Ingressingress:- {}
有了这个策略,任何额外的策略都不会导致到这些 Pod 的任何入站连接被拒绝。 此策略对任何 Pod 的出口隔离没有影响。
场景 2:允许同一命名空间的特定 Pod
要实现允许 default
命名空间下指定 Pod 通过 Service(ClusterIP/DNS) 访问 dev
命名空间下的 Pod,需明确以下两点:
- Service 的流量本质
Kubernetes Service 只是将流量转发到后端 Pod,最终流量仍是 Pod-to-Pod。因此 NetworkPolicy 仍需控制 源 Pod(default
命名空间)到 目标 Pod(dev
命名空间)的流量。 - 关键配置
- 目标 Pod(
dev
命名空间)需要正确标签。 - Service 的
selector
必须匹配目标 Pod 的标签。 - NetworkPolicy 需在
dev
命名空间定义入站规则。
- 目标 Pod(
在default名称空间下在创建测试pod
[root@master networkpolicy]# cat deployment-default.yml
apiVersion: apps/v1
kind: Deployment
metadata:name: test-demo
spec:replicas: 2selector:matchLabels:svc: nginxtemplate:metadata:labels :svc: nginxspec:containers:- name: nginx-1image: nginxports:- containerPort: 80name: http
[root@master networkpolicy]# kubectl apply -f deployment-default.yml
deployment.apps/test-demo created[root@master networkpolicy]# kubectl get pod,deploy
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-6d758bfc44-gg2sw 1/1 Running 5 (4h19m ago) 6d5h
pod/nginx-deployment-6d758bfc44-zsxqb 1/1 Running 3 (4h19m ago) 2d6h
pod/test-demo-64cd7dd9dd-fp44q 1/1 Running 0 30s
pod/test-demo-64cd7dd9dd-qtfbd 1/1 Running 0 30sNAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 2/2 2 2 6d5h
deployment.apps/test-demo 2/2 2 2 31s
创建规则,允许default名称空间下带有svc=nginx标签的pod访问dev名称空间中带有指定标签的pod资源
[root@master networkpolicy]# cat netpol-dev-ingress-2.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: test-default-devnamespace: dev
spec:podSelector:matchLabels:app: demoapprelease: stablepolicyTypes:- Ingressingress:- from:- namespaceSelector:matchLabels:kubernetes.io/metadata.name: defaultpodSelector:matchLabels:svc: nginxports:- port: 80 #目标 Pod 的实际端口(非 Service 端口)[root@master networkpolicy]# kubectl apply -f netpol-dev-ingress-2.yml
networkpolicy.networking.k8s.io/test-default-dev created
[root@master networkpolicy]# kubectl get netpol -n dev
NAME POD-SELECTOR AGE
test-default-dev app=demoapp,release=stable 8s
测试在default名称空间中带有svc=nginx的pod中访问dev名称空间下的pod
[root@master ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-6d758bfc44-gg2sw 1/1 Running 6 (45m ago) 7d app=nginx,pod-template-hash=6d758bfc44
nginx-deployment-6d758bfc44-zsxqb 1/1 Running 4 (45m ago) 3d app=nginx,pod-template-hash=6d758bfc44
test-demo-54449d9d85-kk7s4 1/1 Running 1 (43m ago) 18h pod-template-hash=54449d9d85,svc=nginx
test-demo-54449d9d85-pn56j 1/1 Running 1 (43m ago) 18h pod-template-hash=54449d9d85,svc=nginx[root@master ~]# kubectl exec -it test-demo-54449d9d85-pn56j -- curl -I http://10.244.140.88
HTTP/1.1 200 OK
Server: nginx/1.27.4
Date: Thu, 27 Mar 2025 07:24:38 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Wed, 05 Feb 2025 11:06:32 GMT
Connection: keep-alive
ETag: "67a34638-267"
Accept-Ranges: bytes[root@master ~]# kubectl exec -it test-demo-54449d9d85-pn56j -- curl -I http://10.244.186.221
HTTP/1.1 200 OK
Server: nginx/1.27.4
Date: Thu, 27 Mar 2025 07:24:49 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Wed, 05 Feb 2025 11:06:32 GMT
Connection: keep-alive
ETag: "67a34638-267"
Accept-Ranges: bytes[root@master ~]# kubectl exec -it test-demo-54449d9d85-pn56j -- curl -I http://dev-svc.dev.svc.cluster.local:8080
HTTP/1.1 200 OK
Server: nginx/1.27.4
Date: Thu, 27 Mar 2025 07:25:17 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Wed, 05 Feb 2025 11:06:32 GMT
Connection: keep-alive
ETag: "67a34638-267"
Accept-Ranges: bytes使用default名称空间下带有其它标签的pod访问
[root@master ~]# kubectl exec -it nginx-deployment-6d758bfc44-gg2sw -- curl -I http://dev-svc.dev.svc.cluster.local:8080
^Ccommand terminated with exit code 130
[root@master ~]# kubectl exec -it nginx-deployment-6d758bfc44-gg2sw -- curl -I http://10.244.186.221
^Ccommand terminated with exit code 130
[root@master ~]# kubectl exec -it nginx-deployment-6d758bfc44-gg2sw -- curl -I http://10.244.140.88
^Ccommand terminated with exit code 130
场景 3:允许特定外部 IP
egress:
- to:- ipBlock:cidr: 10.0.0.0/8
场景 4:允许访问 Kubernetes DNS
egress:
- to:- namespaceSelector: {}podSelector:matchLabels:k8s-app: kube-dnsports:- protocol: UDPport: 53
场景 5: 创建NetworkPolicy2 放行dev名称空间
- 规则1: 标签匹配的名称空间所有流量都能访问dev下所有Pod;
- 规则2: 除了app名称空间,其它所有名称空间都可以访问dev下的 80端口
- 组合使用,会以最大允许权限为最优匹配权限
[root@master ~]# kubectl get ns --show-labels
NAME STATUS AGE LABELS
app Active 22h kubernetes.io/metadata.name=app,resource=app,system=app
calico-apiserver Active 7d22h kubernetes.io/metadata.name=calico-apiserver,name=calico-apiserver,pod-security.kubernetes.io/enforce-version=latest,pod-security.kubernetes.io/enforce=restricted
calico-system Active 7d22h kubernetes.io/metadata.name=calico-system,name=calico-system,pod-security.kubernetes.io/enforce-version=latest,pod-security.kubernetes.io/enforce=privileged
default Active 7d23h kubernetes.io/metadata.name=default
dev Active 22h kubernetes.io/metadata.name=dev,resource=dev
kube-node-lease Active 7d23h kubernetes.io/metadata.name=kube-node-lease
kube-public Active 7d23h kubernetes.io/metadata.name=kube-public
kube-system Active 7d23h kubernetes.io/metadata.name=kube-system
tigera-operator Active 7d22h kubernetes.io/metadata.name=tigera-operator,name=tigera-operator,pod-security.kubernetes.io/enforce=privileged[root@master networkpolicy]# cat netpol-dev-ingress.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: input-dev-resourcenamespace: dev #指定dev名称空间
spec:podSelector: #定义pod的标签选择器matchLabels: #选择带有某个标签的podapp: demoapp #dev名称空间下带有这个标签的pod生效release: stablepolicyTypes: #策略类型- Ingress #入站ingress: #入站规则- from: - namespaceSelector: #指定名称空间的标签matchExpressions: #多标签的匹配模式- key: kubernetes.io/metadata.nameoperator: In #包含values: [default,kube-system] #name的值为指定内容的标签名称空间下的资源可以访问dev名称空间下带有指定标签pod的80端口ports: #定义允许访问的端口- port: 80 #目标 Pod 的实际端口(非 Service 端口)[root@master networkpolicy]# kubectl apply -f netpol-dev-ingress.yml
networkpolicy.networking.k8s.io/input-dev-resource created
[root@master networkpolicy]# kubectl get netpol -n dev
NAME POD-SELECTOR AGE
deny-all-ingress <none> 32m
input-dev-resource app=demoapp,resource=latest 7s[root@master networkpolicy]# kubectl describe netpol -n dev input-dev-resource
Name: input-dev-resource
Namespace: dev
Created on: 2025-03-26 17:41:34 +0800 CST
Labels: <none>
Annotations: <none>
Spec:PodSelector: app=demoapp,resource=latestAllowing ingress traffic:To Port: 80/TCPFrom:NamespaceSelector: kubernetes.io/metadata.name in (default,kube-system)Not affecting egress trafficPolicy Types: Ingress
- 在app名称空间下访问dev名称空间
- 80端口测试 依然无法访问 没有匹配到符合规则的条目
[root@master ~]# kubectl get pod -n app
NAME READY STATUS RESTARTS AGE
deployment-demo-app-7c469bff9d-cdm5q 1/1 Running 1 (51m ago) 22h
deployment-demo-app-7c469bff9d-hs4v7 1/1 Running 1 22h[root@master ~]# kubectl exec -it deployment-demo-app-7c469bff9d-cdm5q -n app -- /bin/bash
root@deployment-demo-app-7c469bff9d-cdm5q:/# curl -I http://10.244.140.88
^C
root@deployment-demo-app-7c469bff9d-cdm5q:/# curl -I http://10.244.186.221
^C
root@deployment-demo-app-7c469bff9d-cdm5q:/# curl -I http://dev-svc.dev.svc.cluster.local:8080
^C
- 当名称空间有两个标签时需要同时指定,如果只指定其中一个,将不生效
[root@master networkpolicy]# cat netpol-dev-ingress.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: input-dev-resourcenamespace: dev
spec:podSelector:matchLabels:app: demoapprelease: stablepolicyTypes:- Ingressingress:- from:- namespaceSelector:matchExpressions:- key: systemoperator: Invalues: [app]- from:- namespaceSelector:matchExpressions:- key: resourceoperator: Invalues: [app]ports:- port: 80[root@master networkpolicy]# kubectl apply -f netpol-dev-ingress.yml
networkpolicy.networking.k8s.io/input-dev-resource configured
- 测试在app名称空间下访问dev名称空间
[root@master networkpolicy]# kubectl exec -it deployment-demo-app-7c469bff9d-cdm5q -n app -- /bin/bash
root@deployment-demo-app-7c469bff9d-cdm5q:/# curl -I http://dev-svc.dev.svc.cluster.local:8080
HTTP/1.1 200 OK
Server: nginx/1.27.4
Date: Wed, 26 Mar 2025 12:37:22 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Wed, 05 Feb 2025 11:06:32 GMT
Connection: keep-alive
ETag: "67a34638-267"
Accept-Ranges: bytesroot@deployment-demo-app-7c469bff9d-cdm5q:/# curl -I http://10.244.186.221
HTTP/1.1 200 OK
Server: nginx/1.27.4
Date: Thu, 27 Mar 2025 07:40:35 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Wed, 05 Feb 2025 11:06:32 GMT
Connection: keep-alive
ETag: "67a34638-267"
Accept-Ranges: bytes
五、调试技巧
-
验证策略是否生效:
# kubectl describe networkpolicy <policy-name>[root@master networkpolicy]# kubectl describe netpol -n dev input-dev-resource Name: input-dev-resource Namespace: dev Created on: 2025-03-26 17:41:34 +0800 CST Labels: <none> Annotations: <none> Spec:PodSelector: app=demoapp,release=stableAllowing ingress traffic:To Port: 80/TCPFrom:NamespaceSelector: kubernetes.io/metadata.name in (default,kube-system)Not affecting egress trafficPolicy Types: Ingress
-
检查 Pod 标签和命名空间:
# kubectl get pods --show-labels -n <namespace> # kubectl get namespaces --show-labels
-
网络插件工具:
- Calico:使用
calicoctl
查看端点策略。 - Cilium:运行
cilium connectivity test
。
- Calico:使用
六、注意事项
- CNI 插件支持:确认集群网络插件支持 Network Policy(如 Calico、Cilium)。
- 默认允许:未定义任何策略时,所有流量默认放行。
- 端口范围:不支持端口范围(需逐个指定)。
- 协议限制:仅支持 TCP/UDP,不支持 ICMP 或其他协议。
通过精确配置这些字段,可以实现 Kubernetes 集群内精细化的网络隔离,保障应用的安全性。