淺析 Kubernetes原生NetworkPolicy 網絡策略,讓更安全的容器運行環境唾手可得

k8s中的網絡策略主要分爲原生 NetworkPolicy 和第三方網絡插件提供的網絡策略。本文將主要分析原生Networkpolicy的網絡策略。git

什麼是網絡策略github

網絡策略(NetworkPolicy)是一種關於 Pod 間及 Pod 與其餘網絡端點間所容許的通訊規則的規範。NetworkPolicy 資源使用標籤選擇 Pod,並定義選定 Pod 所容許的通訊規則。web

k8s中的網絡策略由實現了CNI接口的網絡插件提供,網絡插件監聽集羣中 NetworkPolicy 資源的建立/刪除/更新事件生成對應的規則來控制 Pod 的流量是否放行。api

常見的支持 NetworkPolicy 的網絡插件有:數組

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

默認狀況下 Pod 間及 Pod 與其餘網絡端點間的訪問是沒有限制的。網絡

以下是一個 NetworkPolicy 定義的例子,該策略的含義是阻止全部流量訪問有app=web這個 label 的 Pod。app

圖片描述
常常有人會問網絡策略要怎麼寫,或者是這個網絡策略表明了什麼含義。筆者認爲這個問題主要是由於使用者不瞭解網絡策略的省缺行爲。frontend

NetworkPolicy 字段含義spa

NetworkPolicy 這個資源屬於命名空間級別的,所以metadata 中的 namespace 不可省略,不然只會對default 命名空間下的知足條件的 Pod 生效。插件

下面介紹下 NetworkPolicy 中各字段的含義,並說明各字段省缺值及其含義,主要看 Spec 中的字段,
podSelector: 必填字段,Pod 的標籤選擇器,表示該網絡策略做用於哪些 Pod。若是爲空{}則表示選中本命名空間下全部 Pod。

policyTypes: 可選字段,字符串,策略規則類型, 表示該網絡策略中包含哪些類型的策略,可選爲"Ingress", "Egress", 或 "Ingress,Egress"。未填時,這個值依據下面的 ingress 和 egress 來定。若是該字段未設置且下面只出現了 ingress,則對 egress 不作限制。若是填了這個值,同時後續沒有設定對應的規則,則認爲設定的規則對應的流量所有禁止。例如:
圖片描述

該規則就限制了全部 Pod 的出流量。

ingress: 可選字段,數組,入站規則。互相間爲或的關係,知足其中一條則放行。

ports: 可選字段,數組,放行端口信息。互相間爲或的關係,若是爲空表示端口不受約束,若是非空,則表示除了出現的端口放行,其餘未指定的端口都禁止。

-port: 可選字段,數字,協議端口號。若是不寫,表示協議全部端口。
-protocol: 可選字段,字符串,協議。容許取值爲 TCP,UDP,SCTP。省缺爲 TCP。

from: 可選字段,數組,放行源地址信息。互相間爲或的關係,若是爲空表示不約束源地址,若是非空,則表示除了出現的源地址放行外,其餘源地址都禁止。

-ipBlock: 可選字段,放行 ip 段。
cidr: 標準 cidr,除了指定的cidr放行外其餘都禁止。
except: 標準 cidr 字符串數組,表示前面cidr 中的放行的 cidr 段須要再排除掉 except 中指定的。

-namespaceSelector: 可選字段,namespace 的標籤選擇器,表示放行集羣中的哪些命名空間中過來的流量。若是爲空`{}`或未出現則表示選中全部命名空間。

-podSelector: 可選字段,Pod 的標籤選擇器,表示放行哪些 Pod 過來的流量,默認狀況下從NetworkPolicy 同命名空間下的 Pod 中作篩選,若是前面設定了`namespaceSelector`則從符合條件的命名空間中的 Pod 中作篩選。若是爲空`{}`則表示選中知足`namespaceSelector` 條件的全部 Pod。

egress: 可選字段,數組,出站規則。互相間爲或的關係,知足其中一條就放行。

ports: 可選字段,數組,放行端口信息。互相間爲或的關係,若是爲空表示端口不受約束,若是非空,則表示除了出現的端口放行,其餘未指定的端口都禁止。(詳細字段同 ingress 中的 ports)

to: 可選字段,數組,放行目的地址信息。互相間爲或的關係,若是爲空表示不約束目的,若是非空,則表示除了出現的目的地址放行外,其餘目的地址都禁止。(詳細字段同ingress 中的 from)

介紹完 Spec 中各字段的含義及其默認行爲後,作個簡單的小結,NetworkPolicy 定義了放行規則,規則間是或的關係,只要命中其中一條規則就認爲流量能夠放行。

下面以一個kubernetes官網中的例子來回顧下前面的知識。

圖片描述

首先該規則指定了命名空間爲 default, 選擇了其中全部包含 role=db 這個 label 的 Pod,定義了入站流量規則與出站流量規則。

對於入站流量,放行源地址來自 cidr 172.17.0.0/16 除了 172.17.1.0/24 以外的流量,放行來自有project=myproject 這個label的namespace中的流量,放行 default 命名空間下有 label role=frontend 的 Pod 的流量,並限定這些流量只能訪問到 role=db 這個 label 的 Pod 的 TCP 6379端口。

對於出站流量,只放行其訪問目的地址屬於 cidr 10.0.0.0/24 中,且端口爲 TCP 5978的流量。

須要注意的是 NetworkPolicy 選中的 Pod 只能是與 NetworkPolicy 同處一個 namespace 中的 Pod,所以對於有些規則可能須要在多個命名空間中分別設置。或者使用非原生的網絡策略定義,例如 Calico 中的 GlobalNetworkPolicy

NetworkPolicy 變動歷史

v1.6 以及之前的版本須要在 kube-apiserver 中開啓 extensions/v1beta1/networkpolicies;

v1.7 版本 Network Policy 已經 GA,API 版本爲 networking.k8s.io/v1;

v1.8 版本新增 Egress 和 IPBlock 的支持;

附錄

相關文章
相關標籤/搜索