面向 Kubernetes 程式設計:Kubernetes 是下一代作業系統

ServiceMesher發表於2019-02-21
作者:陳俊(心貴),螞蟻金服

此文章適合沒有任何 Kubernetes/容器/Docker 經驗的同學 — 在不久的將來,你不懂如何操作 Kubernetes 介面,就等於現在的你不懂最普通的 Linux 命令。此文章閱讀耗時大概 15 分鐘。

螞蟻金服資源排程組致力於將 Kubernetes 落地到世界上最有價值的金融科技獨角獸公司,歡迎聯絡作者微信 answer1991chen 諮詢招聘事宜。

文章 Markdown 原始碼位於 github.com/answer1991/… ,遵從 Apache License 2.0 開源協議。

導言

此文章著重介紹如何在入門階段使用 Kubernetes,以及要面向 Kubernetes 程式設計帶來的優勢,不會介紹複雜的 Kubernetes 架構、實現。因此此文章適合沒有任何 Kubernetes/容器/Docker 經驗的同學,對 Kubernetes 有了解的同學也可以從此文章裡面獲取一些靈感,可以更加酷炫的玩轉 Kubernetes。

希望在閱讀完此文章之後,你可以從 “我需要一個 Linux VM 做開發、測試和部署”,變成 “我需要一個 Kubernetes 做開發、測試和部署”。

Kubernetes 是下一代作業系統

Kubernetes 是這幾年非常熱門的一個詞彙,大概所有的軟體工程師都已經聽說過這個詞。

那麼 Kubernetes 到底是什麼呢?可能 Google 會告訴你很多,但是我想告訴你的是:Kubernetes 是下一代作業系統;一個 Kubernetes 叢集是一個資源無限大(可擴容)的虛擬機器。而且,Kubernetes 的介面是是宣告式的,是天然面向分散式系統而設計的(下面會詳細介紹)。

說到這裡,大家估計立刻就有疑問了。我想大概是這些:

Q: 那麼,Linux、Windows 要被淘汰了?

A: 不會被淘汰,只是 Linux、Windows 是一個底層的單機作業系統。而我們這些普通的應用軟體工程師將來都不會跟Linux 打交道了,都會使用 Kubernetes 這個更上層、同時功能也更強大的作業系統。

Q: 那麼,我不學 Kubernetes 可以嗎?

A: 不行!在未來不久的某一天,也許雲廠商只賣 Kubernetes “虛擬機器”了:阿里雲不單獨賣 ecs 了,亞馬遜AWS,微軟雲,Google 雲等各種雲廠商都不賣 Linux 虛擬機器了。如果你想買單機版的 Linux 虛擬機器,他們都會一臉驚訝的問你,你買那麼底層的、功能那麼薄弱的計算機幹什麼?就像你現在從雲廠商那裡買不到一個還沒有安裝 Linux 的虛擬機器一樣。以後,雲廠商交付的 “虛擬機器” 必定是 “叢集級別的虛擬機器” ,而 “叢集級別的虛擬機器” 的作業系統就是 Kubernetes。

在不久的將來,你不懂如何操作 Kubernetes 介面,就等於現在的你不懂最普通的 Linux 命令。

Q: 那這樣的話,我買不到 Linux 虛擬機器,我連學習 Linux 的機會都沒有了?

A: 當然不是,有了 Kubernetes,你可以在 1秒內自己搞一個任何 Linux 發行版本的 “單機虛擬機器” 出來。

Q: Kubernetes 真的是一個作業系統? Show me....

A:

