你可以將本文作為開發者快速了解 Kube.NETes 的指南。從基礎知識到更高級的主題,如 Helm Chart,以及所有這些如何影響你作為開發者。
譯自Kubernetes for Lazy Developers。作者 marcobehler 。
介紹
如果你是一位開發者,要么從未使用過 Kubernetes,要么想要復習 Kubernetes 知識,以便讓你的 DevOps 同事對你刮目相看,那么這份指南適合你。
快速問題:為什么將 Kubernetes 縮寫為 K8s?
答案:它將在本指南末尾神奇地揭示,但僅在你完全閱讀完之后。所以,讓我們不再浪費時間。
我們是如何到達這里的?
我在整個職業生涯中遇到的許多開發者,對于他們應用程序生命周期的“現在我已經編寫了代碼,它還需要在某個地方運行”的部分并不一定關心。(根據你的公司對 DevOps 這個詞的定義和認知程度,這可能有所不同)。
但讓我們慢慢開始。運行一個應用程序實際上意味著什么?
這在一定程度上取決于你所使用的編程語言生態系統。例如,在JAVA和現代Web應用程序方面,你可以將所有源代碼編譯成一個單一的可執行 .jar 文件,然后通過簡單的命令運行它。
java -jar myNewAIStartup.jar
對于生產部署,通常你也會希望有一些屬性,用于設置數據庫憑據或其他秘密。在上述的Java Spring Boot情況下,最簡單的方式是擁有一個Application.properties文件,但你也可以使用外部的秘密管理服務。
無論如何,上述的命令實際上是你需要運行的所有內容,用于部署你的應用程序 - 無論你是在裸金屬上、虛擬機上、Docker容器中、有或沒有Kubernetes,甚至是你的Java驅動的烤面包機。
僅運行一個命令肯定不夠。哪里是問題的瓶頸?
關于部署應用程序時可能出現的問題已經在網絡上寫了很多:
- 如果我的DEV環境和PRD環境之間存在庫/操作系統/基礎設施/某些版本不兼容怎么辦?
- 如果某些必需的操作系統軟件包丟失了怎么辦?
- 如果我們不想將應用程序部署到云服務,而是部署到潛水艇上怎么辦?
對于這些問題,根據你使用的編程語言生態系統,解決方法可能會有很大的不同 - 這是在線討論中經常被忽視的一個主題。
對于純粹的Java Web應用程序,上述提到的問題(不包括潛水艇或更明智的基礎設施部分,比如你的數據庫),在很大程度上并不是問題。你在服務器/虛擬機/容器/潛水艇上安裝JDK,運行java -jar,然后幸福地生活在一起。
對于php、Python/ target=_blank class=infotextkey>Python、咳咳,Node,情況就不同了,你很容易在開發、測試或生產環境之間遇到版本不兼容的問題。因此,人們渴望一種解決方案來擺脫這些煩惱:容器。
Docker、Docker Compose和Swarm:回顧
向Docker致敬!
很有可能你已經知道Docker是什么,以及如何使用它。(如果不知道,并且想看一個特定于Docker的指南,請在下面評論!需求越多 → 發布越快)。簡短的總結是:
- 你將源代碼構建為可部署的文件,例如jar文件。
- 你另外構建一個新的Docker鏡像,其中包含你的jar文件。
- 該Docker鏡像還包含運行成功所需的所有附加軟件和配置選項。
→ 你不再部署你的.jar文件,而是部署你的Docker鏡像并運行Docker容器。
這樣做的美妙之處在于:只要在目標機器上安裝了Docker(并且你的主機操作系統與Docker容器兼容內核),你就可以運行任何Docker鏡像。
docker run --name my-new-ai-startup -p 80:8080 -d mynewaistartup
// yay, your application is deployed
// This will start a Docker container based on the `_mynewaistartup_` Docker image.
// That image will, that other things, contain your e.g. -jar file,
// a web application which runs on port 8080, as well as instructions on how to run it.
// Hint: These instructions are `_java -jar mynewaistartup.jar_`.
什么是 'deploying' Docker 鏡像?
你或者你的 CI/CD 服務器設法將你的應用程序制作成了一個 Docker 鏡像。但是這個 Docker 鏡像最終是如何在目標部署服務器上運行的呢?
你理論上可以將 Docker 鏡像保存為 .tar 文件,復制到最終服務器上并在那里加載它。但更現實的情況是,你會將 Docker 鏡像推送到一個 Docker Registry,無論是dockerhub、Amazon ECR還是其他像GitLab的數不勝數的自托管容器 Registry 之一。
一旦你的鏡像成功上傳到 Registry,你可以在目標服務器上登錄到該注冊表。
docker login mysupersecret.registry.com
一旦你在 Registry 上登錄成功,你的 docker run 就能找到你的自定義鏡像了。
docker run --name my-new-ai-startup -p 80:8080 -d mynewaistartup
//....
SUCCESS!
Docker Compose:同時運行多個容器
如果你的應用程序不僅僅包含一個單獨的 Docker 容器,比如說,因為你需要運行98354 個微服務?
Docker Compose 來拯救。你將在一個傳統而又經典的 YAML 文件,即compose.yaml文件中定義所有服務及其之間的依賴關系(運行這個或那個先)。以下是一個定義兩個服務的示例,一個是 Web 服務,另一個是 redis 服務。
services:
web:
build: .
ports:
- "8000:5000"
volumes:
- .:/code
- logvolume01:/var/log
depends_on:
- redis
redis:
image: redis
volumes:
logvolume01: {}
然后只需運行docker compose up,整個環境(由所有獨立服務在單獨的 Docker 容器中運行組成)將被啟動。請注意,這意味著所有容器將在同一臺機器上運行。如果要將其擴展到多臺機器上,您將需要使用Docker Swarm。
雖然Docker Compose可能主要用于快速啟動開發或測試環境,但它實際上也適用于(單主機)生產部署。如果你的應用程序…
- 沒有特定的高可用性要求
- 你不介意一些手動操作(ssh 登錄,docker compose up/down)或使用輔助工具如Ansible
- 或者你只是不想在 DevOps 團隊上投入巨額資金
…使用 Docker Compose 進行生產部署將大有裨益。
Kubernetes 101: 基礎和概念
那么我為什么需要 Kubernetes 呢?
當你想要開始運行數百、數千(或是它們的倍數)的容器時,事情變得有趣起來。如果你不關心或者不想知道這些容器將在哪臺具體的硬件/主機上運行,但仍然希望能夠合理地管理所有這些,那么 Kubernetes 就派上用場了!
(注:相當長時間以前,我讀過一本關于 Kubernetes 的書,在介紹中他們規定了運行 Kubernetes 開始變得有意義的下限數字,我記得它從數百到數千開始,盡管我無法找到那本確切的書了。)
讓我們快速了解一下 Kubernetes 的基礎概念。
圖片
(工作,Worker)節點
你的軟件(或者在 Kubernetes 術語中稱為工作負載)必須在某個地方運行,無論是虛擬機還是物理機器。在 Kubernetes 中,這個地方被稱為節點(Node)。
此外,Kubernetes 部署和運行容器:你好,Docker,我的老朋友!(注:Kubernetes 支持許多容器運行時,包括containerd、CRI-O、Docker Engine等,盡管 Docker 是最常用的)
實際上,這并不完全正確。在 Kubernetes 的術語中,你部署(調度)Pods,一個 Pod 包含一個或多個容器。
好吧,我們在節點上運行Pods,但是誰控制這些節點,以及你在這些節點上如何決定運行什么呢?
(小貼士:一個小映射表)
非 Kubernetes |
Kubernetes 術語 |
軟件/應用 |
工作負載 |
機器 |
節點 |
(1-多個)容器 |
Pod |
部署 |
調度 |
控制平面
認識控制平面。為簡單起見,我們可以將其視為控制節點的一個組件(與其包含的大約 9472 個組件相對)。控制平面,除了其他許多功能…
- 讓你運行調度你的應用程序,即讓你將一個 Pod 放到一個節點上。
- 檢查所有的 Pod 是否處于期望的狀態,例如它們是否響應,或者其中一個是否需要重新啟動?
- 實現每個工程師的幻想:“我們終于需要擴展 10 倍了,讓我們快速啟動 n 個更多的 Pod!”
Pods 與 Nodes
如果Pods和Nodes之間的區別還有點不清楚。Kubernetes 有一個所謂的調度器。每當調度器發現新的 Pod(== 容器(們))需要調度時(耶!),它會嘗試找到 Pod 的最佳節點。這意味著很有可能多個 Pod 在同一節點上運行,或者在不同節點上運行。如果你想深入了解這個主題,你可能需要閱讀有關 "節點選擇" 以及如何影響它的官方文檔。
集群 & 云
取多個節點和你的控制平面,你就有了一個集群。
取多個集群,你可以分隔你的開發、測試和生產環境,或者團隊、項目或不同類型的應用程序 - 這取決于你。
再進一步,嘗試進行多云 Kubernetes,跨越不同的私有和/或公有云平臺運行多個集群(祝賀!你所取得的成就絕非易事。)
擴展
還有許多Kubernetes 擴展。
最重要的是,對于開發人員來說,有一個Web UI/Dashboard,你可以使用它來基本管理你的集群。
如果你沒有自托管你的 Kubernetes 設置,你可以簡單地使用云供應商提供的任何 UI,比如google Cloud、AWS或其他眾多云供應商提供的 UI。
請,讓我們停止 Kubernetes 101
上面的那四個 101 部分將(希望)為你提供足夠的心智模型,讓你開始使用 Kubernetes,我們將在概念上結束。
說實話,如果你在https://learning.oreilly.com上搜索 "Kubernetes",你會感到震驚。你將獲得成千上萬的學習資源結果,其中許多書籍都超過 500 頁長。這對于一個下雨天的冬天是很好的閱讀!好消息是:作為開發人員,你不必關心這些書中大多數內容,這些書教你如何設置、維護和管理你的集群,盡管了解所有這些的復雜性是有幫助的。
我需要做什么才能看到所有這些在運行中的情況?
- Kubernetes 安裝(我們稍后會更詳細地討論)
- YAML,YAML,YAML!
- 與你的 Kubernetes 集群交互的工具:kubectl
我從哪里獲取 kubectl?
你可以下載kubectl,這本質上是用于與你的 Kubernetes 集群做任何你想做的事情的 CLI工具。該頁面列出了為你的特定操作系統安裝 kubectl 的各種方法。
我如何讀 kubectl?†
參見https://www.YouTube.com/watch?v=9oCVGs2oz28。它的發音是 "Kube Control"。
kubectl 要如何工作?
你需要一個配置文件,一個名為 kubeconfig 的文件,它允許你訪問你的 Kubernetes 集群。
默認情況下,該文件位于~/.kube/config。值得注意的是,這個配置文件也被你喜愛的集成開發環境(如IntelliJ IDEA)讀取,以正確設置其 Kubernetes 功能。
我從哪里獲取 kubeconfig 文件?
選項 1如果你正在使用托管的 Kubernetes 安裝(EKS、GKE、AKS),請查看相應的文檔頁面。是的,只需點擊鏈接,我已經為你鏈接到正確的頁面。簡而言之,你將使用它們的 CLI 工具為你生成/下載該文件。
選項 2如果你本地安裝了Minikube,它將自動為你創建一個 kubeconfig 文件。
選項 3如果你碰巧知道你的 Kubernetes 主節點并可以通過 SSH 登錄,運行:cat /etc/kubernetes/admin.conf或cat ~/.kube/config
kubeconfig 文件還有其他需要知道的嗎?
一個 kubeconfig 文件由傳統的 YAML 組成,它可以包含許多內容(clusters、users、contexts)。對于有興趣的人,請查閱官方文檔。
目前,我們可以忽略 users 和 contexts,并且簡化為 kubeconfig 文件包含你可以連接的集群,例如development或test。
以下是一個示例 kubeconfig 文件,摘自官方 Kubernetes 文檔。
(別擔心,你不必逐行理解這個文件,它只是為了讓你感受一下這些文件的樣子)
apiVersion: v1
clusters:
- cluster:
certificate-authority: fake-ca-file
server: https://1.2.3.4
name: development
- cluster:
insecure-skip-tls-verify: true
server: https://5.6.7.8
name: test
contexts:
- context:
cluster: development
namespace: frontend
user: developer
name: dev-frontend
- context:
cluster: development
namespace: storage
user: developer
name: dev-storage
- context:
cluster: test
namespace: default
user: experimenter
name: exp-test
current-context: ""
kind: Config
preferences: {}
users:
- name: developer
user:
client-certificate: fake-cert-file
client-key: fake-key-file
- name: experimenter
user:
# Documentation note (this comment is NOT part of the command output).
# Storing passwords in Kubernetes client config is risky.
# A better alternative would be to use a credential plugin
# and store the credentials separately.
# See https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins
password: some-password
username: exp
Kubectl 101
你現在可以用 Kubectl 做什么呢?記住,一開始我們說你的目標是擁有一個 Pod(n+ 個容器),并在節點(服務器)上調度它(運行它們)。
方法是將 yaml 文件(耶)帶有集群期望狀態的文件輸入到 kubectl 中,它將愉快地將你的集群設置為期望的狀態。
Pod 清單
例如,你可以創建一個名為marcocodes-pod.yaml的文件,內容如下…
apiVersion: v1
kind: Pod
metadata:
name: marcocodes-web
spec:
containers:
- image: gcr.io/marco/marcocodes:1.4
name: marcocodes-web
ports:
- containerPort: 8080
name: http
protocol: TCP
…并使用以下 kubectl 命令將其輸入到你的 Kubernetes 集群中:
kubectl apply -f marcocodes-pod.yaml
應用這個 yaml 文件會做什么呢?嗯,讓我們逐步了解:
Kubernetes 知道各種所謂的對象,Pod 是其中之一,你稍后會遇到其他對象。簡單來說,這個 .yaml 文件描述了我們要部署的 Pod。
metadata:
name: marcocodes-web
Kubernetes 中的每個對象,因此每個 .yaml 文件都充滿了metadata標簽。在這種情況下,我們為我們的 pod 指定了名稱,值為marcocodes_web。這個 metadata 有什么用呢?簡單來說,Kubernetes 需要以某種方式唯一標識集群中的資源:我是否已經運行了一個名稱為marcocodes_web的 pod,還是我需要啟動一個新的 pod?這就是 metadata 的作用。
spec:
containers:
- image: gcr.io/marco/marcocodes:1.4
name: marcocodes-web
ports:
- containerPort: 8080
name: http
protocol: TCP
你需要告訴 Kubernetes 你的 pod 應該是什么樣的。記住,它可以是 n+ 個容器,因此你可以在 YAML 文件中指定容器的列表,盡管通常你只指定一個。
你將指定一個特定的 Docker 鏡像,包括其版本,并通過 http 在該容器上暴露端口 8080。就是這樣。
這個 yaml 文件到底發生了什么?
長話短說,當你運行 kubectl apply 時,你的 yaml 文件將被提交到 Kubernetes API 服務器,最終我們的 Kubernetes 系統將安排一個 pod(帶有 marcocodes 1.4 容器)在我們集群中的一臺健康、可行的節點上運行。
更技術性地說,Kubernetes 有一個協調循環的概念,一個調度器能夠說的花哨點的術語:
"這是我的當前 Kubernetes 集群狀態,這是用戶的 yaml 文件,讓我協調這兩者。用戶想要一個新的 pod 嗎?我會創建它。用戶想要存儲嗎?我會將其附加到容器上,等等。
說到存儲...
資源和卷
僅指定容器鏡像并不是你所能做的全部。首先,你可能想要處理容器的資源消耗:
# ....
spec:
containers:
- image: gcr.io/marco/marcocodes:1.4
resources:
requests:
cpu: "500m"
memory: "128Mi"
# ....
這確保你的容器至少獲得 500m(即 0.5)的 CPU 和 128 MB 的內存(你還可以指定永遠不可突破的上限)。
此外,當一個 pod 被刪除或容器重新啟動時,容器文件系統中的數據也將被刪除。為了避免這種情況,你可能想要將數據存儲在持久卷上。
# ....
spec:
volumes:
- name: "marcocodes-data"
hostPath:
path: "/var/lib/marcocodes"
containers:
- image: gcr.io/marco/marcocodes:1.4
name: marcocodes
volumeMounts:
- mountPath: "/data"
name: "marcocodes-data"
ports:
- containerPort: 8080
name: http
protocol: TCP
# ....
我們將擁有一個名為marcocodes-data的卷,它將被掛載到容器上的/data目錄下,并存在于主機機器上的/var/lib/marcocodes下。
有什么要注意的嗎?
你剛學到有 pod,它們由一個或多個 Docker 鏡像組成,以及資源消耗規則和卷定義。
有了所有這些 YAML,我們成功地安排了一個單一的、靜態的、一次性的 pod。問題來了:與僅運行docker run -d --publish 8080:8080 gcr.io/marco/marcocodes:1.4相比,有何優勢?
嗯,實際上目前并沒有。
這就是為什么我們需要更深入地了解ReplicaSet和Deployment概念的原因。
ReplicaSet
我們要謙卑一點。一開始我們不需要自動縮放,但擁有應用程序的冗余實例和一些負載平衡會很不錯,這樣我們的部署會顯得更專業,不是嗎?
Kubernetes 的ReplicaSet來拯救我們!
讓我們看一個定義了這樣一個最小 ReplicaSet 的marcocodes-replica.yaml文件。
apiVersion: apps/v1
kind: ReplicaSet
# metadata:
# ...
spec:
replicas: 2
selector: "you will learn this later"
# ...
template:
metadata: "you will learn this later"
# ...
spec:
containers:
- name: marcocodes-web
image: "gcr.io/marco/marcocodes:3.85"
我省略了這個 YAML 文件中的很多行(和復雜性),但現在最有趣的是這兩個變化:
這個 .yaml 現在描述的是一個 ReplicaSet,而不再是一個 Pod。
這是重點:我們希望始終有 2 個副本 == pod 在任何給定的時間運行。如果我們在這里填入 10,Kubernetes 將確保同時運行 10 個 pod。
當我們現在應用這個 .yaml 文件...
kubectl apply -f marcocodes-rs.yaml
Kubernetes 將從 Kubernetes API 獲取一個 Pod 清單(并根據metadata過濾結果),根據返回的 pod 數量,Kubernetes 將啟動或停止額外的副本。就是這么簡單。
ReplicaSet:總結
ReplicaSet幾乎是你想要的,但它們存在一個問題:它們與特定版本的容器鏡像綁定(在我們的例子中為 3.85),而這些實際上不應該更改。而且 ReplicaSets 也不能幫助你完成軟件的滾動發布過程(考慮零停機時間)。
因此,我們需要一個新的概念來幫助我們管理新版本的發布。見識一下:Deployment(部署)。
apiVersion: apps/v1
kind: Deployment
metadata: "ignore for now"
# ...
spec:
progressDeadlineSeconds: 600
replicas: 2
revisionHistoryLimit: 10
selector: "ignore for now"
# ...
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
"ignore for now"
# ...
你還需要學習 Deployments 的其他 92387 個 YAML 鍵值對,而我們已經在本文中進行了相當長時間的探討。其要點是:Kubernetes 允許你使用不同的軟件發布策略(rollingUpdate或recreate)。
- Recreate(重新創建)將終止所有舊版本的 pod,并使用新版本重新創建它們:這會導致用戶經歷停機時間。
- RollingUpdate(滾動更新)將在仍然通過舊 pod 提供流量的情況下執行更新,因此通常更受青睞。
K8s 的靜態本質
請注意,到目前為止,你所看到的一切基本上是靜態的。你有 YAML 文件,即使使用上面的 Deployment 對象,如果你有一個新版本的容器,你需要編輯 .yaml 文件,保存并應用它 - 這涉及相當多的手動工作。
如果你希望事情變得更加動態,你將需要使用額外的工具,比如https://helm.sh/,我們將在下面討論。
滾動更新:過于美好而不真實
雖然我們正在談論部署容器的新版本...
一如既往,魔鬼在細節中。滾動更新在 Kubernetes 存在之前很久就已經完成了,即使只是批處理腳本觸發 SSH 命令。
坦率地說,問題并不是能夠關閉并啟動應用程序的新實例,而是在短時間內(在部署期間)你的應用程序基本上需要優雅地支持兩個應用程序版本 - 這總是一個有趣的問題,特別是涉及數據庫或前后端 API 之間進行了重大重構的情況。
因此,請注意營銷材料,它們向你推銷簡單的滾動更新 - 它們真正的挑戰與 Kubernetes 無關。
附注:自愈能力
在類似的背景下,同樣適用于“self-healing”(自愈)一詞。Kubernetes 能夠執行健康檢查,然后終止無響應的 pod,安排啟動一個新的。這也是某種形式上一直存在的功能。你喜歡的 linux 發行版本質上一直能夠通過各種方式監視并重新啟動服務 - 盡管限于當前機器。
Kubernetes 不能自動處理錯誤的數據庫遷移導致的應用程序錯誤,然后通過神奇的方式自愈集群,即修復損壞的數據庫列。
我只是覺得關于自愈系統的討論通常在某種程度上含有后者的意味(也許在管理層之間),而實際上它是更基本的功能。
服務發現、負載均衡和 Ingress
到目前為止,我們討論了動態生成 pod,但從未討論過網絡流量如何實際到達你的應用程序。Kubernetes 本質上是動態的,這意味著你可以在任何時候生成新的 pod 或關閉它們。
Kubernetes 有一些概念可以幫助你解決這個問題,從 Service 對象(允許將集群的部分暴露給外部)到 Ingress 對象(允許進行 HTTP 負載均衡)。同樣,這將涉及大量的 YAML 和相當多的閱讀,但在一天結束時,Kubernetes 允許你將應用程序接收到的任何流量路由到你的集群,反之亦然。
(有趣的 Ingress 事實:您將需要安裝 Ingress 控制器(Kubernetes 沒有內置標準控制器),它將為您執行負載平衡。選擇很多:在像 AWS 這樣的平臺上,您可以簡單地使用 ELB,如果使用裸金屬 Kubernetes,則可以使用Contour,等等。)
最后但同樣重要的是:ConfigMap 和 Secret 管理
除了您已經看到 Kubernetes 執行的各種任務之外,您還可以使用它存儲配置鍵值對,以及秘密(考慮數據庫或 API 憑據)。
(默認情況下,Secrets 以未加密的形式存儲,因此有必要遵循此頁面上“安全使用 Secrets” 部分的建議,甚至可以完全插入外部 Secrets 存儲,從 AWS、GCP 和 Azure 的解決方案到HashiCorp 的 Vault。)
夠了!這些 YAML 文件難道不會變得混亂嗎?
嗯...如果您考慮使用 Kubernetes 部署WordPress等應用,那么您將需要一個 Deployment,以及一個ConfigMap和可能還有Secret。然后還有一些其他服務和我們尚未涉及的對象。這意味著,您最終將得到成千上萬行的 YAML。這并不是本質上的混亂,但在這個小階段,已經涉及了大量的 DevOps 復雜性。
然而,您也是一名開發人員,希望不一定是那位在維護這些文件的人。
只要有需要,使用你的 IDE 的 Kubernetes 支持(在我這里是IntelliJ IDEA)對 Helm charts、Kustomize 文件等進行編碼支持,會極大地幫助你。哦,我們還沒有談論過它們。讓我們來談談。這里有一段視頻,會讓你迅速了解IntelliJ 的 Kubernetes 插件。
Kubernetes:附加主題
什么是 Helm?Helm Chart 又是什么?
你可以把 Helm 想象成 Kubernetes 的包管理器。讓我們了解一些概念:
正如我們上面提到的,僅僅在 Kubernetes 集群中安裝 WordPress 就會導致成千上萬行的 YAML 代碼。如果你不必親自編寫這些 YAML 代碼,而是可以使用預先構建的軟件包,途中只需替換一些變量,那將是非常好的。
這就是Helm Chart,一堆 YAML 文件和模板,按照特定的目錄結構布局。當你開始安裝一個特定的 chart 時,Helm 將下載它,解析它的模板,并與你的值一起生成經典的 Kubernetes YAML 文件/清單,然后將其發送到你的 Kubernetes。
以下是一個這種模板文件的小片段(用于 Deployment 清單),包括一些占位符:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "myChart.name" . }}
labels:
{{- include "myChart.labels" . | nindent 4 }}
你可以將這些 chart 分享到倉庫中。并沒有單一的默認 chart 倉庫。一個查找流行 chart 倉庫的好地方是https://artifacthub.io/。
簡而言之,使用 Helm 的工作流程如下:
- 安裝 Helm 客戶端
- 安裝你喜歡的 chart - 第一部分
helm install my-release oci://registry-1.docker.io/bitnamicharts/wordpress
這條命令會從流行的 bitnami chart 倉庫安裝 wordpress chart 到你的集群,最終結果是一個運行中的 WordPress 安裝。如果你想知道 OCI 是什么:你可以將 Helm charts 托管在支持Open Containers Initiative標準的容器 Registry 中(比如 Amazon ECR、Docker Hub、Artifactory 等)。
- 安裝你喜歡的 chart - 第二部分
由于幾乎總是需要覆蓋一些配置值(在 WordPress 的情況下,可以在這里查看參數的巨大列表),你會想要向安裝命令提供你的具體值。你可以通過一個命名為 values.yaml 的 YAML 文件傳遞值,或者直接使用命令行標志。因此,安裝命令可能會像這樣:
helm install my-release oci://registry-1.docker.io/bitnamicharts/wordpress --values values.yaml
// OR
helm install my-release oci://registry-1.docker.io/bitnamicharts/wordpress --set wordpressUsername=m4rc0 // etc...
- 注意:你還可以使用 helm 來升級你的安裝。可以升級到 chart 的新版本(考慮新的發布),或者通過helm upgrade命令升級安裝的配置。
如果你想深入了解 Helm,我強烈推薦你閱讀《學習 Helm》一書。
什么是 Kustomize?
在前文中,你了解到 Helm 使用模板生成 Kubernetes 清單。這意味著有人需要將 Kubernetes 清單制作成 Helm 模板,進行維護,然后作為最終用戶,你可以使用 helm 命令行客戶端來應用它們。
Kustomize的開發人員選擇了不同的路徑:它允許你通過將額外的更改層疊在原始清單之上來創建清單的自定義版本。因此,與其創建模板并在其中放置 "占位符",你最終會得到一個文件結構,例如:
├── deployment.yaml // your original Kubernetes manifest filef
└── kustomization.yaml //
// (in more relalistic scenarIOS, you'deven have 'overlays' subfolders for different environments, like development/staging/prod etc
然后,你可以運行kustomize build,以便 Kustomize 應用你的覆蓋層,并渲染最終的 YAML 結果,你可以直接輸入kubectl命令(或直接運行kubectl apply -k)。
kustomize build . | kubectl apply -f -
如果你想了解 kustomization.yaml 文件需要如何結構化,可以查看這里。
哪個更好:Helm 還是 Kustomize?
我們都喜歡 Reddit 上的意見,盡管有爭議:https://www.reddit.com/r/kubernetes/comments/w9xug9/helm_vs_kustomize/。
什么是 Terraform 以及與 Kubernetes 的區別是什么?
感謝上帝,我們接近本指南的結束,我不必再在 Terraform 上花費另外一千字(提示:一如既往,你會在 Terraform 上找到很多書籍和學習資源),所以我會盡量簡短:
Kubernetes 是關于容器編排的。"讓我告訴你我在這個 YAML 文件中想要的:為我運行我的容器!"
Terraform 是關于基礎設施的創建: "讓我告訴你我在這些 HashiCorp 配置語言(HCL,.tf)文件中想要的!請為我創建五個服務器,幾個負載均衡器,兩個數據庫,幾個隊列,以及例如我選擇的云中的監控設施。" 或者:"請為我在 AWS 上設置這些 Kubernetes 集群(EKS)"。
我如何在本地使用 Kubernetes 進行開發?
對于本地開發,你基本上有兩個選擇。
你可以運行一個本地的 Kubernetes 集群,并將你的應用程序部署到其中。你可能會使用Minikube來實現這一點。由于整個 "我的應用程序發生了變化 - 現在讓我們構建一個容器鏡像 - 然后讓我們將其部署到我的集群" 這個流程手動執行起來相當繁瑣,因此你可能還想使用類似Skaffold的工具來幫助你。查看這個教程以了解如何開始使用這個工作流。盡管這種設置是有效的,但它伴隨著相當多的復雜性和/或資源消耗。
這就是第二種選擇,解決方案的地方。對于本地開發,你基本上會忽略 Kubernetes,將你需要的任何配置克隆到你自己的 docker-compose.yml 文件中,然后簡單地運行它。這是一個更簡單的設置,但它的缺點是必須維護兩套配置(docker-compose.yml + 你的 K8s 清單文件)。
如果您已經在使用 Kubernetes,請在下面的評論部分告訴我您是如何處理本地開發的。
我真的需要所有這些嗎?
這是一個很好的問題,現在是撒些真實的 Kubernetes 軼事的絕佳時機:系統管理員限制資源以至于 Pod 的啟動時間變得非常長 - 長到它們被標記為不健康并被終止,導致無休止的 Pod 創建和終止循環,但我們將長篇的解釋留到另一個時候。
作為開發者,通常您無法決定,但以下是大局觀:
正如本文早些時候提到的,關于僅“托管” Kubernetes 集群的學習材料是無窮無盡的,我們不僅僅是在談論在裸金屬上進行“自托管”,還有使用任何托管 Kubernetes 變體的情況。如果您有內部專業知識:
- 處理所有這些額外的復雜性
- 您可以向所有開發人員更詳細地解釋本文中描述的所有概念
- 而且首先而且首要的是您確實有管理數百或數千個容器的合法需求(不,不算神奇的突然擴展需求) - 那就選擇 Kubernetes 吧。但我相信很多公司通過采用更簡單的方法而不是幻想擁有 Google 規模的基礎架構挑戰,可以節省大量的時間、金錢和壓力。
常見的 Kubectl 命令
如果有任何對開發人員可能需要的kubectl命令感興趣的話,請在下面留言,我會將最常用的命令添加到這里,作為一個整齊分組/排序的列表。
為什么 Kubernetes 被縮寫為 K8s
我想你可能現在已經忘記了!這里是直接摘自 Kubernetes 文檔的一段引用:
“Kubernetes 的名稱源自希臘語,意為舵手或領航員。K8s 作為縮寫是因為在“K”和“s”之間有八個字母。Google 在2014年開源了 Kubernetes 項目。”
結束語
到目前為止,您應該對 Kubernetes 有了相當好的概述。反饋、更正和隨機的意見都是受歡迎的!只需在下面留下評論。
感謝閱讀。
下一個版本的計劃
在評論部分投票,如果您希望以下任何一項或所有這些都發生:
- 提供復制粘貼命令 * K8s 文件,以便讀者可以跟隨操作
- 可能的:kubectl 命令
- 可能的:Kubernetes vs Docker Compose 并排配置的示例
- 可能的:GitOps
- 建議:使用 Kubectl/K9s/Lens IDE 或 IntelliJ Kubernetes 插件連接到 Kubernetes
- 建議:使用 Istio 的服務網格 - 在處理微服務時的常見用例。
致謝與參考
感謝 Maarten Balliauw、Andreas Eisele、Andrei Efimov、Anton Aleksandrov、Garth Gilmour、Marit van Dijk、Paul Everitt、Mukul Mantosh 的評論、更正和討論。特別感謝《Getting Started with Kubernetes》和《Learning Helm》的作者們。