Kubernetes 一键部署实践
生活随笔
收集整理的這篇文章主要介紹了
Kubernetes 一键部署实践
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
很多人在實際工作中都使用過Kubernetes,我們的容器服務在2016年年底開始提供全托管的Kubernetes服務,主要提供了四個方面的功能。首先是提供了一鍵部署的Kubernetes,與其他容器服務的提供商不一樣,我們的Kubernetes是完全隔離的,每個用戶都會獨享所有的計算節點和控制節點,集群網絡也在用戶自己的VPC中。我們在這個基礎上提供了集群的全生命周期管理,包括集群的創建、銷毀,還有計算節點的添加、刪除,還有一些類似Kubernetes原有組件的初始化以及證書的初始化工作。為了大家更方便地使用Kubernetes,我們在控制臺包裝了一些界面,使大家可以通過可視化的方式創建一些負載來暴露自己的服務,避免了大家手工編碼的煩瑣。第三,我們提供了周邊的監控能力,包括集群本身Pod內存的使用率以及一些Kubernetes事件。這些能力都與騰訊云的云監控產品進行了打通,大家可以直接在云監控產品界面使用這些能力。為了方便大家將自己的一些比較傳統的應用部署到云上,我們在Kubernetes集群之外還提供了Docker鏡像倉庫、TencentHub、CICD的功能,為大家提供了一站式應用的云解決方案。
我今天所講的內容,一方面是介紹Kubernetes相關的知識,另一方面是介紹如何將Kubernetes和騰訊云進行集成。首先帶大家了解一下Kubernetes集群需要哪些組件,將Kubernetes部署好之后還要做什么工作使它正常運行。之后會介紹云上Kubernetes上的網絡存儲和日志與監控,這是將Kubernetes和騰訊云集成時進行的工作。最后介紹Kubernetes的兩種部署方案,一種是容器服務產品發展早期所采用的一種基于CVM的方案,另一種是最近逐漸部署的使用Kubernetes集群來管理Kubernetes集群組件的方案。
隨著容器服務產品以及Kubernetes社區的發展,在我們提供托管的CCS服務通過了CNCF的Kubernetes一致性驗證之后,為了大家更好地認知騰訊的容器服務產品,產品的名字從之前的CCS正式改名為TKE。
第二個組件Kube-controller-manager主要負責將聲明的一些工作負載在實際的集群中運行起來,舉個最簡單的例子,當我們在Kubernetes上創建了一個Deployment之后,Kube-controller-manager就會去創建相應的Replicaset、Pod這些。根據需求將Pod創建出來,在創建Pod后,Kube-scheduler負責對這些Pod進行調度,比如這個Pod實際應該被運行在哪臺機器,比如GPU的結點做這樣的調度工作。當一個集群的Master組件被完全部署好之后,我們會部署一些Node。
在它的上面部署兩個組件,一個是kubelet,負責在這些Node上創建出來我們需要的Pod。另一個是kube-proxy,它在集群中負責的工作是:當一個deployment需要以服務的形式對外暴露的時候,Kude-proxy會負責配置這些iptables規則,讓集群內不管是宿主機上的程序還是容器里的程序,都能夠按照Service的名字去做一個自動的發現和訪問。
在Kubernetes這些標準化的組件之外,我們還提供了額外的組件,主要給大家介紹一下。包括三個,一個是hpa-metrics-server,它是我們為了使用Kubernetes提供本身的Pod橫向擴展控制器而去自研的一個組件,這個組件相比于Kubernetes社區方案的優點,是Kubernetes社區方案只提供了基于CPU和內存的擴展,而我們在這個基礎上更加拓展了Pod的入帶寬和出帶寬的指標,方便大家去適應更多的擴縮容場景。第二個組件是cbs-provisioner,這個組件提供了去讓Kubernetes里面的Pod去消費我們騰訊云一個叫做Cbs塊存儲服務,我們后面會詳細講到。第三是Ccs-log-collector,這個組件主要是負責收集容器里Pod運行的日志,后面也會講到。
容器網絡
總的來說,它實現了Node和container之間的扁平化網絡。同時為了應對服務發現的需求,降低網絡復雜度,還要求不能使用NAT。Kubernetes并沒有內置的網絡解決方案,所以在社區其實有很多不同的解決方案,例如flannel,它是通過Tun/tap設備,再通過內核用戶態的轉化程序,實現一個類似于overlay的網絡能力。Callco不需要進行overlay封裝,直接通過路由的方案可以完成Kubernetes的網絡需求。
接下來為大家介紹一下騰訊云Kubernetes使用的方案,我們的網絡方案主要是直接使用了VPC提供的路由能力,叫做global route。簡單介紹一下Kubernetes結點加入到一個集群中配置網絡的過程,當我們將一個結點加到集群中的時候,Kubernetes的Kube-controller-manager會為這個結點分配一個網端。
例如,集群網絡是172.16.1.0/16掩碼,這時加進去一個結點。按照我們的邏輯,我們會給它賦172.16.1.0/24位掩碼的CIDR。也就是所有在這個主機上創建的Pod,它的ID都在這個CIDR的范圍內。然后我們會去VPC那里做一個動作,將172.16.1.0/24掩碼到目的地址的流量去注冊一條路由規則,使所有的包都發往被賦予這個Pod CIDR的主機。這樣我們就可以完成之前提到的Pod和Node之間的扁平化網絡。
具體過程如下:假設現在有一個位于172.16.1.0/24網端機上的Pod,向另一個機器的Pod發送了這樣一個包,這個包首先從容器出來,到cbr0 bridge然后出了主機。這時就會進入VPC的路由表進行匹配,當它發現這個Pod的目的IP在172.16.2.0/24時,這個包就會被VPC轉發到10.1.1.3,這樣我們就可以完成一個Pod的跨主機通信。Pod在本地的通信比較簡單,這里就不多講了。通過這種方式,我們實現了一個Pod和Node之間的扁平化網絡,這里Docker的網絡模式是用的bridge模式,Pod IP直接由cni插件進行分配。
容器存儲
也就是說,實際去創建一個云盤,當云盤創建好之后會做一個Attach的動作,相當于把剛剛創建好的云盤插到對應主機上,這時,主機上的Kubelet會做一個mount動作,也就是將插進來的這個設備去mount到一個Kubernetes指定的目錄,Kubelet在創建這個Pod的時候,通過mount的形式把mount到的目錄實際掛載到容器的namespace里面。然后當我們這個Pod銷毀,這個volume不再被需要的時候,它就反向去執行,先從主機上把對應的塊設備先mount掉,再將它detach掉,相當于把這塊磁盤從主機上拔下來,然后會由Kube-controller-manager根據對應的plugin設置銷毀或者是保留。
Kubernetes目前通過與cloud provider進行volume集成的方面主要是三種。一種是比較早期,所有要和kubernetes進行集成的Volume代碼都需要寫在kubernetes自己的代碼倉庫中。這樣的缺點在于,假設我是一個存儲提供商,我寫的代碼有些bug,這樣不僅影響存儲功能的正常使用,可能也會影響整個集群的穩定性。所以后來為了更好的擴展性和穩定性,Kubernetes提供了一種叫做Flex volume的形式。具體是將mount和umount這兩個形式由Flex volume實現,Flex volume是一個實現了特定接口的二進制文件,實際上在需要mount、amount的時候,Kubelet會執行這個二進制文件,做一個mount、umount的動作。
這種方式其實也有一個問題,在kubernetes的部署環境中,如果要往主機上放一個二進制的動作,看起來不是那么的容器化。另外二進制文件執行的環境也有一定的要求,所以后來Kubernetes提供了第三種方式,也就是利用社區的CSI接口實現了基于CSI的插件。之前由Flex volume這個二進制文件完成的工作全部放到了容器里面,然后通過unix socket的形式,使Kubelet和實現對應功能的插件做一個通信,最后一個mount、umount的動作。我們現在也與騰訊云的CBS塊存儲做了集成,使用第一種方式,這是因為我們在早期使用的就是這種方式。后期我們也會將這部分獨立出來,計劃通過CSI的方式去提供存儲的能力。這部分代碼我們將會開源,但目前這個工作還正在進行中。
主要的實現原理是:我們會在kube-apiserver上注冊一個LogCollector的custom resource definition,里面聲明了我要收集namespaces下面某一個deployment對應的Pod資源。還有另外一個進程就是LogCollector,去監聽Kubernetes apiserver資源,然后去生成對應的Fluentd的配置文件,再通過sighup信號的形式去觸發Fluentd的重載,然后去收集我們想要的日志文件。因為Kubernetes Pod對應的日志文件是存儲在主機的/var/log/containers的路徑規則下來,直接配置Fluentd去收集這個規則,再根據我們的實際需要做一個日志的路由。這樣就可以把不同的日志發往用戶指定的不同后端,比如Kafka或騰訊云的CIS的日志服務。這是我們目前對于日志收集的方案實現。
在監控方面,我們將Kubernetes中Pod的性能信息和云監控做了對接,主要的實現方法是在用戶的每臺kubernete結點上運行一個agent,這個agent在kubelet中內置的cadvisor收集Pod運行的性能信息,然后再到apiserver獲取這些Pod對應的元數據。
我們將這些性能信息和元數據進行打包,再將它上傳到騰訊云的監控服務上。另外,基于騰訊云存儲的監控指標,我們實現了hpa-metrics-server。Kubernetes提供的HPA能力,是它在kube-controller-manager里面實現了horizontal pod autoscaler,它會定期請求hpa metrics server去獲取這個Pod目前的CPU Usage或者是入帶寬、出帶寬這些指標的數量,根據我們的定義,比如當CPU使用率超過80%的時候,我們要去進行擴容。它也會定期拉取數據,比對當前的Pod負載,直接去修改deployment中的replica字段,實現自動擴縮容。目前日志和監控的方案,是將Kubernetes和騰訊云的基礎設施進行對接時候所需要做的一部分工作,也是我們的主要工作。
在這個方案中,我們所有的節點都處于用戶的VPC里面,通過Agent初始化的方式將整個集群部署起來。缺點在于難以管理,因為我們早期是通過SSH直接登錄到客戶的Master結點上進行一些運維操作,對于客戶的Node結點是沒有辦法訪問的。當然,現在也沒有辦法訪問。對于Master的一些運維工作比較困難,因為它沒有辦法去編程化。
將 Kubernetes 組件部署在 Kubernetes 集群中
大家知道etcd其實并不是為了海量數據存儲而服務的,而我們在線上運行了數萬個集群,導致遇到了很多和etcd有關的問題。在這樣的大背景下,我們推出了第二種方案,也就是將Kubernetes部署在Kubernetes里面,通過Kubernetes API去管理Master組件,包括我們剛才提到的apiserver、kube-controller-manager和一些自研的組件。這樣的好處在于,我們不需要再通過SSH的方式,比如當我們需要做一個apiserver的升級或kube-controller-manager的bug修復的情況,我們不需要再通過SSH的方式去每臺機器上進行操作,可以直接通過API Kubernetes提供的deployment的滾動升級的能力來完成這一點。
我們也可以充分利用Kubernetes運維的能力,包括健康檢查和就緒檢查的機制實現故障自愈。基于之前提到的hpa-metrics-server,可以實現apiserver的動態擴容,應對用戶的集群結點有一個大規模的上升或者突然下降的情況,更好地滿足Kubernetes集群里面的結點對于apiserver性能的需求。在這個基礎上,我們還需要解決一個問題:之前基于CVM的部署方案是將所有的組件部署在用戶的VPC里面,如果我們將所有組件部署在kubernetes Master中又要怎么做呢?
我們并不能給每個用戶部署一個Kubernetes集群,然后再跑它的Master,這樣聽起來好像和第一種方案沒有什么區別。所以我們提供了一個專門的Kubernetes集群,在這個集群里面運行著現在線網所有集群的Master,這個集群運行在我們自己的VPC里面,它又要怎么和用戶的VPC結點進行通信呢?我們利用了VPC提供的彈性網卡能力,這個彈性網卡會被直接綁定到運行apiserver的Pod中。大家可以理解為這個Pod既加入了我們用來運行Master組件集群的VPC,又加入了用戶的VPC,也就是一個Pod同時在兩個網絡中,這樣就可以很好的去實現和用戶Node相關的互通。另外在這個基礎上,我們也可以復用之前提到的一些監控和日志設施,更好地去做信息的收集和運維。
值得提到的一點是,這個方案中,我們可以利用一個叫做etcd operator的組件,也就是CoreOS其中的一個組件來為每個集群提供獨立的etcd的部署,這樣就可以解決在集群數量不斷上升的情況下etcd性能吃緊的問題。通過在Kubernetes集群里面部署Kubernetes Master組件,降低了運維的成本。同時也統一了我們做運維工作的方式,我們都是通過Kubernetes的方式進行運維的。有效降低了Master組件的資源消耗,因為之前Master組件是免費提供給客戶的,但有些客戶的集群規模非常大,Master配置也非常高,這時集群的Master存在資源浪費的情況。
文章來源:騰訊云容器團隊。
總結
以上是生活随笔為你收集整理的Kubernetes 一键部署实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: aop实现原理_从宏观的实现原理和设计本
- 下一篇: c语言程序设计k.r,【答题】C语言程序