API Server and Pod (1)

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

兩種方法

  1. Declarative Configuration (通過 yaml/ json 格式定義,就是俗稱的 manifest,定義完之後將文件傳給 API Server )
  2. Imperative Configuration (直接通過命令去創建、操作)
1
2
kubectl apply -f nginx.yml # Declarative Configuration
kubectl run web --image= nginx # Imperative Configuration

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 使用方法

可以看到更新後的修改。

1
k diff -f my-pod.yml

假如我在上面新增了一個 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=serverkubectl apply -f nginx.yml --dry-run=client 差異是什麼?

差異主要在於執行驗證的位置和深度。

  • --dry-run=client:此選項會在客戶端(即你的電腦或終端機)執行命令,但不會將更改傳送到伺服器。
    • 這是一種驗證你的 yaml 或 json 檔案是否正確的方式,而不實際對集群進行更改。此選項可以捕捉到語法錯誤或其他基本的配置問題。
  • --dry-run=server:此選項會將命令傳送到伺服器並在伺服器端執行,但不會實際應用更改。
    • 這將驗證你的檔案是否符合 API 伺服器的要求,並且能否被集群正確接受。
    • 此選項可以捕捉到更深層次的問題,例如 API 版本不兼容,或者缺少必要的權限或配額等。

因此,--dry-run=server 的驗證比 --dry-run=client 更為全面和精確,因為它考慮到了伺服器端的條件和限制。


API Server and Pod (1)
https://phoebeho.com/sre/20230730/368091597/
作者
Phoebe
發布於
2023年7月30日
許可協議