文/邵珂 蔡國華 萬國雷
中國搜索kubernetes應用平臺項目是一個PaaS服務平臺,以kubernetes為應用基礎,整合項目管理系統、CMDB管理系統以及CI/CD的整體運營平臺,目的是為向用戶提供一個Docker應用的統一管理平臺,統一分配、管理資源。將kubernetes的資源管理接口封裝為應用功能,實現可視化web管理,極大地降低了kubernetes的使用門檻。我們還計劃逐步完善平臺內的應用生態環境,提供豐富的組件及接口供用戶調用。平臺自2018年7月開始研發,10月投入上線,并持續迭代開發新版本。目前,應用平臺支持并提供跨網段計算節點、flannel、calico網絡、萬兆網絡分布式存儲等資源,已有數十個項目在平臺上穩定運行。
Kubernetes是Google基于Borg開源的容器編排調度引擎,作為CNCF(Cloud Native Computing Foundation)最重要的組件之一,它的目標不僅僅是一個編排系統,而且提供一個規范,可以讓你描述集群的架構,定義服務的最終狀態,Kubernetes可以幫你將系統自動地達到和維持在這個狀態。Kubernetes作為云原生應用的基石,相當于一個云操作系統。Kubernetes設計理念和功能其實就是一個類似Linux的分層架構,如下圖所示。

圖1 kubernetes分層設計理念
核心層:Kubernetes最核心的功能是,對外提供API構建高層的應用,對內提供插件式應用執行環境。
應用層:部署(無狀態應用、有狀態應用、批處理任務、集群應用等)和路由(服務發現、DNS解析等)、Service Mesh(部分位于應用層)。
管理層:系統度量(如基礎設施、容器和網絡的度量),自動化(如自動擴展、動態Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)、Service Mesh(部分位于管理層)。
接口層:kubectl命令行工具、客戶端SDK以及集群聯邦。
生態系統:在接口層之上的龐大容器集群管理調度的生態系統,可以劃分為兩個范疇。
Kubernetes外部:日志、監控、配置管理、CI/CD。
Kubernetes內部:CRI(容器運行接口)、CNI(容器網絡接口)、CSI、(容器服務接口)、鏡像倉庫、集群自身的配置和管理等。
高可用集群所需節點配置如下。

角色 數量 描述etcd節點 3 為kubernetes提供配置管理數據庫,要求較高穩定性master節點 2 Kubernetes控制節點,可與etcd節點重用,HA+主備模式,要求較高穩定性node節點 20-100運行應用負載的節點,可根據需要提升機器配置或增加節點數。要求CPU 24核以上,物理內存64G以上網絡分布式存儲服務的節點,部署GlusterFS集群服務,可根據需要擴容節點。要求較高穩定性,萬兆網絡、大硬盤Harbor服務 2 私有鏡像倉庫服務,HA+主備模式,要求較高穩定性存儲節點 10-20
所有服務器被分為三大部分:一部分為master服務;另一部分為node服務;還有一部分為存儲服務。其中,master服務器因需要實現LB,需要在同一網段,存儲服務器因考慮到效率和穩定性,也需要在同一網段且最好是萬兆網絡。節點服務器對網絡依賴不高,各服務器間路由可達即可。集群全部服務器操作系統均可采用centos7.4版本,鏡像yum源要求centos和epel,各節點時區設置一致、時間同步。
Master架構包含etcd集群和kubernetes master服務組件。kuberntes 系統使用 etcd 存儲所有數據,是最重要的組件之一,為保證安全性,etcd 需要安裝服務器證書,也需要安裝客戶端證書。

圖2 kubernetes master服務架構

