Tungsten Fabric SDN — SmartNIC vRouter
734
2022-05-29
先來看一下大多數(shù)公司軟件開發(fā)的場景:
自己搭建虛擬機,然后安裝redis,nginx,mq,mysql,tomcat,jdk,marven等。然后搭完以后鏡像出來,換到另外一臺上,換個ip,單獨做測試環(huán)境。然后每次部署,通過ssh連接到linux服務(wù)器,kill -9,然后備份,重啟服務(wù)器,打war包,真心煩人。
可能,后來會使用jekins,開發(fā)環(huán)境發(fā)布部署就隨便發(fā),測試。非常方便。
最后,公司搞大了!開始使用微服務(wù),分布式,大數(shù)據(jù)等。所以使用docker把微服務(wù)作為一個個單獨的容器,然后單獨運行,不管nginx,redis,mysql,還是hadop等。對于docker都是一個模式,下載docker鏡像,run一下,就OK了。是不是很歷害!
但一旦擁抱了docker容器,用戶就需要一個編排框架來調(diào)度和管理容器。最常見的編排框架有Kubernetes、Mesos、Docker Swarm。Kubernetes是目前市場上最成熟的、最具擴展性的解決方案,占有最大的市場份額。
Kubernetes正迅速成為云計算中部署和管理軟件的新標準。不過,Kubernetes既然能提供極高的價值,也肯定會附帶一個陡峭的學(xué)習(xí)曲線。作為一個新手,試圖解析官方文檔可能會很困難。這個系統(tǒng)由許多不同的片段組成,所以我們可以先從不同片段的關(guān)鍵要素出發(fā)去學(xué)習(xí)。
接下來,先了解一下Dock 容器的基本名詞概念:
容器鏡像(images)
容器鏡像是啟動容器的基石。
容器鏡像是由文件系統(tǒng)疊加而成。最底端是一個文件引導(dǎo)系統(tǒng),即bootfs。Docker用戶不會與引導(dǎo)文件系統(tǒng)有直接的交互。Docker鏡像的第二層是root文件系統(tǒng)rootfs,通常是一種或多種操作系統(tǒng),例如ubuntu等。在Docker中,文件系統(tǒng)永遠都是只讀的,在每次修改時,都是進行拷貝疊加從而形成最終的文件系統(tǒng)。Docker稱這樣的文件為鏡像。一個鏡像可以迭代在另一個鏡像的頂部。位于下方的鏡像稱之為父鏡像,最底層的鏡像稱之為基礎(chǔ)鏡像。最后,當從一個鏡像啟動容器時,Docker會在最頂層加載一個讀寫文件系統(tǒng)作為容器。
容器鏡像是輕量的、可執(zhí)行的獨立軟件包 ,包含軟件運行所需的所有內(nèi)容:代碼、運行時環(huán)境、系統(tǒng)工具、系統(tǒng)庫和設(shè)置。
Docker容器(Container)
容器(container)的定義和鏡像(image)幾乎一模一樣,唯一區(qū)別在于容器的最上面那一層是可讀可寫的。
鏡像是靜態(tài)的,鏡像的每一層都只是可讀的,而容器是動態(tài)的里面運行著我們指定的應(yīng)用,容器里面的應(yīng)用可能會新建一個文件,修改一個目錄,這些操作所帶來的改變并不會作用到鏡像里面,因為鏡像只是可讀的。所以通過鏡像創(chuàng)建容器就是在鏡像上加一個可讀寫的層。
一個鏡像可創(chuàng)建多個容器,每個容器都有各自的一個可讀寫層,這些層相互獨立共享下面的鏡像。
容器的定義并沒有提及容器是否在運行,一個運行態(tài)容器(running container)被定義為一個可讀寫的統(tǒng)一文件系統(tǒng)加上隔離的進程空間和包含其中的進程。
想要快速了解Kubernetes如何管控容器,少走彎路,必須先搞清楚Kubernetes的關(guān)鍵名詞概念:
節(jié)點(Node)
節(jié)點是Kubernetes中最小的計算硬件單元。它是集群中單個機器的表示。在大多數(shù)生產(chǎn)系統(tǒng)中,節(jié)點很可能是數(shù)據(jù)中心中的物理機器,或者是托管在像谷歌云平臺這樣的云供應(yīng)商上的虛擬機。不過,不要讓慣例限制了你的想象力,從理論上講,你可以把任何東西做成一個結(jié)點。
把機器看作一個“節(jié)點”,可以讓我們插入一個抽象層?,F(xiàn)在,我們不必擔(dān)心任何單個機器的獨特特性,而是可以簡單地將每臺機器看作一組可以使用的CPU和RAM資源。這樣,任何機器都可以替代Kubernetes集群中的任何其他機器。
集群(Cluster)
雖然使用單個節(jié)點是有用的,但它與Kubernetes理念不同。一般來說,你應(yīng)該將集群看作一個整體,而無需擔(dān)心單個節(jié)點的狀態(tài)。
在Kubernetes中,節(jié)點匯聚資源,形成更強大的機器。當你將程序部署到集群中時,它將智能地處理將工作分配給你的各個節(jié)點。如果添加或刪除了任何節(jié)點,集群將根據(jù)需要在工作中進行轉(zhuǎn)換。這對程序或程序員來說都不重要,因為機器實際上是在運行代碼。
持久卷(Persistent Volumes)
因為在集群上運行的程序不能保證在特定的節(jié)點上運行,所以無法將數(shù)據(jù)保存到文件系統(tǒng)中的任意位置。如果一個程序試圖將數(shù)據(jù)保存到一個文件中,但隨后又被轉(zhuǎn)移到一個新的節(jié)點上,那么該文件將不再是程序期望的位置。由于這個原因,與每個節(jié)點相關(guān)的傳統(tǒng)本地存儲被當作臨時緩存來保存程序,但本地保存的任何數(shù)據(jù)都不能持久。
為了永久存儲數(shù)據(jù),Kubernetes使用持久卷(Persistent Volumes)。雖然所有節(jié)點的CPU和RAM資源都被集群有效地匯集和管理,但持久的文件存儲卻不是。相反,本地或云驅(qū)動器可以作為持久卷附加到集群上。這可以看作是將外部硬盤插入到集群中。持久卷提供了可以掛載到集群的文件系統(tǒng),而不與任何特定節(jié)點相關(guān)聯(lián)。持久卷是一個系統(tǒng)的資源,因此沒有所屬的命名空間。
容器(Container)
在Kubernetes上運行的程序被打包成Linux容器。容器是一個被廣泛接受的標準,因此已經(jīng)有許多預(yù)先構(gòu)建的映像可以部署在Kubernetes上。
容器化允許你創(chuàng)建自足式的Linux執(zhí)行環(huán)境。任何程序和它的所有依賴項都可以打包成一個文件,然后在網(wǎng)絡(luò)上共享。任何人都可以下載該容器并在其基礎(chǔ)設(shè)施上部署它,所需的設(shè)置非常少。創(chuàng)建一個容器可以通過編程方式完成,從而形成強大的CI和CD管道。
可以將多個程序添加到單個容器中,但是如果可能的話,你應(yīng)該將自己限制為每個容器的一個進程。擁有很多小容器比一個大容器好。如果每個容器都有一個緊密的焦點,那么更新更容易部署,并且問題更容易診斷。
由于容器本身是非持久化的,因此需要解決在容器中運行應(yīng)用程序遇到的一些問題。首先,當容器崩潰時,kubelet將重新啟動容器,但是寫入容器的文件將會丟失,容器將會以鏡像的初始狀態(tài)重新開始;第二,在通過一個Pod中一起運行的容器,通常需要共享容器之間一些文件。Kubernetes通過存儲卷解決上述的兩個問題。
Pod
Pod是Kubernetes 中的最小部署單元,與你過去使用的其他系統(tǒng)不同,Kubernetes不直接運行容器;相反,它將一個或多個容器封裝到一個稱為Pod的高級結(jié)構(gòu)中。相同Pod中的任何容器都將共享相同的命名空間和本地網(wǎng)絡(luò)。容器可以很容易地與其他容器在相同的容器中進行通信,就像它們在同一臺機器上同時保持一定程度的隔離。
Pod被用作Kubernetes的復(fù)制單元。如果你的應(yīng)用程序太受歡迎,單個的Pod實例無法承載負載,那么可以配置Kubernetes以在必要時將你的Pod的新副本部署到集群。即使在沒有重載的情況下,在生產(chǎn)系統(tǒng)中任何時候都要有多個副本,以保證負載均衡和故障抵抗。
Pod可以容納多個容器,但在可能的情況下應(yīng)該限制自己。因為Pod作為一個單位被放大和縮小時,所有在一個Pod里的容器都必須在一起縮放,不管它們是否需要。這將導(dǎo)致資源的浪費和成本增加。為了解決這個問題,Pod應(yīng)該保持盡可能小的大小,通常只保留一個主進程和緊密耦合的輔助容器(這些輔助容器通常被稱為“側(cè)三輪摩托車”)。
Pod是自己有生命周期的,Pod消失后數(shù)據(jù)也會消失,所以我們要把數(shù)據(jù)放在一個容器的外面。
在Kubernetes上刪除Pod,存儲卷也會隨之而刪除的,這一點區(qū)分docker。
在Kubernetes支持多種類型的卷,而Pod可以同時使用各種類型和任意數(shù)量的存儲卷。在Pod中通過指定下面的字段來使用存儲卷
部署(Deployment)
雖然Pod是Kubernetes的基本計算單元,但它們通常不是直接在集群上啟動的。相反,Pod通常由一個抽象層來管理:部署。
部署的主要目的是聲明一個Pod應(yīng)該同時運行多少個副本。當將部署添加到集群中時,它將自動地旋轉(zhuǎn)加速所需的Pod數(shù)量,然后監(jiān)視它們。如果一個Pod消失,部署將自動重新創(chuàng)建它。
使用部署,你不必手動處理Pod。你只需聲明系統(tǒng)的期望狀態(tài),它將自動為你管理。
入口(Ingress)
使用上面描述的概念,你可以創(chuàng)建一個節(jié)點集群,并將Pod部署到集群上。不過,還有一個問題需要解決:允許外部通信流進入你的應(yīng)用程序。
默認情況下,Kubernetes提供隔離艙和外部世界。如果你想要與運行在Pod中的服務(wù)通信,你必須打開一個通信通道。稱作入口(ingress)。
有多種方法可以將入口添加到集群中。最常見的方法是添加入口控制器或負載均衡器。這兩個選項之間的精確權(quán)衡超出了本文的范圍,但是你必須知道,在你可以與Kubernetes進行實驗之前,你需要處理的是入口。
以上是對Kubernetes的簡單描述,旨在為你提供開始試驗所需的基礎(chǔ)知識。想必現(xiàn)在你已經(jīng)了解了組成系統(tǒng)的部分,現(xiàn)在是時候使用它們來部署一個真正的應(yīng)用程序了。
要在本地使用Kubernetes,可以使用Minikube在你的個人硬件上創(chuàng)建一個虛擬集群。如果你準備嘗試云服務(wù),谷歌Kubernetes引擎有一系列教程,可幫助你入門。
了解了上述概念后,在使用中的一些注意事項也是要說明一下:
1) 不要將數(shù)據(jù)儲存在容器中
容器隨時都可以停止、銷毀或遷移,比方說,一個容器里運行的應(yīng)用版本是1.0,我們分分鐘就可以把這個應(yīng)用升級到1.1,同時還不會對數(shù)據(jù)造成任何影響。所以如果用戶想要存數(shù)據(jù)的話,最好是用數(shù)據(jù)卷來存儲。不過在用卷存數(shù)據(jù)的時候大家還是要注意一點,如果有兩個容器共用一個數(shù)據(jù)卷,都往里面寫數(shù)據(jù)的話,是有可能造成程序崩潰的。我們在設(shè)計應(yīng)用程序的時候應(yīng)該考慮到這一點,為保萬無一失,應(yīng)用程序應(yīng)該具備特定的機制,以確保在往共享數(shù)據(jù)存儲區(qū)寫入數(shù)據(jù)的時候不會出錯。
2) 不要把應(yīng)用程序分塊交付
在部分用戶看來,容器跟虛擬機沒什么兩樣,所以有些人往往會把應(yīng)用程序部署到當前運行的若干個容器中。這種做法在開發(fā)階段沒有太大的問題,因為做開發(fā)的時候我們會很頻繁地進行部署和調(diào)試,但是到了持續(xù)交付(CD)階段,下一步就是QA測試和正式投產(chǎn)了,這種做法就不太適合了。在這一階段,我們應(yīng)該充分考慮到容器的不可變特性,最好是將應(yīng)用程序打包到一個鏡像中交付。
3) 不要把鏡像體積建得很大
鏡像越大,就越難發(fā)布。鏡像中只包含必要的文件和library就可以了,能讓應(yīng)用或者進程運行起來就行。千萬不要在鏡像中安裝些沒必要的東西,在構(gòu)建鏡像的時候要避免使用yum這種update命令,免得系統(tǒng)自動下載很多不相干的文件到新鏡像層中。
4) 建鏡像的時候不要只建一層
大家都知道,Docker的文件系統(tǒng)是分層的,在建鏡像的時候我們應(yīng)該這么建,將操作系統(tǒng)單獨建一層,作為基礎(chǔ)鏡像,然后用戶名定義文件、運行時安裝環(huán)境、配置文件都要分別建一層鏡像,最后才是應(yīng)用鏡像層。這么做的話,我們以后重建、管理以及發(fā)布鏡像的時候就要輕省得多了。
5) 不要把本地運行的容器轉(zhuǎn)成鏡像
換句話說就是創(chuàng)建鏡像的時候不要用“docker commit”命令來創(chuàng)建。用這種辦法建鏡像是完全不可取的,因為這種辦法是不能重復(fù)的。我們在建鏡像的時候應(yīng)該從Dockerfile創(chuàng)建,或者用其他S2I(從源文件構(gòu)建鏡像)的方式來創(chuàng)建,這樣鏡像才具有可再生性,而且如果我們把鏡像存在git之類提供版本控制能的系統(tǒng)里的話,還可以對Dockerfile的改動進行跟蹤。
6) 給鏡像打tag的時候不要只打“l(fā)atest"
latest其實就相當于Maven里頭的“快照”。因為容器的文件系統(tǒng)是分層的,我們最好是給鏡像多打幾個tag。如果只有l(wèi)atest的話,可能過段時間我們再來運行應(yīng)用程序的時候就發(fā)現(xiàn)程序運行不起來了,因為應(yīng)用的父層(就是Dockerfile里面的跟在FROM命令后面的那一層)被更新的版本覆蓋了,而新版本又不能向下兼容,還有可能就是從build cache里面取鏡像的時候取到了錯的“l(fā)atest”鏡像。在產(chǎn)品環(huán)境中部署容器的時候也要避免使用latest,不然容易造成無法跟蹤記錄鏡像版本的問題。
7) 不要在單個容器里面運行多個進程
容器本來就是用來運行單個應(yīng)用的(比如http daemon,應(yīng)用服務(wù)器,數(shù)據(jù)庫等等),如果我們非要在一個容器里跑幾個應(yīng)用,那么在管理每個應(yīng)用進程、存取日志、升級應(yīng)用的時候就會很麻煩。
8)不要把認證口令存在鏡像中,用環(huán)境變量比較好
如果我們把用戶名/密碼值對存在鏡像里的話,就只有采用硬編碼的方式來挨個處理,估計這種麻煩事沒人愿意去干。所以我們最好是用環(huán)境變量的方從容器外部獲取此類信息。
9) 不要用root用戶的角色來運行進程
Docker容器默認是以root權(quán)限運行的。不過隨著技術(shù)的成熟,docker也會提供安全性更高的默認操作選項。在現(xiàn)有技術(shù)條件下,以root權(quán)限運行會對其他應(yīng)用帶來安全隱患,而且在有些運行環(huán)境下root權(quán)限是取不到的,所以我們在跑容器的時候應(yīng)該用USER命令來指定非root權(quán)限的用戶。
10) 不要過分依賴IP地址
每個容器都有一個內(nèi)部IP,這個IP不是固定的,我們啟動容器或者停止容器的時候IP都會變。如果我們要讓應(yīng)用或者微服務(wù)模塊在容器之間進行通信的話,正確的做法是通過設(shè)置環(huán)境變量來傳遞主機名和端口號。
容器 Kubernates 云計算 K8S
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。