从CNCF基金会的成立,到Kubernetes社区蓬勃发展,历经6载,17年异军突起,在mesos、swarm等项目角逐中,拔得头筹,继而一统容器编排,其成功的关键缘由可归纳为如下几点:nginx
今天zouyee为你们带来《一文搞懂Kubernetes网络策略(上)》,其中《kuberneter调度由浅入深:框架》正在编写中,敬请期待,当前涉及版本均为1.20.+
。git
随着微服务架构的日渐盛行,Serverless框架的逐步落地,应用上云后带来了模块间网络调用需求的大规模增加,Kubernetes 自 1.3 引入了 Network Policy,其提供以应用为中心, 基于策略的网络控制,用于隔离应用以减小攻击面。github
Pod之间可否通讯可经过以下三种组合进行确认:api
在定义基于 Pod 或namespace的 NetworkPolicy 时,能够使用标签选择器
来设定哪些流量能够进入或离开 Pod。同时,当建立基于 IP 的 NetworkPolicy 时,能够基于 IP CIDR 来定义策略。markdown
如下结构体示意图辅助理解,后面章节有具体说明:网络
Kubernetes 版本 | Networking API 版本 | 说明 |
---|---|---|
v1.5-v1.6 | extensions/v1beta1 | 须要在kube-apiserver开启 extensions/v1beta1/networkpolicies |
v1.7 | networking.k8s.io/v1 | |
v1.8 | networking.k8s.io/v1 | 新增 Egress 和 IPBlock 的支持 |
默认状况下,Pod 是非隔离的,它们接受任何流量。架构
Pod 在被某 NetworkPolicy 选中时进入隔离状态。 一旦名字空间中有 NetworkPolicy 选择了特定的 Pod,该 Pod 会拒绝该 NetworkPolicy 所不容许的链接。 (名字空间下其余未被 NetworkPolicy 所选择的 Pod 会继续接受全部的流量)app
网络策略不会冲突。 若是任何一个或多个策略选择了一个 Pod, 则该 Pod 受限于这些策略的 入站(Ingress)/出站(Egress)规则的并集。框架
⚠️在使用 Network Policy 时,网络插件须要支持 Network Policy,如 Calico、Romana、Weave Net 和 Trireme 等,其中Engress为 出口流量,Ingress为 入口流量。less
staging/src/k8s.io/api/networking/v1/types.go
下面是 NetworkPolicy 的一个示例,如需完整说明,可参看结构定义文档:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-policy-sample
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
复制代码
必需字段:与全部其余的 Kubernetes 对象同样,NetworkPolicy 须要 apiVersion
、 kind
和 metadata
字段。
spec:NetworkPolicy 规约中包含了在名字空间中定义特定网络策略所需的全部信息。
podSelector:每一个 NetworkPolicy 都包括一个 podSelector
,它选择适用该该策略的 Pod。示例中的策略选择带有 "role=db" 标签的 Pod。 若podSelector
为空的,则选择名字空间下全部 Pod。
policyTypes: 每一个 NetworkPolicy 都包含一个 policyTypes
列表,其中包含 Ingress
或 Egress
或(二者亦可)。policyTypes
字段表示给定的策略是应用于 所选 Pod 的入口流量仍是来出口流量(二者亦可)。 若是 NetworkPolicy 未指定 policyTypes
则默认状况下始终设置 Ingress
; 若是 NetworkPolicy 有任何出口规则的话则设置 Egress
。
ingress: 每一个 NetworkPolicy 可包含一个 ingress
规则的白名单列表。 每一个规则都容许同时匹配 from
和 ports
部分的流量。示例策略中包含一条 简单的规则: 它匹配某个特定端口,第一个经过 ipBlock
指定,第二个经过 namespaceSelector
指定,第三个经过 podSelector
指定。
egress: 每一个 NetworkPolicy 可包含一个 egress
规则的白名单列表。 每一个规则都容许匹配 to
和 port
部分的流量。该示例策略包含一条规则, 该规则指定端口上的流量匹配到 10.0.0.0/24
中的任何目的地。
该网络策略总结以下:
default
名字空间下 role=db
的 Pod 。default
名字空间下标签为 role=db
的全部 Pod 的 6379 TCP 端口:
default
名字空间下带有 role=frontend
标签的全部 Podproject=myproject
标签的全部名字空间中的 Pod 172.17.0.0–172.17.0.255
和 172.17.2.0–172.17.255.255
(即除了 172.17.1.0/24 以外的全部 172.17.0.0/16)role=db
标签的名字空间下的任何 Pod 到 CIDR 10.0.0.0/24 下 5978 TCP 端口。以 calico 为例看一下 Network Policy 的具体用法。
kubelet --network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin ...
# 注意修改 CIDR,须要跟 k8s pod-network-cidr 一致,默认为 192.168.0.0/16
# 当前选择的是小于50节点的安装方式,具体安装可查看
# https://docs.projectcalico.org/getting-started/kubernetes/self-managed-onprem/onpremises
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
复制代码
部署 nginx 服务
$ kubectl create deployment nginx --image=nginx
deployment "nginx" created
$ kubectl expose deployment nginx --port=80
service "nginx" exposed
复制代码
测试网络
$ kubectl get svc,pod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 186d
service/nginx ClusterIP 10.233.27.142 <none> 80/TCP 2s
NAME READY STATUS RESTARTS AGE
pod/nginx-f89759699-kfmbj 1/1 Running 0 62s
$ kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget --spider --timeout=1 nginx
Connecting to nginx (10.233.27.142:80)
remote file exists
/ #
复制代码
4)测试网络策略
若是只让那些拥有标签 access: true
的 Pod 访问 nginx
服务, 那么能够建立一个以下所示的 NetworkPolicy 对象:
$ cat nginx-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: access-nginx
spec:
podSelector:
matchLabels:
app: nginx
ingress:
- from:
- podSelector:
matchLabels:
access: "true"
$ kubectl create -f nginx-policy.yaml
networkpolicy "access-nginx" created
# 不带 access=true 标签的 Pod 仍是没法访问 nginx 服务
$ kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget --spider --timeout=1 nginx
Connecting to nginx (10.233.27.142:80)
wget: download timed out
/ #
# 而带有 access=true 标签的 Pod 能够访问 nginx 服务
$ kubectl run busybox --rm -ti --labels="access=true" --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget --spider --timeout=1 nginx
Connecting to nginx (10.233.27.142:80)
/ #
复制代码
后续相关内容,请查看公众号:DCOS