Author: ACatSmiling
Since: 2024-11-05
kubectl 命令
建立 Pod
方式一:使用配置檔案建立。
-
首先,需要建立一個 Pod 的配置檔案(通常是
.yaml
或.yml
格式)。例如,建立一個簡單的 Nginx Pod 配置檔案 nginx-pod.yaml:apiVersion: v1 kind: Pod metadata: name: nginx-pod spec: containers: - name: nginx-container # 單容器 Pod image: nginx:latest
-
kubectl create
:不存在則新建,存在則報錯。$ kubectl create -f nginx-pod.yaml
-
kubectl apply
:不存在則新建,存在則更新。$ kubectl apply -f nginx-pod.yaml
-
建立多容器 Pod:
apiVersion: v1 kind: Pod metadata: name: multi-container-pod labels: app: multi-app-label spec: containers: - name: container-1 # 容器 1 image: nginx:latest ports: - containerPort: 80 - name: container-2 # 容器 2 image: redis:latest
$ kubectl create -f multi-container-pod.yaml # 或者 $ kubectl apply -f multi-container-pod.yaml
方式二:使用命令列引數建立(不推薦用於複雜配置)。
-
kubectl run
:快速建立一個簡單的 Pod。例如,建立一個名為 busybox-pod 的 Pod,執行 busybox 映象:$ kubectl run busybox-pod --image=busybox:latest
檢視 Pod
-
kubectl get pods
:檢視叢集中所有名稱空間下的所有 Pod 列表。示例:[root@k8s-master pods]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-pod 1/1 Running 0 10m
-
輸出結果通常包含以下列:
- NAME:Pod 的名稱,用於在叢集中唯一標識 Pod。
- READY:顯示準備就緒的容器數量與總容器數量的比例。
- STATUS:Pod 的當前狀態,常見的狀態有
Pending
(等待排程或資源分配)、Running
(正在執行)、Succeeded
(成功完成任務,通常用於一次性任務的 Pod)、Failed
(執行失敗)。 - RESTARTS:容器重啟的次數。
- AGE:Pod 自建立以來的時間。
-
<pod-name>
:檢視指定 Pod。示例:[root@k8s-master pods]# kubectl get pods nginx-pod NAME READY STATUS RESTARTS AGE nginx-pod 1/1 Running 0 9h
-
-n, --namespace
:檢視特定名稱空間中的 Pod。示例:[root@k8s-master pods]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE coredns-6d8c4cb4d-d6rrb 1/1 Running 7 (4d11h ago) 11d coredns-6d8c4cb4d-zsx7n 1/1 Running 7 (4d11h ago) 11d etcd-k8s-master 1/1 Running 19 (4d11h ago) 66d kube-apiserver-k8s-master 1/1 Running 17 (4d11h ago) 66d kube-controller-manager-k8s-master 1/1 Running 22 (4d11h ago) 66d kube-proxy-6xntx 1/1 Running 14 (4d11h ago) 59d kube-proxy-m2nbx 1/1 Running 21 (4d11h ago) 66d kube-proxy-vzsp7 1/1 Running 12 (4d11h ago) 59d kube-scheduler-k8s-master 1/1 Running 22 (4d11h ago) 66d
-
-l
:按照標籤來檢視 Pod。示例:[root@k8s-master pods]# kubectl get pods -l app=nginx-pod-app NAME READY STATUS RESTARTS AGE nginx-pod 1/1 Running 0 8h
-
-o wide
:以寬格式檢視,獲取更詳細的資訊,包括 Pod 所在的節點 IP 和節點名稱等。示例:[root@k8s-master pods]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-pod 1/1 Running 0 10m 10.244.2.11 k8s-node2 <none> <none>
-
-o custom-columns
:自定義顯示的列。示例:# 只顯示 Pod 的名稱和狀態 [root@k8s-master pods]# kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase NAME STATUS nginx-pod Running
-
-o yaml|json
:以 YAML 或 JSON 格式呈現 Pod 的完整配置資訊。示例:[root@k8s-master pods]# kubectl get pod nginx-pod -o yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: "2024-11-03T02:56:23Z" labels: app: nginx-pod-app name: nginx-pod namespace: default resourceVersion: "404257" uid: 25c1720e-9653-4516-840a-56694aec429c spec: containers: - command: - nginx - -g - daemon off; env: - name: JVM_OPTS value: -Xms128m -Xmx128m image: nginx:latest imagePullPolicy: IfNotPresent name: nginx-pod ports: - containerPort: 80 name: http protocol: TCP resources: limits: cpu: 200m memory: 256Mi requests: cpu: 100m memory: 128Mi terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: kube-api-access-2qcsr readOnly: true workingDir: /usr/share/nginx/html dnsPolicy: ClusterFirst enableServiceLinks: true nodeName: k8s-node2 preemptionPolicy: PreemptLowerPriority priority: 0 restartPolicy: OnFailure schedulerName: default-scheduler securityContext: {} serviceAccount: default serviceAccountName: default terminationGracePeriodSeconds: 30 tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 300 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 300 volumes: - name: kube-api-access-2qcsr projected: defaultMode: 420 sources: - serviceAccountToken: expirationSeconds: 3607 path: token - configMap: items: - key: ca.crt path: ca.crt name: kube-root-ca.crt - downwardAPI: items: - fieldRef: apiVersion: v1 fieldPath: metadata.namespace path: namespace status: conditions: - lastProbeTime: null lastTransitionTime: "2024-11-03T02:56:23Z" status: "True" type: Initialized - lastProbeTime: null lastTransitionTime: "2024-11-03T02:56:24Z" status: "True" type: Ready - lastProbeTime: null lastTransitionTime: "2024-11-03T02:56:24Z" status: "True" type: ContainersReady - lastProbeTime: null lastTransitionTime: "2024-11-03T02:56:23Z" status: "True" type: PodScheduled containerStatuses: - containerID: docker://986ebb51cd36474dcb6f9789e13e3ed6ddb064e4a799fd282389c7eddf013fe4 image: nginx:latest imageID: docker-pullable://nginx@sha256:04ba374043ccd2fc5c593885c0eacddebabd5ca375f9323666f28dfd5a9710e3 lastState: {} name: nginx-pod ready: true restartCount: 0 started: true state: running: startedAt: "2024-11-03T02:56:23Z" hostIP: 192.168.1.122 phase: Running podIP: 10.244.2.11 podIPs: - ip: 10.244.2.11 qosClass: Burstable startTime: "2024-11-03T02:56:23Z" [root@k8s-master pods]# kubectl get pod nginx-pod -o json { "apiVersion": "v1", "kind": "Pod", "metadata": { "creationTimestamp": "2024-11-03T02:56:23Z", "labels": { "app": "nginx-pod-app" }, "name": "nginx-pod", "namespace": "default", "resourceVersion": "404257", "uid": "25c1720e-9653-4516-840a-56694aec429c" }, "spec": { "containers": [ { "command": [ "nginx", "-g", "daemon off;" ], "env": [ { "name": "JVM_OPTS", "value": "-Xms128m -Xmx128m" } ], "image": "nginx:latest", "imagePullPolicy": "IfNotPresent", "name": "nginx-pod", "ports": [ { "containerPort": 80, "name": "http", "protocol": "TCP" } ], "resources": { "limits": { "cpu": "200m", "memory": "256Mi" }, "requests": { "cpu": "100m", "memory": "128Mi" } }, "terminationMessagePath": "/dev/termination-log", "terminationMessagePolicy": "File", "volumeMounts": [ { "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", "name": "kube-api-access-2qcsr", "readOnly": true } ], "workingDir": "/usr/share/nginx/html" } ], "dnsPolicy": "ClusterFirst", "enableServiceLinks": true, "nodeName": "k8s-node2", "preemptionPolicy": "PreemptLowerPriority", "priority": 0, "restartPolicy": "OnFailure", "schedulerName": "default-scheduler", "securityContext": {}, "serviceAccount": "default", "serviceAccountName": "default", "terminationGracePeriodSeconds": 30, "tolerations": [ { "effect": "NoExecute", "key": "node.kubernetes.io/not-ready", "operator": "Exists", "tolerationSeconds": 300 }, { "effect": "NoExecute", "key": "node.kubernetes.io/unreachable", "operator": "Exists", "tolerationSeconds": 300 } ], "volumes": [ { "name": "kube-api-access-2qcsr", "projected": { "defaultMode": 420, "sources": [ { "serviceAccountToken": { "expirationSeconds": 3607, "path": "token" } }, { "configMap": { "items": [ { "key": "ca.crt", "path": "ca.crt" } ], "name": "kube-root-ca.crt" } }, { "downwardAPI": { "items": [ { "fieldRef": { "apiVersion": "v1", "fieldPath": "metadata.namespace" }, "path": "namespace" } ] } } ] } } ] }, "status": { "conditions": [ { "lastProbeTime": null, "lastTransitionTime": "2024-11-03T02:56:23Z", "status": "True", "type": "Initialized" }, { "lastProbeTime": null, "lastTransitionTime": "2024-11-03T02:56:24Z", "status": "True", "type": "Ready" }, { "lastProbeTime": null, "lastTransitionTime": "2024-11-03T02:56:24Z", "status": "True", "type": "ContainersReady" }, { "lastProbeTime": null, "lastTransitionTime": "2024-11-03T02:56:23Z", "status": "True", "type": "PodScheduled" } ], "containerStatuses": [ { "containerID": "docker://986ebb51cd36474dcb6f9789e13e3ed6ddb064e4a799fd282389c7eddf013fe4", "image": "nginx:latest", "imageID": "docker-pullable://nginx@sha256:04ba374043ccd2fc5c593885c0eacddebabd5ca375f9323666f28dfd5a9710e3", "lastState": {}, "name": "nginx-pod", "ready": true, "restartCount": 0, "started": true, "state": { "running": { "startedAt": "2024-11-03T02:56:23Z" } } } ], "hostIP": "192.168.1.122", "phase": "Running", "podIP": "10.244.2.11", "podIPs": [ { "ip": "10.244.2.11" } ], "qosClass": "Burstable", "startTime": "2024-11-03T02:56:23Z" } }
-
-
kubectl describe pod
:檢視單個 Pod 的詳細資訊,包括容器狀態、事件等。示例:[root@k8s-master pods]# kubectl describe pod nginx-pod Name: nginx-pod Namespace: default Priority: 0 Node: k8s-node2/192.168.1.122 Start Time: Sun, 03 Nov 2024 10:56:23 +0800 Labels: app=nginx-pod-app Annotations: <none> Status: Running IP: 10.244.2.11 IPs: IP: 10.244.2.11 Containers: nginx-pod: Container ID: docker://986ebb51cd36474dcb6f9789e13e3ed6ddb064e4a799fd282389c7eddf013fe4 Image: nginx:latest Image ID: docker-pullable://nginx@sha256:04ba374043ccd2fc5c593885c0eacddebabd5ca375f9323666f28dfd5a9710e3 Port: 80/TCP Host Port: 0/TCP Command: nginx -g daemon off; State: Running Started: Sun, 03 Nov 2024 10:56:23 +0800 Ready: True Restart Count: 0 Limits: cpu: 200m memory: 256Mi Requests: cpu: 100m memory: 128Mi Environment: JVM_OPTS: -Xms128m -Xmx128m Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-2qcsr (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: kube-api-access-2qcsr: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: Burstable Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: <none>
- 輸出內容通常包含以下資訊:
- Pod 的基本資訊:包括名稱、名稱空間、標籤、註釋等。
- 容器資訊:包括容器名稱、映象、埠、資源請求和限制等,還會顯示容器的狀態,以及容器啟動和停止的相關資訊。
- 卷(Volumes)資訊:如果 Pod 掛載了卷,會在這裡顯示卷的型別、來源等資訊。
- 事件資訊:記錄了 Pod 生命週期內發生的事件,例如排程事件、容器啟動和停止事件等。
- 輸出內容通常包含以下資訊:
-
kubectl logs
:檢視 Pod 中容器的日誌。示例:[root@k8s-master pods]# kubectl logs nginx-pod 2024/11/03 02:56:23 [notice] 1#1: using the "epoll" event method 2024/11/03 02:56:23 [notice] 1#1: nginx/1.27.1 2024/11/03 02:56:23 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14) 2024/11/03 02:56:23 [notice] 1#1: OS: Linux 3.10.0-1160.el7.x86_64 2024/11/03 02:56:23 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576 2024/11/03 02:56:23 [notice] 1#1: start worker processes 2024/11/03 02:56:23 [notice] 1#1: start worker process 6 2024/11/03 02:56:23 [notice] 1#1: start worker process 7
-
<pod-name> -c <container-name>
:如果 Pod 中有多個容器,需要指定容器名稱。示例:# 檢視 nginx-pod 中 nginx-pod 容器的日誌 [root@k8s-master pods]# kubectl logs nginx-pod -c nginx-pod 2024/11/03 02:56:23 [notice] 1#1: using the "epoll" event method 2024/11/03 02:56:23 [notice] 1#1: nginx/1.27.1 2024/11/03 02:56:23 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14) 2024/11/03 02:56:23 [notice] 1#1: OS: Linux 3.10.0-1160.el7.x86_64 2024/11/03 02:56:23 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576 2024/11/03 02:56:23 [notice] 1#1: start worker processes 2024/11/03 02:56:23 [notice] 1#1: start worker process 6 2024/11/03 02:56:23 [notice] 1#1: start worker process 7
-
-f
:實時日誌檢視。示例:[root@k8s-master pods]# kubectl logs -f nginx-pod 2024/11/03 02:56:23 [notice] 1#1: using the "epoll" event method 2024/11/03 02:56:23 [notice] 1#1: nginx/1.27.1 2024/11/03 02:56:23 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14) 2024/11/03 02:56:23 [notice] 1#1: OS: Linux 3.10.0-1160.el7.x86_64 2024/11/03 02:56:23 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576 2024/11/03 02:56:23 [notice] 1#1: start worker processes 2024/11/03 02:56:23 [notice] 1#1: start worker process 6 2024/11/03 02:56:23 [notice] 1#1: start worker process 7
-
更新 Pod
-
kubectl set image
:更新容器映象。$ kubectl set image pod/<pod-name> <container-name>=<new-image>
-
引數說明:
<pod-name>
:要更新的 Pod 名稱。<container-name>
:Pod 中要更新映象的容器名稱。<new-image>
:新的容器映象。
-
注意事項:
- 更新過程:當執行此命令後,Kubernetes 會自動觸發容器的重新建立過程,以使用新的映象。這個過程可能會導致短暫的服務中斷,具體取決於應用程式的特性和更新策略。一些應用程式可能能夠平滑地過渡到新映象,而另一些可能需要一些額外的配置來確保資料的完整性和服務的連續性。
- 滾動更新(Deployment):如果 Pod 是由 Deployment 管理的,那麼更新映象會觸發 Deployment 進行滾動更新。滾動更新會逐步替換舊的 Pod 副本為新的副本,以確保服務的可用性,可以透過設定
maxSurge
和maxUnavailable
等引數來控制滾動更新的速度和方式。 - 版本相容性:在更新映象時,要確保新映象與現有應用程式的配置和資料格式相容。例如,如果應用程式的資料庫模式在新映象中有變化,可能需要先進行資料庫遷移等操作,否則可能會導致應用程式無法正常執行。
-
示例:
# 將名為 my-pod 的 Pod,其中名為 my-container 的容器,由當前使用的 nginx:1.19 映象,更新為 nginx:1.23 $ kubectl set image pod/my-pod my-container=nginx:1.23
-
-
更新資源請求和限制(CPU、記憶體等)
-
修改配置檔案並應用更新(推薦)
-
步驟一:修改配置檔案。
# 更新前配置,CPU 為 0.2,記憶體為 256M apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: my - container image: nginx:latest resources: requests: cpu: "0.2" memory: "256Mi"
# 更新後配置,CPU 為 0.3,記憶體為 512M apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: my - container image: nginx:latest resources: requests: cpu: "0.3" memory: "512Mi"
-
步驟二:應用更新。
# Kubernetes 會根據新的配置調整 Pod 的資源分配 $ kubectl apply -f my-pod.yaml
-
-
kubectl edit
:臨時修改。示例:$ kubectl edit pod my-pod
- kubectk edit 命令,會開啟一個文字編輯器(預設是 vi 或 vim),顯示 Pod 的配置資訊。
- 在編輯器中修改資源請求和限制的相關內容,儲存並退出後,Kubernetes 會嘗試根據修改後的配置更新 Pod。不過這種方式的修改是直接作用於叢集中的資源,沒有經過配置檔案的版本控制,所以在生產環境中使用時要謹慎,並且最好在修改後將更新後的配置儲存到配置檔案中,以方便後續的管理和維護。
-
刪除 Pod
-
kubectl delete pod <pod-name>
:刪除單個 Pod。示例:$ kubectl delete pod nginx-pod
-
--force
和--grace-period=0
:強制刪除 Pod,但這種方式可能會導致資料丟失或未完成的操作被中斷,應該謹慎使用。示例:$ kubectl delete pod my-pod --force --grace-period=0
- 正常情況下,當執行刪除命令時,Kubernetes 會先傳送
SIGTERM
訊號給容器內的主程序,等待一段時間(預設是 30 秒,即grace-period
),讓程序進行清理操作(如儲存資料、關閉連線等),然後再傳送SIGKILL
訊號強制終止程序。如果使用了強制刪除選項,就會跳過 SIGTERM 等待階段,直接傳送 SIGKILL 訊號。
- 正常情況下,當執行刪除命令時,Kubernetes 會先傳送
-
-l
:透過標籤選擇器來刪除多個 Pod。示例:# 刪除帶有 "app=my-app" 標籤的 Pod $ kubectl delete pods -l app=my-app
-
--all
和-n
:刪除指定名稱空間下的所有 Pod。示例:# 刪除 my-namespace 下的所有 Pod $ kubectl delete pods --all -n my-namespace
-
在刪除 Pod 時,要確保清楚自己的操作可能帶來的影響。特別是對於一些有狀態的應用,可能會導致資料丟失或服務中斷。如果這些 Pod 是由更高層次的資源(如 Deployment、StatefulSet 等)管理的,刪除後這些資源可能會自動重新建立 Pod,這也需要考慮對系統整體執行的影響。
Pod 配置檔案
在搭建 Kubernetes 叢集時,建立過一個 Nginx 服務用於測試,現在將其刪除:
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-85b98978db-bhrd8 0/1 ImagePullBackOff 0 3d12h
[root@k8s-master ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 0/1 1 0 49d
# 刪除 Nginx 對應的 deployment
[root@k8s-master ~]# kubectl delete deployment nginx
deployment.apps "nginx" deleted
[root@k8s-master ~]# kubectl get deployment
No resources found in default namespace.
# pod 是透過 deployment 建立的,刪除 deplpyment,對應的 pod 也就刪除了
[root@k8s-master ~]# kubectl get pods
No resources found in default namespace.
[root@k8s-master ~]# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 58d
nginx NodePort 10.98.189.130 <none> 80:31173/TCP 49d
# 刪除 Nginx 對應的 service
[root@k8s-master ~]# kubectl delete services nginx
service "nginx" deleted
[root@k8s-master ~]# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 58d
定義一個 nginx-pod.yaml 配置檔案:
apiVersion: v1 # api 文件版本
kind: Pod # 資源物件型別,也可以配置為像 Deployment、StatefulSet 這一類的物件
metadata: # Pod 相關的後設資料,用於描述 Pod 的資料
name: "nginx-pod" # Pod 的名稱
namespace: default # 定義 Pod 的名稱空間
labels: # 定義 Pod 的標籤
app: "nginx-pod-app" # 標籤的 key:value,可以按實際來自定義
spec: # 規約,即期望當前 Pod 應按照下面的描述進行建立
containers: # 對於 Pod 中的容器描述
- name: nginx-pod # 容器的名稱
image: "nginx:latest" # 指定容器的映象
imagePullPolicy: IfNotPresent # 映象拉取策略,指定如果本地有就用本地的,如果沒有就拉取遠端的
command: # 指定容器啟動時執行的命令
- nginx
- -g
- 'daemon off;' # 當前 command 配置等同於命令:nginx -g 'daemon off;'
workingDir: /usr/share/nginx/html # 定義容器啟動後的工作目錄
resources:
limits: # 最多可以使用的資源
cpu: 200m # 限制 cpu 最多使用 0.2 個核心
memory: 256Mi # 限制記憶體最多使用 256 MB
requests: # 最少需要使用的資源
cpu: 100m # 限制 cpu 最少使用 0.1 個核心
memory: 128Mi # 限制記憶體最多使用 128 MB
ports:
- containerPort: 80 # 描述容器內要暴露什麼埠
name: http # 埠名稱
protocol: TCP # 描述該埠是基於哪種協議通訊的
env: # 環境變數
- name: JVM_OPTS # 環境變數名稱
value: '-Xms128m -Xmx128m' # 環境變數的值
restartPolicy: OnFailure # 重啟策略,只有失敗的情況才會重啟
VS Code 中,可以安裝
Kubernetes Templates
外掛,用於快速建立配置檔案。
透過 nginx-po.yaml 配置檔案,建立 Pod:
[root@k8s-master pods]# cd /opt/k8s/pods/
[root@k8s-master pods]# kubectl create -f nginx-pod.yaml
pod/nginx-pod created
檢視新建的 nginx-pod 這個 Pod 的資訊:
# 檢視 Pod 的簡略資訊
[root@k8s-master pods]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 3m5s # 此時 STATUS 已經是 Running,剛建立時狀態為 ContainerCreating
# 檢視 Pod 的詳細資訊
[root@k8s-master pods]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod 1/1 Running 0 46m 10.244.2.10 k8s-node2 <none> <none>
[root@k8s-master pods]# kubectl describe pod nginx-pod
Name: nginx-pod
Namespace: default
Priority: 0
Node: k8s-node2/192.168.1.122
Start Time: Sun, 27 Oct 2024 09:17:02 +0800
Labels: app=nginx-pod-app
Annotations: <none>
Status: Running
IP: 10.244.2.10
IPs:
IP: 10.244.2.10
Containers:
nginx-pod:
Container ID: docker://52e0bb9cd83f20ebb50988bcac9878592c049a0b1b746672a80a7786c685ea72
Image: nginx:latest
Image ID: docker-pullable://nginx@sha256:04ba374043ccd2fc5c593885c0eacddebabd5ca375f9323666f28dfd5a9710e3
Port: 80/TCP
Host Port: 0/TCP
Command:
nginx
-g
daemon off;
State: Running
Started: Sun, 27 Oct 2024 09:17:03 +0800
Ready: True
Restart Count: 0
Limits:
cpu: 200m
memory: 256Mi
Requests:
cpu: 100m
memory: 128Mi
Environment:
JVM_OPTS: -Xms128m -Xmx128m
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-k7zmc (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-k7zmc:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: Burstable
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events: # Pods 的事件
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 17s default-scheduler Successfully assigned default/nginx-pod to k8s-node2 # 分配到 k8s-node2 節點
Normal Pulled 17s kubelet Container image "nginx:latest" already present on machine
Normal Created 17s kubelet Created container nginx-pod
Normal Started 17s kubelet Started container nginx-pod
- 最下面的 Events,描述了 Pod 的建立過程。
探針
探針
:容器內應用的監測機制,根據不同的探針,可以判斷容器應用當前的狀態。
探針的型別
StartupProbe
StartupProbe
:啟動探針,用於檢測容器內應用程式是否已經完成啟動過程。在容器啟動階段,有些應用可能需要較長時間來完成初始化,如載入大量配置檔案、建立資料庫連線等。StartupProbe 允許這個啟動過程完成,避免在啟動階段因為 LivenessProbe 或 ReadinessProbe 檢查失敗而導致容器被錯誤地重啟。只有當 StartupProbe 成功後,LivenessProbe 和 ReadinessProbe 才會開始正常工作。
LivenessProbe
LivenessProbe
:存活探針,用於檢測容器是否還在正常執行狀態。如果容器在執行過程中出現故障,例如進入死迴圈、記憶體洩漏等導致應用程式無法正常工作的情況,LivenessProbe 能夠檢測到這種異常,並根據配置決定是否重啟容器。這有助於保持應用程式的健康執行,及時從故障狀態中恢復。
ReadinessProbe
ReadinessProbe
:就緒探針,用於判斷容器是否已經準備好接收請求。與 LivenessProbe 不同,它關注的是容器是否能夠正常處理業務流量,而不是僅僅是否存活。當容器剛啟動或者在執行過程中,由於某些原因(如正在載入配置檔案、預熱快取等)暫時無法接收請求時,ReadinessProbe 可以檢測到這種狀態,並且控制服務發現元件(如 Kubernetes 的 Service)暫時不將流量傳送到還沒準備好的容器。
探測的方式
三種探針,均支援以下三種探測方式:
exec
:以執行命令的方式進行監測。tcpSocket
:以建立 TCP 連線的方式進行監測。httpGet
:以傳送 HTTP 請求的方式進行監測。
下面以 livenessProbe 為例,給出這三種探測方式的使用說明。
ExecAction
示例:
livenessProbe:
exec:
command: ["ps", "-ef", "|", "grep", "myapp", "|", "grep", "-v", "grep"]
initialDelaySeconds: 20
periodSeconds: 8
failureThreshold: 3
含義:表示在容器啟動 20 秒後開始,每 8 秒執行一次 "ps -ef | grep myapp | grep -v grep" 命令,檢查程序是否存在。如果連續 3 次執行這個命令的結果為程序不存在,就判定容器存活狀態檢查失敗,可能會重啟容器。
TCPSocketAction
示例:
livenessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 2
含義:表示在容器啟動 10 秒後開始,每 5 秒檢查一次容器內 3306 埠是否可以建立 TCP 連線。如果連續 2 次檢查失敗,就判定容器存活狀態檢查失敗,可能會重啟容器。
HTTPGetAction
示例:
livenessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
含義:表示在容器啟動 15 秒後開始,每隔 10 秒向容器內 8080 埠的 /healthz 路徑傳送一個 HTTP 請求。如果連續 3 次請求都沒有得到預期的響應(如返回碼不是 200 ~ 299 之間),就認為容器存活狀態檢查失敗,可能會觸發容器重啟。
探針的引數配置
探針的通用引數配置及含義:
initialDelaySeconds
:初始化時間。timeoutSeconds
:超時時間。periodSeconds
:監測的間隔時間。sucessThreshold
:監測成功多少次,才表示成功。failureThreshold
:監測失敗多少次,才表示失敗。
Pod 的生命週期
Pod 是 Kubernetes 中最小的可部署和可管理的計算單元,它有著完整的生命週期,主要包括以下幾個階段:
Pending(掛起)階段
- 狀態描述:當一個 Pod 被建立後,它首先會進入 Pending 狀態。在這個階段,Pod 正在等待被排程到一個合適的節點上執行。這可能是因為叢集中沒有足夠的資源(如 CPU、記憶體、儲存等)來立即啟動 Pod,或者是因為需要等待一些外部依賴(如儲存卷的準備完成)。
- 關鍵事件:在這個階段,Kubernetes 排程器會不斷評估叢集中的節點資源情況,尋找能夠滿足 Pod 資源請求的節點。同時,系統會檢查 Pod 所依賴的各種資源是否準備就緒。
Running(執行)階段
- 狀態描述:一旦 Pod 被排程到一個節點並且其所有的容器都已經成功啟動,Pod 就會進入 Running 狀態。在這個狀態下,Pod 中的容器正在按照配置執行相應的任務。容器內的應用程式可以正常接收請求、處理資料等。
- 關鍵事件:容器啟動過程中的初始化操作是這個階段的關鍵。例如,對於一個基於 Java 的應用容器,可能會在啟動時執行類載入、資料庫連線初始化等操作。同時,容器會開始監聽配置的埠,準備接收外部請求。
Succeeded(成功完成)階段
- 狀態描述:當 Pod 中的所有容器都正常退出,並且退出碼為 0(表示成功完成任務)時,Pod 就會進入 Succeeded 狀態。這個階段適用於那些執行一次性任務的 Pod,通常用於執行批處理任務、資料遷移任務等 Pod。
- 關鍵事件:容器內任務的完成和正常退出是這個階段的關鍵。例如,在資料遷移的例子中,任務完成後的清理操作(如關閉資料庫連線、釋放資源等)完成後,容器才會正常退出。在這個階段,Pod 的資源會被保留,直到被手動刪除或者根據 Kubernetes 的垃圾回收策略自動清除。可以透過檢視容器的日誌來確認任務是否成功完成,以及獲取相關的執行結果。
Failed(失敗)階段
- 狀態描述:如果 Pod 中的任何一個容器以非零退出碼退出,或者容器無法啟動(例如,由於映象拉取失敗、配置錯誤、資源不足等原因),Pod 就會進入 Failed 狀態。
- 應對措施:容器啟動失敗或者執行過程中出現錯誤導致異常退出是這個階段的關鍵。在這種情況下,需要檢視容器的日誌和相關的事件資訊來確定失敗的原因,例如透過 kubectl describe pod 命令來檢視 Pod 的詳細資訊,包括容器的啟動事件和錯誤訊息。
Unknown(未知)階段
- 狀態描述:當 Kubernetes 無法獲取 Pod 的狀態資訊時,Pod 會進入 Unknown 狀態。這可能是由於網路問題、與節點通訊中斷或者 API 伺服器出現故障等原因導致的。
- 應對措施:需要檢查節點的狀態,嘗試恢復節點與叢集控制平面的通訊,以獲取 Pod 的準確狀態。如果節點已經不可恢復,可以考慮將 Pod 排程到其他節點上重新執行。
圖示:
PostStart 鉤子函式
PostStart
:是一個容器生命週期鉤子函式,它在容器建立後、主程序啟動前被呼叫。主要用於執行一些需要在容器主程序執行之前完成的初始化任務。例如,初始化網路連線、載入配置檔案或者預熱快取等操作。這些操作對於容器主程序的正常執行可能是必需的,透過 PostStart 可以確保這些前置任務先完成。
配置示例:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx:latest
lifecycle: # 生命週期配置
postStart: # PostStart 鉤子函式
exec: # 可以是 exec、tcpSocket 或者 httpGet
command: ["/bin/sh", "-c", "echo 'PostStart hook executed'"]
執行特性:
- 非同步執行:PostStart 鉤子函式是非同步執行的,容器主程序不會等待它完成就會啟動。這意味著它可以在後臺獨立執行。但如果 PostStart 執行時間過長或者出錯,可能會影響容器的啟動。例如,如果 PostStart 執行的命令一直無法完成,容器可能會一直處於啟動過程中。(也因為 PostStart 鉤子函式與 Pod 主容器中的 command 的先後順序難以保證,PostStart 鉤子函式一般用的比較少,如果有要求在 Pod 主容器之前執行的操作,可以放在初始化階段執行)
- 錯誤處理與重啟策略相關:如果 PostStart 執行失敗,Kubernetes 會根據容器的重啟策略來決定是否重啟容器。若重啟策略允許,容器可能會被重新啟動以再次嘗試執行 PostStart 和主程序。
PreStop 鉤子函式
PreStop
:是另一個容器生命週期鉤子函式,它在容器終止之前被呼叫。主要用於執行一些清理操作,例如優雅地關閉資料庫連線、釋放資源(如檔案鎖、網路連線等)、儲存容器狀態或資料等。這有助於確保容器在停止過程中能夠有序地清理自己的資源,避免資料丟失或資源洩漏。
配置示例:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx:latest
lifecycle: # 生命週期配置
preStop: # PreStop 鉤子函式
exec: # 可以是 exec、tcpSocket 或者 httpGet
command: ["/bin/sh", "-c", "echo 'PreStop hook executed'; sleep 10"]
執行特性:
- 同步執行:PreStop 鉤子函式是同步執行的,容器主程序會等待 PreStop 完成後才會完全終止。這是為了確保清理操作能夠順利完成。不過,如果 PreStop 執行的命令陷入死迴圈或者長時間無法完成,容器可能會一直處於停止過程中,直到 PreStop 執行完成或者達到 Pod 的終止寬限期(
grace-period
)。 - 終止寬限期:Kubernetes 在傳送終止訊號給容器後,會等待一段時間(終止寬限期),預設是 30 秒。在這個期間內,PreStop 鉤子函式會執行。如果 PreStop 執行時間超過終止寬限期,Kubernetes 會傳送
SIGKILL
訊號強制終止容器主程序。但通常建議合理設定 PreStop 執行的命令,使其在終止寬限期內完成。
鉤子函式應用
將 nginx-pod.yaml 中,新增 PostStart 和 PreStop 的配置:
apiVersion: v1 # api 文件版本
kind: Pod # 資源物件型別,也可以配置為像 Deployment、StatefulSet 這一類的物件
metadata: # Pod 相關的後設資料,用於描述 Pod 的資料
name: "nginx-pod" # Pod 的名稱
namespace: default # 定義 Pod 的名稱空間
labels: # 定義 Pod 的標籤
app: "nginx-pod-app" # 標籤的 key:value,可以按實際來自定義
spec: # 規約,即期望當前 Pod 應按照下面的描述進行建立
containers: # 對於 Pod 中的容器描述
- name: nginx-pod # 容器的名稱
image: "nginx:latest" # 指定容器的映象
imagePullPolicy: IfNotPresent # 映象拉取策略,指定如果本地有就用本地的,如果沒有就拉取遠端的
lifecycle:
postStart:
exec:
command:
- sh
- -c
- "echo '<h1>pre stop</h1>' > /usr/share/nginx/html/prestop.html"
preStop:
exec:
command:
- sh
- -c
- "sleep 50; echo 'sleep finished...' > /usr/share/nginx/html/prestop.html"
command: # 指定容器啟動時執行的命令
- nginx
- -g
- 'daemon off;' # 當前 command 配置等同於命令:nginx -g 'daemon off;'
workingDir: /usr/share/nginx/html # 定義容器啟動後的工作目錄
resources:
limits: # 最多可以使用的資源
cpu: 200m # 限制 cpu 最多使用 0.2 個核心
memory: 256Mi # 限制記憶體最多使用 256 MB
requests: # 最少需要使用的資源
cpu: 100m # 限制 cpu 最少使用 0.1 個核心
memory: 128Mi # 限制記憶體最多使用 128 MB
ports:
- containerPort: 80 # 描述容器內要暴露什麼埠
name: http # 埠名稱
protocol: TCP # 描述該埠是基於哪種協議通訊的
env: # 環境變數
- name: JVM_OPTS # 環境變數名稱
value: '-Xms128m -Xmx128m' # 環境變數的值
restartPolicy: OnFailure # 重啟策略,只有失敗的情況才會重啟
首先,建立 Pod,檢視 PostStart 鉤子函式的執行情況:
[root@k8s-master pods]# kubectl create -f nginx-pod.yaml
pod/nginx-pod created
[root@k8s-master pods]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod 1/1 Running 0 8s 10.244.2.12 k8s-node2 <none> <none>
# 可以看到,PostStart 鉤子函式的命令已執行
[root@k8s-master pods]# curl 10.244.2.12/prestop.html
<h1>pre stop</h1>
然後,開啟兩個視窗,一個視窗刪除 Pod,另一個視窗監控 Pod 的變化:
# 視窗一,刪除 Pod
[root@k8s-master pods]# time kubectl delete pod nginx-pod
pod "nginx-pod" deleted
real 0m31.454s # 刪除操作實際花費時間 31.454 秒
user 0m0.049s
sys 0m0.013s
[root@k8s-master pods]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 38s
nginx-pod 1/1 Terminating 0 42s
nginx-pod 0/1 Terminating 0 73s # Pod 從開始刪除到刪除完成,時間為 31 秒
nginx-pod 0/1 Terminating 0 73s
nginx-pod 0/1 Terminating 0 73s
因為終止寬限期預設為 30s,雖然 PreStop 鉤子函式設定 sleep 50s,但是 30s 後,容器主程序被強制終止。如果將終止寬限期設定為 40s,重複上面的過程,可以發現,刪除 Pod 操作花費的時間是 40s 左右。
...
spec:
terminationGracePeriodSeconds: 40 # 設定終止寬限期為 40s,預設的是 30s
containers:
...
原文連結
https://github.com/ACatSmiling/zero-to-zero/blob/main/Operation/kubernetes.md