功能/名詞單機 LinuxKubernetes說明
Shell, CMDsh, bashkubectlkubectl 是 Kubernetes 的 shell 工具,有了 kubectl 你就可以連線並管理 Kubernetes 這個超級虛擬機器了。
使用者,登入 LinuxUser, Group, ssh 登入kubeconfig 檔案類似 Linux ssh 的 .key 檔案,使用者使用 kubeconfig 訪問 Kubernetes 就自帶了使用者資訊。Kubernetes 能根據使用者限制許可權,也能限制使用者能使用的資源。kubectl 使用 kubeconfig 訪問 Kubernetes 就好比使用 .ssh key 訪問 LinuxKubernetes 叢集管理員(或者自動化的申請系統)為使用者頒發 kubeconfig 檔案。
程式程式PodPod 就是 Kubernetes 這個 “超級虛擬機器” 的程式。
管理程式ps, killkubectl get po, kubectl delete pod釋出、升級、管理 “程式”(或者說應用)
配置管理登入各個 Linux VM,替換機器上的檔案。kubectl apply -f ./cm.yaml使用 ConfigMap 管理應用的配置檔案,一次提交,程式的每個例項自動生效新的配置。由於篇幅管理,使用 ConfigMap 配置應用(“程式”)啟動引數不在此文章裡面舉例。
釋出、管理、升級應用在 Linux 上面釋出一個應用,需要一頓瘋狂的操作:先閱讀如何釋出、引數有什麼、下載二進位制包、搞定一些配置檔案,然後執行應用。kubectl apply -f ./my-app.yamlmy-app.yaml 可能是應用提供商提供的、面向 Kubernetes 釋出應用的“選單”檔案(為什麼叫“選單”我後面會介紹)。只要提交這個“選單”,應用就部署好了。Kubernetes 讓一切簡單,而且,它是分散式,是天然容災的。只要向 Kubernetes 提交 Deployment 這樣的“資源”即可,下文有介紹。
限制應用資源一頓瘋狂的操作,把應用程式的 Cgroup 限制好。釋出應用時已經做了Kubernetes 讓一切簡單。
分散式應用釋出在各個 Linux 虛擬機器上面釋出好應用,然後把他們組網。釋出應用時已經做了還是那句話,Kubernetes 讓一切簡單。
分散式應用容災搞個監控,監控我們各個 Linux 虛擬機器上面的應用是不是不健康了。不健康了的話,我們起床,來一次“一頓操作猛如虎”的故障恢復操作。/天然容災,安心睡你的覺。
資料持久化,故障時資料遷移“一頓操作猛如虎”用 PV(持久化儲存卷),容災把應用的一個應用例項從 “節點一” 切換到了 “節點二”,都不用做任何資料遷移。新的應用例項起來就能使用老資料。還是那句話,Kubernetes 讓一切簡單。我都不用關心這個事情。(由於篇幅管理,下文的例子中也不會涉及 PV 的例子)

“一頓操作猛如虎” 聽起來很酷,但是你在做一些沒必要的事情,同時你做了這些事情並不討好你的老闆,可能在因為你的失誤操作引起更大的故障和問題。

面向 Kubernetes 做最簡單的操作,達到最佳的效果,才是更酷的事情。

A: 行了行了,別說那麼多了,我還是需要一個 Linux VM。

Q: 好的,我給您一個 Kubernetes,然後給你一個 基礎 OS Pod “選單”檔案,然後您自己就可以建立任何一個 Linux 發行版、任何一個 Linux 版本的的 Linux VM了。在文章的最後會有介紹。

小試牛刀

既然是“小試”,那麼我們來嘗試一個最簡單的應用,一個 HTTP 服務: nignx。同時,我應該部署一個高可用、多副本(例子中為3副本)天然容災的 nginx。

部署完成的結構圖大概如下所示:

面向 Kubernetes 程式設計:Kubernetes 是下一代作業系統

沒有 Kubernetes 之前的部署

在沒有 Kubernetes 之前,我們大概要做這麼些操作才能交付這個 nginx 服務:

  1. 到三個 Linux VM 上面,分別把三個 nginx 程式起好。這裡可能還需要關心 nginx 程式怎麼起、啟動命令是啥、配置怎麼配。

  2. 到負載均衡管理頁面,申請一個負載均衡,把 3個 nignx 程式的 IP 填入。拿回負載均衡的 IP。

  3. 到 DNS 管理頁面申請一個 DNS 記錄,寫入把拿到的負載均衡的 IP 寫入 A 記錄。

  4. 把這個 DNS 記錄作為這個 nginx 服務的交付成果,交付給使用者。

有了 Kubernetes 的部署

