日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Kubernetes从懵圈到熟练:认证与调度

發(fā)布時間:2023/12/20 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Kubernetes从懵圈到熟练:认证与调度 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

不知道大家有沒有意識到一個現(xiàn)實,就是大部分時候,我們已經(jīng)不像以前一樣,通過命令行,或者可視窗口來使用一個系統(tǒng)了。現(xiàn)在我們上微博、或者網(wǎng)購,操作的其實不是眼前這臺設備,而是一個又一個集群。

通常,這樣的集群擁有成百上千個節(jié)點,每個節(jié)點是一臺物理機或虛擬機。集群一般遠離用戶,坐落在數(shù)據(jù)中心。為了讓這些節(jié)點互相協(xié)作,對外提供一致且高效的服務,集群需要操作系統(tǒng)。Kubernetes就是這樣的操作系統(tǒng)。

比較Kubernetes和單機操作系統(tǒng),Kubernetes相當于內(nèi)核,它負責集群軟硬件資源管理,并對外提供統(tǒng)一的入口,用戶可以通過這個入口來使用集群,和集群溝通。

而運行在集群之上的程序,與普通程序有很大的不同。這樣的程序,是“關在籠子里”的程序。它們從被制作,到被部署,再到被使用,都不尋常。我們只有深挖根源,才能理解其本質。

“關在籠子里”的程序

代碼

我們使用go語言寫了一個簡單的web服務器程序app.go,這個程序監(jiān)聽在2580這個端口。通過http協(xié)議訪問這個服務的根路徑,服務會返回“This is a small app for kubernetes...”字符串。


package mainimport ("github.com/gorilla/mux""log""net/http")func about(w http.ResponseWriter, r *http.Request) {w.Write([]byte("This is a small app for kubernetes...\n"))}func main() {r := mux.NewRouter()r.HandleFunc("/", about)log.Fatal(http.ListenAndServe("0.0.0.0:2580", r))}

使用go build命令編譯這個程序,產(chǎn)生app可執(zhí)行文件。這是一個普通的可執(zhí)行文件,它在操作系統(tǒng)里運行,會依賴系統(tǒng)里的庫文件。


# ldd applinux-vdso.so.1 => (0x00007ffd1f7a3000)libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f554fd4a000)libc.so.6 => /lib64/libc.so.6 (0x00007f554f97d000)/lib64/ld-linux-x86-64.so.2 (0x00007f554ff66000)

“籠子”

為了讓這個程序不依賴于操作系統(tǒng)自身的庫文件,我們需要制作容器鏡像,即隔離的運行環(huán)境。Dockerfile是制作容器鏡像的“菜譜”。我們的菜譜就只有兩個步驟,下載一個centos的基礎鏡像,把app這個可執(zhí)行文件放到鏡像中/usr/local/bin目錄中去。


FROM centosADD app /usr/local/bin

地址

制作好的鏡像存再本地,我們需要把這個鏡像上傳到鏡像倉庫里去。這里的鏡像倉庫,相當于應用商店。我們使用阿里云的鏡像倉庫,上傳之后鏡像地址是:


registry.cn-hangzhou.aliyuncs.com/kube-easy/app:latest

鏡像地址可以拆分成四個部分:倉庫地址/命名空間/鏡像名稱:鏡像版本。顯然,鏡像上邊的鏡像,在阿里云杭州鏡像倉庫,使用的命名空間是kube-easy,鏡像名:版本是app:latest。至此,我們有了一個可以在Kubernetes集群上運行的,“關在籠子里”的小程序。

得其門而入

入口

Kubernetes作為操作系統(tǒng),和普通的操作系統(tǒng)一樣,有API的概念。有了API,集群就有了入口;有了API,我們使用集群,才能得其門而入。Kubernetes的API被實現(xiàn)為運行在集群節(jié)點上的組件API Server。這個組件是典型的web服務器程序,通過對外暴露http(s)接口來提供服務。

這里我們創(chuàng)建一個阿里云Kubernetes集群。登錄集群管理頁面,我們可以看到API Server的公網(wǎng)入口。


API Server 內(nèi)網(wǎng)連接端點: https://xx.xxx.xxx.xxx:6443

雙向數(shù)字證書驗證

阿里云Kubernetes集群API Server組件,使用基于CA簽名的雙向數(shù)字證書認證來保證客戶端與api server之間的安全通信。這句話很繞口,對于初學者不太好理解,我們來深入解釋一下。

