networkpolicy
网络策略基于ip和端口控制流量(OSI 第 3 层或第 4 层)),NetworkPolicy 适用于一端或两端与 Pod 的连接,与其他连接无关。
需要依赖cni 网络插件,calico 通过自定义k8s 资源支持网络策略
配置文件
第一步:配置文件结构
字段 | 释义 | 举例 |
---|---|---|
apiversion | api群组 | networking.k8s.io/v1 |
kind | 资源类型 | NetworkPolicy |
metadata | 元数据信息 | |
spec |
第二步:剖析spec
字段 | 释义 | 举例 |
---|---|---|
podSelector | 选中要实施网络策略的pod | |
poicyTypes | 策略的类型,["Ingress","Egress"] | 5中特殊情况接下来描述 |
ingress | 入栈流量的过滤策略 | |
egress | 出栈流量的过滤策略 |
第三步:具体展开
-
podSelector
-
选择该资源所在名称空间下的所有pod
spec: podSelector: {}
-
选择该资源所在名称空间下拥有指定标签的pod
spec: podSelector: matchLables: app: db
sepc: podSelector: matchExpressions: - key: app operator: In values: - db
-
-
policyTypes
-
不应用任何自定义策略,执行默认策略(允许任何的出栈和入栈流量)
spec: policyTypes: []
-
禁止所有的出栈流量
spec: policyTypes: - Egress ... spec下没有定义 egress
-
禁止所有的入栈流量
spec: policyTypes: - Ingress ... spec 下没有定义 ingress
-
允许所有的出栈流量
spec: policyTypes: - Egress egress: {}
-
允许所有的入栈流量
spec: policyTypes: - Ingress ingress:{}
-
-
ingress
-
定义来源:例如允许哪个ip、名称空间、pod 访问
-
定义允许访问本地的端口、协议
from
和ports
两种是交际的关系,而from和ports中以列表展示的资源是并集关系spec: ingress: - from: - ipBlock: cidr: "10.4.7.1/24" expect: - "10.4.7.50/32" - "192.168.123.1/24" - namespaceSelector: matchLabels: {} matchExpressions: {} # 默认从networPolicy所定义的名称空间选择pod - podSelector: matchLabels: {} matchExpressions: {} #namespaceSelector:{} - ports: - protocol: TCP port: 8000
-
-
egress
spec: ingress: - to: - ipBlock: cidr: "10.4.7.1/24" expect: - "10.4.7.50/32" - "192.168.123.1/24" - namespaceSelector: matchLabels: {} matchExpressions: {} # 默认从networPolicy所定义的名称空间选择pod - podSelector: matchLabels: {} matchExpressions: {} #namespaceSelector:{} - ports: - protocol: TCP port: 8000
案例测试
kubectl create ns ns01
kubectl create ns ns02
kubectl create deploy test-networkpolicy --image=python -n ns01 --image=python --replicas=2
kubectl create deploy test-networkpolicy --image=python -n ns02 --image=python --replicas=2
kubectl create ns web
kubectl create ns db
kubectl run web --image=python -n web --port=8000 -- python -m http.server
kubectl run web2 --image=python -n web --port=8001 -- python -m http.server 8001
kubectl run db --image=python -n db --port=8000 -- python -m http.server 8000
kubectl run db2 --image=python -n db --port=8001 -- python -m http.server 8001
场景一:只允许同名称空间的pod通讯
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: only-communication-onenamespace
namespace: web
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: "web"
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: "web"
场景二:只允许该名称空间pod访问外部应用
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: out-to-anyone
namespace: web
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
egress:
- {}
场景三:只允许该名称空间的pod访问指定名称空间的指定端口
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: speci-namespace-port
namespace: web
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: db
ports:
- port: 8001
场景四:只允许该名称空间的pod访问指定名称空间下指定pod的指定端口
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: spec-namespace-pod-port
namespace: web
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
"kubernetes.io/metadata.name": "db"
podSelector:
matchLabels:
run: "db2"
ports:
- port: 8001
场景五:只允许指定名称空间的pod访问本名称空间
场景六: 只允许指定名称空间的指定pod访问本名称空间
场景七:只允许指定名称空间的指定pod访问本名称空间指定端口
场景八:只允许指定名称空间的指定pod访问本名称空间指定pod的端口
场景九:只允许指定指定ip段访问本名称空间
场景十:本名称空间只允许访问指定指定ip段的pod
场景九:禁止该名称空间pod与任何pod 通讯
第一题:只允许ns01 名称空间内部通讯
# 隔离名称空间的通讯
# 名称空间ns01的pod只允许名称空间内pod通讯
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: isolation-namespace
namespace: ns01
spec:
podSelector: {} #选择该名称空间下的所有pod
policyTypes:
- Ingress
- egress
ingress:
- from:
- namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- ns01
egress:
- to:
- namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- ns0
第二题:只允许通过ns02中的pod访问ns01 监听8080的pod
# ns01 中创建一个 netpol allow-port-from-namespace
# 允许 ns02 中的pod 连接到 ns01 中的监听8080的pod
# 不允许访问ns01中未监听8080的pod访问
# 不允许名称空间ns02 外的访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-port-from-namespace
namespace: ns01
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- ns02
- ports:
- protocol: TCP
port: 8080