API Server 簡介
Kubernetes 的 API Server 是一個 clinet / server 的架構。
- 通過 HTTP 對外提供 Restful API 服務,Client 提交請求,Server 回覆。
- 他是無狀態的 Stateless,所有的狀態都儲存在 Cluster Store 裡(etcd)。
API Object
API Object 代表着 Kubernetes 集群中的各種資源。
幾乎所有的元素在 Kubernetes 都被表示為 API Object。
Pods、Services、ReplicaSets、Deployments、ConfigMaps 等等。
簡單來說,就是定義服務(apply -f service.yaml
)後產生出來的東西。
API Object 是透握以下的文字組織起來:
- Kind (Pod、Deployment、Service…)
- Group (core、apps、storage)
- Version (v1、beta、alpha)
1 2 3 4 5 6 7 8 9 10 11 12
| apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 8080 type: ClusterIP
|
- 透過
k api-resources
指令,可以了解 Kubernetes API 中可用的資源類型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ➜ k api-resources NAME SHORTNAMES APIVERSION NAMESPACED KIND bindings v1 true Binding componentstatuses cs v1 false ComponentStatus configmaps cm v1 true ConfigMap endpoints ep v1 true Endpoints events ev v1 true Event limitranges limits v1 true LimitRange namespaces ns v1 false Namespace nodes no v1 false Node persistentvolumeclaims pvc v1 true PersistentVolumeClaim persistentvolumes pv v1 false PersistentVolume pods po v1 true Pod controllerrevisions apps/v1 true ControllerRevision ...
|
kubectl api-resources --api-group=apps | more
,列出當前集群中屬於 apps API 群組的所有 API 資源。
1 2 3 4 5 6 7
| ➜ kubectl api-resources --api-group=apps | more NAME SHORTNAMES APIVERSION NAMESPACED KIND controllerrevisions apps/v1 true ControllerRevision daemonsets ds apps/v1 true DaemonSet deployments deploy apps/v1 true Deployment replicasets rs apps/v1 true ReplicaSet statefulsets sts apps/v1 true StatefulSet
|
如何操作 API Object
兩種方法
- Declarative Configuration (通過 yaml/ json 格式定義,就是俗稱的 manifest,定義完之後將文件傳給 API Server )
- Imperative Configuration (直接通過命令去創建、操作)
1 2
| kubectl apply -f nginx.yml kubectl run web --image= nginx
|
nginx.yml
1 2 3 4 5 6 7 8
| apiVersion: v1 kind: Pod metadata: name: web spec: containers: - name: nginx-container image: nginx:latest
|
Pod 是什麼
在 Kubernetes 中,Pod 是最小的、最簡單的部署單位。
每個 Pod 都包含一個或多個容器,這些容器緊密相連並共享資源。
Pod 的特性有:
- 共享存儲空間:每個 Pod 都可以定義一組 Volume(共享存儲體卷)。
- Pod 中的所有容器都可以訪問這些 Volume,這意味著它們可以共享文件。
- 網路和 IP 位址:每個 Pod 都被分配一個單一的 IP 位址。
- Pod 中的每個容器共享網路命名空間,包括 IP 位址和網路連接埠。這使得 Pod 內的容器可以透過 localhost 進行通信。
- 於容器的資訊:Pod 可以包含多個容器,並且這些容器可能需要不同的資源。
- Pod 中的每個容器都有其自己的 image、容器的資源需求和容器的運行設定。
- 管理方式:Pod 是由 Kubernetes 系統(而不是直接由使用者)創建和管理的。
- Pod 可以透過一系列的 Controller Manager,如 Deployments、ReplicaSets、Jobs 等進行管理。
Pod 是 Kubernetes 的基本組成單位。
用於將一組具有密切關聯性的 Conatiner 和 Volume 組合在一起,並提供共享調度和管理的功能。
Pod 的比喻
想像你在廚房裡面準備一頓豐盛的晚餐,並且有多道菜需要同時處理。
在這個廚房裡,每個廚師就像是 Pod 裡面的容器,而每道菜則對應到一個容器內運行的應用程式。
現在,你可能需要一個廚師負責煎牛排,一個廚師負責煮義大利麵,還有一個廚師負責製作沙拉。
每個廚師都有自己的專長,並且可以同時處理自己負責的部分。
這些廚師一起組成了一個廚房團隊,而這個廚房團隊就是 Kubernetes Pod。
廚房團隊中的廚師(容器)共享同一個廚房(節點),這個廚房裡備有各種廚具和材料,讓他們能夠順利完成各自的任務。
同時,你作為廚房的主廚,就像是 Kubernetes 在這個比喻中的角色。
你負責協調廚師的動作,確保每道菜都能按照預定的流程完成。
如果有任何一個廚師需要換成其他人,或是需要一個額外的廚師來幫忙,你會做出相應的調整。
此外,如果某個廚師遇到了一個問題(比如火力不夠大),你會找出解決方案或是指派其他廚師來協助處理,這就像是 Kubernetes 在節點出現故障時,會重新安排 Pod 到其他健康的節點上。
總結來說,創建 Pod 在 Kubernetes 中就像是組建一個廚房團隊,每個廚師(容器)負責一道菜(應用程式),而 Kubernetes 則是廚房的主廚,負責協調和管理整個廚房團隊。
Multi-container Pod
如果要創建多個 container 在同一個 pod,就不能使用 Imperative 的方法,只能使用 Declarative 的方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: nginx image: nginx - name: client image: busybox command: - sh - -c - "sleep 1000000"
|
實作 dry-run
透過指令創建 pod,因為使用 dry run 所以不會創建。
1 2
| ➜ k run web --image=nginx --dry-run=client pod/web created (dry run)
|
可以使用 -o yaml
查看產生出來的 yaml 檔
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| ➜ k run web --image=nginx --dry-run=client -o yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: web name: web spec: containers: - image: nginx name: web resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {}
|
修改一下,變成兩個 container。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: web name: web spec: containers: - image: nginx name: web resources: {} - image: busybox name: busybox command: - sh - -c - "sleep 1000000" dnsPolicy: ClusterFirst restartPolicy: Always status: {}
|
可以看到他成功 create
1 2
| ➜ k apply -f nginx.yml --dry-run=server pod/web created (server dry run)
|
取得所有的 pods,Ready 裡面是 2/2 代表有兩個 Container。
1 2 3
| ➜ k get pods NAME READY STATUS RESTARTS AGE web 2/2 Running 0 111s
|
如果不想要每次都複製貼上的話,可以使用> nginx.yml 這個方法。
1
| k run web --image=nginx --dry-run=client -o yaml > nginx.yml
|
diff 使用方法
可以看到更新後的修改。
假如我在上面新增了一個 label,他就會產生 + 號。
1 2 3 4 5 6 7 8 9 10 11 12
| ➜ k diff -f my-pod.yml diff -u -N /var/folders/p0/dbhr5v7d2d10rtddyhdx81rc0000gn/T/LIVE-3205435047/v1.Pod.default.web /var/folders/p0/dbhr5v7d2d10rtddyhdx81rc0000gn/T/MERGED-90136941/v1.Pod.default.web --- /var/folders/p0/dbhr5v7d2d10rtddyhdx81rc0000gn/T/LIVE-3205435047/v1.Pod.default.web 2023-06-18 15:36:10 +++ /var/folders/p0/dbhr5v7d2d10rtddyhdx81rc0000gn/T/MERGED-90136941/v1.Pod.default.web 2023-06-18 15:36:10 @@ -6,6 +6,7 @@ {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"creationTimestamp":null,"labels":{"run":"web"},"name":"web","namespace":"default"},"spec":{"containers":[{"image":"nginx","name":"web","resources":{}},{"command":["sh","-c","sleep 1000000"],"image":"busybox","name":"busybox"}],"dnsPolicy":"ClusterFirst","restartPolicy":"Always"},"status":{}} creationTimestamp: "2023-06-18T07:23:23Z" labels: + demo: test run: web name: web namespace: default
|
透過 get pods --show-labels
可以看到 label 改變了。
1 2 3
| ➜ k get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS web 2/2 Running 0 14m demo=test,run=web
|
dry-run 的差異
kubectl apply -f nginx.yml --dry-run=server
與 kubectl apply -f nginx.yml --dry-run=client
差異是什麼?
差異主要在於執行驗證的位置和深度。
--dry-run=client
:此選項會在客戶端(即你的電腦或終端機)執行命令,但不會將更改傳送到伺服器。
- 這是一種驗證你的 yaml 或 json 檔案是否正確的方式,而不實際對集群進行更改。此選項可以捕捉到語法錯誤或其他基本的配置問題。
--dry-run=server
:此選項會將命令傳送到伺服器並在伺服器端執行,但不會實際應用更改。
- 這將驗證你的檔案是否符合 API 伺服器的要求,並且能否被集群正確接受。
- 此選項可以捕捉到更深層次的問題,例如 API 版本不兼容,或者缺少必要的權限或配額等。
因此,--dry-run=server
的驗證比 --dry-run=client
更為全面和精確,因為它考慮到了伺服器端的條件和限制。