作者 | Julia Evans
譯者 | qhwdw
在我剛開始學習 Kubernetes(大約是一年半以前吧?)時,我真的不明白為什麼應該去關註它。
在我使用 Kubernetes 全職工作了三個多月後,我才逐漸明白了為什麼我應該使用它。(我距離成為一個 Kubernetes 專家還很遠!)希望這篇文章對你理解 Kubernetes 能做什麼會有幫助!
我將嘗試去解釋我對 Kubernetes 感興趣的一些原因,而不去使用 “原生雲”、“編排系統”、“容器”,或者任何 Kubernetes 專用的術語 :)。我去解釋的這些觀點主要來自一位 Kubernetes 操作者/基礎設施工程師,因為,我現在的工作就是去配置 Kubernetes 和讓它工作的更好。
我不會去嘗試解決一些如 “你應該在你的生產系統中使用 Kubernetes 嗎?”這樣的問題。那是非常複雜的問題。(不僅是因為“生產系統”根據你的用途而總是有不同的要求)
Kubernetes 可以讓你無需設定一臺新的伺服器即可在生產系統中執行程式碼
我首次被說教使用 Kubernetes 是與我的夥伴 Kamal 的下麵的談話:
大致是這樣的:
這裡有一種陷阱,設定一個生產用 Kubernetes 叢集(在我的經險中)確實並不容易。(檢視 Kubernetes 艱難之旅[1] 中去開始使用時有哪些複雜的東西)但是,我們現在並不深入討論它。
因此,Kubernetes 第一個很酷的事情是,它可能使那些想在生產系統中部署新開發的軟體的方式變得更容易。那是很酷的事,而且它真的是這樣,因此,一旦你使用一個運作中的 Kubernetes 叢集,你真的可以僅使用一個配置檔案就在生產系統中設定一臺 HTTP 服務(在 5 分鐘內執行這個應用程式,設定一個負載均衡,給它一個 DNS 名字,等等)。看起來真的很有趣。
對於執行在生產系統中的程式碼,Kubernetes 可以提供更好的可見性和可管理性
在我看來,在理解 etcd 之前,你可能不會理解 Kubernetes 的。因此,讓我們先討論 etcd!
想像一下,如果現在我這樣問你,“告訴我你執行在生產系統中的每個應用程式,它執行在哪臺主機上?它是否狀態很好?是否為它分配了一個 DNS 名字?”我並不知道這些,但是,我可能需要到很多不同的地方去查詢來回答這些問題,並且,我需要花很長的時間才能搞定。我現在可以很確定地說不需要查詢,僅一個 API 就可以搞定它們。
在 Kubernetes 中,你的叢集的所有狀態 – 執行中的應用程式 (“pod”)、節點、DNS 名字、 cron 任務、 等等 —— 都儲存在一個單一的資料庫中(etcd)。每個 Kubernetes 元件是無狀態的,並且基本是透過下列方式工作的:
這意味著,如果你想去回答諸如 “在那個可用區中有多少臺執行著 nginx 的 pod?” 這樣的問題時,你可以透過查詢一個統一的 API(Kubernetes API)去回答它。並且,你可以在每個其它 Kubernetes 元件上執行那個 API 去進行同樣的訪問。
這也意味著,你可以很容易地去管理每個執行在 Kubernetes 中的任何東西。比如說,如果你想要:
這些你只需要寫一個程式與 Kubernetes API(“controller”)通訊就可以了。
另一個關於 Kubernetes API 的令人激動的事情是,你不會侷限於 Kubernetes 所提供的現有功能!如果對於你要部署/建立/監視的軟體有你自己的方案,那麼,你可以使用 Kubernetes API 去寫一些程式碼去達到你的目的!它可以讓你做到你想做的任何事情。
即便每個 Kubernetes 元件都“掛了”,你的程式碼將仍然保持執行
關於 Kubernetes 我(在各種部落格文章中 :))承諾的一件事情是,“如果 Kubernetes API 服務和其它元件‘掛了’也沒事,你的程式碼將一直保持執行狀態”。我認為理論上這聽起來很酷,但是我不確定它是否真是這樣的。
到目前為止,這似乎是真的!
我已經斷開了一些正在執行的 etcd,發生了這些情況:
這樣做意味著如果 etcd 宕掉,並且你的應用程式的其中之一崩潰或者發生其它事情,在 etcd 恢復之前,它不能夠恢復。
Kubernetes 的設計對 bug 很有彈性
與任何軟體一樣,Kubernetes 也會有 bug。例如,到目前為止,我們的叢集控制管理器有記憶體洩漏,並且,排程器經常崩潰。bug 當然不好,但是,我發現 Kubernetes 的設計可以幫助減輕它的許多核心元件中的錯誤的影響。
如果你重啟動任何元件,將會發生:
因為,所有的元件並不會在記憶體中保持狀態,你在任何時候都可以重啟它們,這可以幫助你減輕各種 bug 的影響。
例如,如果在你的控制管理器中有記憶體洩露。因為,控制管理器是無狀態的,你可以每小時定期去重啟它,或者,在感覺到可能導致任何不一致的問題發生時重啟它。又或者,在排程器中遇到了一個 bug,它有時忘記了某個 pod,從來不去排程它們。你可以每隔 10 分鐘來重啟排程器來緩減這種情況。(我們並不會這麼做,而是去修複這個 bug,但是,你可以這樣做 :))
因此,我覺得即使在它的核心元件中有 bug,我仍然可以信任 Kubernetes 的設計可以讓我確保叢集狀態的一致性。並且,總在來說,隨著時間的推移軟體質量會提高。唯一你必須去操作的有狀態的東西就是 etcd。
不用過多地討論“狀態”這個東西 —— 而我認為在 Kubernetes 中很酷的一件事情是,唯一需要去做備份/恢復計劃的東西是 etcd (除非為你的 pod 使用了持久化儲存的捲)。我認為這樣可以使 Kubernetes 運維比你想的更容易一些。
在 Kubernetes 之上實現新的分散式系統是非常容易的
假設你想去實現一個分散式 cron 作業排程系統!從零開始做工作量非常大。但是,在 Kubernetes 裡面實現一個分散式 cron 作業排程系統是非常容易的!(仍然沒那麼簡單,畢竟它是一個分散式系統)
我第一次讀到 Kubernetes 的 cron 作業控制器的程式碼時,我對它是如此的簡單感到由衷高興。去讀讀看,其主要的邏輯大約是 400 行的 Go 程式碼。去讀它吧! => cronjob_controller.go[3] <=
cron 作業控制器基本上做的是:
Kubernetes 模型是很受限制的(它有定義在 etcd 中的資源樣式,控制器讀取這個資源並更新 etcd),我認為這種相關的固有的/受限制的模型,可以使它更容易地在 Kubernetes 框架中開發你自己的分散式系統。
Kamal 給我說的是 “Kubernetes 是一個寫你自己的分散式系統的很好的平臺” ,而不是“ Kubernetes 是一個你可以使用的分散式系統”,並且,我覺得它真的很有意思。他做了一個 為你推送到 GitHub 的每個分支執行一個 HTTP 服務的系統[2] 的原型。這花了他一個週末的時間,大約 800 行 Go 程式碼,我認為它真不可思議!
Kubernetes 可以使你做一些非常神奇的事情(但並不容易)
我一開始就說 “kubernetes 可以讓你做一些很神奇的事情,你可以用一個配置檔案來做這麼多的基礎設施,它太神奇了”。這是真的!
為什麼說 “Kubernetes 並不容易”呢?是因為 Kubernetes 有很多部分,學習怎麼去成功地運營一個高可用的 Kubernetes 叢集要做很多的工作。就像我發現它給我了許多抽象的東西,我需要去理解這些抽象的東西才能除錯問題和正確地配置它們。我喜歡學習新東西,因此,它並不會使我發狂或者生氣,但是我認為瞭解這一點很重要 :)
對於 “我不能僅依靠抽象概念” 的一個具體的例子是,我努力學習了許多 Linux 上網路是如何工作的[4],才讓我對設定 Kubernetes 網路稍有信心,這比我以前學過的關於網路的知識要多很多。這種方式很有意思但是非常費時間。在以後的某個時間,我或許寫更多的關於設定 Kubernetes 網路的困難/有趣的事情。
或者,為了成功設定我的 Kubernetes CA,我寫了一篇 2000 字的部落格文章[5],述及了我不得不學習 Kubernetes 不同方式的 CA 的各種細節。
我覺得,像 GKE (Google 的 Kubernetes 產品) 這樣的一些監管的 Kubernetes 的系統可能更簡單,因為,他們為你做了許多的決定,但是,我沒有嘗試過它們。
via: https://jvns.ca/blog/2017/10/05/reasons-kubernetes-is-cool/
作者:Julia Evans[7] 譯者:qhwdw 校對:wxy
本文由 LCTT 原創編譯,Linux中國 榮譽推出