第 7 章 网络策略
7.1. 关于网络策略
作为集群管理员,您可以定义网络策略以限制到集群中的 pod 的网络通讯。
7.1.1. 关于网络策略
在使用支持 Kubernetes 网络策略的 Kubernetes Container Network Interface(CNI)插件的集群中,网络隔离完全由 NetworkPolicy
对象控制。在 OpenShift Container Platform 4.4 中,OpenShift SDN 支持在默认的网络隔离模式中使用网络策略。
OpenShift Container Platform 中提供了 Kubernetes v1
网络策略功能,但出口策略类型和 IPBlock 除外。
网络策略不适用于主机网络命名空间。启用主机网络的 Pod 不受网络策略规则的影响。
默认情况下,项目中的所有 pod 都可被其他 pod 和网络端点访问。要在一个项目中隔离一个或多个 Pod,您可以在该项目中创建 NetworkPolicy
对象来指示允许的入站连接。项目管理员可以在自己的项目中创建和删除 NetworkPolicy
对象。
如果一个 pod 由一个或多个 NetworkPolicy
对象中的选择器匹配,那么该 pod 将只接受至少被其中一个 NetworkPolicy
对象所允许的连接。未被任何 NetworkPolicy
对象选择的 pod 可以完全访问。
以下示例 NetworkPolicy
对象演示了支持不同的情景:
拒绝所有流量:
要使项目默认为拒绝流量,请添加一个匹配所有 pod 但不接受任何流量的
NetworkPolicy
对象:kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: deny-by-default spec: podSelector: ingress: []
只允许 OpenShift Container Platform Ingress Controller 的连接:
要使项目只允许 OpenShift Container Platform Ingress Controller 的连接,请添加以下
NetworkPolicy
对象:apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-openshift-ingress spec: ingress: - from: - namespaceSelector: matchLabels: network.openshift.io/policy-group: ingress podSelector: {} policyTypes: - Ingress
如果 Ingress Controller 配置了
endpointPublishingStrategy: HostNetwork
,则 Ingress Controller pod 在主机网络中运行。在主机网络中运行时,来自 Ingress Controller 的网络流量会被分配netid:0
Virtual Network ID (VNID) 。与 Ingress Operator 关联的命名空间的netid
不同,因此allow-from-openshift-ingress
中的matchLabel
网络策略与default
Ingress Controller 的流量不匹配。因为default
命名空间被分配了netid:0
VNID,所以可以通过把default
命名空间标记(label)为network.openshift.io/policy-group: ingress
来允许来自于default
Ingress Controller 的网络流量。只接受项目中 pod 的连接:
要使 pod 接受同一项目中其他 pod 的连接,但拒绝其他项目中所有 pod 的连接,请添加以下
NetworkPolicy
对象:kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-same-namespace spec: podSelector: ingress: - from: - podSelector: {}
仅允许基于 pod 标签的 HTTP 和 HTTPS 流量:
要对带有特定标签(以下示例中的
role=frontend
)的 pod 仅启用 HTTP 和 HTTPS 访问,请添加类似如下的NetworkPolicy
对象:kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-http-and-https spec: podSelector: matchLabels: role: frontend ingress: - ports: - protocol: TCP port: 80 - protocol: TCP port: 443
使用命名空间和 pod 选择器接受连接:
要通过组合使用命名空间和 pod 选择器来匹配网络流量,您可以使用类似如下的
NetworkPolicy
对象:kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-pod-and-namespace-both spec: podSelector: matchLabels: name: test-pods ingress: - from: - namespaceSelector: matchLabels: project: project_name podSelector: matchLabels: name: test-pods
NetworkPolicy
对象是可添加的;也就是说,您可以组合多个 NetworkPolicy
对象来满足复杂的网络要求。
例如,对于以上示例中定义的 NetworkPolicy
对象,您可以在同一个项目中定义 allow-same-namespace
和 allow-http-and-https
策略。因此,允许带有标签 role=frontend
的 pod 接受每一策略所允许的任何连接。即,任何端口上来自同一命名空间中的 pod 的连接,以及端口 80
和 443
上的来自任意命名空间中 pod 的连接。
7.1.2. 网络策略优化
使用一个网络策略来通过 pod 上的不同标签来在命名空间中将不同 pod 进行隔离。
有效使用网络策略规则的指南只适用于 OpenShift SDN 集群网络供应商。
将 NetworkPolicy
对象应用到单一命名空间中的大量 pod 时,效率较低。因为 Pod 标签不存在于 IP 地址一级,因此网络策略会为使用 podSelector
选择的每个 pod 之间生成单独的 Open vSwitch(OVS)流量规则 。
例如,在一个 NetworkPolicy
对象中,如果 spec podSelector
和 ingress podSelector
每个都匹配 200 个 pod,则会产生 40,000 (200*200) OVS 流规则。这可能会减慢节点的速度。
在设计您的网络策略时,请参考以下指南:
使用命名空间使其包含需要隔离的 pod 组,可以减少 OVS 流规则数量。
使用
namespaceSelector
或空podSelector
选择整个命名空间的NetworkPolicy
对象会只生成 一个与命名空间的 VXLAN 虚拟网络 ID(VNID)匹配的 OVS 流量规则。- 保留不需要在原始命名空间中隔离的 pod,并将需要隔离的 pod 移到一个或多个不同的命名空间中。
- 创建额外的目标跨命名空间网络策略,以允许来自不同隔离的 pod 的特定流量。