k8s中的网络策略主要分为原生 NetworkPolicy 和第三方网络插件提供的网络策略。本文将主要分析原生Networkpolicy的网络策略。git
什么是网络策略github
网络策略(NetworkPolicy)是一种关于 Pod 间及 Pod 与其余网络端点间所容许的通讯规则的规范。NetworkPolicy 资源使用标签选择 Pod,并定义选定 Pod 所容许的通讯规则。web
k8s中的网络策略由实现了CNI接口的网络插件提供,网络插件监听集群中 NetworkPolicy 资源的建立/删除/更新事件生成对应的规则来控制 Pod 的流量是否放行。api
常见的支持 NetworkPolicy 的网络插件有:数组
默认状况下 Pod 间及 Pod 与其余网络端点间的访问是没有限制的。网络
以下是一个 NetworkPolicy 定义的例子,该策略的含义是阻止全部流量访问有app=web
这个 label 的 Pod。app
常常有人会问网络策略要怎么写,或者是这个网络策略表明了什么含义。笔者认为这个问题主要是由于使用者不了解网络策略的省缺行为。frontend
NetworkPolicy 字段含义spa
NetworkPolicy 这个资源属于命名空间级别的,所以metadata 中的 namespace 不可省略,不然只会对default 命名空间下的知足条件的 Pod 生效。插件
下面介绍下 NetworkPolicy 中各字段的含义,并说明各字段省缺值及其含义,主要看 Spec 中的字段,
podSelector: 必填字段,Pod 的标签选择器,表示该网络策略做用于哪些 Pod。若是为空{}
则表示选中本命名空间下全部 Pod。
policyTypes: 可选字段,字符串,策略规则类型, 表示该网络策略中包含哪些类型的策略,可选为"Ingress", "Egress", 或 "Ingress,Egress"。未填时,这个值依据下面的 ingress 和 egress 来定。若是该字段未设置且下面只出现了 ingress,则对 egress 不作限制。若是填了这个值,同时后续没有设定对应的规则,则认为设定的规则对应的流量所有禁止。例如:
该规则就限制了全部 Pod 的出流量。
ingress: 可选字段,数组,入站规则。互相间为或的关系,知足其中一条则放行。
ports: 可选字段,数组,放行端口信息。互相间为或的关系,若是为空表示端口不受约束,若是非空,则表示除了出现的端口放行,其余未指定的端口都禁止。
-port: 可选字段,数字,协议端口号。若是不写,表示协议全部端口。 -protocol: 可选字段,字符串,协议。容许取值为 TCP,UDP,SCTP。省缺为 TCP。
from: 可选字段,数组,放行源地址信息。互相间为或的关系,若是为空表示不约束源地址,若是非空,则表示除了出现的源地址放行外,其余源地址都禁止。
-ipBlock: 可选字段,放行 ip 段。 cidr: 标准 cidr,除了指定的cidr放行外其余都禁止。 except: 标准 cidr 字符串数组,表示前面cidr 中的放行的 cidr 段须要再排除掉 except 中指定的。 -namespaceSelector: 可选字段,namespace 的标签选择器,表示放行集群中的哪些命名空间中过来的流量。若是为空`{}`或未出现则表示选中全部命名空间。 -podSelector: 可选字段,Pod 的标签选择器,表示放行哪些 Pod 过来的流量,默认状况下从NetworkPolicy 同命名空间下的 Pod 中作筛选,若是前面设定了`namespaceSelector`则从符合条件的命名空间中的 Pod 中作筛选。若是为空`{}`则表示选中知足`namespaceSelector` 条件的全部 Pod。
egress: 可选字段,数组,出站规则。互相间为或的关系,知足其中一条就放行。
ports: 可选字段,数组,放行端口信息。互相间为或的关系,若是为空表示端口不受约束,若是非空,则表示除了出现的端口放行,其余未指定的端口都禁止。(详细字段同 ingress 中的 ports)
to: 可选字段,数组,放行目的地址信息。互相间为或的关系,若是为空表示不约束目的,若是非空,则表示除了出现的目的地址放行外,其余目的地址都禁止。(详细字段同ingress 中的 from)
介绍完 Spec 中各字段的含义及其默认行为后,作个简单的小结,NetworkPolicy 定义了放行规则,规则间是或的关系,只要命中其中一条规则就认为流量能够放行。
下面以一个kubernetes官网中的例子来回顾下前面的知识。
首先该规则指定了命名空间为 default, 选择了其中全部包含 role=db
这个 label 的 Pod,定义了入站流量规则与出站流量规则。
对于入站流量,放行源地址来自 cidr 172.17.0.0/16 除了 172.17.1.0/24 以外的流量,放行来自有project=myproject
这个label的namespace中的流量,放行 default 命名空间下有 label role=frontend
的 Pod 的流量,并限定这些流量只能访问到 role=db
这个 label 的 Pod 的 TCP 6379端口。
对于出站流量,只放行其访问目的地址属于 cidr 10.0.0.0/24 中,且端口为 TCP 5978的流量。
须要注意的是 NetworkPolicy 选中的 Pod 只能是与 NetworkPolicy 同处一个 namespace 中的 Pod,所以对于有些规则可能须要在多个命名空间中分别设置。或者使用非原生的网络策略定义,例如 Calico 中的 GlobalNetworkPolicy。
NetworkPolicy 变动历史
v1.6 以及之前的版本须要在 kube-apiserver 中开启 extensions/v1beta1/networkpolicies;
v1.7 版本 Network Policy 已经 GA,API 版本为 networking.k8s.io/v1;
v1.8 版本新增 Egress 和 IPBlock 的支持;
附录