一文帶你理解14個K8S必備基礎概念

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在微服務、雲計算和無服務架構時代,理解Kubernetes並且知道如何使用它是十分有用的。然而,官方的Kubernetes文檔對於剛開始接觸雲計算的用戶來說有些難以理解。在本文中,我們將瞭解在Kubernetes中的重要概念。在之後的系列文章中,我們還將瞭解如何寫配置文件、使用Helm作爲軟件包管理器、創建一個雲基礎架構、使用Kubernetes輕鬆編排服務並且創建一個CI\/CD流水線來自動化整個工作流。有了這些信息,你可以啓動任意種類的項目,並且創建一個強大的基礎架構。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先,我們知道使用容器有多種好處,從部署速度的提升到大規模一致性交付等。即使如此,容器也並非一切問題的解決之道,因爲使用容器會帶來一定的開銷,比如維護一個容器編排層。所以,你需要在項目開始的時候分析成本\/效益。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"現在,讓我們開啓Kubernetes世界之旅吧!"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Kubernetes硬件結構"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"節點"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"節點是Kubernetes中的worker機器,可以是任何具有CPU和RAM的設備。例如,智能手錶、智能手機或者筆記本,甚至是樹莓派都可以成爲一個節點。當我們使用雲時,節點就是一個虛擬機(VM)。所以,簡單來說,節點是單一設備的抽象概念。這種抽象的好處是,我們不需要知道底層的硬件結構。我們只使用節點,這樣一來,我們的基礎設施就獨立於平臺。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/16\/16dbdcef75bc8a329aecb6b681706f45.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"集羣"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一個集羣是一組節點。當你將程序部署到集羣上時,它會自動將工作分配到各個節點。如果需要更多的資源(簡單來講,我們需要更多錢),那麼集羣中將會加入新的節點並且將會自動重新分配工作。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們在集羣上運行我們的代碼,但我們不需要關心具體在哪個節點上運行了哪部分的代碼。工作的分配是自動的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/d6\/d6a6f5ec95d3517f23b5b48bdbd45044.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"持久卷(persistent volumes)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因爲我們的代碼可以從一個節點轉移到另一個節點(例如,某個節點沒有足夠的內存,那麼工作將會被重新調度到另一個擁有充足內存的節點上),所以在節點上保存數據容易丟失。如果我們想要永久保存我們的數據,我們應該使用持久卷。持久卷有點類似外部的硬盤,你可以將它插入並在上面保存你的數據。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Google開發的Kubernetes是一個無狀態應用程序的平臺,其持久性數據存儲在其他地方。當這一項目發展成熟之後,許多企業想要在有狀態應用程序中使用它,所以開發人員需要添加持久卷管理。如同早期的虛擬化技術,數據庫server通常情況下並不是首要遷移到新架構上去的server。這是因爲數據庫是許多應用程序的核心,並且可能包含很多重要信息,所以本地數據庫系統在虛擬機或物理機中通常規模很大。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以,問題是,我們應該什麼時候開始使用持久卷?要回答這個問題,首先,我們應該理解數據庫應用的不同類型。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們將數據管理解決方案分爲以下兩類:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"垂直伸縮——包括傳統的RDMS解決方案,例如MySQL、PostgreSQL以及SQL Server"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"水平伸縮——包括“NoSQL”解決方案,例如ElasticSearch或基於Hadoop的解決方案"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"垂直伸縮解決方案(如MySQL、PostgreSQL以及Microsoft SQL)不應該應用在容器內。這些數據庫平臺要求高I\/O、共享磁盤以及block存儲等,並且無法處理集羣內的節點丟失,但這一情況常常會發生在基於容器的生態系統內。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於水平伸縮應用程序(如Elastic、Cassanda、Kafka等)可以使用容器。他們能夠承受數據庫集羣內的節點丟失以及數據庫應用可以自行恢復均衡。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通常情況下,你應該容器化分佈式數據庫,從而利用冗餘的存儲技術並且能夠處理數據庫集羣內的節點丟失(ElasticSearch是一個很好的例子)。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Kubernetes軟件組件"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"容器"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"現代軟件開發的目標之一是保證各類應用程序在相同的主機或集羣上可以彼此隔離。虛擬機是解決該問題的一個方案。但虛擬機需要他們自己的操作系統,所以他們的規模通常是千兆字節。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器則恰恰相反,它可以隔離應用程序的執行環境但共享底層操作系統。所以,容器就像一個盒子,我們可以在其中保存一切運行應用程序所需要的:代碼、運行時、系統工具、系統倉庫、設置等。它們通常僅需要幾兆字節即可運行,遠遠少於虛擬機所需資源,並且可以立即啓動。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Pods"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Pod是一組容器。在Kubernetes中,最小的單位是Pod。一個pod可以包含多個容器,但通常情況下我們在每個pod中僅使用一個容器,因爲在Kubernetes中最小複製單位是pod。如果我們想要爲每個容器單獨擴容,我們添加一個容器到Pod中即可。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/96\/96167f024a7bfc0606d526440baaaa3e.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Deployments"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Deployment的最初功能是爲pod和ReplicaSet(相同Pod在其中會被複制很多次)提供聲明式更新。使用deployment,我們可以指定有多少相同pod的副本應該隨時運行。Deployment類似於pod的管理器,它可以自動啓動所需數量的pod、監控pod並在出現故障時重新創建Pod。Deployment極其有用,因爲你不需要單獨創建和管理每個pod。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們通常爲無狀態應用程序使用deployment。然而,你可以通過給他附加一個持久捲來殘存deployment的狀態並使其變得有狀態。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Stateful Sets"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"StatefulSet是Kubernetes中的一個新概念並且它是用於管理有狀態應用的資源。它管理deployment和一組pod的擴展,並且確保這些pod的順序以及獨特性。它與deployment類似,唯一的區別是deployment創建一組任意名稱的pod,並且pod的順序對它來說並不重要,而StatefulSet創建的pod都有獨一無二的名稱以及順序。所以,如果你想爲名爲example的pod創建3個副本,那麼StatefulSet將會創建爲:example-0、example-1、example-2。因此,這一創建方式最重要的好處就是你可以通過pod的名稱就瞭解大致的情況。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"DaemonSets"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"DaemonSet可以確保pod運行在集羣的所有節點上。如果從集羣中添加\/移除了一個節點,DaemonSet會自動添加\/刪除該pod。這對於監控以及日誌十分重要,因爲你可以監控每個節點並且不需要手動監控集羣。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Services"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Deployment負責保持一組Pod處於運行狀態,那麼Service負責爲一組Pod啓動網絡訪問。Services可以跨集羣提供標準化的特性:負載均衡、應用間的服務發現以及零宕機應用程序deployment。每個服務都有獨一無二的IP地址以及DNS主機名稱。可以爲需要使用服務的應用程序手動配置相應的IP地址或主機名稱,然後流量將會被負載均衡到正確的pod。在外部流量的部分,我們會了解到更多的服務類型以及我們如何在內部服務和外部世界間進行通信。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/f7\/f7a0a532d779236736113f84c6f04ad9.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"ConfigMaps"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你想部署到多個環境中,如staging、開發環境和生產環境,bake配置到應用程序中並不是一個好的操作,因爲環境之間存在差異性。理想狀況下,你會希望每個部署環境對應不同的配置。於是,ConfigMap應運而生。ConfigMaps可以讓你從鏡像中解耦配置工件以保持容器化應用程序的便攜性。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"外部流量"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"既然你已經瞭解運行在集羣中的服務,那麼你如何獲取外部流量到你的集羣中呢?有三種服務類型可以處理外部流量:ClusterIP、NodePort以及LoadBalancer。還有第4種解決方案:再添加一個抽象層,稱爲Ingress Controller。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"ClusterIP"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"ClusterIP是Kubernetes中默認的服務類型,它可以讓你在集羣內部與其他服務進行通信。雖然ClusterIP不是爲外部訪問而設計的,但只要使用代理進行了一些改動,外部流量就可以訪問我們的服務。不要在生產環境中採用這一解決方案,但可以用其來進行調試。聲明爲ClusterIP的服務不應該可以從外部直接可見。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"NodePort"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"正如我們在本文第一部分中所看到的那樣,pod正在節點上運行。節點可以是各種不同的設備,如筆記本電腦或虛擬機(但在雲端運行時)。每個節點有一個固定的IP地址。通過將一個服務聲明爲NodePort,服務將會暴露節點IP地址,以便你可以從外部訪問它。你可以在生產環境中使用NodePort,但對於擁有許多服務的大型應用程序來說,手動管理所有不同的IP地址十分麻煩。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/37\/372c9cb16d02ef6541c9fc7146d2b046.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"LoadBalancer"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"聲明一個LoadBalancer類型的服務,就可以使用雲提供商的LoadBalancer向外部公開。外部load balancer如何將流量路由到服務Pod取決於集羣提供程序。有了這個解決方案,你不必管理集羣中每個節點的所有IP地址,但你將爲每個服務配備一個load balancer。缺點是,每個服務都有一個單獨的load balancer,你將按照load balancer實例付費。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/a2\/a2dfb578d2665b52b6e253f3915a1f2a.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這一解決方案適用於生產環境,但它有些昂貴。接下來,我們來看看稍微便宜一些的解決方案。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Ingress"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Ingress不是一個服務,而是一個API對象,它可以管理外部對集羣服務的訪問。它作爲反向代理和單一入口點(entry point)進入你的集羣,將請求路由到不同的服務。我通常使用NGINX Ingress Controller,它承擔了反向代理,同時也作爲SSL發揮作用。暴露ingress的最佳生產方案是使用一個load balancer。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"藉助這一解決方案,你可以使用單個load balancer暴露任意數量的服務,所以你可以讓費用保持在最低水平。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/04\/04e82c4c64a59bd5f187924a8aebb41c.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"總結"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在本文中,我們瞭解了Kubernetes中的基本概念及其硬件架構。我們還討論了不同的軟件組件,如Pod、Deployment、StatefulSets以及Services,並且瞭解了服務與外部世界之間如何進行通信。希望可以幫助你再次梳理Kubernetes裏錯綜複雜的組件架構。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文轉載自:RancherLabs(ID:RancherLabs)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文鏈接:"},{"type":"link","attrs":{"href":"https:\/\/mp.weixin.qq.com\/s\/f2oOspiW8c-RouBTMey41A","title":"xxx","type":null},"content":[{"type":"text","text":"一文帶你理解14個K8S必備基礎概念"}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章