Kubernetes NetworkPolicy与Pod流量隔离

Kubernetes NetworkPolicy与Pod流量隔离

_

一、Network Policy

1. Network Policy概述

NetworkPolicy(网络策略)是Kubernetes原生资源对象,用于控制Pod之间、Pod与外部端点之间的网络进出流量,实现集群内微分段网络访问控制。NetworkPolicy作用于Pod,通过标签选择器筛选目标Pod,定义Ingress(入站流量)和Egress(出站流量)访问规则。

NetworkPolicy依赖支持该特性的CNI网络插件,如Calico、Weave等。Flannel默认不支持NetworkPolicy,如果使用Flannel,策略不会生效。

1.1 默认拒绝原则 当一个Pod被NetworkPolicy匹配时:

  • 若策略中没有写明允许的入站规则,所有入站流量默认拒绝。

  • 若策略中没有写明允许的出站规则,所有出站流量默认拒绝。

  • 没有任何NetworkPolicy作用的Pod,保持集群默认互通。

1.2 NetworkPolicy识别可与Pod通信的对象,依靠三类标识

  • 允许通信的Pod:Pod自身访问自身的流量默认不受阻断;

  • 允许通信的命名空间;

  • IP地址段:Pod与所在节点之间的通信始终放行,不受Pod、节点IP地址影响。

1.3 配置NetworkPolicy规则时存在两种模式

  • 若采用Pod、命名空间作为管控对象,借助标签选择器筛选Pod,以此定义进入匹配Pod的流量权限;

  • 若基于IP进行管控,则通过CIDR地址段设置访问策略。

2. 集群Pod默认互通特性

默认情况下,k8s集群内所有Pod之间网络互通,能够接收任何来源的流量,不存在网络隔离限制。

[Step1] 创建两个namespace,分别名为space01和space02。

root@k8s-master:~# kubectl create namespace space01
root@k8s-master:~# kubectl create namespace space02

[Step2] 本地新建YAML清单,定义Pod资源描述模板。使用busybox镜像在分别在space01和space02命名空间内创建Pod。

root@k8s-master:~# vim busybox-pod.yml
​
# 写入下列内容
apiVersion: v1
kind: Pod
metadata:
  name: busybox01
  namespace: space01
spec:
  containers:
    - name: busybox01
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ["sleep","1000"]
---
apiVersion: v1
kind: Pod
metadata:
  name: busybox02
  namespace: space02
spec:
  containers:
    - name: busybox02
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ["sleep","1000"]

[Step3] 基于YAML清单向Kubernetes集群声明式地创建Pod资源。

root@k8s-master:~# kubectl create -f busybox-pod.yml

[Step4] 验证:基于文件内定义的资源清单,查询集群中该资源的运行状态与基础信息。由此可以观察到,尽管两个Pod分属不同命名空间,但集群为其分配的IP地址仍属于同一子网。

root@k8s-master:~# kubectl get -f busybox-pod.yml -o wide

[Step5] 登录到busybox01容器,测试与busybox02的连通性,网络正常通信。

root@k8s-master:~# kubectl exec -n space01 -it busybox01 -- /bin/sh
/ # ping 172.16.126.4 -c 5

[Step6] 登录到busybox02容器,测试与busybox01的连通性,网络正常通信。

root@k8s-master:~# kubectl exec -n space02 -it busybox02 -- /bin/sh
/ # ping 172.16.126.5 -c 5

3. Pod隔离

当Pod被NetworkPolicy匹配时,会开启网络隔离。只要命名空间内存在的网络策略选中某个Pod,该Pod将会拒绝所有策略没有明确放行的网络连接。多条网络策略之间不会相互冲突,规则效果会叠加生效。如果多条策略同时作用于同一个Pod,最终生效规则是所有策略入站、出站规则的合集,策略先后顺序不会影响最终结果。

如果要实现两个Pod正常通信,源Pod的出站规则和目标Pod的入站规则都必须放行这条流量。只要源端出站策略拦截或目标端入站策略拦截,通信都会失败。

4. 流量方向选择

当前存在两个命名空间:targetspace和clientspace。

  • targetspace:服务端命名空间,里面存放需要被网络策略保护的Pod,负责接收外部访问流量。

  • clientspace:客户端命名空间,里面的Pod会主动发起访问请求,作为流量的发送方。

NetworkPolicy默认会拒绝所有请求,只要Pod被策略匹配,所有进出流量都会被拦截,只有写在白名单规则中的流量才能正常通行。同时网络策略只对和它同一命名空间内的Pod生效,而入站规则用来管控外部Pod访问当前命名空间内Pod的流量。

因此想要保护targetspace内的服务Pod,网络策略必须部署在targetspace命名空间,才能识别并管控该命名空间下的目标Pod。

