ASP.NET Core on K8S深入学习(11)K8S网络知多少
Photo :Kubernetes
文?| Edison Zhou
本文已加入《.NET Core on K8S 學(xué)習(xí)與實(shí)踐系列文章索引目錄》,點(diǎn)擊查看容器化相關(guān)文章,希望對(duì)你有所幫助!
Kubernetes網(wǎng)絡(luò)模型
? ? ? ?我們都知道Kubernetes作為容器編排引擎,它有一個(gè)強(qiáng)大又復(fù)雜的網(wǎng)絡(luò)模型,也牽引出了Pod網(wǎng)絡(luò)、Service網(wǎng)絡(luò)、ClusterIP、NodePort、Ingress等多個(gè)概念。這里我們采用楊波老師(架構(gòu)師楊波)模仿TCP/IP協(xié)議棧總結(jié)的一個(gè)K8S網(wǎng)絡(luò)模型圖來(lái)看看K8S的四個(gè)抽象層次,從而了解一下K8S的網(wǎng)絡(luò)。本小節(jié)的文字主要引用自楊波老師關(guān)于K8S網(wǎng)絡(luò)模型的文章及CloudMan的《每天5分鐘玩轉(zhuǎn)Kubernetes》一書。
K8S網(wǎng)絡(luò)層次模型圖 (From 波波老師)
根據(jù)上圖模型中展示的四個(gè)層次,從0到3,除了第0層,每一層都是構(gòu)建于前一層之上。
(1)第0層:節(jié)點(diǎn)主機(jī)互通互聯(lián)
主要保證K8S節(jié)點(diǎn)(物理或虛擬機(jī))之間能夠正常IP尋址和互通的網(wǎng)絡(luò),這個(gè)一般由底層(公有云或數(shù)據(jù)中心)網(wǎng)絡(luò)基礎(chǔ)設(shè)施支持,這里我們無(wú)需過(guò)多關(guān)心。
(2)第1層:Pod虛擬機(jī)互聯(lián)
? 在一個(gè)Pod中可以運(yùn)行一個(gè)或多個(gè)容器,且Pod中所有容器使用同一個(gè)網(wǎng)絡(luò)namespace,即相同的IP和端口空間,可以直接用localhost通信,而且還可以共享存儲(chǔ)(本質(zhì)是通過(guò)將Volume掛載到Pod中的每個(gè)容器)。
?Pod網(wǎng)絡(luò)模型圖 (From 波波老師)
(3)第2層:服務(wù)發(fā)現(xiàn)和負(fù)載均衡
? 在K8S集群中,Pod的IP并不是固定的,可能會(huì)頻繁地銷毀和創(chuàng)建實(shí)例,為了解決此問(wèn)題,Service提供了訪問(wèn)Pod的抽象層。即無(wú)論后端Pod如何變化,Service都作為穩(wěn)定的前端對(duì)外提供服務(wù)。此外,Service還提供了高可用和負(fù)載均衡的功能,它負(fù)責(zé)將請(qǐng)求轉(zhuǎn)發(fā)給正確的Pod。
??Service網(wǎng)絡(luò)模型圖 (From 波波老師)
(4)第3層:外部流量接入
? K8s的Service網(wǎng)絡(luò)只是一個(gè)集群內(nèi)部網(wǎng)絡(luò),集群外部是無(wú)法直接訪問(wèn)的。為此,想要將應(yīng)用暴露出去讓公網(wǎng)能夠訪問(wèn),K8S提供了兩種方式:
① NodePort:使Service通過(guò)Cluster節(jié)點(diǎn)的靜態(tài)端口對(duì)外提供服務(wù),外部可以通過(guò) NodeIP:NodePort 來(lái)訪問(wèn)Service。
??Node Port方式示意圖 (From 波波老師)
② LoadBalancer:使Service利用Cloud Provider提供的Load Balancer對(duì)外提供服務(wù),Cloud Provider負(fù)責(zé)將Load Balancer的流量導(dǎo)向Service。目前支持的Cloud Provider包括AWS、Azure、阿里云、騰訊云等。
?Load Balancer方式示意圖 (From 波波老師)
More:關(guān)于K8S網(wǎng)絡(luò)的更多基本原理與講解,強(qiáng)力推薦閱讀波波老師的以下文章:
Kubernetes網(wǎng)絡(luò)三部曲-Pod網(wǎng)絡(luò)(From 楊波老師)
Kubernetes網(wǎng)絡(luò)三部曲-Service網(wǎng)絡(luò)(From 楊波老師)
Kubernetes網(wǎng)絡(luò)三部曲-外部接入網(wǎng)絡(luò)(From 楊波老師)
傳說(shuō)中的CNI規(guī)范
????????為了保證網(wǎng)絡(luò)方案的標(biāo)準(zhǔn)化、擴(kuò)展性和靈活性,K8S采用了CNI(Container Networking Interface)規(guī)范。CNI是一個(gè)Pod網(wǎng)絡(luò)集成標(biāo)準(zhǔn),簡(jiǎn)化了K8S和不同Pod網(wǎng)絡(luò)實(shí)現(xiàn)技術(shù)的集成。CNI最大的優(yōu)點(diǎn)就是支持多種容器runtime,而不僅僅是Docker。目前已經(jīng)有多種支持K8S的網(wǎng)絡(luò)方案,包括 Flannel、Calico、Canal等,它們都實(shí)現(xiàn)了CNI規(guī)范,因此無(wú)論我們選擇哪種具體方案,它們的網(wǎng)絡(luò)模型都是一致的。
?CNI模型圖
More:關(guān)于CNI的更多基本原理與講解,推薦閱讀陳Sir的文章《K8S網(wǎng)絡(luò)詳解:CNI與CNI網(wǎng)絡(luò)模型》
Network Policy
關(guān)于Network Policy
Network Policy是K8S的一種資源,它使K8S可以通過(guò)Label選擇Pod,并指定其他Pod或外界如何與這些Pod通信。換句話說(shuō),當(dāng)Pod被定義了Network Policy時(shí),只有Policy允許的流量才能訪問(wèn)Pod(默認(rèn)情況下,任何來(lái)源的流量都可以訪問(wèn)Pod,是沒(méi)有限制的)即幫助K8S實(shí)現(xiàn)更為精細(xì)的流量控制,實(shí)現(xiàn)租戶隔離機(jī)制。
But,并不是所有K8S網(wǎng)絡(luò)方案都支持Network Policy,比如Flannel就不支持,而Calico是支持的。
????????下面我們就來(lái)實(shí)踐一下Network Policy,只要三步!
部署Canal
想要部署Canal,需要切換網(wǎng)絡(luò)方案,這里我們使用最簡(jiǎn)單粗暴的方式:重建當(dāng)前K8S集群
kubeadm reset # 在每個(gè)節(jié)點(diǎn)上執(zhí)行一次然后,重新對(duì)Master節(jié)點(diǎn)進(jìn)行初始化:
kubeadm init \ --apiserver-advertise-address=192.168.2.100 \ --image-repository registry.aliyuncs.com/google_containers \ --kubernetes-version v1.13.3 \ --service-cidr=10.1.0.0/16 \ --pod-network-cidr=10.244.0.0/16在兩個(gè)Node節(jié)點(diǎn)上執(zhí)行以下命令重新加入集群:(注意這里的token請(qǐng)?zhí)顚懩愕腗aster節(jié)點(diǎn)初始化后的輸出結(jié)果)
kubeadm?join?192.168.2.100:6443?--token?ekqxk2.iiu5wx5bbnbdtxsw?\ --discovery-token-ca-cert-hash?\ sha256:c50bb83d04f64f4a714b745f04682b27768c1298f331e697419451f3550f2d05最后,通過(guò)以下命令部署Canal:(參考自K8S官方文檔)
kubectl apply -f https://docs.projectcalico.org/v3.8/manifests/canal.yaml此時(shí),再次令驗(yàn)證的集群結(jié)果如下:
(1)集群節(jié)點(diǎn)狀態(tài)
? (2)Pod狀態(tài)
?
部署測(cè)試應(yīng)用
????????這里通過(guò)一個(gè)httpd應(yīng)用來(lái)演示Network Policy,該應(yīng)用的yaml定義如下:
apiVersion: apps/v1 kind: Deployment metadata:name: httpd spec:replicas: 3selector:matchLabels:name: networkpolicy-demotemplate:metadata:labels:name: networkpolicy-demospec:containers:- name: httpdimage: httpd:latestports:- containerPort: 80imagePullPolicy: IfNotPresent---kind: Service apiVersion: v1 metadata:name: httpd-svc spec:type: NodePortports:- protocol: TCPnodePort: 31000port: 8080targetPort: 80selector:name: networkpolicy-demo通過(guò)kubectl將其部署到K8S集群:
kubectl apply -f httpd-demo.yaml這時(shí)候三個(gè)httpd Pod已經(jīng)成功Running:
由于定義的是NodePort方式暴露服務(wù),這里我們?cè)诩和獠吭L問(wèn)Service看看:
由于當(dāng)前并沒(méi)有創(chuàng)建任何Network Policy,這里我們可以通過(guò)創(chuàng)建一個(gè)Pod應(yīng)用(我們熟悉的busybox)來(lái)驗(yàn)證一下是否可以在K8S集群內(nèi)部隨意訪問(wèn)該httpd應(yīng)用:
kubectl run busybox --rm -it --image=busybox /bin/sh
? 從上圖可以知道,它可以正常訪問(wèn)到Service,也可以正常ping到Pod節(jié)點(diǎn)。
部署Network Policy有效性
現(xiàn)在我們創(chuàng)建一個(gè)Network Policy,其配置文件yaml如下:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata:name: access-httpd spec:podSelector:matchLabels:name: networkpolicy-demoingress:- from:- podSelector:matchLabels:access: "true"ports:- protocol: TCPport: 80該Network Policy定義了如下規(guī)則:
(1)應(yīng)用于所有 label 為 name : networkpolicy-demo 的Pod,這里即剛剛創(chuàng)建的三個(gè)httpd pod。
(2)ingress中定義了只有 label 為 access : "true" 的Pod才能訪問(wèn)應(yīng)用。
(3)即使通過(guò)Policy也只能訪問(wèn)80端口
通過(guò)kubectl將其應(yīng)用到K8S集群中:
kubectl apply -f networkpolicy.yaml下面再次在busybox pod中驗(yàn)證Network Policy的有效性:
從上圖中可以看到,已經(jīng)無(wú)法再成功訪問(wèn)Service,也無(wú)法再ping通三個(gè)Pod節(jié)點(diǎn)。
這個(gè)時(shí)候,集群外也無(wú)法再通過(guò)NodePort訪問(wèn)到Service:
如果想要讓測(cè)試Pod(busybox)能訪問(wèn)到應(yīng)用了Network Policy的httpd應(yīng)用,我們可以對(duì)busybox pod加一個(gè)label("access=true")就可以:
kubectl run busybox --rm -it --image=busybox \ --labels="access=true" /bin/sh運(yùn)行后的驗(yàn)證結(jié)果如下,可以訪問(wèn)到Service,但Ping卻被禁止:
? 但是,此時(shí)集群節(jié)點(diǎn)(k8s-master與兩個(gè)node)與集群仍然無(wú)法訪問(wèn)到應(yīng)用了Network Policy的httpd應(yīng)用,如果想要讓它們也訪問(wèn)到,則需要修改Network Policy做一個(gè)類似于開防火墻白名單的操作(注意下面的ipBlock配置):
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata:name: access-httpd spec:podSelector:matchLabels:name: networkpolicy-demoingress:- from:- podSelector:matchLabels:access: "true"- ipBlock:cidr: 192.168.2.0/24ports:- protocol: TCPport: 80再次應(yīng)用到K8S集群后,再來(lái)通過(guò)集群外部的訪問(wèn)者瀏覽器試試:
? 可以看到,已經(jīng)可以正常訪問(wèn)啦!
小結(jié)
???????本文簡(jiǎn)單介紹了Kubernetes的4層網(wǎng)絡(luò)模型、CNI 容器網(wǎng)絡(luò)接口規(guī)范 和 Network Policy,并通過(guò)改造K8S集群的網(wǎng)絡(luò)配置從Flannel到Canal來(lái)驗(yàn)證Network Policy的有效性。對(duì)于Kubernetes的網(wǎng)絡(luò)模型的原理與介紹,強(qiáng)烈推薦閱讀楊波老師的《Kubernetes網(wǎng)絡(luò)三部曲》,它的傳送門位于下方的參考資料列表中。
????????最后,碼字不易,也希望各位看官看完覺(jué)得還行就在本文右下方順手點(diǎn)個(gè)“在看”,就是對(duì)我最大的鼓勵(lì)!
參考資料:
(1)CloudMan,《每天5分鐘玩轉(zhuǎn)Kubernetes》?
(2)李振良,《一天入門Kubernets教程》?
(3)馬哥(馬永亮),《Kubernetes快速入門》?
(4)Liang,《K8S CNI網(wǎng)絡(luò)最強(qiáng)對(duì)比》?
(5)楊波,《K8S網(wǎng)絡(luò)三部曲》?
(6)陳Sir,《K8S網(wǎng)絡(luò)詳解:CNI與CNI網(wǎng)絡(luò)模型》
往期精彩回顧
.NET Core on K8S學(xué)習(xí)與實(shí)踐系列文章索引目錄
熊逸《唐詩(shī)必修50講》學(xué)習(xí)筆記系列文章索引目錄
【重磅】2019 .NET China Conf 資料下載
2019?.NET?Conf China - 路一直都在,社區(qū)會(huì)更好
阿里云MVP第十期全球發(fā)布—讓天下沒(méi)有難做的技術(shù)
基于Jenkins的開發(fā)測(cè)試全流程持續(xù)集成實(shí)踐
基于Jenkins Pipeline的ASP.NET Core持續(xù)集成實(shí)踐
恰童鞋騷年,風(fēng)華也許不再正茂,但卻仍想揮斥方遒。
本公眾號(hào)會(huì)長(zhǎng)期關(guān)注和分享.NET Core,Microservice,Cloud Native,DevOps等技術(shù)內(nèi)容文章,還會(huì)與你分享個(gè)人生活成長(zhǎng)的點(diǎn)滴及各類好書的讀書筆記,希望能對(duì)你有所幫助,一起成長(zhǎng)!
長(zhǎng)按訂閱更多精彩▼
點(diǎn)個(gè)【在看】和更多人一起分享
總結(jié)
以上是生活随笔為你收集整理的ASP.NET Core on K8S深入学习(11)K8S网络知多少的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 特意向大家推荐.NET技术圈一些优秀开发
- 下一篇: Amazon、Linux基金会开发边缘网