從概念上來講,數(shù)字證書是用來驗證網(wǎng)絡通信參與者的一個文件。這和學校頒發(fā)給學生的畢業(yè)證書類似。在學校和學生之間,學校是可信第三方CA,而學生是通信參與者。如果社會普遍信任一個學校的聲譽的話,那么這個學校頒發(fā)的畢業(yè)證書,也會得到社會認可。參與者證書和CA證書可以類比畢業(yè)證和學校的辦學許可證。

這里我們有兩類參與者,CA和普通參與者;與此對應,我們有兩種證書,CA證書和參與者證書;另外我們還有兩種關系,證書簽發(fā)關系,以及信任關系。這兩種關系至關重要。

我們先看簽發(fā)關系。如下圖,我們有兩張CA證書,三個參與者證書。其中最上邊的CA證書,簽發(fā)了兩張證書,一張是中間的CA證書,另一張是右邊的參與者證書;中間的CA證書,簽發(fā)了下邊兩張參與者證書。這六張證書以簽發(fā)關系為聯(lián)系,形成了樹狀的證書簽發(fā)關系圖。

然而,證書以及簽發(fā)關系本身,并不能保證可信的通信可以在參與者之間進行。以上圖為例,假設最右邊的參與者是一個網(wǎng)站,最左邊的參與者是一個瀏覽器,瀏覽器相信網(wǎng)站的數(shù)據(jù),不是因為網(wǎng)站有證書,也不是因為網(wǎng)站的證書是CA簽發(fā)的,而是因為瀏覽器相信最上邊的CA,也就是信任關系。

理解了CA(證書),參與者(證書),簽發(fā)關系,以及信任關系之后,我們回過頭來看“基于CA簽名的雙向數(shù)字證書認證”。客戶端和API Server作為通信的普通參與者,各有一張證書。而這兩張證書,都是由CA簽發(fā),我們簡單稱它們?yōu)榧篊A和客戶端CA。客戶端信任集群CA,所以它信任擁有集群CA簽發(fā)證書的API Server;反過來API Server需要信任客戶端CA,它才愿意與客戶端通信。

阿里云Kubernetes集群,集群CA證書,和客戶端CA證書,實現(xiàn)上其實是一張證書,所以我們有這樣的關系圖。

KubeConfig文件

登錄集群管理控制臺,我們可以拿到KubeConfig文件。這個文件包括了客戶端證書,集群CA證書,以及其他。證書使用base64編碼,所以我們可以使用base64工具解碼證書,并使用openssl查看證書文本。

  • 首先,客戶端證書的簽發(fā)者CN是集群id c0256a3b8e4b948bb9c21e66b0e1d9a72,而證書本身的CN是子賬號252771643302762862。

Certificate:Data:Version: 3 (0x2)Serial Number: 787224 (0xc0318)Signature Algorithm: sha256WithRSAEncryptionIssuer: O=c0256a3b8e4b948bb9c21e66b0e1d9a72, OU=default, CN=c0256a3b8e4b948bb9c21e66b0e1d9a72ValidityNot Before: Nov 29 06:03:00 2018 GMTNot After : Nov 28 06:08:39 2021 GMTSubject: O=system:users, OU=, CN=252771643302762862
  • 其次,只有在API Server信任客戶端CA證書的情況下,上邊的客戶端證書才能通過API Server的驗證。kube-apiserver進程通過client-ca-file這個參數(shù)指定其信任的客戶端CA證書,其指定的證書是/etc/kubernetes/pki/apiserver-ca.crt。這個文件實際上包含了兩張客戶端CA證書,其中一張和集群管控有關系,這里不做解釋,另外一張如下,它的CN與客戶端證書的簽發(fā)者CN一致。

Certificate:Data:Version: 3 (0x2)Serial Number: 787224 (0xc0318)Signature Algorithm: sha256WithRSAEncryptionIssuer: O=c0256a3b8e4b948bb9c21e66b0e1d9a72, OU=default, CN=c0256a3b8e4b948bb9c21e66b0e1d9a72ValidityNot Before: Nov 29 06:03:00 2018 GMTNot After : Nov 28 06:08:39 2021 GMTSubject: O=system:users, OU=, CN=252771643302762862

  • 再次,API Server使用的證書,由kube-apiserver的參數(shù)tls-cert-file決定,這個參數(shù)指向證書/etc/kubernetes/pki/apiserver.crt。這個證書的CN是kube-apiserver,簽發(fā)者是c0256a3b8e4b948bb9c21e66b0e1d9a72,即集群CA證書。

