備戰CKA每日一題——第10天 | (網絡隔離)允許A訪問B,不允許C訪問B,怎麼做;k8s訪問控制RBAC、Role、RoleBinding以及serviceaccount引出

本活動在微信公衆號【我的小碗湯】上舉行,有送書活動!這裏參與答題不能參與到送書活動哦!

昨日考題

部署三個deployment應用(A,B,C),允許A訪問B應用,但是不允許C訪問B應用。

  • Deployment的名稱爲cka-1128-01,cka-1128-02,cka-1128-03
  • Network Policy的名稱爲cka-1128-np
    注意:將所用命令、創建的deployment以及network policy完整yaml、以及證明A可以訪問B應用;C不允許訪問B應用。可分多次評論。

昨日答案

第一個Deploy文件cka-1128-01.yaml,使用radial/busyboxplus鏡像是因爲busybox裏沒有curl命令。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cka-1128-01
spec:
  selector:
    matchLabels:
      app: cka-1128-01
  template:
    metadata:
      labels:
        app: cka-1128-01
    spec:
      containers:
        - name: cka-1128-01
          image: radial/busyboxplus
          command: ['sh', '-c', 'sleep 1000']
          imagePullPolicy: IfNotPresent

cka-1128-02.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cka-1128-02
spec:
  selector:
    matchLabels:
      app: cka-1128-02
  template:
    metadata:
      labels:
        app: cka-1128-02
    spec:
      containers:
        - name: cka-1128-02
          image: radial/busyboxplus
          command: ['sh', '-c', 'sleep 1000']
          imagePullPolicy: IfNotPresent

cka-1128-03.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cka-1128-03
spec:
  selector:
    matchLabels:
      app: cka-1128-03
  template:
    metadata:
      labels:
        app: cka-1128-03
    spec:
      containers:
        - name: cka-1128-03
          image: radial/busyboxplus
          command: ['sh', '-c', 'sleep 1000']
          imagePullPolicy: IfNotPresent

可以看到A、C都可以訪問B:

[root@liabio cka]# kubectl get pod -owide | grep cka
cka-1128-01-7b8b8cb79-mll6d        1/1     Running   0          3m5s   192.168.155.124   liabio   <none>           <none>
cka-1128-02-69dd65bdb7-mfq26       1/1     Running   0          3m8s   192.168.155.117   liabio   <none>           <none>
cka-1128-03-66f8f69ff-64q75        1/1     Running   0          3m3s   192.168.155.116   liabio   <none>           <none>
[root@liabio cka]# kubectl exec -ti cka-1128-01-7b8b8cb79-mll6d  -- ping 192.168.155.117
PING 192.168.155.117 (192.168.155.117): 56 data bytes
64 bytes from 192.168.155.117: seq=0 ttl=63 time=0.146 ms
64 bytes from 192.168.155.117: seq=1 ttl=63 time=0.095 ms
[root@liabio cka]# kubectl exec -ti cka-1128-03-66f8f69ff-64q75  -- ping 192.168.155.117
PING 192.168.155.117 (192.168.155.117): 56 data bytes
64 bytes from 192.168.155.117: seq=0 ttl=63 time=0.209 ms
64 bytes from 192.168.155.117: seq=1 ttl=63 time=0.112 ms

新建cka-1128-np.yaml,kubectl apply -f cka-1128-np.yaml創建Network Policy,spec.podSelector.matchLabels選擇B管理的Pod;ingress.from.podSelector.matchLabels指定只給來自A的流量開白名單。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: cka-1128-np
spec:
  podSelector:
    matchLabels:
      app: cka-1128-02
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: cka-1128-01

驗證發現A可以ping通B,C不能ping通B。

[root@liabio cka]# kubectl apply -f cka-1128-np.yaml 
networkpolicy.networking.k8s.io/cka-1128-np created
[root@liabio cka]# kubectl get networkpolicies.
NAME          POD-SELECTOR      AGE
cka-1128-np   app=cka-1128-02   13s
[root@liabio cka]# 
[root@liabio cka]# kubectl get pod -owide | grep cka
cka-1128-01-7b8b8cb79-mll6d        1/1     Running   1          24m    192.168.155.124   liabio   <none>           <none>
cka-1128-02-69dd65bdb7-mfq26       1/1     Running   1          24m    192.168.155.117   liabio   <none>           <none>
cka-1128-03-66f8f69ff-64q75        1/1     Running   1          24m    192.168.155.116   liabio   <none>           <none>
[root@liabio cka]# kubectl exec -ti cka-1128-01-7b8b8cb79-mll6d  -- ping 192.168.155.117
PING 192.168.155.117 (192.168.155.117): 56 data bytes
64 bytes from 192.168.155.117: seq=0 ttl=63 time=0.213 ms

