Kubernetes 官方文件基礎教學翻譯

August 6, 2018

Photo by Joseph Barrientos on Unsplash

本文翻譯自 Kubernetes 官方文件的基礎教學,主要用來學習 Kubernetes 的基礎概念。

翻譯內容主要著重於 Kubernetes 的概念,課程內容所包含的線上互動教學操作不在翻譯範圍之內,如果有興趣請到官方網站自行體驗。

概述

Kubernetes 基礎

本教學提供了一個 Kubernetes 叢集編排系統的基礎知識的演練。每個章節包含一些 Kubernetes 主要的特色以及概念的背景知識,並包含了一個線上的互動教學。這些互動教學讓你管理一個簡單的叢集和容器化的應用程式

Kubernetes 可以為我做些什麼?

使用現代 Web 服務,使用者期望應用程式是隨時都可以使用的,而開發者則希望每天可以多次部署應用程式的新版本。

容器化有助於軟體的打包來實現這些目標,讓應用程式能夠以簡單快速的方式發佈和更新,而無需停機。

Kubernetes 幫助你確保這些容器化應用程式隨時隨地的執行,並幫助它們找到工作所需要的資源和工具。

Kubernetes 是一個 production-ready 的開源平台,借助 Google 在容器編排方面累積的豐富經驗,與結合社群中的優秀想法。

建立一個叢集

使用 Minikube 建立一個叢集

目標

  • 學習什麼是 Kubernetes 叢集
  • 學習什麼是 Minikube
  • 使用線上 Terminal 啟動一個 Kubernetes 叢集

Kubernetes 叢集

Kubernetes 協調一個高可用性的計算機叢集,將它們連接起來作為一個工作單元。Kubernetes 的抽象層允許你部署容器化的應用程式到一個叢集,而不需要將它們綁定到特定的獨立機器。要使用這種新的部署模式,應用程式需要一種將獨立 host 分離的方式被打包:它們需要被容器化。相較於過去的部署模式,容器化的應用程式更加靈活可用,其中應用程式作為 package 深度的被整合到 host,直接安裝到指定的計算機上。Kubernetes 以更有效的方式自動化跨叢集分發和調度應用程式容器。Kubernetes 是一個開源平台而且是 production-ready。

Kubernetes 叢集由兩種類型的資源組成:

  • Master 協調叢集
  • Node 是執行應用程式的 worker

叢集圖解

kubernetes cluster

Master 主要負責管理叢集,協調所有在叢集的活動,像是調度應用程式、保持應用程式的狀態,擴展應用程式,以及滾動更新。

一個 Node 是一個 VM 或是一個實體的主機,在 Kubernetes 叢集中被作為一個工作的計算機。每個 Node 有一個 Kubelet,它是一個管理節點並與 Kubernetes master 溝通的代理。Node 應該需要有工具可以管理容器的操作,例如 Dockerrkt。處理 production traffic 的 Kubernetes 叢集至少要有三個 Node。

當你在 Kubernetes 上部署應用程式時,告訴 master 要啟動應用程式的容器,master 會調度容器以在叢集上的 Node 執行。Node 使用 Kubernetes API 來和 master 溝通,API 是由 master 所公開的。終端使用者也可以使用 Kubernetes API 直接與叢集互動。

Kubernetes 叢集可以被部署在實體或是虛擬主機。在開始使用 Kubernetes 開發時,你可以使用 Minikube。Minikube 是一個輕量化的 Kubernetes 實作,它在你的本地機器建立一個 VM 並且部署只有一個 Node 的簡易叢集。Minikube 可以在 Linux、macOS、以及 Windows 系統上使用。Minikube CLI 提供了與叢集配合使用的基本引導操作,包含 startstopstatus 以及 delete

部署一個應用程式

使用 kubectl 來建立一個 Deployment

目標

  • 學習關於應用程式的 Deployment
  • 使用 kubectl 部署你的第一個應用程式在 Kubernetes

Kubernetes Deployments

一旦你有了一個執行 Kuberentes 的叢集,你可以在上面部署你容器化的應用程式。因此,你要建立一個 Kubernetes 的 Deployment 設定。Deployment 說明 Kubernetes 如何建立和更新你的應用程式的 Instance。一旦你建立了一個 Deployment,Kubernetes 調度提及的應用程式 Instance 到叢集上獨立的 Node。

一旦應用程式的 Instance 被建立後,Kubernetes Deployment Controller 持續的監控這些 Instance。如果 Node host 的 Instance 被關閉或刪除,Deployment Controller 會替換它。這個提供了一個自我修復的機制來解決機器的故障或者是維護問題。在預先編排(pre-orchestration)的世界,安裝 script 通常可以被用來啟動應用程式,但沒辦法讓機器從故障中恢復。透過建立應用程式 Instance 並讓它們在 Node 之間執行,Kubernetes Deployment 提供了一個從根本上完全不同的應用程式管理方法。

