openshift networkpolicy

目標(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í)匹配 fromports 部分的流量

egress:: 每個(gè) NetworkPolicy 可包含一個(gè) egress 規(guī)則的白名單列表。 每個(gè)規(guī)則都允許匹配 toport 部分的流量

選擇器 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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容