1. 写在最前
请注意你的集群 cni 插件是否支持网络策略功能,否则将无法生效
2. 描述概念
网络策略的组成是选中一组目标容器pod,然后对这一组目标容器pod进行限制出入站
3. 例子详解
3.1 标签选择
default 名称空间
选中 default 名称空间中 带有app: nginx标签的pod容器
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
namespace: default
name: test-policy
spec:
podSelector:
matchLabels:
app: nginx
3.2 标签表达式
default 名称空间
选中 default 名称空间中带有app标签 包含 nginx,tomcat,kafka的pod容器
operator有In 包含、NotIn 不包含、DoesNotExist 不存在
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
namespace: default
name: test-policy
spec:
podSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
- tomcat
- kafka
3.3 策略类型
完成 podSelector 只是第一步,第二步则是配置策略类型(policyTypes)
策略类型有两个值,一个是 Ingress(进站) 另一个是Egress(出站)
3.4 进站Ingress
如果你只写上了 policyTypes 却没有写它的具体实现,则表示拒绝所有
3.4.1 拒绝入站流量
tanqidi 名称空间
选中 tanqidi 名称空间中带有app标签是 tanqidi-service 的pod容器
拒绝所有入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
namespace: tanqidi
name: tanqidi-service
spec:
podSelector:
matchLabels:
app: tanqidi-service
policyTypes:
- Ingress
3.4.2 允许入站流量
tanqidi 名称空间
选中 tanqidi 名称空间中带有app标签是 tanqidi-service 的pod容器
允许当前 namespace 中的其他pod容器访问我
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
namespace: tanqidi
name: tanqidi-service
spec:
podSelector:
matchLabels:
app: tanqidi-service
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
3.4.3 标签选择
tanqidi 名称空间
选中 tanqidi 名称空间中带有app标签是 tanqidi-service 的pod容器
允许当前 namespace 中的 app 标签包含 tanqidi-web、tanqidi-mgt、tanqid-center 的pod容器访问我
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
namespace: tanqidi
name: tanqidi-service
spec:
podSelector:
matchLabels:
app: tanqidi-service
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchExpressions:
#可以是任意你想选择的标签
- key: app
operator: In
values:
- tanqidi-web
- tanqidi-mgt
- tanqidi-center
3.4.4 跨 namespace 入站
namespaceSelector 可以做到跨越namespace的出入站限制,不仅仅是当前 namespace
tanqidi 名称空间
选中 tanqidi 名称空间中带有app标签是 tanqidi-service 的pod容器
允许 lisi 名称空间下的所有pod访问我
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
namespace: tanqidi
name: tanqidi-service
spec:
podSelector:
matchLabels:
app: tanqidi-service
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: lisi
3.4.5 跨 namespace 入站,and关系
tanqidi 名称空间
选中 tanqidi 名称空间中带有app标签是 tanqidi-service 的pod容器
允许 lisi 名称空间的 并且 app 标签是 lisi-service 的pod访问我
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
namespace: tanqidi
name: tanqidi-service
spec:
podSelector:
matchLabels:
app: tanqidi-service
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: lisi
# 开头没有-表示 and关系
podSelector:
matchLabels:
app: lisi-service
3.5 出站egress
3.5.1 拒绝出站流量
如果你只写上了 policyTypes 却没有写它的具体实现,则表示拒绝所有
tanqidi 名称空间
选中 tanqidi 名称空间中带有app标签是 tanqidi-service 的pod容器
拒绝所有流量出站
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
namespace: tanqidi
name: tanqidi-service
spec:
podSelector:
matchLabels:
app: tanqidi-service
policyTypes:
- Egress
3.5.2 允许出站流量
这里描述的允许出站指的是仅只能访问当前的 namespace下的任意pod容器,不同的 namespace 他是无法访问的,因为没有使用 namespaceSelector 跨越名称空间
tanqidi 名称空间
选中 tanqidi 名称空间中带有app标签是 tanqidi-service 的pod容器
允许出站到当前名称空间
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
namespace: tanqidi
name: tanqidi-service
spec:
podSelector:
matchLabels:
app: tanqidi-service
policyTypes:
- Egress
egress:
- to:
- podSelector: {}
3.5.3 跨 namespace 出站流量(复杂)
目标
tanqidi 名称空间
选中 tanqidi 名称空间中带有app标签是 tanqidi-db 的pod容器
入站
允许当前 namespace 中的app 标签是 tanqidi-service的pod容器访问我
允许 namespace 包含zhangsan,lisi,wangwu的名称空间下的 app 标签包含 app-mgt,app-center,app-proxy下的 pod容器访问我
出站
允许流量出站到当前 namespace 中的 app标签是 tanqidi-service 的pod容器
允许流量出站到 namespace 包含zhangsan,lisi,wangwu的名称空间下任意 any 容器
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
namespace: tanqidi
name: tanqidi-db
spec:
podSelector:
matchLabels:
app: tanqidi-db
policyTypes:
- Ingress
- Egress
ingress:
# 允许当前 namespace 下的 app标签是 tanqidi-service 容器访问我
- from:
- podSelector:
matchLabels:
app: tanqidi-service
# 允许 namespace包含 zhangsan、lisi、wangwu 的名称空间下 并且 app 标签 包含 app-mgt,app-center,app-proxy 的pod访问我
- from:
- namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- zhangsan
- lisi
- wangwu
# 组合方式,表示 and 关系
podSelector:
matchExpressions:
- key: app
operator: In
values:
- app-mgt
- app-center
- app-proxy
egress:
- to:
# 允许出站流量到当前 namespace 中的app标签是 tanqidi-service的容器
- podSelector:
matchLabels:
app: tanqidi-service
# 允许流量出站到 namespace 包含 zhangsan,lisi,wangwu的任意pod
- namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- zhangsan
- lisi
- wangwu
3.6 条件 and 与 or
3.6.1 and 关系
tanqidi 名称空间
选中 tanqidi 名称空间中带有app标签是 tanqidi-db 的pod容器
允许 namespace 为 lisi 的名称空间下的 app标签是 lisi-service的pod访问我
当为namespaceSelector选中 kubernetes.io/metadata.name 为 lisi 的时候,此刻该名称空间下的所有pod 都能访问 目标 tanqidi 名称空间下的 tanqidi-db的pod,但是紧接着你使用了 and关系添加了podSelector 为 app: lisi-service,换而言之条件就变小了变成 lisi的namespace 下的 lisi-service的pod能访问目标 tanqidi 名称空间下的 tanqidi-db的pod
请注意 and 关系到第二个的时候不能在开头加上- 否则就是or 关系了
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
namespace: tanqidi
name: tanqidi-db
spec:
podSelector:
matchLabels:
app: tanqidi-db
policyTypes:
- Ingress
ingress:
- from:
# 允许 namespace 名称空间为 lisi的访问我
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: lisi
# 允许 namespace 名称空间为 lisi的 app标签为 lisi-service的访问我。此时就变了,不再是任意lisi下的pod访问我,而只是 lisi下的lisi-service的pod访问我,换而言之 and的关系会将条件进一步缩小
podSelector:
matchLabels:
app: lisi-service
3.6.2 or 关系
tanqidi 名称空间
选中 tanqidi 名称空间中带有app标签是 tanqidi-db 的pod容器
允许当前名称空间中 app标签带有 tanqidi-service 的pod访问我
允许 namespace 为 lisi 的名称空间下的任意pod访问我
or 关系两个都是独立的,需要在新的规则前加上-
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
namespace: tanqidi
name: tanqidi-db
spec:
podSelector:
matchLabels:
app: tanqidi-db
policyTypes:
- Ingress
ingress:
# 允许当前 namespace 下的 app标签是 tanqidi-service 容器访问我
- from:
- podSelector:
matchLabels:
app: tanqidi-service
# 允许 namespace 为 lisi 的名称空间下的任意pod访问我
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: lisi