Kubernetes网络策略
概念
网络策略
在kubernetes集群中可以使用网络策略(NetworkPolicy)对Pod的IP或端口进行网络流量控制,NetworkPolicy是一种以应用为中心的结构,允许Pod与网络上的各类实体通信,NetworkPolicies适用于一端或者两端与Pod的连接,与其他连接无关
Pod是通过如下三个标识符的组合来辨识的:
- 被允许的Pods
- 被允许的名称空间
- IP组
隔离类型
Pod有两种隔离:
- 出口隔离
- 入口隔离
默认情况下,一个Pod的出口是非隔离的,所有向外的连接都是被允许的。如果有网络策略
选择改Pod并在其policyTypes
中包含了Egress
,则改Pod的出口是隔离的;这样的策略适用于该Pod的出口,当Pod的出口被隔离时,则Pod的连接必须符合NetworkPolicy
中的egress
的策略,egress
列表中的策略效果是相加的
Ingress同理,Pod的入口是非隔离的,所有向内的连接都是被允许的。如果有网络策略
选择改Pod并在其policyTypes
中包含了Ingress
,则改Pod的入口是隔离的;这样的策略适用于该Pod的入口,当Pod的入口被隔离时,则Pod的连接必须符合NetworkPolicy
中的Ingress
的策略,Ingress
列表中的策略效果是相加的
选择器
两种行为:
- from(源):从哪来
- to(目的):到哪去
四种选择器:
PodSelector
此选择器在Network的名称空间中选择特定的Pod,将其作为流量的入站目的地或出站来源
namespaceSelector
此选择器将选择特定的名称空间,将所有的Pod的流量作为入站目的地或出站来源
namespaceSelector和podselector
此选择器将特定名称空间下特定的Pod作为流量作为入站目的地或出站来源
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24# 这种写法from列表包含一个元素,只允许来自标有role=client的Pod且该Pod所在的名称空间标有user=alice的连接
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
podSelector:
matchLabels:
role: client
...
#######################################################################
# 这种写法from列表包含两个元素,允许来自标有role=client的Pod的连接,或来自名称空间标有user=alice
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
- podSelector:
matchLabels:
role: client
...ipBlock
此选择器将选择特定的IP CIDR范围以作为入站流量来源或出站流量的目的地
例子
1 | apiVersion: networking.k8s.io/v1 |
实验
实验环境
1 | [root@master networkpolicy]# kubectl get pod -o wide |
禁止访问Default
测试默认情况下是否能访问
下面实验结论在没有策略的情况下不同名称空间的Pod网络是互通的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34[root@master networkpolicy]# kubectl exec -it app01 -n app02 -- sh
/ # ping 172.11.196.133
PING 172.11.196.133 (172.11.196.133): 56 data bytes
64 bytes from 172.11.196.133: seq=0 ttl=63 time=0.102 ms
64 bytes from 172.11.196.133: seq=1 ttl=63 time=0.095 ms
^C
--- 172.11.196.133 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.095/0.098/0.102 ms
/ # ping 172.11.196.134
PING 172.11.196.134 (172.11.196.134): 56 data bytes
64 bytes from 172.11.196.134: seq=0 ttl=63 time=0.108 ms
64 bytes from 172.11.196.134: seq=1 ttl=63 time=0.092 ms
^C
--- 172.11.196.134 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.092/0.100/0.108 ms
==================================================================================================
[root@master networkpolicy]# kubectl exec -it app02 -n app03 -- sh
/ # ping 172.11.196.133
PING 172.11.196.133 (172.11.196.133): 56 data bytes
64 bytes from 172.11.196.133: seq=0 ttl=63 time=0.102 ms
^C
--- 172.11.196.133 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.102/0.102/0.102 ms
/ # ping 172.11.196.134
PING 172.11.196.134 (172.11.196.134): 56 data bytes
64 bytes from 172.11.196.134: seq=0 ttl=63 time=0.086 ms
^C
--- 172.11.196.134 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.086/0.086/0.086 ms创建网络策略
1
2
3
4
5
6
7
8
9
10
11
12[root@master networkpolicy]# vi network01.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-in
spec:
podSelector: {}
policyTypes:
- Ingress
[root@master networkpolicy]# kubectl apply -f network01.yaml
networkpolicy.networking.k8s.io/deny-all-in created测试
1
2
3
4
5
6
7
8
9
10
11
12
13[root@master networkpolicy]# kubectl exec -it app01 -n app02 -- sh
/ # ping 172.11.196.133
PING 172.11.196.133 (172.11.196.133): 56 data bytes
--- 172.11.196.133 ping statistics ---
33 packets transmitted, 0 packets received, 100% packet loss
无响应
/ # ping 172.11.196.134
PING 172.11.196.134 (172.11.196.134): 56 data bytes
--- 172.11.196.134 ping statistics ---
24 packets transmitted, 0 packets received, 100% packet loss
无响应注意:
只是禁止了所有流量进入default名称空间,不是真的所有的流量都无法进入,default名称空间下Pod的响应流量是可以回来的
禁止所有流量出站,同理将策略的Ingress改成Egress。同理,自己的请求流量无法出站,但是响应可以
同时拒绝进站出站流量,需要将两个一起加上即可
清除策略
1
2[root@master networkpolicy]# kubectl delete -f network01.yaml
networkpolicy.networking.k8s.io "deny-all-in" deleted
只允许app02空间访问app03名称空间的80端口
确保之前测试的网络策略删除了
查看namespace标签
1
2
3
4
5
6
7
8[root@master networkpolicy]# kubectl get ns --show-labels
NAME STATUS AGE LABELS
app02 Active 96m kubernetes.io/metadata.name=app02
app03 Active 96m kubernetes.io/metadata.name=app03
default Active 32d kubernetes.io/metadata.name=default
kube-node-lease Active 32d kubernetes.io/metadata.name=kube-node-lease
kube-public Active 32d kubernetes.io/metadata.name=kube-public
kube-system Active 32d kubernetes.io/metadata.name=kube-system创建网络策略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28[root@master networkpolicy]# kubectl get ns --show-labels
NAME STATUS AGE LABELS
app02 Active 96m kubernetes.io/metadata.name=app02
app03 Active 96m kubernetes.io/metadata.name=app03
default Active 32d kubernetes.io/metadata.name=default
kube-node-lease Active 32d kubernetes.io/metadata.name=kube-node-lease
kube-public Active 32d kubernetes.io/metadata.name=kube-public
kube-system Active 32d kubernetes.io/metadata.name=kube-system
[root@master networkpolicy]# vi network02.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-app02-in
namespace: app03
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: app02
ports:
- protocol: TCP
port: 80
[root@master networkpolicy]# kubectl apply -f network02.yaml
networkpolicy.networking.k8s.io/allow-app02-in created测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66### app02名称空间的Pod可以访问app03名称空间的Pod
[root@master networkpolicy]# kubectl exec -it app01 -n app02 -- sh
/ # curl 172.11.140.73
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
/ # curl 172.11.196.137
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
/ #
### default名称空间的Pod不可以访问app03名称空间的Pod
[root@master networkpolicy]# kubectl exec -it app01 -- sh
/ # curl 172.11.196.137
卡死(超时)
/ # ping 172.11.196.137
PING 172.11.196.137 (172.11.196.137): 56 data bytes
^C
--- 172.11.196.137 ping statistics ---
8 packets transmitted, 0 packets received, 100% packet loss
同样无法ping通