Certificate:Data:Version: 3 (0x2)Serial Number: 2184578451551960857 (0x1e512e86fcba3f19)Signature Algorithm: sha256WithRSAEncryptionIssuer: O=c0256a3b8e4b948bb9c21e66b0e1d9a72, OU=default, CN=c0256a3b8e4b948bb9c21e66b0e1d9a72ValidityNot Before: Nov 29 03:59:00 2018 GMTNot After : Nov 29 04:14:23 2019 GMTSubject: CN=kube-apiserver

  • 最后,客戶端需要驗證上邊這張API Server的證書,因而KubeConfig文件里包含了其簽發(fā)者,即集群CA證書。對比集群CA證書和客戶端CA證書,發(fā)現(xiàn)兩張證書完全一樣,這符合我們的預期。

Certificate:Data:Version: 3 (0x2)Serial Number: 786974 (0xc021e)Signature Algorithm: sha256WithRSAEncryptionIssuer: C=CN, ST=ZheJiang, L=HangZhou, O=Alibaba, OU=ACS, CN=rootValidityNot Before: Nov 29 03:59:00 2018 GMTNot After : Nov 24 04:04:00 2038 GMTSubject: O=c0256a3b8e4b948bb9c21e66b0e1d9a72, OU=default, CN=c0256a3b8e4b948bb9c21e66b0e1d9a72

訪問

理解了原理之后,我們可以做一個簡單的測試。我們以證書作為參數(shù),使用curl訪問api server,并得到預期結果。


# curl --cert ./client.crt --cacert ./ca.crt --key ./client.key https://xx.xx.xx.xxx:6443/api/{"kind": "APIVersions","versions": ["v1"],"serverAddressByClientCIDRs": [{"clientCIDR": "0.0.0.0/0","serverAddress": "192.168.0.222:6443"}]}

擇優(yōu)而居

兩種節(jié)點,一種任務

如開始所講,Kubernetes是管理集群多個節(jié)點的操作系統(tǒng)。這些節(jié)點在集群中的角色,卻不必完全一樣。Kubernetes集群有兩種節(jié)點,master節(jié)點和worker節(jié)點。

這種角色的區(qū)分,實際上就是一種分工:master負責整個集群的管理,其上運行的以集群管理組件為主,這些組件包括實現(xiàn)集群入口的api server;而worker節(jié)點主要負責承載普通任務。

在Kubernetes集群中,任務被定義為pod這個概念。pod是集群可承載任務的原子單元。pod被翻譯成容器組,其實是意譯,因為一個pod實際上封裝了多個容器化的應用。原則上來講,被封裝在一個pod里邊的容器,應該是存在相當程度的耦合關系。

擇優(yōu)而居

調度算法需要解決的問題,是替pod選擇一個舒適的“居所”,讓pod所定義的任務可以在這個節(jié)點上順利地完成。

為了實現(xiàn)“擇優(yōu)而居”的目標,Kubernetes集群調度算法采用了兩步走的策略:第一步,從所有節(jié)點中排除不滿足條件的節(jié)點,即預選;第二步,給剩余的節(jié)點打分,最后得分高者勝出,即優(yōu)選。

下邊,我們使用文章開始的時候制作的鏡像,創(chuàng)建一個pod,并通過日志來具體分析一下,這個pod怎么樣被調度到某一個集群節(jié)點。

Pod配置

首先,我們創(chuàng)建pod的配置文件,配置文件格式是json。這個配置文件有三個地方比較關鍵,分別是鏡像地址,命令以及容器的端口。


{"apiVersion": "v1","kind": "Pod","metadata": {"name": "app"},"spec": {"containers": [{"name": "app","image": "registry.cn-hangzhou.aliyuncs.com/kube-easy/app:latest","command": ["app"],"ports": [{"containerPort": 2580}]}]}}

日志級別

集群調度算法被實現(xiàn)為運行在master節(jié)點上的系統(tǒng)組件,這一點和api server類似。其對應的進程名是kube-scheduler。kube-scheduler支持多個級別的日志輸出,但社區(qū)并沒有提供詳細的日志級別說明文檔。查看調度算法對節(jié)點進行篩選、打分的過程,我們需要把日志級別提高到10,即加入?yún)?shù)--v=10。