有了 Kubernetes 之後, 我們只需要寫一個 nginx 如何部署的 “選單”,然後提交這個“選單”給 Kubernetes,我們就完成了部署。 “選單” 是一個 yaml 檔案(例子中檔名 nginx.yaml),大概這個樣子:

 apiVersion: apps/v1 kind: Deployment metadata:   name: nginx spec:   replicas: 3   selector:     matchLabels:       app-name: my-nginx   template:     metadata:       labels:         app-name: my-nginx     spec:       containers:         - name: nginx           image: nginx --- apiVersion: v1 kind: Service metadata:   name: nginx spec:   selector:     app-name: my-nginx   type: ClusterIP   ports:     - name: http       port: 80       protocol: TCP       targetPort: 80複製程式碼

提交“選單”到 Kubernetes 叢集:

 $ kubectl apply -f ./nginx.yaml複製程式碼

訪問剛部署的 HTTP 服務:

面向 Kubernetes 程式設計:Kubernetes 是下一代作業系統

發生了什麼?這裡大概簡單的介紹一下我們的“選單”:

  1. 我們向 Kubernetes 提交了一個叫 nginx 的 Deployment。Deployment 是 Kubernetes 裡的一種副本保持 “資源宣告”,我們在我們的 Deployment 宣告瞭 需要3個副本(replica: 3),副本的內容(template: ... )是用 nginx 映象啟動的Pod(Pod 即 Linux 裡的程式,如上章節介紹的)。如果沒有玩過 docker 的同學,可以把 nginx 映象 認為是 nginx 二進位制包,只不過它是 docker 映象方式存在的,不在這裡詳細展開。我們的 nginx Pod 打上了 my-app=nginx 這樣的 Label, Label 可以理解成 分類“標籤”,別人(Service)來定位我們 Pod 需要用這樣的 “標籤” 來匹配。

  2. 我們還向 Kubernetes 提交了一個 Service。 提交一個 Service 就是向 Kubernetes 申請一個 負載均衡。Service 依靠 Label (selector: ...) 去找到它的後端真實程式(Pod)。

  3. Service 會根據規則自動生成域名。規則不在這裡詳細展開介紹。

  4. 我們就能用 Service 自動生成的域名作為交付成果,交付給使用者了!

容災

Deployment 能自動副本保持,即我們的 nginx Pod 少了一個,Kubernetes 能自動幫我們補齊。

變更、釋出、升級
  1. 如需要調整副本數目,我們只需要修改 Deployment.Spec.Replica 欄位,再次 kubectl apply -f ./nginx.yaml 即可,副本調整完成。

  2. 如果我們需要升級映象(nginx 二進位制版本),同樣的修改 PodSpec.Containers[*].Image 即可,然後 kubectl apply -f ./nginx.yaml

  3. Deployment 支援滾動升級,在升級時可以一個個升級你的 Pod(滾動升級)。當然,我們線上可能有更加複雜的升級策略,螞蟻金服提供的增強版 Kubernetes 提供比 Deployment 更加實用的升級策略,比如“灰度升級”, “分批升級” 等更加符合生產環境釋出策略的升級方案。

關於“選單” 和 宣告式系統

Kubernetes 是宣告式的系統。關於詳細的介紹 “什麼是宣告式系統”,您可以去 Google 或者內網上面也有許多宣告式系統的介紹。

我這邊有個簡單的比喻:假如你需要一桌菜(至於為什麼是“菜”,是因為這個文章是我在做飯的時候構思的)。但是,這個放菜的 “桌子” 不太穩定(或者說有老鼠來偷吃菜品),一直髮生一些事故,就像我們的線上部署應用的環境一樣,伺服器可能故障。當你需要在這個桌子上面擺上一桌 “菜” 的時候,“菜”可能會壞掉。別擔心,在宣告式系統裡,“廚師長”是個盡職的好同志,當你提交了一份“選單”之後,我們的“廚師長”會一直保證你桌子上的菜一直會和你寫的“選單”裡的菜一模一樣。如果某道“菜”壞了,“廚師長”就幫你再做一份。

在 Kubernetes 裡面,有各種各樣這樣盡職的廚師長(有負責 Deployment 的廚師長,有負責 Service 的廚師長等等)。只要天沒塌下來,你提交的“選單”裡的菜都會一直美美的在桌子上“迎客”。

