摘要:基于年底或年初沒有推廣的現狀,唯品會部門目前已經做了兩年的時間。唯品會現狀唯品會目前線上有一千多個域,每個域之間相互的依賴比較復雜,每次的部署發布困難。這是唯品會的架構,主要包含持續集成和持續部署。
數人云上海&深圳兩地“容器之Mesos/K8S/Swarm三國演義”的嘉賓精彩實錄第三更來啦。唯品會是數人云Meetup的老朋友,去年曾做過RPC服務框架和Mesos容器化的分享。本次分享中,嘉賓王成昌分享了唯品會在Kubernetes上兩年的PaaS實踐,干貨滿滿誠意奉上~
王成昌,唯品會PaaS平臺高級開發工程師
主要工作內容包括:平臺DevOps方案流程優化,持續部署,平臺日志收集,Docker以及Kubernetes研究。
大家好,我是唯品會PaaS團隊的王成昌,與大家分享一下PaaS在Kubernetes的實踐。基于2014年底或2015年初PaaS沒有推廣的現狀,唯品會PaaS部門目前已經做了兩年的時間。
PaaS 主要工作將分為三個部分進行介紹,首先,PaaS定義的標準構建流程,持續集成和持續部署的架構以及已有組建上的功能定制;第二部分,基于Kubernetes實現的網絡方案,以及根據網絡方案做的擴展定制;第三部分,PaaS如何做日志收集和監控方案,最后列一下唯品會目前為止所遇到的問題和總結。
唯品會現狀唯品會目前線上有一千多個域,每個域之間相互的依賴比較復雜,每次的部署發布困難。線下有多套的測試環境,每套測試環境都要去維護多帶帶的應用升級和管理。公司層面也沒有統一的持續集成和部署的流程,大家各自去維護一個Jenkins或者一個Jenkins slave,看工程師的個人追求是否能夠寫一個完整的從源代碼、到打包、最后到部署的腳本。
唯品會線上全部用物理機在跑,之前Openstack方式沒有在線上,只是在測試環境跑,物理機的使用效率還是比較低的。即使在7周年大促的高峰時段,60~80%的物理機利用率也均低于10%。
唯品會PaaS構建流程基于前面提到的現狀,唯品會的PaaS定義了一個構建流程,整個流程不是一蹴而就,這是目前為止的定義,首先從源代碼的角度出發,即Git,所有的7個Phase全部包括在Jenkins Pipeline里,由于是基于Kubernetes,所以Jenkins Pipeline的執行是通過Jenkins k8s Plugin去調度后臺的k8s Cluster,由k8s產生的Pod去運行Pipeline。整個Pipeline的幾個階段,除了傳統的編譯單元測試和打包之外,加入了烘焙鏡像、部署以及集成公司的集成測試(即VTP),打包和鏡像完成后會正常上傳到公司統一的包管理系統Cider和平臺維護的Docker registry。
部署完成后會觸發集成測試,如果通過測試的話,會把這個包或者是鏡像標記為可用的狀態,一般先從測試環境標記,然后通過到staging環境。目前PaaS 平臺主要是維護測試環境和staging環境,線上還沒有,但是已經定義了一個審批的流程,如果標記了這個包為可用的狀態,需要一個審批來決定它是否可以上線。部署后通過k8s client,由另外一套k8s的集群來管理部署里面所有的節點。
這是唯品會的PaaS架構,主要包含持續集成和持續部署。首先由一個統一UI的入口Dashboard,使用Nginx和Tomcat作為服務的網關。其背后有兩套系統——CPMS和API server,CPMS主要管理持續集成的各個流程,API server主要管理應用部署,在CPMS背后是使用多個Jenkins server統一連到一個Kubernetes集群上產生Pod作為Jenkins slave去運行,不同的構建有多種語言也有不同的模板,這里會提供各種方案讓不同的Jenkins Pipeline運行在不同的Kubernetes node里面。
在部署實現一個Cloud Framework,可以接入各種cloud provider,目前使用的是k8s provider,背后的服務發現也是k8s推薦使用的Skydns。為了兼容公司基于包發布的這樣一套模式,鏡像管理這部分會把包管理系統Cider接入進入,平臺的Docker Registry,以及應公司安全方面的要求,通過Clair對鏡像的內容進行檢查。
在日志收集方面,使用fluentd+ELK的組合,采用Prometheus做監控。在PaaS架構里,安全是通過接入公司的CAS做認證的動作,有一個Oauth組件做鑒權機制,通過Gnats做消息傳輸的系統。配額的問題在構建和部署中都會有所體現,包括用戶對于Pipeline的個數控制或者Pipeline觸發的個數,以及對應用上的物理配額或者邏輯資源配額等。
Docker Registry改造,主要在Middleware做了一些工作,做了一個接入公司的CAS和Oauth做的驗證和授權。也接入了當有新的鏡像Push進來的時候,會自動觸發應用的部署。Docker Registry本身對所有的repository不同的tag索引還是比較慢的,所以會針對push進來所有的鏡像信息存入數據庫做一個索引,方便查找鏡像。用戶行為記錄主要針對pull和push的動作,把它記錄下來。鏡像安全通過接入Clair做掃描,push鏡像layer完成之后在push鏡像的manifest時,會將鏡像layer信息發送到Clair做鏡像的安全掃描。
原來的Jenkins Kubernetes Plugin,默認把Jenkins slave調度在所有Kubernetes node上,我們做了一個node selecter,針對不同的Pipeline類型,需要跑在不同的節點上。調度上加入了node selecter,此外在每個Pipeline要去run的時候申請資源,加入了資源的request limit,防止單個的Pipeline在運行的時候占用過多的資源,導致其他的應用或者是構建任務受影響。在掛載方面,像傳統的maven項目在下載過一個包之后,如果是同一個主機上會把.m2文件會掛載在主機上,不同的Jenkins Pool在跑的時候,可以共享已經下載過的資源文件。
最后,實現了Container slave pool的策略。當要run一個Pipeline的時候,每次告訴k8s要起一個Jenkins slave Pod,當需要執行一個job的時候,等待時間比較長,這里會定一個池的策略,就是一個預先準備的過程,當有一個新的任務要run的時候,立刻就可以拿到一個可用的containerslave。
這是PaaS的功能點,包含三個主要的部分,構建,部署和測試集。構建是關于用戶定義Pipeline以及對Pipeline觸發的record的管理,以及Pipeline各個phase的管理。部署主要對應用配置的管理,這個應用包括服務的配置如何、資源的申請如何,以及應用實例的一些管理。測試集對接公司的集成測試環境,和平臺的應用進行關聯。
空間管理和鏡像管理,空間主要提供不同的隔離空間,提供應用快速的復制,比如你有一個測試環境,我也有一個測試環境,為了大家環境之間相互不干擾可以提供應用的快速復制。鏡像管理主要分三種,即平臺提供的基礎鏡像,業務部門一些特殊的需求會基于基礎鏡像做一些定制,以及具體業務鏡像。
PaaS網絡方案和定制PaaS采用的網絡方案,網絡方案最開始直接使用的k8s 1.0的版本加flannel的一套工作模式,后來由于業務需求,用戶需求能夠直接訪問到實例IP,而flannel當時是封閉的子網。目前采用Contiv這套網絡模式,由公司統一分配Pod的IP網段。這里做了一個kube-HAProxy,替換了節點上kube-proxy這個組件,用kube-HAProxy來做Service IP到end point的一個轉發。
在kube2sky,完成域名和服務IP的注冊。傳統的模式下,域名是短域名,Service的名字作為短域名,還有Service本身的IP會注冊到Skydns上。這里做了一些定制,因為公司的應用比如兩個業務域A和B都有本身的域名——a.vip.com和b.vip.com,A如果要訪問B,不能讓這個訪問跑到線上或者其他環境去,于是通過kube-sky去解析規則,把b.vip.com加入到里面,再加一個subdomain作為擴展的domain search,最終找到平臺內部部署的B域。
goroute 主要是平臺內部的應用,每個應用都會提供一個平臺的域名,這個域名主要是有一個組件叫做state aggregator,會watch k8s apiserver發出來的Service和end point的變化,最終通過Service的名字和end point的地址,把它寫到gorouter的route注冊表信息中,當我們訪問平臺域名時就可以找到真正的end point地址。這里也有定制,采用HAproxy和KeepAlived替換了kube-proxy,之前從Service IP到end point IP的轉化,通過每個節點部署的kube-proxy,它會檢測到 Service和end point的變化,去寫IPtables的規則,來找到最終end point的地址的IP。
現在統一使用的HAproxy加上KeepAlived,有一個kube2HAproxy組件,功能和kube-proxy前面一部分相似,都要watch kube-apiserver的Service和 end point的event來動態的生成一個HAproxy最新的配置。KeepAlived主要為了高可用。有一個值得注意的細節,kube2HAproxy所在機器的IP,要和Service IP的網段在同一個網段里,用戶在訪問真正的應用的時候直接使用Service IP是公共可見的,而不是隨便定義的Service IP。
對外應用訪問是由平臺提供的域名,后綴均為*.PaaS.vip.com,解析到之后會有公司的DNS統一轉發到gorouter這臺機器上,因為gorouter會監聽到Service和end point的變化,route表里面會存儲每個域名對應的end point的地址,通過round robin的方式找到最終的Pod來完成http訪問。
最后一個定制關于Pod的IP固定,為什么要做PodIP固定?因為之前的測試環境很多應用都是部署在VM甚至在物理機上,IP都是固定的,有一些應用是需要白名單訪問的,應用在這個部署機上,需要將IP提供給相應的調用方或者是公司的某個部門來告訴他加入白名單。Docker 默認情況下,每次銷毀和重建的過程中,IP都會隨機申請和釋放,所以IP有可能變化。IP固定主要在k8s apiserver做,加了兩個對象,即Pod IP Allocator和IP recycler,Pod IP Allocator是一個大的Pod的網段,可以認為它是Pod的IP池, IP recycler主要記錄一些臨時回收的IP,或者叫臨時暫存區,IP不是一直存在,否則是一種IP浪費,有一個TTL時效性的。
當應用重新部署的時候,原本的Pod會被刪掉,刪掉的過程中會先放在IP recycler中,當一個新的Pod啟動的時候,會通過namespace+RC name的規則去找是否有可用的IP,如果找到優先用這樣的IP記錄在Pod里,這個Pod對象最終會交由kubelet去啟動,kubelet 啟動的時候會讀取這個Pod IP,然后告訴Docker 啟動的IP是什么。最終有新的Pod啟動之后,它的IP是之前已經被銷毀的Pod IP,達到的效果就是Pod IP固定。在kubelet因為修改了Pod對象的結構,增加了Pod IP記錄使用IP的情況,根據Pod的IP告訴Docker run的時候執行剛剛的IP來啟動。kubelet 在刪除Pod的時候會告訴k8s去release這個IP。
日志收集和監控日志收集主要分三種類型:首先是平臺自身的服務組件的收集,比如像jenkins、Docker 或者Kubernetes 相關組件的日志收集,另一個是所有部署在平臺里面應用的收集,最后還有一些域,因為公司一些已有系統(dragonfly)也是做日志收集和監控的,有一些特定的規則對接公司。
平臺自身日志收集的規則,包含系統組件還有平臺應用兩種設計。系統組件比較簡單,無外乎通過systemd或者是指定日志文件的路徑做日志的收集,應用收集主要在k8snode上,k8s會把每一個Pod日志link在一個特定的文件路徑下,因為Docker會記錄每一個容器的日志,可以從這個地方讀取應用的日志,但是只拿到namespace和Pod name這樣的結構,我們會通過fluentd里的filter反向去k8s拿Pod所對應的meta data,最終發送到kafka,通過logstash達到elastic search。
Kibana的展現做了一些定制,因為平臺的展現主要基于namespace和應用名稱的概念查看日志的,定制能夠展現特定的namespace下的特定應用的日志,同時把自定義的告警加在了這里,因為告警是通過elastalert來做的,在Kibana上做一個自定義告警的UI入口,由用戶來指定想要監聽什么樣的日志內容的告警,去配置監聽的間隔或者出現的次數,以及最終的郵件接收人。
有一個組件是當用戶創建了自定義告警的規則時會發送到后面的elastalert ruler,ruler解析前臺UI的信息,生成elastalert能夠識別的configure文件,動態地讀取configure的加入。
對接公司的業務系統比較簡單,特定的收集規則都是特定的,比如具體的目錄規則,一般來講都是通過掛載容器的目錄到主機目錄上,在主機上統一部署一個agent去run,主要體現在k8s node上,所以仍然使用Daemonset的方式去跑agent。
監控有兩種,一種是對單個Pod的實例監控,在頁面上是可以直接看這樣的實例的,單個Pod是一個應用實例了,然后通過node agent去包裝了cAdviser,前端去統一訪問,獲取對應的CPU和Memory使用信息。cAdviser對Network收集到的數據是不正確的,通過node agent 讀取Linux file獲取Network的信息。Websocket Server 是為了提供網頁上直接對容器進行網頁控制臺的登錄。
另一個是看整個的應用,因為應用是有多個實例的,通過Graphana去定制,去展現namespace的應用,有多個實例,就把多個實例的監控都展現出來。此處有一個promethus plugin的定制,之前有一些Swarm的節點加入,持續部署提到過它是一個多個cloud framework都可以接入的。唯品會接入了一些Swarm的信息,針對Swarm創建的容器的話,也要能夠監控到它的容器監控信息的數據。在Promethus plugin通過Docker info獲取不同的Swarm node的信息,在每個Swarm node上部署cAdviser,獲取由Swarm創建的容器的監控信息。
問題總結遇到的問題非常多,到現在為止將近兩年的時間,有很多都是可以在GitHub找到的問題,以及通過升級可以解決的問題。最開始采用的是Docker 1.6以及Kubernetes 1.0,中間經歷兩次的升級,現在主要使用Docker 1.10和Kubernetes 1.2。
Devicemapper loopback 性能問題production使用direct-lvm做Devicemapper存儲。
Pod實例處于 pending狀態無法刪除目前發現一些Pod一直處于pending的狀態,使用kubectl或者Kubernetes API沒有辦法直接對Pod做任何操作,目前只能通過手動Docker的方式刪除容器。
k8s 僵死容器太多,占用太多空間k8s僵死容器是以前碰到的問題,現在最新版的Kubelet是支持這樣的參數,允許每一個節點上最大僵死容器個數,交由Kubelet自己做清理的工作。
Kubernetes1.1.4上ResourceQuota更新比較慢因為以前發現用戶來告訴配額不足的時候,調整配額并不會立馬的生效,升級以后就沒有這種問題了。
k8s batch job 正常退出會不斷重啟這個是應用的問題,不是傳統理解的跑一次性任務,k8s batch job要求一定要exit 0。也有一些Job的類型,目前是直接對應的背后k8s的Pod方式。
Skydns ping get wrong IP這是最新遇到的問題,上下文的話,稍微有一點復雜,有兩個應用部署在唯品會的平臺上,每個應用都有自己的legacy域名,比如有一個域名叫user.vip.com,另一個叫info.user.vip.com,這時候ping user.vip.com,有可能會拿到info.user.vip.com的IP,由于kube-sky本身在寫Skydns record時候有問題,所以會添加一個group做一個唯一性的識別,這樣在ping子域名(user.vip.com)的時候就不會讀到info.user.vip.com。Skydns本身目錄結構的問題,加上group就不會再去讀到下面的子路徑。
Overlayfs issue: can’t doing mv operation唯品會一直使用Devicemapper,中間嘗試一些節點用Overlayfs的存儲,但是在目錄操作時會file not found,官方也有一個issue說當Overlayfs 在不同的layer的時候,牽扯到刪除的操作,會出現這個問題。可以升級解決,但是系統是固定的,升級很麻煩,所以沒有做升級而是切回了Devicemapper。
Devicemapper空間滿,需要改造cAdvisor監控容器空間使用由于容器占用的磁盤空間過多,導致了整個k8s node的磁盤空間被占滿的問題,唯品會是在Cadviser做一些改造,可以監控到每一個容器所占用的磁盤空間,對磁盤空間做一些限制。
Kubernetes namespaces stuck in terminating state在刪除一個namespace的時候,namespace是可以動態創建和刪除的,在刪除的時候會看到namespace一直處于terminating的狀態,這個在GitHub上有一些解決方法,因為它本身是由于namespace的finalizer會進入一個死循環,有一個work around,可以手動的置空finalizer,把這個namespace update回去,就可以正常刪除了。
以上就是我要分享的主要內容,謝謝大家。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/32546.html
摘要:正在走遠,新年之初,小數精選過去一年閱讀量居高的技術干貨,從容器到微服務云原生,匯集成篇精華集錦,充分反映了這一年的技術熱點走向。此文值得收藏,方便隨時搜索和查看。,小數將繼續陪伴大家,為朋友們奉獻更有逼格的技術內容。 2017正在走遠,新年之初,小數精選過去一年閱讀量居高的技術干貨,從容器、K8S 到微服務、云原生、Service Mesh,匯集成52篇精華集錦,充分反映了這一年的技...
摘要:平臺上的微服務架構應用再來看一下我眼中的基于當前最流行的微服務架構的設計是什么樣的,即我們平臺上要運行的典型應用是什么樣的。 showImg(https://segmentfault.com/img/remote/1460000010900878); 8月19日的數人云Container Meetup上,張龍老師做了《基于Kubernetes的PaaS平臺的設計和思考》的精彩分享,分別...
摘要:王磊此次演講的題目為容器新技術架構下的運維實踐,詳細為大家講解了在基于構建容器的過程中,如何以應用為中心,通過新的技術工具對服務節點集群平臺等多個方面進行管理運維,提高系統的自動化運維能力。 2018年11月16-17日,運維&容器技術盛會 CNUTCon 全球運維技術大會在上海·光大會展中心成功舉辦。時速云聯合創始人兼 CTO 王磊受邀參加此次大會,并發表主題演講。王磊此次演講的題目...
摘要:月日至日,高可用架構和聯合主辦的全球互聯網架構大會將于上海光大會展中心舉行。全球互聯網架構大會是高可用架構技術社區推廣的面向架構師技術負責人及高端技術從業人員的技術架構大會。本次大會共有大板塊方向,場技術專題,個互聯網架構案例。 showImg(https://segmentfault.com/img/bVZ3Vh?w=600&h=375);12月22日至23日,高可用架構和msup聯...
摘要:月日至日,高可用架構和聯合主辦的全球互聯網架構大會將于上海光大會展中心舉行。全球互聯網架構大會是高可用架構技術社區推廣的面向架構師技術負責人及高端技術從業人員的技術架構大會。本次大會共有大板塊方向,場技術專題,個互聯網架構案例。 showImg(https://segmentfault.com/img/bVZ3Vh?w=600&h=375);12月22日至23日,高可用架構和msup聯...
閱讀 2104·2021-11-23 10:06
閱讀 3456·2021-11-11 16:54
閱讀 3336·2019-08-29 17:31
閱讀 3563·2019-08-29 17:05
閱讀 2165·2019-08-26 13:36
閱讀 2154·2019-08-26 12:17
閱讀 519·2019-08-26 12:12
閱讀 1668·2019-08-26 10:19