Kubernetes的网络策略
Network Policy的主要功能是对Pod或者Namespace之间的网络通讯进行限制和准入控制,设置方式为将目标对象的Label
作为查询条件,设置允许访问或禁止访问的客户端Pod列表。目前查询条件可以作用于Pod和Namespace级别。
网络策略设置说明
网络策略的设置主要用于对目标Pod的网络访问进行控制,在默认情况下对所有Pod都是允许访问的,在设置了指向Pod的NetworkPolicy网络策略后,到Pod的访问才会被限制。
下面通过一个例子对NetworkPolicy资源对象的使用进行说明:
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
对主要参数说明如下:
- podSelector:定义该网络策略作用的Pod范围,本例的选择条件为包含
role=db
标签的Pod。 - policyTypes:网络策略的类型,包括ingress和egress两种,用于设置目标Pod的入站和出站的网络限制。如果未指定policyTypes,则系统默认会设置Ingress类型;若设置了egress策略,则系统自动设置Egress类型。
- ingress:定义允许访问目标Pod的入站白名单规则,满足
from
条件的客户端才能访问ports定义的目标Pod端口号。- from:对符合条件的客户端Pod进行网络放行,规则包括基于客户端Pod的Label、基于客户端Pod所在命名空间的Label或者客户端的IP范围。
- ports:允许访问的目标Pod监听的端口号。
- egress:定义目标Pod允许访问的“出站”白名单规则,目标Pod仅允许访问满足
to
条件的服务端IP范围和ports定义的端口号。- to:允许访问的服务端信息,可以基于服务端Pod的Label、基于服务端Pod所在命名空间的Label或者服务端IP范围。
- ports:允许访问的服务端的端口号。
通过本例所示的NetworkPolicy设置,对不同命名空间中的目标Pod进行了网络访问,发现该网络策略作用于命名空间default中包含role=db标签的全部Pod。
Ingress规则包括:
- 允许与目标Pod在同一个命名空间中的包含
role=frontend
标签的客户端Pod访问目标Pod; - 允许属于包含
project=myproject
标签的命名空间的客户端Pod访问目标Pod; - 允许属于IP地址范围172.17.0.0/16的客户端Pod访问目标Pod,但不包括属于IP地址范围172.17.1.0/24的客户端应用。
Egress规则包括:
- 允许目标Pod去访问属于IP地址范围10.0.0.0/24并监听5978端口的服务。
Selector功能说明
在form或to配置中,namespaceSelector和PodSelector可以单独设置,也可以组合设置。ingress的from段落和egress的to段落总共可以有4种选择器(Selector)的设置方式。
- podSelector:同一个命名空间选中的目标Pod应作为ingress来源或egress目标允许网络访问。
- namespaceSelector:目标命名空间中的全部Pod应作为ingress来源或egress目标允许网络访问。
- podSelector和namespaceSelector:在from或to配置中如果既设置了namespaceSelector又设置了podSelector,则表示选中指定命名空间的Pod。这在YAML定义中需要进行准确设置。
- ipBlock:其设置的IP地址范围应作为ingress来源或egress目标允许网络访问,通常应设置为集群外部的IP地址。
通过两个例子对Selector的作用进行说明。
例1,在from中同时设置namespaceSelector和podSelector,该策略允许从拥有user=alice标签的命名空间中,且拥有role=client标签的Pod发起访问:
......
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
podSelector:
matchLabels:
role: client
.....
例2,在from中分别设置namespaceSelector和podSelector,该策略即允许从有user=alice标签的命名空间中任意Pod发起访问,也允许从当前命名空间中有role=client标签的Pod发起访问:
......
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
- podSelector:
matchLabels:
role: client
.....
为命名空间配置默认的网络策略
在一个命名空间没有配置任何网络策略的情况下,对其中的Pod的ingress和egress网络流量并不会有任何限制。在命名空间级别可以设置一些默认的全局网络策略,以便管理员对整个命名空间进行统一的网络策略设置。
以下是一些常用的命名空间级别的默认网络策略。
- 默认禁止ingress访问。该策略禁止任意客户端访问该命名空间中的任意Pod,起到隔离访问的作用:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- 默认允许ingress访问。该策略允许任意客户端访问该命名空间中的任意Pod:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
ingress:
- {}
policyTypes:
- Ingress
- 默认禁止egress访问。该策略禁止该命名空间中的所有Pod访问任意外部服务:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Egress
- 默认允许egress访问。该策略允许该命名空间中的所有Pod访问任意外部服务:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress
- 默认同时禁止ingress和egress访问。该策略禁止任意客户端访问该命名空间中的任意Pod,同时禁止该命名空间的所有Pod访问任意外部服务:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
网络策略应用示例
下面以一个提供服务的Nginx Pod为例,为两个客户端Pod设置不同的网络访问权限:允许拥有role=nginxclient标签的Pod访问Nginx容器,没有这个标签的客户端容器会被禁止访问。
- 创建一个名为
nginx.yaml
的目标Pod,设置app=nginx
标签:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
创建Pod:
[root@master1 ~]# kubectl create -f nginx.yaml
pod/nginx created
- 创建一个名为
networkpolicy-allow-nginxclient.yaml
为目标Nginx Pod设置网络策略,创建NetworkPolicy的YAML文件,内容如下:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: allow-nginxclient
spec:
podSelector:
matchLabels:
app: nginx
ingress:
- from:
- podSelector:
matchLabels:
role: nginxclient
ports:
- protocol: TCP
port: 80
该网络策略的作用目标Pod应包含app=nginx标签,通过from设置允许客户端包含role=nginxclient
标签的Pod访问,并设置允许客户端访问的端口号为80。
创建该NetworkPolicy资源对象,并查看信息:
[root@master1 ~]# kubectl create -f networkpolicy-allow-nginxclient.yaml
networkpolicy.networking.k8s.io/allow-nginxclient created
[root@master1 ~]# kubectl describe networkpolicies allow-nginxclient
Name: allow-nginxclient
Namespace: default
Created on: 2022-06-24 17:54:36 +0800 CST
Labels: <none>
Annotations: <none>
Spec:
PodSelector: app=nginx
Allowing ingress traffic:
To Port: 80/TCP
From:
PodSelector: role=nginxclient
Not affecting egress traffic
Policy Types: Ingress
- 创建两个客户端Pod,一个包含role=nginxclient标签,另一个无此标签。分别进入Pod,访问Nginx容器,验证网络策略的效果:
client1.yaml
文件内容如下:
apiVersion: v1
kind: Pod
metadata:
name: client1
labels:
role: nginxclient
spec:
containers:
- name: client1
image: busybox
command: ["sleep", "3600"]
client2.yaml
文件内容如下:
apiVersion: v1
kind: Pod
metadata:
name: client2
spec:
containers:
- name: client2
image: busybox
command: ["sleep", "3600"]
创建两个Pod,并查看所有Pod信息:
[root@master1 ~]# kubectl create -f client1.yaml -f client2.yaml
pod/client1 created
pod/client2 created
[root@master1 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
client1 1/1 Running 0 11s 10.0.166.144 node1 <none> <none>
client2 1/1 Running 0 11s 10.0.104.25 node2 <none> <none>
nginx 1/1 Running 0 9m5s 10.0.104.28 node2 <none> <none>
看到刚刚创建nginx的IP是10.0.104.28,用client1尝试连接Nginx容器的80端口:
[root@master1 ~]# kubectl exec -it client1 -- wget 10.0.104.28
Connecting to 10.0.104.28 (10.0.104.28:80)
saving to 'index.html'
index.html 100% |********************************| 615 0:00:00 ETA
'index.html' saved
成功访问到Nginx服务器,说明NetworkPolicy生效。
用client2尝试连接Nginx容器的80端口:
[root@master1 ~]# kubectl exec -it client2 -- wget --timeout=5 10.0.104.28
Connecting to 10.0.104.28 (10.0.104.28:80)
wget: download timed out
command terminated with exit code 1
访问超时,说明NetworkPolicy生效,对没有role=nginxclient
标签的客户端Pod拒绝访问。
原文:《Kubernetes权威指南(第5版)》