[root@liabio cka]# kubectl exec -ti cka-1128-03-66f8f69ff-64q75  -- ping 192.168.155.117
PING 192.168.155.117 (192.168.155.117): 56 data bytes
......

昨日解析

本題的關鍵點就是考察k8s網絡策略NetworkPolicy,這塊知識點面試中也經常會被問到。以下摘抄自官方文檔:

概念

網絡策略(NetworkPolicy)是一種關於pod間及pod與其他網絡端點間所允許的通信規則的規範。
NetworkPolicy資源使用標籤選擇pod,並定義選定pod所允許的通信規則。網絡策略通過網絡插件來實現,所以用戶必須使用支持 NetworkPolicy 的網絡解決方案,

網絡策略概念與介紹官方文檔:
https://kubernetes.io/docs/concepts/services-networking/network-policies/#the-networkpolicy-resource

網絡策略實踐官方文檔,本題目完全可以參考該文檔完成。
https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy/

前提

網絡策略通過網絡插件來實現,所以用戶必須使用支持 NetworkPolicy 的網絡解決方案 - 簡單地創建資源對象,而沒有控制器來使它生效的話,是沒有任何作用的。

支持的網絡方案

Calico、 Kube-router、 Cilium、Romana、Weave Net

k8s官方文檔說明:
https://kubernetes.io/docs/tasks/administer-cluster/network-policy-provider/

隔離和非隔離的Pod

默認情況下,Pod是非隔離的,它們接受任何來源的流量。

Pod可以通過相關的網絡策略進行隔離。一旦命名空間中有NetworkPolicy選擇了特定的Pod,該Pod會拒絕網絡策略所不允許的連接。 (命名空間下其他未被網絡策略所選擇的Pod會繼續接收所有的流量)

NetworkPolicy 資源

下面是一個 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

除非選擇支持NetworkPolicy 的網絡解決方案,否則將上述示例發送到APIServer沒有任何效果。

spec: NetworkPolicy spec 中包含了在一個命名空間中定義特定網絡策略所需的所有信息

podSelector: 每個 NetworkPolicy 都包括一個 podSelector ,它對該策略所應用的一組Pod進行選擇。因爲 NetworkPolicy 目前只支持定義 ingress 規則,這裏的 podSelector 本質上是爲該策略定義 “目標pod” 。示例中的策略選擇帶有 “role=db” 標籤的pod。空的 podSelector 選擇命名空間下的所有pod。

policyTypes:每個NetworkPolicy都包含一個policyTypes列表,其中可能包含Ingress,Egress或兩者。 policyTypes字段指示給定的策略是否適用於到選定Pod的入站流量,來自選定Pod的出站流量,或兩者都適用。 如果在NetworkPolicy上未指定任何policyType,則默認情況下將始終設置Ingress,並且如果NetworkPolicy具有任何出口規則,則將設置Egress。

ingress: 每個 NetworkPolicy 包含一個 ingress 規則的白名單列表。(其中的)規則允許同時匹配 from 和 ports 部分的流量。示例策略中包含一條簡單的規則: 它匹配一個單一的port,來自兩個來源中的一個, 第一個通過 namespaceSelector 指定,第二個通過 podSelector 指定。

egress: 每個 NetworkPolicy 包含一個 egress 規則的白名單列表。每個規則都允許匹配 to 和 port 部分的流量。該示例策略包含一條規則,該規則將單個端口上的流量匹配到 10.0.0.0/24 中的任何目的地。

所以,示例網絡策略:

隔離 “default” 命名空間下 “role=db” 的pod (如果它們不是已經被隔離的話)。
允許從 “default” 命名空間下帶有 “role=frontend” 標籤的pod到 “default” 命名空間下的pod的6379 TCP端口的連接。

  • “default” 名稱空間中,帶有標籤爲 “role=frontend” 的任何Pod;
  • namespaces中帶有標籤“project=myproject” 的任何pod;
  • IP 地址範圍爲 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)

允許從帶有 “project=myproject” 標籤的命名空間下的任何 pod 到 “default” 命名空間下的 pod 的6379 TCP端口的連接。

選擇器 to 和 from 的行爲

可以在 ingress from 部分或 egress to 部分中指定四種選擇器:

podSelector: 這將在與 NetworkPolicy 相同的名稱空間中選擇特定的 Pod,應將其允許作爲入口源或出口目的地。

