NetworkPolicy(网络策略)
1. 介绍
1.1 基本概念
NetworkPolicy 是一种以应用为中心的结构,允许你设置如何允许 Pod 与网络上的各类网络“实体”,实现以下功能:
- 限制 Pod 之间和外部网络的流量:通过指定 Ingress 规则,可以阻止来自其他网络段、命名空间、 Pod的流量进入目标 Pod。
- 允许 Pod 之间和外部网络的流量:需要为目标 Pod 配置 Egress 规则,允许访问其他网络段、命名空间、pod。
1.2 使用原理
使用 NetworkPolicy 时,需要考虑以下几个方面:
- NetworkPolicy 只在支持它的网络插件中起作用,例如 Calico、Cilium 和 Weave Net 等。
- 没有定义任何 NetworkPolicy 规则,则所有的流量都会被允许。
- 定义 NetworkPolicy 后,它只适用于当前命名空间中的 Pod。
- 在 NetworkPolicy 中指定标签选择器时,应保证其唯一性,以免给其他 Pod 带来影响。
- 网络策略是相加的,所以不会产生冲突。如果策略适用于 Pod 某一特定方向的流量, Pod 在对应方向所允许的连接是适用的网络策略所允许的集合。 因此,评估的顺序不影响策略的结果。要允许从源 Pod 到目的 Pod 的连接,源 Pod 的出口策略和目的 Pod 的入口策略都需要允许连接。 如果任何一方不允许连接,建立连接将会失败。
- 默认pod都是未隔离的,如果指定某个命名空间pod进行网络策略隔离,其他未被指定的pod不会收到影响,将会继续接收流量
2. 资源定义
下面是一个 NetworkPolicy 的示例:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
2.1 字段含义
必需字段:与所有其他的 Kubernetes 配置一样,NetworkPolicy 需要 apiVersion
、 kind
和 metadata
字段。
spec:NetworkPolicy 中包含了在一个名字空间中定义特定网络策略所需的所有信息。
podSelector: 它对该策略所适用的一组 Pod 进行选择。示例中的策略选择带有 “role=db” 标签的 Pod。 空的 podSelector
选择名字空间下的所有 Pod。
policyTypes:包含 Ingress
或 Egress
或两者兼具。 如果 NetworkPolicy 未指定 policyTypes
则默认情况下始终设置 Ingress
; 如果 NetworkPolicy 有任何出口规则的话则设置 Egress
。
ingress:每个 NetworkPolicy 可包含一个 ingress
规则的白名单列表。 每个规则都允许同时匹配 from
和 ports
部分的流量。示例策略中包含一条简单的规则: 它匹配某个特定端口,来自三个来源中的一个,第一个通过 ipBlock
指定,第二个通过 namespaceSelector
指定,第三个通过 podSelector
指定。
egress:每个 NetworkPolicy 可包含一个 egress
规则的白名单列表。 每个规则都允许匹配 to
和 port
部分的流量。该示例策略包含一条规则, 该规则将指定端口上的流量匹配到 10.0.0.0/24
中的任何目的地。
所以,该网络策略示例:
- 隔离
default
名字空间下role=db
的 Pod (如果它们不是已经被隔离的话)。 - (Ingress 规则)允许以下 Pod 连接到
default
名字空间下的带有role=db
标签的所有 Pod 的 6379 TCP 端口:default
名字空间下带有role=frontend
标签的所有 Pod- 带有
project=myproject
标签的所有名字空间中的 Pod - IP 地址范围为 172.17.0.0–172.17.0.255 和 172.17.2.0–172.17.255.255 (即,除了 172.17.1.0/24 之外的所有 172.17.0.0/16)
- (Egress 规则)允许
default
名字空间中任何带有标签role=db
的 Pod 到 CIDR 10.0.0.0/24 下 5978 TCP 端口的连接。
每个 ingress 或 egress 规则包括以下部分:
- from(ingress) 或to(egress): 定义流量的源 (ingress) 或目的地 (egress)。这可以包括以下一个或多个字段:
podSelector
: 选择符合特定 label 的 Pod。namespaceSelector
: 选择符合特定 label 的命名空间。ipBlock
: 定义一个 IP 地址范围。
ports
: 定义流量可以使用的端口/范围和协议。
2.2 使用案例
2.2.1 默认拒绝所有入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
2.2.2 允许所有入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
spec:
podSelector: {}
ingress:
- {}
policyTypes:
- Ingress
2.2.3 默认拒绝所有出站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
spec:
podSelector: {}
policyTypes:
- Egress
2.2.4 允许所有出站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-egress
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress
2.2.5 实验
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: xjy1
name: xjy1
namespace: xjy
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: xjy1
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: xjy1
name: xjy1
namespace: xjy
spec:
containers:
- image: nginx:1.20
imagePullPolicy: IfNotPresent
name: xjy1
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
---
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2023-07-27T07:23:23Z"
name: sv1
namespace: xjy
resourceVersion: "116021339"
uid: db6f12c3-0380-4dc0-996d-6695cb6f36ab
spec:
clusterIP: 10.233.17.100
clusterIPs:
- 10.233.17.100
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: sv1-8080-8080
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: xjy1
sessionAffinity: None
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
labels:
app: dev-test-xjy
name: dev-test-xjy
namespace: xjy2
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: dev-test-xjy
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: dev-test-xjy
name: dev-test-xjy
namespace: xjy2
spec:
containers:
- image: nginx:1.20
imagePullPolicy: IfNotPresent
name: dev-test-xjy
resources:
limits:
cpu: "1"
memory: 100Mi
requests:
cpu: "1"
memory: 100Mi
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: xjy
spec:
podSelector:
matchLabels:
app: xjy1
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: xjy2
ports:
- protocol: TCP
port: 8080
egress:
- to:
- ipBlock:
cidr: 10.233.0.0/16
ports:
- protocol: TCP
port: 8081
[k8s NetworkPolicy]: https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/ “k8s官网”