系列目录html
Kubernetes要求集群中全部pod,不管是节点内仍是跨节点,均可以直接通讯,或者说全部pod工做在同一跨节点网络,此网络通常是二层虚拟网络,称为pod网络。在安装引导kubernetes时,由选择并安装的network plugin实现。默认状况下,集群中全部pod之间、pod与节点之间能够互通。nginx
网络主要解决两个问题,一个是连通性,实体之间可以经过网络互通。另外一个是隔离性,出于安全、限制网络流量的目的,又要控制实体之间的连通性。Network Policy用来实现隔离性,只有匹配规则的流量才能进入pod,同理只有匹配规则的流量才能够离开pod。api
但请注意,kubernetes支持的用以实现pod网络的network plugin有不少种,并非所有都支持Network Policy,为kubernetes选择network plugin时须要考虑到这点,是否须要隔离?可用network plugin及是否支持Network Policy请参考这里。数组
Network Policy是kubernetes中的一种资源类型,它从属于某个namespace。其内容从逻辑上看包含两个关键部分,一是pod选择器,基于标签选择相同namespace下的pod,将其中定义的规则做用于选中的pod。另外一个就是规则了,就是网络流量进出pod的规则,其采用的是白名单模式,符合规则的经过,不符合规则的拒绝。安全
首先给出示例Spec,结合示例说明Spec中的关键字段与逻辑,关于Spec彻底说明参考这里。示例以下:bash
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
对象建立方法与其它如ReplicaSet相同。apiVersion、kind、metadata与其它类型对象含义相同,不详细描述。网络
顾名思义,它是pod选择器,基于标签选择与Network Policy处于同一namespace下的pod,若是pod被选中,则对其应用Network Policy中定义的规则。此为可选字段,当没有此字段时,表示选中全部pod。frontend
Network Policy定义的规则能够分红两种,一种是入pod的Ingress规则,一种是出pod的Egress规则。本字段能够看做是一个开关,若是其中包含Ingress,则Ingress部分定义的规则生效,若是是Egress则Egress部分定义的规则生效,若是都包含则所有生效。固然此字段也可选,若是没有指定的话,则默认Ingress生效,若是Egress部分有定义的话,Egress才生效。怎么理解这句话,下文会提到,没有明肯定义Ingress、Egress部分,它也是一种规则,默认规则而非没有规则。ide
前者定义入pod规则,后者定义出pod规则,详细参考这里,这里只讲一下重点。上例中ingress与egress都只包含一条规则,二者都是数组,能够包含多条规则。当包含多条时,条目之间的逻辑关系是“或”,只要匹配其中一条就能够。.spec.ingress[].from
也是数组,数组成员对访问pod的外部source进行描述,符合条件的source才能够访问pod,有多种方法,如示例中的ip地址块、名称空间、pod标签等,数组中的成员也是逻辑或的关系。spec.ingress[].from.prots表示容许经过的协议及端口号。测试
.spec.egress.to定义的是pod想要访问的外部destination,其它与ingress相同。
不定义规则并不是没有规则,此时默认规则生效,如下展现默认规则用法。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny spec: podSelector: {} policyTypes: - Ingress
上例中没有定义pod选择器,表示若是namespace下的某个pod没有被任何Network Policy对象选中,则应用此对象,若是被其它Network Policy先中则不该用此对象。
policyTypes的值为Ingress,表示本例启用Ingress规则。可是本例没有定义具体的Ingress,那就应用默认规则。默认规则禁止全部入pod流量,但例外状况是若是source就是pod运行的节点,则容许经过。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all spec: podSelector: {} ingress: - {}
一样没有定义pod选择器,意义与上例同。注意ingress的定义,这个是有规则的,只是规则中的条目为空,与默认规则不一样,表示所有容许经过。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny spec: podSelector: {} policyTypes: - Egress
与默认禁止全部入pod流量(Default deny all ingress traffic)同,只是流量由入变成出
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all spec: podSelector: {} egress: - {} policyTypes: - Egress
与默认容许全部入pod流量(Default allow all ingress traffic)同,只是流量由入变成出。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny spec: podSelector: {} policyTypes: - Ingress - Egress
无需详解,但请注意,pod与所运行节点之间流量不受Network Policy限制。
下面经过一个真实示例展现Network Policy普通用法
$ kubectl run nginx --image=nginx --replicas=2 deployment "nginx" created $ kubectl expose deployment nginx --port=80 service "nginx" exposed
$ kubectl get svc,pod NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE svc/kubernetes 10.100.0.1 <none> 443/TCP 46m svc/nginx 10.100.0.16 <none> 80/TCP 33s NAME READY STATUS RESTARTS AGE po/nginx-701339712-e0qfq 1/1 Running 0 35s po/nginx-701339712-o00ef 1/1 Running 0 35s
$ kubectl run busybox --rm -ti --image=busybox /bin/sh Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending, pod ready: false Hit enter for command prompt / # wget --spider --timeout=1 nginx Connecting to nginx (10.100.0.16:80) / #
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: access-nginx spec: podSelector: matchLabels: run: nginx ingress: - from: - podSelector: matchLabels: access: "true"
只容许包含access: "true"标签的pod访问nginx服务。
$ kubectl create -f nginx-policy.yaml networkpolicy "access-nginx" created
$ kubectl run busybox --rm -ti --image=busybox /bin/sh Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending, pod ready: false Hit enter for command prompt / # wget --spider --timeout=1 nginx Connecting to nginx (10.100.0.16:80) wget: download timed out / #
$ kubectl run busybox --rm -ti --labels="access=true" --image=busybox /bin/sh Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending, pod ready: false Hit enter for command prompt / # wget --spider --timeout=1 nginx Connecting to nginx (10.100.0.16:80) / #