這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Kubernetes 之所以酷
前言
當我最開始瞭解到 Kubernetes 的時候(大概一年半以前?),我真的找不出需要關注它的理由。
滿打滿算,我已經使用 Kubernetes 快三個月以上了。關於為什麼我覺得它非常有用,有了一些想法,雖然我仍然還算是一個剛入門的,不過,幸運的是,本文依然能夠向您闡述一下,Kubernetes 究竟是怎麼一回事。
我在向您解釋 Kubernetes 多麼有趣的過程中,會盡量避免使用一些太專業的名詞,比如 Native Cloud、Orchestration、Container、Kubernetes 的一些專用語 。我主要是從一個 Kubernetes 營運工程師的角度向你解釋,因為我當前的工作就是搭建並配置 Kubernetes 運行環境,並讓他正常運行。
我不會去討論如“我是否應該把 Kubernetes 應用到生產環境中?”這種不是一兩句話能說明的問題(因為“是否用於生產環境”完全取決於你做的是什麼)。
Kubernetes 讓你無需啟動新伺服器就直接在生產環境運行代碼
我最開始接觸 Kubernetes 是源自於和我同事 Kamal 的對話:
- Kamal:用
Kubernetes 你只需要簡單的一個命令就能啟動一個新服務
- Julia:這怎麼可能?
- Kamal:比如,你只需要寫一份設定檔,然後應用它,然後你就有了一個運行在生產環境的
HTTP 服務
- Julia:但是,當前如果我要建立一個
AWS(亞馬遜雲端服務)執行個體,需要寫一個
manifest,然後啟動服務發現,配置我的負載平衡,配置我們的開發軟體,還要保證 DNS 工作正常,就算這切都順利完成,也要至少 4 個小時的時間啊!
- Kamal:Yeah。用
Kubernetes ,你就不再需要做這些事情了,你能夠在 5 分鐘內啟動一個 HTTP 服務,並且他將自動運行。只要你叢集有相應的空間容納這個服務,它就直接能用!
- Julia:估計這裡面有不少坑吧。
這裡面的坑,應該要算配置 Kubernetes 了,確確實實不簡單(以我的經驗來說),你可以查看這個Kubernetes The Hard Way。但至少目前來說,我們不用擔心這個事情。
呐,現在第一個酷的地方在於,Kubernetes 有巨大的潛力讓開發人員輕鬆地部署服務到生產環境。這真的很酷,使用 Kubernetes 工作,你真的可以在 5 分鐘內,用一個設定檔啟動一個新的 HTTP 服務(包括“啟動 5 個服務程式”、“配置負載平衡”、“配置 DNS”),值得瞭解一下。
Kubernetes 提供可視化介面讓你管理你啟動並執行代碼
在我看來,你在瞭解 Kubernetes 之前,必須要瞭解 etcd。那就讓我們先看看 etcd
是個什麼!
想象一下,今天我問你“告訴我,生產環境中現在都運行了些什麼應用?都運行在哪些主機上的?服務狀態正常嗎?是否有 DNS 綁定?”,我不清楚你的情況,我只知道,如果是我,我需要查看一大堆不同位置的伺服器,花我一小會兒時間才能搞明白並回答這些問題,不可能通過一個 API 就能得到所有資訊。
在 Kubernetes 上,你叢集中所有的狀態:啟動並執行應用、節點、DNS 名、定時任務等等,都儲存在一個統一的資料庫中,Kubernetes 所有的組建都是無狀態的,並且都是通過一下過程來啟動並執行:
- 從
etcd 中讀取狀態,比如:1 號節點中的應用清單
- 改變狀態,比如:在 1 號節點中啟動一個應用 A
- 更新
etcd 中的狀態,比如:將應用 A 的狀態設定為“運行中”
這意味著,如果你想要回答一個問題“嘿,在可用性區域域中,有多少 nginx 在運行?”,你只需要查詢一個統一的 API(Kubernetes提供)即可,Kubernetes 中其他的組建也都能通過這種簡單的 API 方式使用。
這同時也意味著,你能夠通過一個簡單的方式,控制所有 Kubernetes 中啟動並執行東西。只要你願意,你可以這樣做:
- 執行一個複雜的發布策略(部署 1 個任務,等待 5 分鐘,部署 5 個或更多,等待 3.7 分鐘等等)
- 在將一個分支提交到
Github 後,自動啟動一個 webserver
- 監控所有運行中的應用,以確保他們每個都有一個合理的
cgroups 記憶體上線
你所需要做的只是寫一個調用 Kubernetes API 的程式(控制器“controller”)
另一個比較酷的關於 Kubernetes API 的事情就是,你不用局限於 Kubernetes 所提供的一些管理方式,你可以自己編寫程式調用 Kubernetes API 實現自訂的 部署/建立/監測任務。他讓你能做所有你需要的事情!
就算 Kubernetes 所有組件都掛了,你的應用照樣運行
許多寫 Kubernetes 的部落格一開始就保證的一件事是:“如果 Kubernetes 的 API 服務和其他組件都掛了,這沒什麼事兒,你的程式將會繼續運行!”,我認為,這件事理論上聽起來很酷,但我並不敢確定這是真的。
使用了這麼久,這的確是真的!
我經曆了一些 etcd 掛掉的情況,但是:
- 所有程式都照常在運行
- 沒有其他新的連鎖事件發生(當然,你無法部署新的程式或者提交修改,定時任務也會停止運行)
- 當所有問題都修複後,叢集會重新搜集之前丟失的資訊
當然這也意味著,如果 etcd 掛了,然後某個運行中的程式崩潰了或者發生其他錯誤,在 etcd 重新啟動之前他將無法自動處理問題。
Kubernetes 的設計協助其不會輕易被 bug 搞崩潰
像其他軟體一樣,Kubernetes 也會有 bug。比如,現在我們叢集中的控制器就有記憶體流失的問題,調度器經常崩潰。Bug 當然不是什麼好東西,但是使用下來,我發現 Kubernetes 的設計協助其減少了很多在核心組件中潛在的 bug。
如果你重啟任何一個組建,將會發生:
- 從
etcd 中讀取所有相關的狀態資料
- 開始執行一些基於目前狀態必要的操作(調度應用、記憶體回收、調度任務、部署守護進程等等)
因為所有的組建都不在記憶體中儲存其狀態,所以你能夠在任何時候重啟組件,這通常還能避免一些 bug 的發生。
例如,你的控制管理組件有記憶體流失的問題,由於控制管理組件是無狀態的,你能夠間歇的重啟它,比如每小時一次,並且完全不會產生其他不好的連鎖反應。又比如,我們的調度器出了 bug,他有時會落下某些程式然後從不調度他們。你就可以通過每十分鐘重啟一次調度器來減少這個問題的發生。(我們沒這樣做,因為我們修複了這個 bug,但你可以這樣做啊 )
因此我覺得,我能夠相信 Kubernetes 的設計,相信它能夠保證即使核心組件出了問題,也能夠保持叢集狀態的連續性。並且一般來說,我認為軟體的品質是隨著時間慢慢提高的,現在有狀態的並且需要你操作的,就只有 etcd。
關於 state 我就不再多說什麼了,我認為你唯一需要解決的備份/恢複問題就只有 etcd(除非你應用都是寫入到永久儲存空間上的)。我認為,這讓 Kubernetes 的操作變得簡單了很多。
在 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 有很多組件,要想學會如何配置一個高可用的 Kubernetes 叢集需要大量的工作。比如我發現他給了我很多抽象的介面,我需要瞭解這些介面底層都是怎麼實現的,才能讓我更快速的調試以及寫出更好的配置。我喜歡學習新事物,所以這並沒有讓我感到不開心或者其他什麼的,我只是覺得,這個認識很重要!
一個更加實際的,關於“我不能僅僅依靠這些抽象的介面”的例子。我很掙紮地學習 linux 的網路知識,才能讓我很自信的配置 Kubernetes 的網路,肯定會比我完全不瞭解網路更好。這會很有趣,但是也很耗時間。以後我或許會寫一些關於配置 Kubernetes 網路的難與樂。
另外我寫了一篇 2000 字的博文,講了在配置 Kubernetes CA 中,所有必須學習的、關於 Kubernetes 認證認證的不同配置項的知識。
我認為一些 Kubernetes 系統管理軟體,比如 GKE (google’s kubernetes product),可能會簡單一點,因為他為使用者做了大量預設的設定,但我並沒有嘗試過任何一種。