K8s的網路模型設計是為了解決四個通訊需求
Pod內部的容器會共享同一個網路名稱空間, 通常由構建容器的基礎架構提供, 例如:由pause鏡像啟動的容器。可以理解為同一台主機內部的服務可以相互溝通的模式。
Pod 和Pod之間的溝通必須存在同一個網路平面, 每個Pod都會有cluster配置一個唯一的地址, 可以讓Pod之間直接通訊, 而運行Pod的節點之間也可以透過橋接設備等持有網路中的一個IP地址, 讓Node跟Pod之間也可以溝通。可以將Pod之間的溝通理解為網路中主機間的彼此溝通。
Service專用的網路稱為Cluster Network, 它會在Service創建時由kube-apiserver指定一個IP地址, 稱為ClusterIP, 再由API Server儲存下來, 透過觸發節點上的kube-proxy根據不同代理模式定義iptables或ipvs的規則來完成ClusterIP與Pod IP之間的轉發。
外部流量要訪問到Pod對象要經過 hostPort, nodePort, hostNetwork, 以及NodePort或LoadBalancer類型的Service, 需要經過層層轉發才能達到Pod。
網路策略(Network Policy) 是用在控制Pod之間如何溝通以及如何與其他網路溝通的規範, 目的在幫K8s實現更精細的流量控制以及租戶隔離機制。K8s提供一個NetworkPolicy
供使用, 有效範圍是整個Namespace。
NetworkPolicy 會使用標籤選擇器定義一組Pod作為控制對象, 管控入站流量的是Ingress
, 負責出站流量的是Egress
, 兩個可以共用, 負責規範生效範圍的是spec.policyType
。
Pod預設可以接收任何來源的流量, 也可以向外部發出期望的所有流量, 一旦Nameapace 中有NetworkPolicy規範Pod, Pod就會依照NetworkPolicy的規範拒絕請求, 並且若是在spec中定義了沒有規則的Ingress或Egress就會造成拒絕相關的一切流量。
Ingress 字段是一個列表, 主要有兩個字段組成:
from
<[]Object> : 可訪問的Pod列表, 如果設定多項則判斷邏輯為"聯集", 是一個白名單的概念ports
<[]Object>: 可訪問的Pod上面的允許Port列表, 有設定就就是白名單。拒絕所有流量配置YAML示意
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector:{}
policyType:["Ingress"]
接收所有流量YAML配置示意
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
spec:
podSelector:{}
policyType:["Ingress"]
ingress:
- {}
設置允許特定入站流量YAML
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
namespace: default
spec:
podSelector:
matchLabels:
app: myapp
policyTypes: ["Ingress"]
ingress:
- from:
- ipBlock:
cidr: 10.244.0.0/16
except:
- 10.244.3.0/24
- podSelector:
matchLabels:
app: myapp
ports:
- protocol: TCP
port: 80
inBlock
: 根據IP或網段選擇流量源端點namespaceSelector
: NameSpace標籤選擇器, 用來匹配Namespace底下所有的PodpodSelector
: pod 標籤選擇器, 給空值代表全選ports
: 內含port
,protocol
用來匹配Pod上面的portport
: 未定義時匹配所有端口protocol
: TCP或UDP, 預設TCP
Egress 字段是一個列表, 主要有兩個字段組成:
拒絕所有流量配置YAML示意
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
spec:
podSelector:{}
policyType:["Egress"]
接收所有流量YAML配置示意
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-egress
spec:
podSelector:{}
policyType:["Egress"]
egress:
- {}
設置允許特定入站流量YAML
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
namespace: default
spec:
podSelector:
matchLabels:
app: myapp
policyTypes: ["Egress"]
egress:
- to:
- podSelector:
matchLabels:
app: nginx
ports:
- protocol: TCP
port: 80
- to:
- podSelector:
matchLabels:
app: mysql
ports:
- protocol: TCP
port: 3306
因為團隊參賽所以都會讀一下團隊裡的文章, 最近每天讀遠離 DevOops都覺得篇篇實用, 篇篇精彩, 每篇都有收穫!