Kubernetes無疑是當前最火熱的容器編排工具,網絡是kubernetes中很是重要的一環, 本文主要介紹一些相應的網絡原理及術語,以及kubernetes中的網絡方案和對比。
Kubernetes自己並不提供網絡功能,只是把網絡接口開放出來,經過插件的形式實現。爲了知足不一樣的網絡功能及需求,使容器在建立或銷燬時可以容易地配置容器網絡, CNI(Container Network Interface)應運而生, CNI旨在定義運行時和插件之間的接口,在kubernetes中,CNI鏈接kubelet和網絡插件來爲容器配置對應的網絡設置。
容器網絡是容器選擇鏈接到其餘容器、主機和外部網絡的機制。在kubernetes網絡模型設計中,每每須要每一個Pod都擁有一個獨立的IP地址,並且假定全部的pod都在一個能夠直接連通的、扁平的網絡空間中。用戶不須要額外考慮如何創建Pod之間的鏈接,也不須要考慮將容器端口映射到主機端口等問題。全部節點均可在不用NAT的方式下同全部容器通信,容器的地址和別人看到的地址是同一個地址。node
IPAM:IP地址管理;這個IP地址管理並非容器所特有的,傳統的網絡好比說DHCP其實也是一種IPAM,到了容器時代咱們談IPAM,主流的兩種方法:基於CIDR的IP地址段分配地或者精確爲每個容器分配IP。但總之一旦造成一個容器主機集羣以後,上面的容器都要給它分配一個全局惟一的IP地址,這就涉及到IPAM的話題。git
Overlay:在現有二層或三層網絡之上再構建起來一個獨立的網絡,這個網絡一般會有本身獨立的IP地址空間、交換或者路由的實現。github
BGP:主幹網自治網絡的路由協議,用於管理邊緣路由器之間數據包的路由方式。BGP經過考慮可用路徑,路由規則和特定網絡策略,幫助弄清楚如何將數據包從一個網絡發送到另外一個網絡。BGP有時被用做CNI插件中的路由機制,而不是封裝的覆蓋網絡。docker
封裝:封裝是指在附加層中封裝網絡數據包以提供其餘上下文和信息的過程。在overlay網絡中,封裝被用於從虛擬網絡轉換到底層地址空間,從而能路由到不一樣的位置(數據包能夠被解封裝,並繼續到其目的地)。後端
Container Network Interface (CNI) 最先是由CoreOS發起的容器網絡規範,是Kubernetes網絡插件的基礎。其基本思想爲:Container Runtime在建立容器時,先建立好network namespace,而後調用CNI插件爲這個netns配置網絡,其後再啓動容器內的進程。安全
CNI Plugin負責給容器配置網絡,必須實現爲由容器管理系統(rkt或者kubernetes)調用的可執行文件,包括兩個基本的接口來配置網絡:網絡
配置網絡: AddNetwork(net NetworkConfig, rt RuntimeConf) (types.Result, error)架構
清理網絡:DelNetwork(net NetworkConfig, rt RuntimeConf) error運維
在Kubernetes中,kubelet決定了容器應該加入哪一個網絡以及它須要調用哪一個插件。而後插件會將接口添加到容器網絡命名空間中,做爲一個veth對的一側。接着它會在主機上進行更改,好比將veth的其餘部分鏈接到網橋。再以後,它會經過調用單獨的IPAM(IP地址管理)插件來分配IP地址並設置路由。工具
以上CNI插件解決了Pod內網絡配置的問題,可是網絡還有一個問題要解決的即是IP管理,爲了解耦網絡配置和ip管理, CNI定義了第二種類型的插件-ip地址管理插件(IPAM插件)。
與CNI插件同樣,IPAM插件經過運行可執行文件來調用。IPAM插件負責爲接口配置和管理IP地址。
CNI插件在執行時調用IPAM插件,IPAM插件來肯定接口IP /子網,網關和路由等信息,從而在容器啓動時分配IP地址並配置網絡,並將此信息返回給CNI插件,在刪除容器時再次調用它以清理這些資源。
IPAM插件能夠經過協議(例如dhcp),存儲在本地文件系統上的數據,網絡配置文件的「ipam」部分或上述各項的組合來獲取信息。
flannel是CoreOS團隊設計的一個網絡方案,以etcd做爲存儲,給node上的每一個容器分配全局惟一的IP地址, 容器間經過overlay網絡互相通訊。
Pod間通訊以下:
• Pod1和pod不在同一宿主機
數據從源容器中發出後,經由所在主機的docker0虛擬網卡轉發到flannel0虛擬網卡(veth pair),flanneld服務監聽在網卡的另一端,Flannel經過Etcd服務維護了一張節點間的路由表,利用etcd來管理可分配的IP地址段資源,同時監控etcd中每一個Pod的實際地址,源主機的flanneld服務將本來的數據內容UDP封裝後根據本身的路由表投遞給目的節點的flanneld服務,數據到達之後被解包,而後直接進入目的節點的flannel0虛擬網卡,而後被轉發到目的主機的docker0虛擬網卡,最後就像本機容器通訊一下的有docker0路由到達目標容器。
• Pod1和Pod2在同一臺宿主機
Pod1和Pod2在同一臺主機的話,由Docker0網橋直接轉發請求到Pod2,不通過Flannel。
Calico是一個純3層的數據中心網絡方案,並且無縫集成像OpenStack這種IaaS雲架構,可以提供可控的VM、容器、裸機之間的IP通訊。
經過將整個互聯網的可擴展IP網絡原則壓縮到數據中心級別,Calico在每個計算節點利用Linux Kernel實現了一個高效的vRouter來負責數據轉發,而每一個vRouter經過BGP協議負責把本身上運行的workload的路由信息像整個Calico網絡內傳播——小規模部署能夠直接互聯,大規模下可經過指定的BGP route reflector來完成。這樣保證最終全部的workload之間的數據流量都是經過IP路由的方式完成互聯的。
Calico節點組網能夠直接利用數據中心的網絡結構(不管是L2或者L3),不須要額外的NAT,隧道或者Overlay Network。
Calico還提供了豐富而靈活的網絡Policy,保證經過各個節點上的ACLs來提供Workload的多租戶隔離、安全組以及其餘可達性限制等功能。
容器技術的誕生,伴隨本身諸多的優勢被普遍應用。容器消除了部署環境差別,保證了應用生命週期的環境一致性標準,高資源利用率和隔離性,以及快速部署的特性,給企業的生產提高了效率,節約了成本。
隨着京東雲業務的快速增加,業務部署不能再侷限於物理機、虛擬機等傳統的方式, 雲翼早在2017年就開始了容器方向的探索之路,咱們發現容器背後的理念很超前,但現實中生產環境有許多存量的業務,沒法與之匹配,理念上是有一些差別, 如社區的容器倡導one process one container(在容器中只運行一個應用)。
雲翼做爲京東雲DevOps平臺,提供了集部署、運維、監控、日誌等諸多功能,這些功能實現大多都是須要在實例內部署Agent與對應的服務通訊,而實例如何標識到自身每每是使用IP的方式,容器在內部落地的一個很強烈的需求就是可以固定IP,使運維或者開發能方便登陸容器排查問題;另外很大一部分存量的業務架構依賴固定IP;還有內部的一些基礎系統都是經過IP來過濾,例如接入/LB 等後端須要填寫IP地址。容器在內部的落地,不能徹底不考慮存量業務的兼容性,很難放棄原有的技術體系, 咱們但願容器的引用能減輕上手成本,能更貼近傳統運維的習慣,爲了方便管理,咱們把容器的網絡和機房的內網放在一個平坦的網絡。
咱們開發了ipamD,大概的實現原理是pod每次建立時調用IPAMclient去請求ipamD申請地址, ipamD是一個常駐進程,維護了各個應用下對應分組的地址信息,經過pod前綴名能夠查到對應實例的IP,經過這種方式實現了IP地址固定的需求。
另外爲了降本增效,提高並知足一些業務方的特定需求,但願容器可以跑在京東雲的虛擬機上以方便管控相關的業務,咱們開發了相應的網絡插件來知足在雲主機中運行容器的需求,使雲翼的用戶能無差異的使用IaaS的資源。
雲主機上的CNI插件藉助彈性網卡、路由策略實現了:
(圖片來自https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/cni-proposal.md)
注:具體實現可參考amazon-vpc-cni-k8s(https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/cni-proposal.md)
雲翼藉助 docker/k8s 大幅提高了開發、測試、運維的生產力,簡化了人工和自動系統管理工做。若是你想了解更多關於京東雲翼,歡迎點擊「閱讀」~
歡迎點擊「京東雲」瞭解更多精彩內容