那麼,我們回過頭來看我說的 “不久的某一天,雲廠商只賣 Kubernetes 虛擬機器了,而不單純的賣 Linux VM”。你真的要買幾個 Linux VM 自己去啟動程式(命令式),然後自己去搭建一套宣告式的系統去守護你的落在各個機器上的分散式應用程式?而不使用更高階、更好用的 Kubernetes 作業系統?

談軟體交付

軟體交付即把我們開發的一套應用程式部署到其它環境。

軟體交付幾個重要關注的點:

  1. 如何快速的部署一套我們的 “全家桶” 應用到客戶環境。為什麼說“全家桶”,是因為我們不可能只交付一個 nginx 服務,我們肯定會交付一套非常複雜的應用或者中介軟體系統,比如交付一套 “支付寶系統” 到某個商業銀行。

  2. 如何在客戶現場做自動化容災,降低駐場和支援成本,或者根本不駐場。

  3. 如何簡單、可靠地升級後續的版本。

  4. 上述的幾點,不管是 “部署”,“容災”,“升級” 都需要關注客戶現場的執行環境,我們有沒有辦法遮蔽這種執行環境差異。比如:我們帶過去的可執行軟體,在客戶的 OS 上是不是能執行;客戶現場的負載均衡方案都不一樣,如果到了客戶現場檢視了他們的負載均衡方案之後再寫一個負責均衡部署方案肯定大大降低了交付效率。

  5. 客戶現場的環境不一樣,必定帶來配置檔案不一樣。讓一個現場交付人員弄懂所有應用的配置引數,是不是一件讓他很頭疼的事情?

軟體交付方案的歷史:

  1. 交付 原始碼: 這應該是最早的時代,客戶現場的環境(作業系統、機型)都不同,需要帶著程式碼到客戶現場編譯,然後執行軟體。

  2. 交付 可執行檔案:像 Java 提出的 "Build once, run everywhere" 概念,在這個時代,我們可以面向一個執行時虛擬機器交付軟體。或者我們都面向 Linux 交付,我們的使用 Go 編譯的二進位制,能順利的部署到大多數的 Linux OS 上。但是這種方案也強依賴客戶現場需要裝上指定版本的 Java 虛擬機器,或者 Linux 特定的版本(應用依賴 Linux 核心特性)。

  3. 交付 映象:交付映象,最大可能的遮蔽了底層 OS, Java 虛擬機器的差異。在映象裡面,我們把自己需要的 OS 基礎 和 Java 虛擬機器也裝上了。不再依賴客戶現場的 OS 和 Java 虛擬機器版本了。

映象最大可能的程度上把我們需要的執行時環境和我們的應用可執行檔案打在一起,在各種環境下面都能完美地執行。那麼,只有映象就能快樂的交付軟體了嗎?在我眼裡,映象做的事情完全不夠。原因無非也是這麼些:

  1. 怎麼配置啟動引數,要交付人員辛苦的讀懂啟動引數配置說明說嗎?

  2. 怎麼做分散式應用的組網、服務發現

  3. 怎麼做容災

  4. 怎麼做部署的後設資料錄入: 今天我在客戶現場把 A 應用部署到了 節點1 上面,我要把這個資訊記在哪兒?

你可能會告訴我,你說的這些我們的 PaaS 系統都能搞定。是的,你說的沒錯!但是當 PaaS 能用統一標準管理應用、遮蔽應用的細節,解決應用的組網和服務發現,監聽每個應用的例項變化(自動化感知故障發生)然後自動恢復(副本保持),那麼它就已經差不多是 Kubernetes 了。把上述的所有功能邏輯都整合在 PaaS,勢必導致 PaaS 的臃腫,我們是不是可以面向 Kubernetes 這個 OS 去做一個輕量級的 PaaS?因為很多功能在 Kubernetes 已經有了,而且肯定比我們自己研發的 PaaS 要好用許多。我們的 PaaS 是不是可以向 Kubernetes 提交 Deployment,而不是自己親自去做程式拉起、副本健康檢查、副本保持等功能。

面向 Kubernetes 交付軟體

正如我上文所說,可能有一天所有客戶現場的 OS 都是 Kubernetes,那我們是不是可以像上文啟動 nginx 服務一樣,用這種 YAML “宣告” 的方式去交付我們的軟體?