namespaceSelector: 這將選擇特定的名稱空間,應將所有 Pod 用作其輸入源或輸出目的地。

namespaceSelector 和 podSelector: 一個指定 namespaceSelector 和 podSelector 的 to/from 條目選擇特定命名空間中的特定 Pod。注意使用正確的YAML語法;這項策略:

...
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          user: alice
      podSelector:
        matchLabels:
          role: client
  ...

在 from 數組中僅包含一個元素,只允許來自標有 role = client 的 Pod 且該 Pod 所在的名稱空間中標有user=alice的連接。這項策略:

  ...
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          user: alice
    - podSelector:
        matchLabels:
          role: client
  ...

在 from 數組中包含兩個元素,允許來自本地命名空間中標有 role = client 的 Pod 的連接,來自任何名稱空間中標有user = alice的任何Pod的連接。

ipBlock: 這將選擇特定的 IP CIDR 範圍以用作入口源或出口目的地。 這些應該是集羣外部 IP,因爲 Pod IP 存在時間短暫的且隨機產生。

集羣的入口和出口機制通常需要重寫數據包的源 IP 或目標 IP。在發生這種情況的情況下,不確定在 NetworkPolicy 處理之前還是之後發生,並且對於網絡插件,雲提供商,Service 實現等的不同組合,其行爲可能會有所不同。

在進入的情況下,這意味着在某些情況下,您可以根據實際的原始源 IP 過濾傳入的數據包,而在其他情況下,NetworkPolicy 所作用的 源IP 則可能是 LoadBalancer 或 Pod的節點等。

對於出口,這意味着從 Pod 到被重寫爲集羣外部 IP 的 Service IP 的連接可能會或可能不會受到基於 ipBlock 的策略的約束。

默認策略

默認情況下,如果名稱空間中不存在任何策略,則所有進出該名稱空間中的Pod的流量都被允許。以下示例使您可以更改該名稱空間中的默認行爲。

默認拒絕所有入口流量

您可以通過創建選擇所有容器但不允許任何進入這些容器的入口流量的 NetworkPolicy 來爲名稱空間創建 “default” 隔離策略。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Ingress

這樣可以確保即使容器沒有選擇其他任何 NetworkPolicy,也仍然可以被隔離。此策略不會更改默認的出口隔離行爲。

默認允許所有入口流量

如果要允許所有流量進入某個命名空間中的所有 Pod(即使添加了導致某些 Pod 被視爲“隔離”的策略),則可以創建一個策略來明確允許該命名空間中的所有流量。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
spec:
  podSelector: {}
  ingress:
  - {}
  policyTypes:
  - Ingress

默認拒絕所有出口流量

您可以通過創建選擇所有容器但不允許來自這些容器的任何出口流量的 NetworkPolicy 來爲名稱空間創建 “default” egress 隔離策略。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Egress

這樣可以確保即使沒有被其他任何 NetworkPolicy 選擇的 Pod 也不會被允許流出流量。此策略不會更改默認的 ingress 隔離行爲。

默認允許所有出口流量

如果要允許來自命名空間中所有 Pod 的所有流量(即使添加了導致某些 Pod 被視爲“隔離”的策略),則可以創建一個策略,該策略明確允許該命名空間中的所有出口流量。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
spec:
  podSelector: {}
  egress:
  - {}
  policyTypes:
  - Egress

默認拒絕所有入口和所有出口流量

您可以爲名稱空間創建 “default” 策略,以通過在該名稱空間中創建以下 NetworkPolicy 來阻止所有入站和出站流量。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

這樣可以確保即使沒有被其他任何 NetworkPolicy 選擇的 Pod 也不會被允許進入或流出流量。

今日考題

創建一個Role(只有cka namespace下pods的所有操作權限)和RoleBinding(使用serviceaccount認證鑑權),使用對應serviceaccount作爲認證信息對cka namespace下的pod進行操作以及對default namespace下的pods進行操作。
– Role和RoleBinding的名稱的名稱爲cka-1202-role、cka-1202-rb
注意:請附所用命令、創建的Role、RoleBinding以及serviceaccount的完整yaml,可分多次評論。

作者簡介

作者:小碗湯,一位熱愛、認真寫作的小夥,目前維護原創公衆號:『我的小碗湯』,專注於寫linux、golang、docker、kubernetes等知識等提升硬實力的文章,期待你的關注。轉載說明:務必註明來源(註明:來源於公衆號:我的小碗湯, 作者:小碗湯)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章