部署你的第一個應用程式在 Kubernetes

First App

你可以透過 Kubernetes 的命令提示介面 Kubectl 來建立並管理一個 Deployment。Kubectl 使用 Kubernetes API 來和叢集互動。在這個章節,你將學習到在 Kubernetes 叢集上建立 Deployment 來執行你的應用程式常用的 Kubectl 命令。

當你建立一個 Deployment,你將需要指定應用程式的容器映像檔,以及你想要執行的副本數量。你可以在之後改變資訊透過更新 Deployment;章節 56 討論如何擴展和更新你的 Deployment。

對於我們第一個 Deployment,我們將打包 Node.js 應用程式到 Docker 容器。原始碼和 Dockerfile 可以在 GitHub Repository 上找到。

探索你的應用程式

Pod 和 Node 概觀

目標

  • 學習關於 Kubernetes Pod
  • 學習關於 Kubernetes Node
  • 部署應用程式的常見問題

Kubernetes Pod

當你在章節 2 建立一個 Deployment,Kubernetes 建立一個 Pod 來 host 你的應用程式 Instance。Pod 是一個 Kubernetes 的抽象,代表一組或是多個應用程式的容器(像是 Dockerrkt),以及這些容器的一些共享的資源,這些資源包括:

  • 共享的 Storage,作為 Volumes
  • Networking,作為一個獨立的叢集 IP 位址
  • 關於如何執行每個容器的資訊,像是容器映像檔的版本以及使用的特定端口

Pod 是一個特定於應用程式的「Logical Host」,並且可以包含相對緊密耦合的不同應用程式容器。例如,一個 Pod 可能包含 Node.js 應用程式的容器,以及一個透過 Node.js Web Server 提供要發布的資料的不同容器。在 Pod 內的容器共用一個 IP 位置、端口位置,始終位於同一個位置,共同被調度,在同一個 Node 並執行在一個共享的 Context。

Pod 在 Kubernetes 平台上是 Atomic Unit 的。當我們在 Kubernetes 上建立一個 Deployment,Deployment 建立 Pod 以及在 Pod 內部的容器(而不是直接建立容器)。每個 Pod 都與調度它的 Node 綁定,並保持在那裡直到終止(根據重啟策略)或刪除。如果 Node 發生故障,在叢集內的相同 Pod 會被調度到其他的可用的 Node 上。

Pod 概觀

Pod

Node

一個 Pod 總是執行在 Node 上。Node 是 Kubernetes 上的工作機器(Worker Machine),可能是一個虛擬或是實體機器,具體取決於叢集,每個 Node 都由 master 管理。一個 Node 可以有多個 Pod,而且 Kubernetes master 會在叢集內自動的處理 Node 之間的調度。Master 的自動調度考慮到了每個 Node 上可用的資源。每個 Kuberntes Node 至少需要執行:

  • Kubelet,一個在 Kubernetes master 和 Node 之間負責溝通的程序;它管理在機器上的 Pod 和容器的執行。
  • 一個容器 runtime(像是 Dockerrkt)負責從 registry 拉取(Pulling)映像檔,取出容器並執行應用程式。

Node 概觀

Node

kubectl 常見問題

在章節 2,你使用了 Kubectl 命令列介面。你將會在章節 3 持續地使用它們來部署應用程式和它們的環境。常見的操作可以透過以下的 kubectl 命令:

  • kubectl get - 列出所有資源
  • kubectl describe - 顯示關於資源的詳細資料
  • kubectl logs - 從 Pod 列印日誌
  • kubectl exec - 從 Pod 執行命令

你可以使用這些命令了解應用程式的部署時間、目前的狀態,以及它們執行位置和設定。

公開你的應用程式

使用 Service 來公開你的應用程式

目標

  • 學習 Kubernetes 的 Service
  • 了解如何將 Label 和 LabelSelector Object 關聯到一個 Service
  • 使用 Service 在 Kubernetes 叢集外部公開應用程式

Kubernetes Service 概觀

Kubernetes 的 Pod 是有生命週期的。事實上,Pod 具有 Lifecyle。當一個工作節點故障時,在 Node 上所有執行的 Pod 都會丟失。ReplicationController 可以動態的驅動叢集經由建立新的 Pod 回到原來的狀態來保持應用程式的執行。另一個例子,考慮具有三個副本的影像處理後端。這些副本是可替代的;前端系統不在意關於後端的副本,或是 Pod 已經在丟失後被重新建立。也就是說,每個在 Kubernetes 叢集的 Pod 有一個獨立的 IP 位址,甚至 Pod 在相同的 Node 上,所以需要一種方法來自動的協調 Pod 之間的更改,讓程式可以繼續的執行。Kubernetes 中的 Service 是一個抽象化的概念,它定義一組邏輯的 Pod 和存取它們的方針。服務啟用與 Pod 之間是一個鬆散的依賴。一個 Service 使用 YAML(首選) 或是 JSON 來定義,像所有的 Kuberntes 的 Object。一個 Service 所針對的 Pod 通常透過 LabelSelect 被確定。