當然可以!但是,當我們去交付一個 “全家桶” 服務的時候,我們會發現我們的 YAML 寫了幾千行,甚至上萬行了。這個上萬行的 YAML 誰來維護?就算是分開給各個子應用的 owner 維護,是不是也可能會發生牽一髮而動全身。有沒有更加簡單的方式?

當然有。我們再回來談 “選單” 和做菜。我是一個吃貨,但是我很懶。當我點菜的時候,非常希望點一個 “套餐”,而不希望一個個的去點每個菜,更不希望弄懂菜是怎麼做出來的。我想要點一個 “滿漢全席”(複雜的應用),可我不想清楚的弄懂套餐裡面單獨有什麼菜、每個菜的配方是什麼。一個“滿漢全席”(複雜的應用)裡面,可能有“山珍”(資料庫)和“海味”(Web服務)。我只想告訴我們的“大廚”, 我要 “滿漢全席” ,然後我們的 “大廚” 就心領神會的知道 “滿漢全席” 裡面有什麼,然後把 “滿漢全席” 給做出來。那麼這個 “大廚” 要親自做這裡的每道菜嗎?也不必,因為我們的 “大廚” 也可能是個 “懶人”,當需要一桌 “滿漢全席” 的時候,他只會告訴負責 “山珍” 的 “大廚” ,要一桌 “山珍”(資料庫),然後告訴負責 “海味” 的 “大廚”,要一桌 “海味”(Web服務)。當我們的大廚發現 “山珍“ 和 “海味” 都準備好的時候,他會告我 “滿漢全席” 準備好了。

是不是發現和交付軟體很像?為什麼我們不交付一個 “大廚” 出去?到客戶現場負責交付的人員,只要告訴 “大廚” 我們需要一個 “滿漢全席” 這種套餐級別的宣告就行了。並不是說套餐沒有引數,只是套餐的引數能做到對使用者遮蔽不必要的細節:比如我們的 “滿漢全席” 就只要一個引數,只要讓使用者填他的 “滿漢全席” 需要支援 “多少QPS”。

面向 Kubernetes 程式設計:使用 Operator 交付軟體

上面提到的使用“交付大廚”的方式去交付軟體看起來很美好。那麼,如何實現呢?也就是我們要怎麼培養出屬於我們自己的“廚師”。

其實我們在 “小試牛刀” 的章節已經介紹了一位 “廚師” 了: 負責 “Deployment” 的廚師。只是,他的工作比較通用化、沒有什麼業務含義。它只是負責守護使用者在 “選單” 裡面描述的 “程式”(Pod) 數量,至於怎麼起 “程式” 都是使用者傳入的。

那麼,我們是不是可以根據這個 “廚師” 的模仿出有業務含義的 “廚師”?比如,業界有一位比較出名的一個 “廚師”,是負責 etcd 叢集的。如果我需要一個副本數是3的 etcd 叢集,只要向 Kubernetes 提交如下的一個 “選單”:

 apiVersion: "etcd.database.coreos.com/v1beta2" kind: "EtcdCluster" metadata:   name: "example-etcd-cluster" spec:   size: 3複製程式碼

“etcd廚師長” 就會根據這個 “選單” 做出一個副本數是3(Spec.Size=3)的 etcd 叢集給你。使用者不需要知道 3 副本的 etcd 叢集裡每個副本引數是什麼樣的。

“etcd廚師長” 真實的名字叫 etcd-operator。顧名思義,operator 就是“廚師長”,“xxx-operator”就是 “xxx應用-廚師長”。在不久的將來,我覺得我們也會有 “xx-db-operator”,“xx-web-operator”,我們也用這種簡潔明瞭的宣告方式,快速得到一個 db 例項, 或者一個 “xx-web” 應用。

