【 Kubernetes 】Networkpolicy
作者:互联网
参考文档 :
https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/
https://docs.projectcalico.org/v3.10/getting-started/kubernetes/installation/flannel
https://github.com/ahmetb/kubernetes-network-policy-recipes
https://www.cnblogs.com/ssgeek/p/11714487.html
一、Networkpolicy简介
为了实现细粒度的容器间网络访问隔离策略(防火墙), Kubernetes从1.3版本开始,由SIG-Network小组主导研发了Network Policy机制,目前已升级为networking.k8s.io/v1稳定版本。
- 网络策略(
NetworkPolicy
) 是一种关于Pod间及Pod于其他网络端点间所允许的通信规则的规范,主要功能是对Pod间的网络通信进行限制和准入控制
; - 简单理解,NetworkPolicy就是对pod进行网络策略控制。用于为Kubernetes实现更为精细的流量控制,实现租户隔离机制。Kubernetes使用标准的资源对象NetworkPolicy供管理员按需定义网络访问控制策略。
- 设置方式为将Pod的Label作为查询条件,设置允许访问或禁止访问的客户端Pod列表。查询条件可以作用于Pod和Namespace级别。
二、NetworkPolicy策略模型
三、网络策略配置说明
网络策略
的设置主要用于对目标Pod
的网络访问进行限制,在默认情况下对所有Pod都是允许访问
的,在设置了指向Pod的NetworkPolicy网络策略
之后,到Pod的访问才会被限制。 需要注意的是网络策略是基于Pod的;- NetWorkPolicy基于命名空间进行限制,即只作用当前命名空间,分为两种:
ingress
: 定义允许访问目标Pod的入站白名单规则;egress
: 定义目标Pod允许访问的“出站”白名单规则;
- 具体的规则限制方式分为三种(需要注意的是,多个限制之间是或的逻辑关系,如果希望变成与的关系,yaml文件需要配置为数组):
- IP策略
- 命名空间策略
- pod选择器限制
- NetWorkPolicy基于命名空间进行限制,即只作用当前命名空间,分为两种:
官方 demo
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector: #用于定义该网络策略作用的Pod范围
matchLabels:
role: db
policyTypes: #网络策略的类型,包括ingress和egress两种
- Ingress
- Egress
ingress: #定义允许访问目标Pod的入站白名单规则
- from: #满足from 条件的客户端才能访问ports定义的目标Pod端口号。
- ipBlock: # IP限制
cidr: 172.17.0.0/16
except: #排除那些IP
- 172.17.1.0/24
- namespaceSelector: #命名空间限制
matchLabels:
project: myproject
- podSelector: # pod选择器限制
matchLabels:
role: frontend
ports: #允许访问的目标Pod监听的端口号。
- protocol: TCP
port: 6379
egress: #定义目标Pod允许访问的“出站”白名单规则
- to: #目标Pod仅允许访问满足to条件的服务端IP范围和ports定义的端口号
- ipBlock:
cidr: 10.0.0.0/24
ports: #允许访问的服务端的端口号。
- protocol: TCP
port: 5978
metadata
: 描述信息。podSelector
: pod选择器,选定的$ pod$ 所有的出入站流量要遵循本$ networkpolicy$ 的约束。policyTypes
: 策略类型。包括了Ingress$ 和$ Egress,默认情况下一个policyTypes的值一定会包含Ingress,当有egress 规则时,policyTypes的值中会包含Egress 。ingress入站
: 即由其他网络端点发往特定$ Pod$ 组的流量 ,通常由流量发出的源站点$ from$ 和流量的目标端口所定义 。egress出站
: 即由特定的Pod
组发往其他网络端点的流量 ,通常由流量的目标网络端点to
和端口ports
来进行定义 。port
端口 :TCP
或UDP
的端口号。to,from
端点 : 流量目标和流量源相关的组件, 它可以是CIDR
格式的IP
地址块ipBlock
、网络名称空间选择器namespaceSelector
匹配的名称空间, 或Pod
选择器podSelector
匹配的Pod
组。
四、NetworkPolicy默认策略
- 默认情况下,如果名称空间中不存在任何策略,则所有进出该名称空间中的Pod的流量都被允许。以下示例用于更改该名称空间中的默认行为。
4.1、默认拒绝所有入口流量
通过创建选择所有容器但不允许任何进入这些容器的入口流量的$ NetworkPolicy$ 来为名称空间创建$ default$ 隔离策略。这样可以确保即使容器没有选择其他任何$ NetworkPolicy$ ,也仍然可以被隔离。此策略不会更改默认的出口隔离行为。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
4.2、默认允许所有入口流量
如果要允许所有流量进入某个命名空间中的所有Pod(即使添加了导致某些Pod被视为“隔离”的策略),则可以创建一个策略来明确允许该命名空间中的所有流量。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
ingress:
- {}
policyTypes:
- Ingress
4.3、默认拒绝所有出口流量
通过创建选择所有容器但不允许来自这些容器的任何出口流量的NetworkPolicy来为名称空间创建default egress隔离策略。这样可以确保即使没有被其他任何NetworkPolicy选择的Pod也不会被允许流出流量。此策略不会更改默认的ingress隔离行为。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Egress
4.4、默认允许所有出口流量
如果要允许来自命名空间中所有Pod的所有流量(即使添加了导致某些Pod被视为“隔离”的策略),则可以创建一个策略,该策略明确允许该命名空间中的所有出口流量。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress
4.5、默认拒绝所有入口和所有出口流量
为名称空间创建default策略,以通过在该名称空间中创建以下NetworkPolicy来阻止所有入站和出站流量。这样可以确保即使没有被其他任何NetworkPolicy选择的Pod也不会被允许进入或流出流量。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
4.6、实战 :仅允许流量出向 ingress
为 test 名称空间创建仅允许 该名称空间服务 8080 出向 ingress-controller的流量策略;
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-only-igress
namespace: test
spec:
podSelector: {} # 匹配 test ns下的所有Pod
policyTypes:
- Ingress
egress:
- to:
- namespaceSelector:
matchLabels:
app.kubernetes.io/name: ingress-nginx-main
podSelector:
matchLabels:
"app.kubernetes.io/name": ingress-nginx-main
ports:
- protocol: TCP
port: 8080
4.7、实战 : redis 流量限制示例
允许default namespace中带有role=frontend标签的Pod访问default namespace中带有role=db标签Pod的6379端口
允许带有project=myprojects标签的namespace中所有Pod访问default namespace中带有role=db标签Pod的6379端口
# apiVersion: extensions/v1beta1
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
ingress:
- from:
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: tcp
port: 6379
4.8、实战 :允许带有access=true的Pod访问nginx的网络策略
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: access-nginx
spec:
podSelector:
matchLabels:
run: nginx
ingress:
- from:
- podSelector:
matchLabels:
access: "true"
4.9、实战 :禁止访问指定服务
# kubectl run web --image=nginx --labels app=web,env=prod --expose --port 80
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-deny-all
spec:
podSelector:
matchLabels:
app: web
env: prod
4.10、实战 :只允许指定pod访问服务
# kubectl run apiserver --image=nginx --labels app=bookstore,role=api --expose --port 80
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: api-allow
spec:
podSelector:
matchLabels:
app: bookstore
role: api
ingress:
- from:
- podSelector:
matchLabels:
app: bookstore
4.11、实战 :禁止 namespace 中所有 Pod 之间的相互访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: default
spec:
podSelector: {}
4.12、实战 :禁止其他 namespace 访问服务
# kubectl create namespace secondary
# kubectl run web --namespace secondary --image=nginx --labels=app=web --expose --port 80
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
namespace: secondary
name: web-deny-other-namespaces
spec:
podSelector:
matchLabels:
ingress:
- from:
- podSelector: {}
4.13、实战 :只允许指定namespace访问服务
# kubectl run web --image=nginx --labels=app=web --expose --port 80
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-allow-prod
spec:
podSelector:
matchLabels:
app: web
ingress:
- from:
- namespaceSelector:
matchLabels:
purpose: production
4.14、实战 :允许外网访问服务
# kubectl run web --image=nginx --labels=app=web --port 80
# kubectl expose deployment/web --type=LoadBalancer
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-allow-external
spec:
podSelector:
matchLabels:
app: web
ingress:
- ports:
- port: 80
from: []
五、使用flannel+canal实现k8s的NetworkPolicy
- $ Flannel$ 是解决容器网络方案最为普遍和简单的方案,$ Canal$ 代表了针对云原生应用程序的最佳网络策略解决方案,旨在让用户轻松的将$ Calico$ 和$ Flannel$ 网络部署在一起作为统一的网络解决方案,将$ Calico$ 的网络策略执行和$ Flannel$ 的叠加及非叠加网络连接选项的丰富功能相结合。 在$ Calico$ 的官方文档的相应部分中描述到此种方案是:用于策略的$ Calico$ 和用于网络的$ Flannel$ 相组合。
- 官方文档见:Installing Calico for policy and flannel for networking -> https://docs.projectcalico.org/v3.10/getting-started/kubernetes/installation/flannel
标签:networking,Networkpolicy,Kubernetes,--,podSelector,io,Pod,NetworkPolicy 来源: https://blog.csdn.net/weixin_41989934/article/details/122838726