來自個人博客小站 Level Uplinux
當我最開始瞭解到 Kubernetes
的時候(大概一年半之前?),我真的找不出須要關注它的理由。nginx
滿打滿算,我已經使用 Kubernetes
快三個月以上了。關於爲何我以爲它很是有用,有了一些想法,雖然我仍然還算是一個剛入門的,不過,幸運的是,本文依然可以向您闡述一下,Kubernetes
到底是怎麼一回事。git
我在向您解釋 Kubernetes
多麼有趣的過程當中,會盡可能避免使用一些太專業的名詞,好比 Native Cloud、Orchestration、Container、Kubernetes 的一些專用語? 。我主要是從一個 Kubernetes
運維工程師的角度向你解釋,由於我當前的工做就是搭建並配置 Kubernetes
運行環境,並讓他正常運行。github
我不會去討論如「我是否應該把 Kubernetes
應用到生產環境中?」這種不是一兩句話能說明的問題(由於「是否用於生產環境」徹底取決於你作的是什麼)。web
我最開始接觸 Kubernetes
是源自於和我同事 Kamal 的對話:數據庫
Kubernetes
你只須要簡單的一個命令就能啓動一個新服務HTTP
服務AWS
(亞馬遜雲服務)實例,須要寫一個manifest
,而後啓動服務發現,配置個人負載均衡,配置咱們的開發軟件,還要保證 DNS
工做正常,就算這切都順利完成,也要至少 4 個小時的時間啊!Kubernetes
,你就再也不須要作這些事情了,你可以在 5 分鐘內啓動一個 HTTP
服務,而且他將自動運行。只要你集羣有相應的空間容納這個服務,它就直接能用!這裏面的坑,應該要算配置 Kubernetes
了,確確實實不簡單(以個人經驗來講),你能夠查看這個Kubernetes The Hard Way。但至少目前來講,咱們不用擔憂這個事情。服務器
吶,如今第一個酷的地方在於,Kubernetes
有巨大的潛力讓開發者輕鬆地部署服務到生產環境。這真的很酷,使用 Kubernetes
工做,你真的能夠在 5 分鐘內,用一個配置文件啓動一個新的 HTTP
服務(包括「啓動 5 個服務程序」、「配置負載均衡」、「配置 DNS」),值得了解一下。網絡
在我看來,你在瞭解 Kubernetes
以前,必需要了解 etcd
。那就讓咱們先看看 etcd
是個什麼!app
想象一下,今天我問你「告訴我,生產環境中如今都運行了些什麼應用?都運行在哪些主機上的?服務狀態正常嗎?是否有 DNS
綁定?」,我不清楚你的狀況,我只知道,若是是我,我須要查看一大堆不一樣位置的服務器,花我一小會兒時間才能搞明白並回答這些問題,不可能經過一個 API
就能獲得全部信息。負載均衡
在 Kubernetes
上,你集羣中全部的狀態:運行的應用、節點、DNS 名、定時任務等等,都存儲在一個統一的數據庫中,Kubernetes
全部的組建都是無狀態的,而且都是經過一下過程來運行的:
etcd
中讀取狀態,好比:1 號節點中的應用清單etcd
中的狀態,好比:將應用 A 的狀態設置爲「運行中」這意味着,若是你想要回答一個問題「嘿,在可用區域中,有多少 nginx
在運行?」,你只須要查詢一個統一的 API
(Kubernetes提供)便可,Kubernetes
中其餘的組建也都能經過這種簡單的 API
方式使用。
這同時也意味着,你可以經過一個簡單的方式,控制全部 Kubernetes
中運行的東西。只要你願意,你能夠這樣作:
Github
後,自動啓動一個 webserver
cgroups
內存上線你所須要作的只是寫一個調用 Kubernetes API
的程序(控制器「controller」)
另外一個比較酷的關於 Kubernetes API
的事情就是,你不用侷限於 Kubernetes
所提供的一些管理方式,你能夠本身編寫程序調用 Kubernetes API
實現自定義的 部署/新建/監測任務
。他讓你能作全部你須要的事情!
許多寫 Kubernetes
的博客一開始就保證的一件事是:「若是 Kubernetes
的 API
服務和其餘組件都掛了,這沒什麼事兒,你的程序將會繼續運行!」,我認爲,這件事理論上聽起來很酷,但我並不敢肯定這是真的。
使用了這麼久,這的確是真的!
我經歷了一些 etcd
掛掉的狀況,可是:
固然這也意味着,若是 etcd
掛了,而後某個運行中的程序崩潰了或者發生其餘錯誤,在 etcd
從新啓動以前他將沒法自動處理問題。
像其餘軟件同樣,Kubernetes
也會有 bug
。好比,如今咱們集羣中的控制器就有內存泄漏的問題,調度器常常崩潰。Bug
固然不是什麼好東西,可是使用下來,我發現 Kubernetes
的設計幫助其減小了不少在覈心組件中潛在的 bug
。
若是你重啓任何一個組建,將會發生:
etcd
中讀取全部相關的狀態數據由於全部的組建都不在內存中保存其狀態,因此你可以在任什麼時候候重啓組件,這一般還能避免一些 bug
的發生。
例如,你的控制管理組件有內存泄漏的問題,因爲控制管理組件是無狀態的,你可以間歇的重啓它,好比每小時一次,而且徹底不會產生其餘很差的連鎖反應。又好比,咱們的調度器出了 bug
,他有時會落下某些程序而後從不調度他們。你就能夠經過每十分鐘重啓一次調度器來減小這個問題的發生。(咱們沒這樣作,由於咱們修復了這個 bug
,但你能夠這樣作啊? )
所以我以爲,我可以相信 Kubernetes
的設計,相信它可以保證即便核心組件出了問題,也可以保持集羣狀態的連續性。而且通常來講,我認爲軟件的質量是隨着時間慢慢提升的,如今有狀態的而且須要你操做的,就只有 etcd
。
關於 state
我就再也不多說什麼了,我認爲你惟一須要解決的備份/恢復
問題就只有 etcd
(除非你應用都是寫入到永久存儲器上的)。我認爲,這讓 Kubernetes
的操做變得簡單了不少。
假設你想部署一個新發布的定時任務系統!用其餘方式作的話,這將是成噸的工做量。可是,在 Kubernetes
上部署一個新的發佈的定時任務系統卻至關簡單!(它仍然只是一個發佈系統)
最開始我讀 Kubernetes
定時任務控制器代碼的時候,我真的很開心,由於他代碼很簡單。點擊這裏閱讀cronjob_controller.go,主要邏輯代碼也就 400 多行的 go
代碼。
定時任務管理器的主要工做是:
每 10 秒:
Kubernetes
控制器組件執行Kubernetes
的模型挺限制的(他是這麼一種模式:資源都定義在 etcd
中,控制器經過讀取這些資源而後更新 etcd
),而且我認爲這種相關的選項和限制性的模型會讓你在 Kubernetes
的框架中開發本身的發佈系統更加簡單。
Kamal 給我傳遞了這麼一種思想:「Kubernetes
是一個編寫你本身發佈系統的好平臺」而不只僅是 「Kubernetes
是一個你能使用的發佈系統」,我認爲這頗有趣。他有一個原型放在 Github
上的 system to run an HTTP service for every branch you push to github。這花了他兩週的時間,好像只有 800 行的 go
代碼,這讓我眼前一亮!
我一開始就說 「Kubernetes
讓你作不少神奇的事情,你僅僅只須要用一個配置文件,就能串起大量的部件以及流程,這讓人難以置信」,固然這是真的!
爲何我說 「Kubernetes
並非那麼簡單」是由於 Kubernetes
有不少部件,要想學會如何配置一個高可用的 Kubernetes
集羣須要大量的工做。好比我發現他給了我不少抽象的接口,我須要瞭解這些接口底層都是怎麼實現的,才能讓我更快速的調試以及寫出更好的配置。我喜歡學習新事物,因此這並無讓我感到不開心或者其餘什麼的,我只是以爲,這個認識很重要!
一個更加實際的,關於「我不能僅僅依靠這些抽象的接口」的例子。我很掙扎地學習 linux 的網絡知識,才能讓我很自信的配置 Kubernetes
的網絡,確定會比我徹底不瞭解網絡更好。這會頗有趣,可是也很耗時間。之後我或許會寫一些關於配置 Kubernetes
網絡的難與樂。
另外我寫了一篇 2000 字的博文,講了在配置 Kubernetes CA
中,全部必須學習的、關於 Kubernetes
證書認證的不一樣配置項的知識。
我認爲一些 Kubernetes
系統管理軟件,好比 GKE
(google’s kubernetes product),可能會簡單一點,由於他爲用戶作了大量默認的設置,但我並無嘗試過任何一種。