回到怎麼培養廚師長的話題,首先我們來介紹一下名詞:

  1. CRD (CustomResourceDefinitions):定義“滿漢全席”這樣的全家桶。Deployment 是 Kubernetes 官方的資源定義,Kubernetes 同時向開發者提供了 “自定義資源定義”。開發者可以向 Kubernetes 叢集提交有 “滿漢全席” 的定義,那麼當使用者提交一桌 “滿漢全席” 時,Kubernetes 就明白使用者的請求了,也就是說 Kubernetes 知道使用者所說的 “滿漢全席” 是什麼了。

  2. CR (Custom Resources):一個 CRD 例項,即一桌 “滿漢全席”,也就是類似上文一樣的 YAML 宣告。

  3. Custom Controller: 我們的“廚師長”。當 Controller 發現使用者提交了 一桌 “滿漢全席”,那麼他就開始做菜了。當然它並不是完全親自做每道菜,正如我上文所說。我們的 “廚師長” 可以依賴另一位 “廚師長”,比如 “db 廚師長” 可以依賴 “Deployment 廚師長”,當使用者需要一個 db 例項的時候,“db 廚師長” 只需要負責再向 Kubernetes 提交一個 Deployment 宣告即可。注意:“廚師長” 之間的互動也是靠 “CR” 或者 Kubernetes 官方定義的資源(如 Deployment、Pod)。“廚師長” 一般也是通過 Deployment 的方式部署在 Kubernetes 叢集內(保證了 “廚師長” 自身的穩定性),除非像 “Deployment 廚師長” 這種 Kubernetes 核心 “廚師長”的穩定性 由 Kubernetes 服務提供商保證。

  4. Operator: Kubernetes 裡的 Operator,即 CRD + Custom Controller。

一個簡單的圖將它們串起來:

面向 Kubernetes 程式設計:Kubernetes 是下一代作業系統

上圖展示了我們的 My-App-Operator 的 “廚師長” 的關係圖。當我們需要一個 "my-app" 應用例項時,我們只要告訴我們的 “廚師長” 是需要多少副本數的例項。我們的 “廚師長” 自動將需求轉化成 Deployment,其它的功能就完全依靠了 “Deployment 廚師長”。

如何面向 Kubernetes 寫一個 Operator

首先我們來看一下 “廚師長” (Operator) 需要關注一些什麼事情,以及它做了什麼事情:

  1. 多久要開始做菜(Observe):即 “廚師長” (Operator/Controller) 需要知道多久他要開始工作了。當使用者提交了 “選單”(CR),“廚師長” 要開始做菜。或者,因為 “桌子” 上少了一個預期中的 “菜”(Pod 因為故障少了一個),“廚師長” 也要開始做菜了。

  2. 做什麼菜(Analyze): “廚師長” 首先要看看桌子上的菜,再對比一下使用者的 “選單”,得出還缺少什麼菜,那麼就做什麼菜。

  3. 開始做菜(Action):得出做什麼菜之後,那麼後面的事情就簡單了。通知其他 “廚師長” 做菜(提交一個其他的CR),或者自己親手做個菜(提交一個 Pod)。

這3件事情,其實就是 Controller 模式的核心三件事:

面向 Kubernetes 程式設計:Kubernetes 是下一代作業系統

那麼用 Kubernetes 寫一個 Operator 需要多久?

可能從 “0” 到可以把 Operator 執行起來只需要 10分鐘吧。因為 Kubernetes 的 Kube-Apiserver 提供天然的 watch 介面,我們可以去關注我們在意的資源(我們的 CR,我們的 Pod 等),這樣我們的 “廚師” 就能很自然的得到通知該幹活了。然後 “廚師” 就開始做出分析,到最後再向 Kube-Apiserver 提交我們想要的資源(Deployment,或者其它的 CR)。我們都面向 Kube-Apiserver 做程式設計, 所有的“廚師”都 向 Kube-Apiserver 提交、修改、Watch資源作為統一的互動協議,一切都會變得簡單許多。

最後,再加上 Operator 的腳手架幫我們生成基礎程式碼(初始化 Kubernetes 客戶端,建立 Watch 等),我們開發者只需要關心的怎麼 Analyze 和 Action 即可。 Operator 的腳手架社群常見的有 kube-builder 和 coreos 提供的 operator-framework 等。

