一文搞懂Kubernetes網絡策略(上)

從CNCF基金會的成立,到Kubernetes社區蓬勃發展,歷經6載,17年異軍突起,在mesos、swarm等項目角逐中,拔得頭籌,繼而一統容器編排,其成功的關鍵緣由可歸納爲如下幾點:nginx

  • 項目領導者們的堅守與遠見
  • 社區的良好的運做與社區文化
  • 社區與企業落地的正反饋

今天zouyee爲你們帶來《一文搞懂Kubernetes網絡策略(上)》,其中《kuberneter調度由淺入深:框架》正在編寫中,敬請期待,當前涉及版本均爲1.20.+git


1、Network Policy簡介

​ 隨着微服務架構的日漸盛行,Serverless框架的逐步落地,應用上雲後帶來了模塊間網絡調用需求的大規模增加,Kubernetes 自 1.3 引入了 Network Policy,其提供以應用爲中心, 基於策略的網絡控制,用於隔離應用以減小攻擊面。github

​ Pod之間可否通訊可經過以下三種組合進行確認:api

  1. 其餘被容許的 Pods(例如:Pod 沒法限制對自身的訪問)
  2. 被容許訪問的namespace
  3. IP CIDR(例如:與 Pod 運行所在節點的通訊老是被容許的)

在定義基於 Pod 或namespace的 NetworkPolicy 時,能夠使用標籤選擇器來設定哪些流量能夠進入或離開 Pod。同時,當建立基於 IP 的 NetworkPolicy 時,能夠基於 IP CIDR 來定義策略。markdown

如下結構體示意圖輔助理解,後面章節有具體說明:網絡

版本變遷
Kubernetes 版本 Networking API 版本 說明
v1.5-v1.6 extensions/v1beta1 須要在kube-apiserver開啓 extensions/v1beta1/networkpolicies
v1.7 networking.k8s.io/v1
v1.8 networking.k8s.io/v1 新增 EgressIPBlock 的支持

2、簡要介紹

默認狀況下,Pod 是非隔離的,它們接受任何流量。架構

Pod 在被某 NetworkPolicy 選中時進入隔離狀態。 一旦名字空間中有 NetworkPolicy 選擇了特定的 Pod,該 Pod 會拒絕該 NetworkPolicy 所不容許的鏈接。 (名字空間下其餘未被 NetworkPolicy 所選擇的 Pod 會繼續接受全部的流量)app

網絡策略不會衝突。 若是任何一個或多個策略選擇了一個 Pod, 則該 Pod 受限於這些策略的 入站(Ingress)/出站(Egress)規則的並集。框架

⚠️在使用 Network Policy 時,網絡插件須要支持 Network Policy,如 Calico、Romana、Weave Net 和 Trireme 等,其中Engress爲 出口流量,Ingress爲 入口流量。less

2.1 結構體說明

staging/src/k8s.io/api/networking/v1/types.go

下面是 NetworkPolicy 的一個示例,如需完整說明,可參看結構定義文檔:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: network-policy-sample
  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
複製代碼

必需字段:與全部其餘的 Kubernetes 對象同樣,NetworkPolicy 須要 apiVersionkindmetadata 字段。

spec:NetworkPolicy 規約中包含了在名字空間中定義特定網絡策略所需的全部信息。

podSelector:每一個 NetworkPolicy 都包括一個 podSelector,它選擇適用該該策略的 Pod。示例中的策略選擇帶有 "role=db" 標籤的 Pod。 若podSelector爲空的,則選擇名字空間下全部 Pod。

policyTypes: 每一個 NetworkPolicy 都包含一個 policyTypes 列表,其中包含 IngressEgress 或(二者亦可)。policyTypes 字段表示給定的策略是應用於 所選 Pod 的入口流量仍是來出口流量(二者亦可)。 若是 NetworkPolicy 未指定 policyTypes 則默認狀況下始終設置 Ingress; 若是 NetworkPolicy 有任何出口規則的話則設置 Egress

ingress: 每一個 NetworkPolicy 可包含一個 ingress 規則的白名單列表。 每一個規則都容許同時匹配 fromports 部分的流量。示例策略中包含一條 簡單的規則: 它匹配某個特定端口,第一個經過 ipBlock 指定,第二個經過 namespaceSelector 指定,第三個經過 podSelector 指定。

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

該網絡策略總結以下:

  1. 隔離 default名字空間下 role=db 的 Pod 。
  2. 出口限制:容許符合如下條件的 Pod 鏈接到 default名字空間下標籤爲 role=db的全部 Pod 的 6379 TCP 端口:
    • default名字空間下帶有 role=frontend 標籤的全部 Pod
    • 帶有 project=myproject 標籤的全部名字空間中的 Pod
    • IP 地址範圍爲 172.17.0.0–172.17.0.255172.17.2.0–172.17.255.255 (即除了 172.17.1.0/24 以外的全部 172.17.0.0/16)
  3. 入口限制:容許從帶有 role=db標籤的名字空間下的任何 Pod 到 CIDR 10.0.0.0/24 下 5978 TCP 端口。
2.2 簡單示例

以 calico 爲例看一下 Network Policy 的具體用法。

  1. 配置 kubelet 使用 CNI 網絡插件(默認已經配置,無需更改)

kubelet --network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin ...

  1. 安裝 calio 網絡插件
# 注意修改 CIDR,須要跟 k8s pod-network-cidr 一致,默認爲 192.168.0.0/16
# 當前選擇的是小於50節點的安裝方式,具體安裝可查看
# https://docs.projectcalico.org/getting-started/kubernetes/self-managed-onprem/onpremises
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
複製代碼
  1. 部署應用

部署 nginx 服務

$ kubectl create deployment nginx --image=nginx
deployment "nginx" created
$ kubectl expose deployment nginx --port=80
service "nginx" exposed
複製代碼

測試網絡

$ kubectl get svc,pod
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.233.0.1      <none>        443/TCP   186d
service/nginx        ClusterIP   10.233.27.142   <none>        80/TCP    2s

NAME                            READY   STATUS              RESTARTS   AGE
pod/nginx-f89759699-kfmbj       1/1     Running   					0          62s

$ kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.

/ # wget --spider --timeout=1 nginx
Connecting to nginx (10.233.27.142:80)
remote file exists
/ #
複製代碼

4)測試網絡策略

若是隻讓那些擁有標籤 access: true 的 Pod 訪問 nginx 服務, 那麼能夠建立一個以下所示的 NetworkPolicy 對象:

$ cat nginx-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: access-nginx
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - from:
    - podSelector:
        matchLabels:
          access: "true"

$ kubectl create -f nginx-policy.yaml
networkpolicy "access-nginx" created

# 不帶 access=true 標籤的 Pod 仍是沒法訪問 nginx 服務
$ kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.

/ # wget --spider --timeout=1 nginx
Connecting to nginx (10.233.27.142:80)
wget: download timed out
/ #


# 而帶有 access=true 標籤的 Pod 能夠訪問 nginx 服務
$ kubectl run busybox --rm -ti --labels="access=true" --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.

/ # wget --spider --timeout=1 nginx
Connecting to nginx (10.233.27.142:80)
/ #
複製代碼
參考文檔

後續相關內容,請查看公衆號:DCOS

相關文章
相關標籤/搜索