圖3 kubernetes node服務架構
master節點主要包含三個組件:apiserver、scheduler controller-manager。其中:
apiserver提供集群管理的REST API接口,包括認證授權、數據校驗以及集群狀態變更等。
只有API Server才直接操作etcd,其他模塊通過API Server查詢或修改數據,提供其他模塊之間的數據交互和通信的樞紐。
scheduler負責分配調度Pod到集群內的node節點,監聽kube-apiserver,查詢還未分配Node的Pod,根據調度策略為這些Pod分配節點。
controller-manager由一系列的控制器組成,它通過apiserver監控整個集群的狀態,并確保集群處于預期的工作狀態。
master節點的高可用主要就是實現apiserver組件的高可用,通過部署配置haproxy對apiserver進行負載均衡。
節點服務器主要包含docker服務、kuber-node組件。
3.2.1 Docker
docker 從 1.13 版本開始,將 iptables 的 filter 表的FORWARD 鏈的默認策略設置為DROP,從而導致 ping其他 Node 上的 Pod IP 失敗,因此,必須在 filter 表的FORWARD 鏈增加一條默認允許規則 iptables -I FORWARD-s 0.0.0.0/0 -j ACCEPT。
docker鏡像倉庫使用國搜內部私有倉庫 https://reg.docker.chinaso365.com,可配置在 /etc/docker/daemon.json,替換docker的默認倉庫。
3.2.2 Kube-node
kube-node 是集群中承載應用的節點,前置條件需要先部署好kube-master節點(因為需要操作用戶角色綁定、批準kubelet TLS 證書請求等),它需要部署如下組件。
docker:運行容器。
calico: 配置容器網絡。
kubelet: kube-node上最主要的組件。kube-proxy: 發布應用服務與負載均衡。
Kubernetes基于CNI driver 調用各種網絡插件來配置kubernetes的網絡,常用的CNI插件有 flannel、calico、weave等,這些插件各有優勢,也在互相借鑒學習優點。比如,在所有node節點都在一個二層網絡時候,flannel提供hostgw實現,避免vxlan實現的udp封裝開銷;calico針對L3 Fabric推出了IPinIP的選項,利用了GRE隧道封裝。結合我們的業務需求,采用calico網絡組建方案。

圖4 calico組網示意
Calico是一個基于BGP的純三層的數據中心網絡方案(不需要 Overlay),并且與 OpenStack、Kubernetes、AWS、GCE 等 IaaS 和容器平臺都有良好的集成。
Calico 在每一個計算節點利用 Linux Kernel 實現了一個高效的 vRouter 負責數據轉發,而每個 vRouter 通過BGP 協議負責把自己上運行的 workload 的路由信息向整個 Calico 網絡內傳播——小規模部署可以直接互聯,大規模下可通過指定的 BGP route reflector 來完成。 這樣保證最終所有的 workload 之間的數據流量都是通過 IP 路由的方式完成互聯。Calico 節點組網可以直接利用數據中心的網絡結構(無論是 L2 或者 L3),不需要額外的NAT、隧道或者 Overlay Network。
此外,Calico 基于 iptables 還提供了豐富而靈活的網絡 Policy,保證通過各個節點上的 ACLs 提供 Workload 的多租戶隔離、安全組以及其他可達性限制等功能。
GlusterFS是kubernetes私有化部署方案中的最優存儲解決方案,它是一個開源的分布式文件系統,具有強大的橫向擴展能力,通過擴展能夠支持數PB存儲容量和處理數千客戶端。GlusterFS借助TCP/IP或InfiniBand RDMA網絡將物理分布的存儲資源聚集在一起,使用單一全局命名空間來管理數據。GlusterFS基于可堆疊的用戶空間設計,可為各種不同的數據負載提供優異的性能。
我們建議采用分散卷的方式,通過指定冗余塊的數量(3:1)達到高可用,同時可提供性價比最優的IO吞吐量和網絡性能。
性能測試,在萬兆網絡環境下,IO約為本地磁盤IO性能的30%,千兆網絡環境下對比,接近阿里云NAS服務性能的2倍。
測試數據如下:

萬兆環境 655360 bytes(655 kB)copied, 0.00240202 s, 273 MB/s千兆環境 655360 bytes(655 kB)copied, 0.0103234 s, 63.5 MB/s本地磁盤 655360 bytes(655 kB)copied, 0.000753129 s, 870 MB/s阿里云NFS 655360 bytes(655 kB)copied, 0.0177044 s, 37.0 MB/s
3.5.1 集群部署
部署方式:ansible統一部署管理工具,可實現etcd服務、docker服務、master節點、node節點、集群網絡、證書全自動安裝。
集群管理:ansible統一部署管理工具,可實現node節點增、刪,master節點增加/替換,etcd節點增加/替換,集群升級,備份恢復。
3.5.2 主要軟件及版本