我們用虛擬碼來寫一下上文畫的 My-App-Operator 核心邏輯 (其它都腳手架做好了,甚至如何 build,Operator 本身它自己如何部署的“選單” YAML 都是腳手架生成好了):

 // Reconcile 即我們 Operator 核心程式碼邏輯 // Reconcile 何時觸發,也是 Operator 生成好了 func Reconcile(crName string) error {     // 獲取 CR (使用者提交的“選單”)     cr := client.getCR(crName)     // 計算出這個 CR 期望的 Deployment (使用者提交的“選單”應該在桌子上有什麼菜)     desireDeployment := getDesireDeployment(client, cr)     // 目前叢集裡面實際的 Deployment (實際上桌子上有什麼菜)     deployment := client.GetDeployment(crName)          // 如果期望和實際的不太一樣,把實際的更新一下就行了。     if diff(desireDeployment, deployment) {         return client.UpdateDeployment(desireDeployment);     }           // 如果期望和實際都一樣,什麼事情都不做了。     return nil }複製程式碼
面向 Kubernetes 變成 和 Operator 的優勢總結
  1. 統一的資訊獲取源和統一的介面: Kube-Apiserver 就像是一個大的資訊流轉中心。所有的元件(“廚師長”)都通過這個中心上傳他負責的資源(CR,Deployment,Pod都是 Kubernetes 的資源)的資訊,同時,他也通過這個介面,去感知其它資源狀態的變化,如果這些變化是他感興趣的,那麼他就開始工作(“廚師長” 開始工作)。

  2. 構建在 Kubernetes 核心元件以及 社群通用的 Operator 之上:站在巨人的肩膀上能讓我們的工作更加的減負同時達到更加理想的效果。上文中,我們的 Operator 可能在依賴 Deployment 之後,他負責的 “菜”(Pod)就自帶副本保持功能。同時,假如我們的應用(DB,Web)要依賴社群的 MySQL 資料庫,那麼我們的應用 Operator(Web + DB) 可以通過社群的 MySQL-Operator 提供的 CR 快速建出 MySQL 例項,然後再使用 Deployment 建出 Web。

優秀的社群 Operator
  1. 優秀的社群 Operator (awesome-operators): github.com/operator-fr…

FaaS

用 Operator 交付軟體,目前看起來是最酷的一種交付軟體方式。

但是在當今雲原生技術快速發展的時代,可能在不久的將來,Operator 模式可能也會被淘汰。因為 Operator 也需要開發者關注一些部署的細節,讓開發者真正只關注在自己的業務邏輯,“業務程式碼” 變成 “服務” 完全對開發者透明,可能需要比 Kubernetes 更上層的框架 - FaaS框架。

FaaS 全稱是 Function as a service 。使用者只要寫自己的業務函式,向 Kubernetes 提交業務函式,FaaS 框架將業務函式變成 Deployment,變成 Pod,變成 Service。但是 FaaS 目前還在發展階段,並不像 Kubernetes 已經變成事實標準,這裡不再詳細討論。

落地

說了那麼多,其實我的初衷是希望每個開發者都從 Linux VM 轉向 Kubernetes "VM"。但是轉變發生在每個人身上,應該是有各種困難。我能想到的一些最基本的困難大概列在下面,同時歡迎跟我交流你的一些困惑。

程式碼變成映象

大家都知道,Kubernetes 只允許以 Pod 的方式執行“程式”。在 FaaS 沒成熟之前,如何把我們的程式碼變成一個映象是一個比較頭疼的事情。可能應用的開發同學並不想自己去理解 docker,怎麼去打映象。

別擔心!Spring 框架或者其擴充套件的腳手架應該已經可以在工程裡自動新增 Dockerfile 檔案,使用腳手架之後,使用者只要執行 make image 這樣的命令,就能構建出映象了。

別說了,我還是想要一個 Linux VM

向 Kubernetes 提交下面這樣的一個 YAML 檔案,你就能得到一個 ubuntu VM:

 apiVersion: v1 kind: Pod metadata:   name: my-vm-1 spec:   containers:   - name: vm     image: ubuntu複製程式碼

同時,告訴你一個更酷炫的玩法:自己定製一個屬於你自己的 Linux 發行版!在原有的 OS 映象基礎上,加上你的 Shell 工具指令碼、寫一串向愛人表白的話、搞個開機 Logo,都很簡單!做一個屬於你自己的 Linux 映象,那麼在世界的任何地方,你都能起動一個經過你定製的 Linux VM。

哪裡去獲取一個 Kubernetes

首先,試試 mini-kube,或者立刻向阿里雲買一個!

面向 Kubernetes 程式設計:Kubernetes 是下一代作業系統

相關文章