儘管每個 Pod 有一個獨立的 IP 位址,但如果沒有 Service,這些 IP 不會在叢集外部公開。Service 允許你的應用程式接收 traffic。透過在 ServiceSpec 指定 type,可以用不同的方式公開服務:

  • ClusterIP(預設):在叢集內部的 IP 上公開服務。此類型使服務只能從叢集中訪問。
  • NodePort:在叢集內使用 NAT 每個選定 Node 上的同一 Port 的公開服務。使用 <NodeIP>:<NodePort> 讓服務可以被外部訪問。ClusterIp 的超集。
  • LoadBalancer:在目前的 Cloud(如果支援)建立一個外部的 Load balancer 並為服務分配固定的 IP。NodePort 的超集。
  • ExternalName:通過回傳帶有名稱的 CNAME 記錄,使用任意名稱(在規範中由 externalName 指定)公開服務。沒有使用任何的 proxy,這個類型需要 v1.7 或更高版本的 kube-dns

更多不同的類型的 Service 可以在  Using Source IP 教學中找到。也可以參考 Connecting Applications with Services

此外,請注意有些 Service 的使用情境涉及未在規範中定義 selector。被建立的 Service 沒有 selector 將不會建立對應的 endpoints object。這讓使用者可以手動的 map 服務到特定的 endpoints。另一種沒有 selector 的可能性是你嚴格的使用 type: ExternalName

Service

Service 通過一組 Pod 路由流量。Service 是一種抽象,允許 Pod 在 Kubernetes 中死亡和複製,而不會影響你的應用程式。Kubernetes Service 處理依賴的 Pod(如應用程式中的前端和後端元件)之間的 Discovery 和 Routing。

Service 使用 labels 和 selectors 來匹配 Pod,一個分組的 Primitive 允許對 Kubernetes 中的 Object 進行邏輯運算。Label 是 Key/Value 被附加到 Object,而且可以以多種方式使用:

  • 指定 Object 為 development、test、或者是 production。
  • 嵌入版本 Tag
  • 使用 Tag 分類 Object
Label

Label 可以在建立的時候被附加到 Object,或者是在建立 Object 完成之後。它可以在任何時候被修改。

擴展你的應用程式

執行多個應用程式的 Instance

目標

  • 使用 kubectl 擴展應用程式

擴展應用程式

在先前的章節我們建立了 Deployment,並且藉由 Service 公開服務。Deployment 只建立一個 Pod 來執行我們的應用程式。當流量增加時,我們將需要擴展應用程式來滿足用戶的需求。透過更改 Deployment 內的副本數量來完成擴展。

Scaling-1Scaling-2

擴展一個 Deployment 將確保可用的資源被用來建立 Pod 並調度到 Node。擴展將會增加 Pod 的數量到新的理想狀態。Kubernetes 也支援 Pod 的 Auto Scaling,但這超出了這個教學的範圍。擴展到 0 也是有可能發生的事,但它將終止指定 Deployment 所有的 Pod。

執行多個應用程式的實例將需要一個方式來將流量分散給所有這些實例。Service 有一個整合的 Load-Balancer,可將網路的流量分散到公開的 Deployment 的所有 Pod。Service 將使用 Endpoints 持續監控執行的 Pod,來確保流量只被傳送到可用的 Pod。

一旦你的應用程式有多個執行的實例,你可以在沒有 Downtime 的情況下執行滾動更新。

更新你的應用程式

執行滾動更新

目標

  • 使用 kubectl 執行滾動更新

更新應用程式

使用者希望應用程式始終可用,而開發者則每天則需要多次部署新版本的應用程式。在 Kubernetes 中,是通過滾動更新完成的。滾動更新透過增加更新的 Pod 實例,讓 Depolyment 的更新在 Zero Downtime 完成。新的 Pod 將在具有可用資源的 Node 上進行調度。在前面的章節,我們擴展了應用程式來執行多個 Instance。這是一個執行更新而不影響應用程式使用的要求。預設情況下,在更新期間的最大 Pod 可用數量以及新建立的 Pod 數量是一個,兩者選項都可以被設定為數字或是百分比。在 Kubernetes 中,更新是有版控的 ,任何 Deployment 的更新都可以被 revert 到先前的(穩定)版本。

滾動更新概觀

module_06_rollingupdates1module_06_rollingupdates2module_06_rollingupdates3module_06_rollingupdates4

與應用程式的擴展類似,如果一個 Deployment 是公開的,在更新的時候,Service 將在更新期間僅將流量負載平衡到可用的 Pod。一個可用的 Pod 是一個使用者可以使用的應用程式實例。

滾動更新以下的操作:

  • 將一個應用程式從一個環境 promote 到另一個環境(經由容器映像檔來升級)
  • Rollback 到先前的版本
  • Zero Downtime 的持續整合和持續交付的應用程式