1,NetworkPolicy
簡介
為了實現(xiàn)細粒度的容器間往來訪問隔離策略之斯,Kubernetes 從 1.3 版本開始齐唆,由 SIG-Network 小組主導(dǎo)研發(fā)了 Network Policy 機制,目前已升級為 networking.k8s.io/v1 穩(wěn)定版本爬橡。Network Policy 的主導(dǎo)功能是對 Pod 間的網(wǎng)絡(luò)通信進行限制和準入控制治唤,設(shè)置方式為將 Pod 的 Label 作為查詢條件,設(shè)置允許訪問或禁止訪問的客戶端 Pod 列表糙申。目前查詢條件可以作用于 Pod 和 Namespace 級別宾添。
為了使用 Network Policy,Kubernetes 引入了一個新的資源對象 NetworkPolicy柜裸,供用戶設(shè)置 Pod 間網(wǎng)絡(luò)訪問的策略缕陕。但僅定義一個網(wǎng)絡(luò)策略是無法完成實際的網(wǎng)絡(luò)隔離的,還需要一個策略控制器(Policy Controller)進行策略的實現(xiàn)疙挺。策略控制器由第三方網(wǎng)絡(luò)組建提供扛邑,目前 Calico、Cilium铐然、Kube-router蔬崩、Romana、Weave Net 等開源項目均支持網(wǎng)絡(luò)策略的實現(xiàn)搀暑。
Policy Controller 需要實現(xiàn)一個 API Listener沥阳,監(jiān)聽用戶設(shè)置的 NetworkPolicy 定義,并將網(wǎng)絡(luò)訪問規(guī)則通過各 Node 的 Agent 進行實際設(shè)置(Agent 則需要通過 CNI 網(wǎng)絡(luò)插件實現(xiàn))自点。
隔離和非隔離的 Pod
默認情況下桐罕,Pod 是非隔離的,它們接受任何來源的流量。
Pod 在被某 NetworkPolicy 選中時進入被隔離狀態(tài)冈绊。 一旦名稱空間中有 NetworkPolicy 選擇了特定的 Pod侠鳄,該 Pod 會拒絕該 NetworkPolicy 所不允許的連接。 (名稱空間下其他未被 NetworkPolicy 所選擇的 Pod 會繼續(xù)接受所有的流量)
網(wǎng)絡(luò)策略不會沖突死宣,它們是累積的伟恶。 如果任何一個或多個策略選擇了一個 Pod, 則該 Pod 受限于這些策略的 入站(Ingress)/出站(Egress)規(guī)則的并集。因此評估的順序并不會影響策略的結(jié)果毅该。
為了允許兩個 Pods 之間的網(wǎng)絡(luò)數(shù)據(jù)流博秫,源端 Pod 上的出站(Egress)規(guī)則和 目標端 Pod 上的入站(Ingress)規(guī)則都需要允許該流量。 如果源端的出站(Egress)規(guī)則或目標端的入站(Ingress)規(guī)則拒絕該流量眶掌, 則流量將被拒絕挡育。
部署calic網(wǎng)絡(luò)
wget https://docs.projectcalico.org/v3.9/manifests/calico.yaml
kubectl apply -f calico.yaml
[root@master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-5fbfc9dfb6-jhddm 1/1 Running 0 16m
calico-node-2d28h 1/1 Running 0 16m
calico-node-77rx5 1/1 Running 0 16m
calico-node-xzrdh 1/1 Running 0 16m
coredns-7ff77c879f-p4smr 1/1 Running 0 18m
coredns-7ff77c879f-tn7w9 1/1 Running 0 18m
etcd-master 1/1 Running 0 18m
kube-apiserver-master 1/1 Running 0 18m
kube-controller-manager-master 1/1 Running 0 18m
kube-proxy-8h5gh 1/1 Running 0 18m
kube-proxy-97dzz 1/1 Running 0 18m
kube-proxy-986fs 1/1 Running 0 18m
kube-scheduler-master 1/1 Running 0 18m
NetworkPolicy示例
參數(shù)說明:
podSelector:用于定義該網(wǎng)絡(luò)策略作用的 Pod 方位,本例的選擇條件為包含 "role=db" 標簽的 Pod朴爬。
policyTypes:網(wǎng)絡(luò)策略的類型即寒,包括 ingress 和 egress 兩種,用于設(shè)置目標 Pod 的入站和出站的網(wǎng)絡(luò)限制召噩。
ingress:定義允許訪問目標 Pod 的入站白名單規(guī)則母赵,滿足 from 條件的客戶端才能訪問 ports 定義的目標 Pod 端口號。
- from:對符合條件的客戶端 Pod 進行網(wǎng)絡(luò)放行具滴,規(guī)則包括基于客戶端 Pod 的 Label凹嘲、基于客戶端 Pod 所在的 Namespace 的 Label 或者客戶端的 IP 范圍。
- ports:允許訪問的目標 Pod 監(jiān)聽的端口號构韵。
egress:定義目標 Pod 允許訪問的 "出站" 白名單規(guī)則周蹭,目標 Pod 僅允許訪問滿足 to 條件的服務(wù)端 IP 范圍和 ports 定義的端口號。
- to: 允許訪問的服務(wù)端信息疲恢,可以基于服務(wù)端 Pod 的Label凶朗、基于服務(wù)端 Pod 所在的 Namespace 的 Label 或者服務(wù)端 IP 范圍。
- ports:允許訪問的服務(wù)端的端口號冈闭。
創(chuàng)建兩個名稱空間
[root@master ~]# kubectl create namespace dev
namespace/dev created
[root@master ~]# kubectl create namespace prod
namespace/prod created
[root@master ~]# cat pods.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
[root@master ~]# kubectl apply -f pods.yaml -n dev
[root@master ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 57s 192.168.196.131 node01 <none> <none>
[root@master ~]# cat ingres-def.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: ingres
namespace: dev
spec:
podSelector: {}
policyTypes:
- Ingress
測試:
image.png
將pod創(chuàng)建在prod中
[root@master ~]# kubectl apply -f pods.yaml -n prod
pod/pod1 created
[root@master ~]# kubectl get pods -n prod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 14s 192.168.140.69 node02 <none>
<none>
測試:
[root@master ~]# curl 192.168.140.69
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
上面的networkpolicy中定義了ingress要生效但是ingress沒有定義規(guī)則就表示默認不允許任何人訪問俱尼,egress沒有定義默認所有的都可以訪問
定義所有訪問
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: ingres
namespace: dev
spec:
podSelector: {}
ingress:
- {}
policyTypes:
- Ingress
[root@master ~]# kubectl apply -f ingres-def.yaml
networkpolicy.networking.k8s.io/ingres configured
測試:
[root@master ~]# curl 192.168.196.131
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
允許別人來放著這組pod
給pod打個標簽
[root@master ~]# kubectl label pods pod1 app=myapp -n dev
pod/pod1 labeled
vim allow-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress
spec:
podSelector:
matchLabels:
app: myapp
ingress:
- from:
- ipBlock:
cidr: 192.168.0.0/16
except:
- 192.168.1.12/32
ports:
- protocol: TCP
port: 80
[root@master ~]# kubectl apply -f allow-ingress.yaml -n dev
[root@master ~]# kubectl get netpol -n dev
NAME POD-SELECTOR AGE
allow-ingress app=myapp 65s
ingres <none> 45m
官方文檔:https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/