Docker v18.06.1-ce Kubernetes v1.13 Etcd v3.2.24 Calico v3.4.1 Coredns v1.2.6 Glusterfs v4.1.5
3.5.3 Iptables/IPVS
因為calico網絡、kube-proxy等大量使用 iptables規則,安裝前清空所有iptables策略規則;CentOS的firewalld等基于iptables的防火墻直接卸載,避免不必要的沖突。
kube-proxy 組件監聽 API server 中 service 和 endpoint的變化情況,從而為 k8s 集群內部的 service 提供動態負載均衡。kubernetes在v1.10之前主要通過 iptables實現,是穩定、推薦的方式,但在當服務多的時候會產生太多的 iptables 規則,大規模情況下有明顯的性能問題;在v1.11 GA的 ipvs高性能負載模式,采用增量式更新,并可以保證 service 更新期間連接的保持。
3.5.4 Add-ones
DNS 是kubernetes集群首先需要部署的,集群中的其他 pods 使用它提供域名解析服務;主要可以解析 集群服務名 SVC 和 Pod hostname;目前, k8s v1.9+ 版本可以有兩個選擇:kube-dns 和 coredns,可以選擇其中一個部署安裝。
Ingress就是從外部訪問k8s集群的入口,將用戶的URL請求轉發到不同的service上。ingress相當于nginx反向代理服務器,它包括的規則定義就是URL的路由信息;它的實現需要部署Ingress controller(比如 traefik ingress-nginx 等 ),Ingress controller通 過 apiserver監 聽ingress和service的變化,并根據規則配置負載均衡并提供訪問入口,起到服務發現的作用。
Heapster 監控整個集群資源的過程:首先,kubelet內置的cAdvisor收集本node節點的容器資源占用情況;然后,heapster從kubelet提供的api采集節點和容器的資源占用;最后,heapster 持久化數據存儲到influxdb中。
EFG 插件是kubernetes項目的一個日志解決方案,它 包 括 三 個 組 件:Elasticsearch、Fluentd、 Grafana。Elasticsearch是日志存儲和日志搜索引擎;Fluentd 負責把kubernetes集群的日志發送給Elasticsearch;Grafana則是可視化界面查看和檢索存儲在 Elasticsearch 的數據。
3.5.6 集群升級
集群升級存在一定風險,升級前對 etcd數據做備份。快速升級是指只升級kubernetes版本,比較常見,如Bug修復,重要特性發布時使用。快速升級可平滑實現,不會對業務產生中斷。
其他升級是指升級kubernetes組件,包括etcd版本、docker版本,需制定詳細的升級方案和可能的業務中斷方案。
中國搜索kubernetes應用平臺是用于管理數據中心主機集群上的容器化的應用平臺,是提升服務器性能利用率、高效部署與彈性計算、高冗余和定制化的PaaS服務平臺。該平臺的目標是讓部署容器化的應用簡單和高效。
持續部署:平臺實現快速、可視化自動部署功能。彈性伸縮:構建具有需求預測和容器按需供給能力的彈性伸縮子系統。
組件管理:將一個應用涉及的所有組件均做了統一管理。
高可靠性:自動的故障遷移,達到秒級啟動,恢復業務。
生態衍生:將可標準化的應用轉變為模塊化服務,形成應用生態圈。

圖5 中國搜索kubernetes應用平臺-儀表盤(一)