kube-scheduler --address=127.0.0.1 --kubeconfig=/etc/kubernetes/scheduler.conf --leader-elect=true --v=10

創(chuàng)建Pod

使用curl,以證書和pod配置文件等作為參數(shù),通過POST請求訪問api server的接口,我們可以在集群里創(chuàng)建對應的pod。


# curl -X POST -H 'Content-Type: application/json;charset=utf-8' --cert ./client.crt --cacert ./ca.crt --key ./client.key https://47.110.197.238:6443/api/v1/namespaces/default/pods -d@app.json

預選

預選是Kubernetes調度的第一步,這一步要做的事情,是根據(jù)預先定義的規(guī)則,把不符合條件的節(jié)點過濾掉。不同版本的Kubernetes所實現(xiàn)的預選規(guī)則有很大的不同,但基本的趨勢,是預選規(guī)則會越來越豐富。

比較常見的兩個預選規(guī)則是PodFitsResourcesPred和PodFitsHostPortsPred。前一個規(guī)則用來判斷,一個節(jié)點上的剩余資源,是不是能夠滿足pod的需求;而后一個規(guī)則,檢查一個節(jié)點上某一個端口是不是已經(jīng)被其他pod所使用了。

下圖是調度算法在處理測試pod的時候,輸出的預選規(guī)則的日志。這段日志記錄了預選規(guī)則CheckVolumeBindingPred?的執(zhí)行情況。某些類型的存儲卷(PV),只能掛載到一個節(jié)點上,這個規(guī)則可以過濾掉不滿足pod對PV需求的節(jié)點。

從app的編排文件里可以看到,pod對存儲卷并沒有什么需求,所以這個條件并沒有過濾掉節(jié)點。

優(yōu)選

調度算法的第二個階段是優(yōu)選階段。這個階段,kube-scheduler會根據(jù)節(jié)點可用資源及其他一些規(guī)則,給剩余節(jié)點打分。

目前,CPU和內(nèi)存是調度算法考量的兩種主要資源,但考量的方式并不是簡單的,剩余CPU、內(nèi)存資源越多,得分就越高。

日志記錄了兩種計算方式:LeastResourceAllocation和BalancedResourceAllocation。前一種方式計算pod調度到節(jié)點之后,節(jié)點剩余CPU和內(nèi)存占總CPU和內(nèi)存的比例,比例越高得分就越高;第二種方式計算節(jié)點上CPU和內(nèi)存使用比例之差的絕對值,絕對值越大,得分越少。

這兩種方式,一種傾向于選出資源使用率較低的節(jié)點,第二種希望選出兩種資源使用比例接近的節(jié)點。這兩種方式有一些矛盾,最終依靠一定的權重來平衡這兩個因素。

除了資源之外,優(yōu)選算法會考慮其他一些因素,比如pod與節(jié)點的親和性,或者如果一個服務有多個相同pod組成的情況下,多個pod在不同節(jié)點上的分散程度,這是保證高可用的一種策略。

得分

最后,調度算法會給所有的得分項乘以它們的權重,然后求和得到每個節(jié)點最終的得分。因為測試集群使用的是默認調度算法,而默認調度算法把日志中出現(xiàn)的得分項所對應的權重,都設置成了1,所以如果按日志里有記錄得分項來計算,最終三個節(jié)點的得分應該是29,28和29。

之所以會出現(xiàn)日志輸出的得分和我們自己計算的得分不符的情況,是因為日志并沒有輸出所有的得分項,猜測漏掉的策略應該是NodePreferAvoidPodsPriority,這個策略的權重是10000,每個節(jié)點得分10,所以才得出最終日志輸出的結果。

結束語

在這篇文章中,我們以一個簡單的容器化web程序為例,著重分析了客戶端怎么樣通過Kubernetes集群API Server認證,以及容器應用怎么樣被分派到合適節(jié)點這兩件事情。

在分析過程中,我們棄用了一些便利的工具,比如kubectl,或者控制臺。我們用了一些更接近底層的小實驗,比如拆解KubeConfig文件,再比如分析調度器日志來分析認證和調度算法的運作原理。希望這些對大家進一步理解Kubernetes集群有所幫助。

?

總結

以上是生活随笔為你收集整理的Kubernetes从懵圈到熟练:认证与调度的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。