二、NetworkPolicy案例配置

1. 创建NetworkPolicy

[Step1] 本地新建YAML清单,定义NetworkPolicy资源描述模板。对当前命名空间内标签为“label=access”的Pod启用网络隔离。配置入站规则,仅允许同命名空间具备“access=true”标签的Pod进行访问。由于未定义出站规则,受控Pod所有出站流量将默认拒绝。

root@k8s-master:~# vim network-policy.yml
​
# 写入下列内容
apiVersion: networking.k8s.io/v1    # 版本信息
kind: NetworkPolicy     # 资源类型
metadata:
  name: network-policy
spec:
  podSelector:      # Pod选择器
    matchLabels:    # 采用标签精确匹配的筛选方式
      # 匹配携带标签 label=true的Pod,符合该条件的Pod开启网络隔离
      label: "true"
  ingress:      # 定义入站规则
    - from:     # 流量来源白名单,允许哪些对象发起访问
      - podSelector:        # 筛选条件,从Pod维度匹配访问源
          matchLabels:      # 对访问源Pod使用标签精准匹配
            access: "true"  # 仅允许当前命名空间内携带标签 access=true 的Pod建立访问

[Step2] 基于YAML清单向Kubernetes集群声明式地创建NetworkPolicy资源。

root@k8s-master:~# kubectl create -f network-policy.yml

[Step3] 验证:查看当前集群中名为network-policy的NetworkPolicy资源详细信息。

root@k8s-master:~# kubectl describe networkpolicies.networking.k8s.io/network-policy

2. 创建正常的Pod

[Step1] 本地新建YAML清单,定义Pod资源描述模板。

root@k8s-master:~# vim busybox-pod.yml

# 写入下列内容
apiVersion: v1	# 版本信息
kind: Pod		# 资源类型
metadata:
  name: busybox-pod
spec:
  containers:
    - name: pod-target
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ["sleep","1000"]

[Step2] 基于YAML清单向Kubernetes集群声明式地创建Pod资源。

root@k8s-master:~# kubectl create -f busybox-pod.yml

[Step3] 验证:基于文件内定义的资源清单,查询集群中该资源的详细信息。

root@k8s-master:~# kubectl get -f busybox-pod.yml -o wide

3. 创建网络隔离受控Pod

[Step1] 本地新建YAML清单,定义Pod资源描述模板。基于busybox镜像创建pod-target,将其设置为受控对象,打上标签“label:access”。

root@k8s-master:~# vim pod-target.yml

# 写入下列内容
apiVersion: v1	# 版本信息
kind: Pod		# 资源类型
metadata:
  name: pod-target
  labels:		# 给当前资源加上标签
    label: access	# 标签键值对
spec:
  containers:
    - name: pod-target
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ["sleep","1000"]

[Step2] 基于YAML清单向Kubernetes集群声明式地创建Pod资源。

root@k8s-master:~# kubectl create -f pod-target.yml

[Step3] 验证:基于文件内定义的资源清单,查询集群中该资源的运行状态与基础信息。

root@k8s-master:~# kubectl get -f pod-target.yml -o wide

[Step4] 验证:登录到busybox-pod容器,测试与pod-target的连通性,此时网络无法联通。

root@k8s-master:~# kubectl exec -it busybox-pod -- /bin/sh
/ # ping 172.16.126.43 -c 5
/ # exit

[Step5] 验证:使用k8s-master测试与pod-target的连通性,同样网络无法联通。

root@k8s-master:~# ping 172.16.126.43 -c 5

4. 创建允许访问的Pod

[Step1] 本地新建YAML清单,定义Pod资源描述模板。基于busybox镜像创建pod-client,允许其访问受控Pod,打上标签“access=true”。

root@k8s-master:~# vim pod-client.yml

# 写入下列内容
apiVersion: v1	# 版本信息
kind: Pod		# 资源类型
metadata:
  name: pod-client
  labels:			# 给当前资源加上标签
    access: "true"	# 标签键值对,true本身具备含义,因此需要加上双引号
spec:
  containers:
    - name: pod-target
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ["sleep","1000"]

[Step2] 基于YAML清单向Kubernetes集群声明式地创建Pod资源。

root@k8s-master:~# kubectl create -f pod-client.yml

[Step3] 验证:基于文件内定义的资源清单,查询集群中该资源的详细信息。

root@k8s-master:~# kubectl get -f pod-client.yml -o wide

[Step4] 验证:登录到pod-client容器,测试与pod-target的连通性,网络正常通信。

root@k8s-master:~# kubectl exec -it pod-client -- /bin/sh
/ # ping 172.16.126.43 -c 5
/ # exit

—


Kubernetes 认证授权、RBAC 角色绑定与网络隔离 2026-10-29
Kubernetes Helm 基础操作 2026-10-29

评论区