圖6 中國搜索kubernetes應用平臺-儀表盤(二)
在kubernetes集群高效管理的基礎上,我們實現了對整體應用情況進行統計分析,相對于傳統的物理層監控,應用平臺實現了按項目按應用獲取、分析、展示資源分配情況、服務健康狀態、應用飽和度等應用層面的監控。
通過集群節點狀態監控和管理,查看集群服務器運行狀態,幫助管理人員實時了解整體情況,及時發現、排查故障隱患。
Kubernetes應用平臺采用按項目分配和管理資源及應用的模式,更貼近于常規的運營管理思路,用戶按項目為單位在平臺上申請權限,獲取服務所需資源,包括CPU使用量配額、內存使用量配額、存儲使用量配額。項目與項目之間相互隔離,并可添加私有鏡像倉庫認證、kube-api接口調用認證等訪問控制。
項目管理模式實際對應了kubernetes中的namespace,命名空間是一種在多個用戶之間劃分群集資源的方法(通過資源配額),旨在用于多個用戶分布在多個團隊或項目中的環境中。
命名空間提供名稱范圍。資源名稱在名稱空間中必須是唯一的,而不是跨名稱空間。在Kubernetes中,在默認情況下,同一名稱空間中的對象將具有相同的訪問控制策略。
平臺支持項目成員管理,在項目管理中可定義多種角色,在命名空間的基礎上補充擴展了kubernetes對應用管理權限的管理機制。
項目管理員,擁有對項目資源的申請和修改權限。項目負責人,擁有對項目應用的信息修改權限。項目成員,擁有對項目應用的訪問和控制權限。
應用服務管理模塊,統一管理項目下的所有應用,是應用配置和訪問的入口。包括創建應用服務、查看應用狀態,獲取應用服務信息。
平臺應用服務,即對應調度kubernetes中的POD服務,是一組一個或多個容器(Docker容器)化實例,具有共享存儲/網絡,以及如何運行容器的規范。pod的內容始終位于同一位置并共同調度,并在共享上下文中運行。pod模擬特定于應用程序的“邏輯主機” ,它包含一個或多個相對緊密耦合的應用程序容器。
通過平臺提供的應用管理功能,我們可以對kubernetes上運行的應用進行標準化的快速配置和應用。通過應用編排實現kubernetes應用邏輯的自動配置,通過配置管理實現configmap定義或更新,通過任務管理來啟動、升級、回滾或停止應用服務,還可通過應用監控實時調用查看應用監控和運行日志。
除了kubernetes默認收集的docker運行日志外,平臺還支持用戶自定義應用日志的采集,即應用產生的日志文件。通過平臺的應用日志收集模塊配置分配日志收集服務至項目下,并自動關聯項目下應用的存儲服務來上傳日志。支持多日志格式解析、分類索引配置、自定義索引格式、自定義日志保存時間等。
平臺支持通過kubernetes api訪問每個應用容器,即通過web終端進入容器內,進行命令行操作,幫助對應用的直觀運行控制。容器終端的訪問經kubernetes api的訪問控制及應用平臺的權限控制,同時具備高安全性和便捷性。
有狀態服務是相對無狀態服務的一種kubernetes應用部署模式,平臺支持無狀態應用和有狀態應用模式兩種應用。使用有狀態應用部署模式,應用中的每個POD都擁有獨立分配且固定的SVCIP地址及存儲空間,如果容器重啟或漂移,它們所使用的資源將不變,使虛擬化更接近于物理層設備。通過有狀態應用的模式可在kubernetes中實現組建運行,如redis、kafka、MongoDB等集群模式服務。
平臺提供應用備份和復制功能,快速解決應用的重復部署或多環境部署需求。通過應用復制,可快速創建測試環境、預發布環境、生產環境的同步,或者快速部署相同應用需求的組件服務。
平臺通過域名配置實現kubernetes外部訪問應用,通過調用kubernetes接口實現Ingress配置,提供應用對外服務的出口。通過自定義域名接入內部服務,支持自定義域名配置、路徑配置,支持http和tcp兩種模式。
Kubernetes平臺下運行的應用服務會存在一些在不同的應用間互相調用或狀態控制的情況。基于容器間隔離的機制,我們采用API實現遠程調用,在kubernetes應用平臺已封裝好一套第三方接口服務,滿足項目內部的應用間互訪需求。平臺提供一套統一的客戶端SDK來滿足Java、Python工程項目的此類需求。調用流程如下。
容器a通過調用SDK請求在容器b上執行命令,SDK實現步驟如下:
(1)容器a調用SDK,請求參數包括項目私有access key和命令行;
(2)SDK調用Project token接口鑒權,返回鑒權結果,成功返回token,失敗返回錯誤代碼;
(3)SDK攜帶token請求kubernetes API,調用接口執行操作命令;
(4)Kubernetes API在容器b上順序執行操作命令,并異步返回結果給SDK;
(5)SDK將執行結果異步返回給容器a上的應用。