k8s网络架构图_唯品会基于Kubernetes(k8s)网络方案演进
VIP PaaS在接近兩年時間里,基于kubernetes主要經歷四次網絡方案的變遷:
1. kubernetes + flannel
2. 基于Docker libnetwork的網絡定制
3. kubernetes + contiv + kube-haproxy
4. 應用容器IP固定
先簡單說一下背景,PaaS平臺的應用管理包括應用配置管理,應用的運行態管理。一個應用的運行態對應kubernetes的一個Replication Controller(后面使用RC簡稱)和一個Service,應用實例對應kubernetes中的Pod, 我們基于這樣的管理方式,需要提供應用之間的相互調用,同時對部分應用要提供基于http/tcp的直接訪問。
首先說一下kubernetes + flannel。
flannel主要提供了跨主機間的容器通信;
在kubernetes的Pod、Service模型里,kube-proxy又借助iptables實現了Pod和Service間通信。
基于這種網絡訪問功能,我們平臺提供了以下功能:
基于gorouter提供的平臺域名的訪問 – watch k8s endpoints event管理router信息;
基于skydns并定制化kube2sky組件和kubelet,提供同一命名空間下應用(Pod)之間基于業務域名的訪問 – kube2sky基于k8s Service annotation解析并注冊域名信息、kubelet設置容器啟動時的domain search及外部dns;
實現容器tty訪問控制臺 – 每臺k8s node部署平臺組件 tty agent(根據Pod所屬node信息, 建立對應k8s結點的tty連接);
網絡訪問關系圖如下:
在k8s + flannel的模型下,容器網絡是封閉子網,可以提供平臺內部應用之間基于4層和7層的調用,同時對外部提供應用基于域名(工作在七層)的直接訪問,但無法滿足用戶在平臺外部需要直接使用IP訪問的需求。
在flannel網絡穩定使用后,開始研究network plugin以使應用服務實例以public IP 方式供用戶直接使用。
當時docker的版本為1.8, 本身還不支持網絡插件.同時 kubernetes本身提供一套基于CNI的網絡插件, 但本身有bug[CNI delete invoked twice with non-infra container id #20379]。
于是我們嘗試從docker network plugin的角度入手,結合libnetwork從docker源碼的角度進行定制。
整個架構分為三層:
Client Layer – Docker CLI和kubernetes(Docker client);
Docker Layer – Docker daemon 并在代碼層面集成libnetwork(內置OVS driver);
Controller Layer – ovsdb-server及network controller(自開發IPAM);
整體訪問結構圖:
整個方案包括以下三個流程:
1. 啟動Docker Daemon:
初始化network controller -> 加載OVS Driver -> OVS Driver調用libovsdb創建docker0-ovs Bridge -> OVS Driver將主機上的一物理網卡attach到docker0-ovs上;
2. 啟動容器:
OVS Driver 創建veth pair 用于連接network namespaces -> OVS Driver調用network controller獲取容器IP和VLAN Tag -> OVS Driver將veth pair的一端添加到docker0-ovs上,并設置VLAN Tag -> OVS Driver設置容器內interface的IP,Mac Address以及路由 -> 設置各network interface為up;
3. 停止容器:
OVS Driver調用network controller釋放容器IP -> 刪除network link -> OVS Driver調用libovsdb刪除port;
libnetwork工作完成了測試階段但沒有經歷上線,隨著Docker版本的推進,Docker1.9開始支持 contiv netplugin,我們開始研究contiv應用,在期間我們也完成了使用haproxy替換kube-proxy的開發[https://github.com/AdoHe/kube2haproxy],并最后采用docker1.10+contiv上線。
這里根據我們實際網絡訪問關系再描述下PaaS在contiv整體部署結構:
Kube-haproxy替代了kube-proxy,主要是提供服務ip的公共調用,同時避免了容器數量增加后帶來的iptables規則的大量增長,方便調試。
contiv帶來的方便是用戶可以根據實例IP直接進行訪問;我們在使用過程中整體比較穩定,中間出現過一次問題: 機房停電導致了部分IP的分配狀態不正確,而且contiv當時還沒有提供查看已分配IP的接口。
Docker 1.10版本支持指定IP啟動容器,并且由于部分應用對實例IP固定有需求,我們開始著手容器IP固定方案的設計與開發。
前面提到應用運行時,對應k8s內一個ReplicationController以及一個Service。 應用的重新部署目前采用的策略主要是重建策略。 重建的流程包括刪除RC及RC下所有Pod,更新并創建新的RC(kubernetes會根據RC配置產生新的POD)。
在默認的k8s+contiv的網絡環境下,容器(Pod)的IP網絡連接是由contiv network plugin來完成的, contiv master只實現了簡單的IP地址分配和回收,每次部署應用時,并不能保證Pod IP不變。所以我們引入了新的Pod層面的IPAM,以保證同一個應用多次發生部署時,Pod IP始終是不變的。
作為Pod層面的IPAM,我們把這一功能直接集成在了kubernetes。Pod作為k8s的最小調度單元,原有的k8s Pod Registry(主要負責處理所有與Pod以及Pod subresource相關的請求:Pod的增刪改查,Pod的綁定及狀態更新,exec/attach/log等操作) 并不支持在創建Pod時為Pod分配IP,Pod IP是通過獲取Pod Infra Container的IP來獲取的,而Pod Infra Container的IP即為contiv動態分配得來的。
Pod Registry 訪問設計圖:
在原有kubernetes代碼基礎上,我們修改了Pod結構(在PodSpec中加入PodIP)并重寫了Pod Registry 同時引入了兩個新的資源對象:
1. Pod IP Allocator: Pod IP Allocator是一個基于etcd的IP地址分配器,主要實現Pod IP的分配與回收。
Pod IP Allocator通過位圖記錄IP地址的分配情況,并且將該位圖持久化到Etcd;
2. Pod IP Recycler: Pod IP Recycler是一個基于etcd的IP地址回收站,也是實現PodConsistent IP的核心。Pod IP Recycler基于RC全名(namespace + RC name)記錄每一個應用曾經使用過的IP地址,并且在下一次部署的時候預先使用處于回收狀態的IP。
Pod IP Recycler只會回收通過RC創建的Pod的IP,通過其他controller或者直接創建的Pod的IP并不會記錄,所以通過這種方式創建的Pod的IP并不會保持不變; 同時Pod IP Recycle檢測每個已回收IP對象的TTL,目前設置的保留時間為一天。
這里對kubelet也進行了改造,主要包括根據Pod Spec中指定IP進行相關的容器創建(docker run加入IP指定)以及Pod刪除時釋放IP操作。
創建和刪除Pod的UML時序圖如下:
Pod的創建在PaaS里主要有兩種情形:
應用的第一次部署及擴容,這種情況主要是從IP pool中隨機分配;
應用的重新部署:在重新部署時,已經釋放的IP已根據RC全名存放于IP Recycle列表中,這里優先從回收列表中獲取IP,從而達到IP固定的效果。
整體刪除過程為:由PaaSNg或kube-controller-manager調用apiserver Pod Delete并設置DeletionTimestamp, kubelet監聽到刪除時間并獲取GracefulDeletiontime,刪除應用容器, 通知apiserver釋放IP(釋放IP時獲取Pod所屬RC,根據是否有對應RC 名稱決定是否存放在IP Recycle列表),刪除Pause Pod,通知apiserver 刪除Pod對象。
另外為了防止IP固定方案中可能出現的問題,我們在kubernetes中加入了額外的REST api: 包括對已分配IP的查詢,手動分配/釋放IP..。
對目前方案的總結:
容器IP固定方案已上線,運行基本沒問題,但穩定性有待提升。主要表現為偶然性不能在預期時間內停止舊Pod,從而無法釋放IP造成無法復用(初步原因是由于Docker偶爾的卡頓造成無法在規定時間內停止容器)。我們短期的work around是使用額外添加的REST apiss手動修復,后期IP固定方案會繼續加強穩定性并根據需求進行優化。
總結
以上是生活随笔為你收集整理的k8s网络架构图_唯品会基于Kubernetes(k8s)网络方案演进的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 边框回归的损失函数_一文搞懂常用的七种损
- 下一篇: tata木门jo016价格?