目標(biāo)
- OpenshiftSDN, networkpolicy 使用說(shuō)明
說(shuō)明: 以下示例基于OCP4.6 進(jìn)行驗(yàn)證
networkpolicy 說(shuō)明
- networkpolicy 是一種以應(yīng)用為中心的結(jié)構(gòu),允許你設(shè)置POD如何與各種網(wǎng)絡(luò)實(shí)體進(jìn)行通信的規(guī)則
- 默認(rèn)情況下,POD是非隔離的,他接受任何來(lái)源的流量
- POD在被某個(gè)Networkpolicy選中時(shí)進(jìn)入隔離狀態(tài),一旦有namespace下
參數(shù)說(shuō)明
下面是一個(gè)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: 選擇適用于該規(guī)則的pod
podSelector: 每個(gè)Networkpolicy 都包含一個(gè)policyTypes列表,其中包含 Ingress , Egress或者兩者兼具。如果policyTypes沒(méi)有配置,則默認(rèn)使用Ingress,
ingress: 每個(gè) NetworkPolicy 可包含一個(gè) ingress 規(guī)則的白名單列表。 每個(gè)規(guī)則都允許同時(shí)匹配 from 和 ports 部分的流量
egress:: 每個(gè) NetworkPolicy 可包含一個(gè) egress 規(guī)則的白名單列表。 每個(gè)規(guī)則都允許匹配 to 和 port 部分的流量
選擇器 to 和 from 的行為
可以在 ingress 的 from 部分或 egress 的 to 部分中指定四種選擇器
podSelector: 此選擇器將在與 NetworkPolicy 相同的名字空間中選擇特定的 Pod,應(yīng)將其允許作為入站流量來(lái)源或出站流量目的地。
namespaceSelector:此選擇器將選擇特定的名字空間,應(yīng)將所有 Pod 用作其 入站流量來(lái)源或出站流量目的地。
namespaceSelector 和 podSelector
ipBlock: 此選擇器將選擇特定的 IP CIDR 范圍以用作入站流量來(lái)源或出站流量目的地。 這些應(yīng)該是集群外部 IP,因?yàn)?Pod IP 存在時(shí)間短暫的且隨機(jī)產(chǎn)生
Demo
準(zhǔn)備工作,部署測(cè)試應(yīng)用
oc new-project project1
oc label namespace project1 name=project1
oc new-project project2
oc label namespace project2 name=project2
oc new-project project3
oc label namespace project3 name=project3
oc new-app -n project1 openshiftroadshow/parksmap --name=web-db
oc new-app -n project1 openshiftroadshow/parksmap --name=client
oc new-app -n project1 openshiftroadshow/parksmap --name=booksotre -l app=bookstore
oc new-app -n project2 openshiftroadshow/parksmap --name=client2
oc new-app -n project2 openshiftroadshow/parksmap --name=booksotre-ns2 -l app=bookstore
oc new-app -n project1 openshift/hello-openshift --name=web -l app=web
oc new-app -n project1 openshift/hello-openshift --name=web-db -l app=web-db
oc new-app -n project1 openshift/hello-openshift --name=redis -l app=redis
oc new-app -n project1 openshiftroadshow/parksmap --name=inventory -l app=inventory,role=web
oc new-app -n project3 openshiftroadshow/parksmap --name=client-ns3
oc new-app -n project3 openshiftroadshow/parksmap --name=inventory -l app=inventory role=web
測(cè)試方案
參考以下方式進(jìn)行測(cè)試
[root@clientvm 0 ~/work/network/policy]# oc get pod
NAME READY STATUS RESTARTS AGE
bookinfo-64f7654cf5-7ttrw 1/1 Running 0 16m
client-67b7dbd85b-5k85j 1/1 Running 0 31m
hello-c9b7d7b89-hpq4f 1/1 Running 0 31m
web-56b44b5b4d-sz2x6 1/1 Running 0 31m
web-db-6cd6bff489-m9kwk 1/1 Running 0 31m
[root@clientvm 130 ~/work/network/policy]# oc get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
bookinfo ClusterIP 172.30.86.141 <none> 8080/TCP,8888/TCP 16m
client ClusterIP 172.30.223.91 <none> 8080/TCP 32m
hello ClusterIP 172.30.206.159 <none> 8080/TCP,8888/TCP 32m
web ClusterIP 172.30.152.210 <none> 8080/TCP,8888/TCP 32m
web-db ClusterIP 172.30.217.121 <none> 8080/TCP,8888/TCP 32m
[root@clientvm 0 ~/work/network/policy]# oc rsh client-67b7dbd85b-5k85j
sh-4.2$ curl 172.30.86.141:8080
Hello OpenShift!
sh-4.2$
1. 拒絕所有請(qǐng)求
拒絕所有請(qǐng)求
# cat deny-all.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: deny-by-default
spec:
podSelector:
ingress: []
2. 允許某個(gè)應(yīng)用可以被訪問(wèn)
允許 app=bookinfo 的應(yīng)用可以被訪問(wèn)
# cat bookinfo-allow-all.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: bookinfo-allow-all
spec:
podSelector:
matchLabels:
app: bookinfo
ingress:
- {}
3. 禁止某個(gè)應(yīng)用被訪問(wèn)
禁止 app=web 應(yīng)用被訪問(wèn)
# cat web-deny-all.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-deny-all
spec:
podSelector:
matchLabels:
app: web
ingress: []
4. 限制某個(gè)應(yīng)用被訪問(wèn)
限制 web-db 只能被label為bookstore的應(yīng)用訪問(wèn)
# cat web-db-allow.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-db-allow
spec:
podSelector:
matchLabels:
app: web-db
ingress:
- from:
- podSelector:
matchLabels:
app: bookstore
5. 拒絕其他namespace的所有請(qǐng)求
允許同一個(gè)namespace內(nèi)的pod互相通信,拒絕其他namespace的pod請(qǐng)求
# cat allow-same-policy.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
namespace: project1
name: allow-same-namespace
spec:
podSelector:
ingress:
- from:
- podSelector: {}
這里有兩道思考題
Q1: 如果project1 同時(shí)配置了拒接所有請(qǐng)求和允許namespace內(nèi)所有pod互相通信,那么同一個(gè)集群內(nèi)的pod之間能否互相通信
Q2:如果project1 配置了拒絕所有外部namespace請(qǐng)求,然后配置了一個(gè)允許指定label 的pod 訪問(wèn)請(qǐng)求,此時(shí)project2 中的含有指定label的pod 能否訪問(wèn)該目標(biāo)pod
6. 允許 指定 namespace 的所有流量
允許project3 到project1 的所有流量
# cat web-allow-project3.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-allow-project3
namespace: project1
spec:
podSelector: {}
ingress:
- from:
- namespaceSelector:
matchLabels:
name: project3
7. 允許其他project 的指定pod訪問(wèn)指定的pod
其實(shí)以下內(nèi)容就是上邊Q2 的答案,可以在networkpolicy 中添加一個(gè)namespaceSelector 來(lái)指定允許哪些namespace訪問(wèn)pod
# cat web-db-allow-other-ns.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-db-allow-other-ns
namespace: project1
spec:
podSelector:
matchLabels:
app: web-db
ingress:
- from:
- namespaceSelector:
matchLabels:
name: project2
podSelector:
matchLabels:
app: bookstore
8. 允許ingress controller
允許通過(guò)router 進(jìn)行訪問(wèn)
# cat allow-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-openshift-ingress
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
network.openshift.io/policy-group: ingress
podSelector: {}
policyTypes:
- Ingress
openshift4 里邊,router 是部署在namespace openshift-ingress 中,從下面的信息可以發(fā)現(xiàn),openshift-ingress 中包含label, network.openshift.io/policy-group=ingress,因此可以通過(guò)此label設(shè)置流量可以通過(guò)router進(jìn)去
# oc describe namespace openshift-ingress
Name: openshift-ingress
Labels: name=openshift-ingress
network.openshift.io/policy-group=ingress
olm.operatorgroup.uid/71df423a-e1e6-4cec-9011-8f91a3e90d0e=
openshift.io/cluster-monitoring=true
Annotations: openshift.io/node-selector:
openshift.io/sa.scc.mcs: s0:c23,c12
openshift.io/sa.scc.supplemental-groups: 1000530000/10000
openshift.io/sa.scc.uid-range: 1000530000/10000
Status: Active
9. 限定只能訪問(wèn)指定端口
限定只能訪問(wèn)8888 端口,此時(shí)無(wú)法訪問(wèn)8080端口
說(shuō)明:本文使用的openshift/hello-openshift, 鏡像本身對(duì)外暴露了8080和8888端口,兩個(gè)端口都能訪問(wèn),且輸出一致,可以使用該鏡像驗(yàn)證此特性
# cat allow-port-only.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: allow-port-only
namespace: project1
spec:
podSelector:
matchLabels:
app: web-db
ingress:
- ports:
- port: 8888
from: []
10. 多個(gè)podselector
數(shù)據(jù)庫(kù)或者redis這樣的公共資源可能需要為其創(chuàng)建一個(gè)白名單,只有白名單上的應(yīng)用可以對(duì)其進(jìn)行訪問(wèn),基于前文中的例子,通過(guò)測(cè)試可以發(fā)現(xiàn),只有bookstore 和 inventory 可以訪問(wèn)redis
# cat redis-allow-services.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: redis-allow-services
namespace: project1
spec:
podSelector:
matchLabels:
app: redis
ingress:
- from:
- podSelector:
matchLabels:
app: bookstore
- podSelector:
matchLabels:
app: inventory
role: web
注意:此時(shí)需要清理networkpolicy 規(guī)則,在這個(gè)例子中,需要使用以下規(guī)則,其他規(guī)則可以需要清理下
# oc get networkpolicy
NAME POD-SELECTOR AGE
deny-by-default <none> 114m
redis-allow-services app=redis 19m
11. openshift 不支持 包含 except的 IPBlock
openshiftSDN 不支持包含except的IPBlock,因此如果配置類似以下的規(guī)則,會(huì)在SDNpod中出現(xiàn)warning日志,同時(shí)整條規(guī)則也會(huì)被忽略掉
# cat ipblock-except.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: ipblock-access
namespace: project1
spec:
podSelector:
matchLabels:
role: redis
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 10.131.0.0/23
except:
- 10.131.1.0/24
異常日志情況
# oc -n openshift-sdn logs -f sdn-d9hxt -c sdn
...
W0215 09:43:32.291167 1844 networkpolicy.go:542] IPBlocks with except rules are not supported (NetworkPolicy [ipblock-access], Namespace [project1])
W0215 09:43:45.231881 1844 networkpolicy.go:542] IPBlocks with except rules are not supported (NetworkPolicy [ipblock-access], Namespace [project1])
W0215 09:44:15.232054 1844 networkpolicy.go:542] IPBlocks with except rules are not supported (NetworkPolicy [ipblock-access], Namespace [project1])
W0215 09:44:45.232161 1844 networkpolicy.go:542] IPBlocks with except rules are not supported (NetworkPolicy [ipblock-access], Namespace [project1])
W0215 09:45:15.232221 1844 networkpolicy.go:542] IPBlocks with except rules are not supported (NetworkPolicy [ipblock-access], Namespace [project1])
Egress
refrence
https://access.redhat.com/documentation/zh-cn/openshift_container_platform/4.6/html-single/networking/index#nw-http2-haproxy_configuring-ingress
https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/
https://github.com/ahmetb/kubernetes-network-policy-recipes
https://blog.csdn.net/weixin_43902588/article/details/103536739