04-K8S資源編排
阿新 • • 發佈:2020-10-31
一. 資源清單檔案-YAML
1. YAML 概述
K8S叢集中對資源管理和資源物件編排部署都可以通過宣告樣式(YAML)檔案來解決,我們把這種檔案叫做資原始檔清單語法格式:- 通過縮排表示層級關係
- 不能使用Tab進行縮排,只能使用空格,一般縮排2個空格
- 字元後縮排一個空格,比如: 冒號,逗號後面
- 使用---表示新的yaml段開始
- 使用#註釋
2. K8S中的資源
1. 名稱空間: 僅在此空間有效。K8S中所有內容都抽象為資源,資源例項化之後,叫做物件- 工作負載型資源: Pod, ReplicaSet, Deployment, StatefulSet, DaemonSet, Jobs...
- 服務發現及負載均衡型資源: Service, Ingress, LoadBalance...
- 配置與儲存型資源: Volume(儲存卷)...
- 特殊型別的儲存卷: ConfigMap(配置中心), Secret(加密資料)...
3. 常用欄位
1. 必選引數名 | 型別 | 描述 |
apiVersion | String | K8S Api 版本 |
kind | String | 指定建立資源的Controller型別和角色 |
matadata | Object | 元資料物件 |
matadata.name | String | 元資料物件的名字 |
matadata.namespace | String | 指定名稱空間 |
spec | Object | 詳細定義資源的規格 |
spec.containers[] | List | 定義容器的列表 |
spec.containers[].name | String | 定義容器的名字 |
spec.containers[].image | String | 定義映象名稱 |
引數名 | 型別 | 描述 |
spec.containers[].imagePullPolicy | String | 定義映象拉取的策略, 預設是IfNotPresent 1. Always: 意思是每次都嘗試拉取映象 2. Never: 表示僅使用本地映象 3. ifNotPresent: 如果本地有就使用本地,沒有在拉取 |
spec.containers[].command[] | List | 指定容器啟動命令,可以指定多個 |
spec.containers[].args[] | List | 指定容器啟動命令引數 |
spec.containers[].workingDir | String | 指定容器的工作目錄 |
spec.containers[].volumeMounts[] | List | 指定容器內部的儲存卷配置 |
spec.containers[].volumeMounts[].name | String | 指定儲存卷名稱 |
spec.containers[].volumeMounts[].mountPath | String | 指定被容器掛載的儲存卷的路徑 |
spec.containers[].volumeMounts[].readOnly | String | 是否只讀,預設是讀寫 |
spec.containers[].ports[] | List | 指定容器需要的埠列表 |
spec.containers[].ports[].name | String | 指定埠名稱 |
spec.containers[].ports[].containerPort | String | 指定容器需要監聽的埠號 |
spec.containers[].ports[].hostPort | String | 指定容器所在主機需要監聽的埠號,預設跟containerPort相同,注意設定了hostPort同一臺主機無法啟動相同副本 |
spec.containers[].ports[].protocol | String | 指定埠協議,支援TCP和UDP,預設值為TCP |
spec.containers[].evn[] | List | 環境變數列表 |
spec.containers[].evn[].name | String | 指定環境變數名稱 |
spec.containers[].evn[].value | String | 指定環境變數值 |
spec.containers[].resources | Object | 指定資源限制和資源請求的值 |
spec.containers[].resources.limits | Object | 設定容器執行時資源的執行上限 |
spec.containers[].resources.limits.cpu | String | 指定CPU的限制,單位core數 1c = 1000m |
spec.containers[].resources.limits.memory | String | 指定MEM記憶體的限制,單位為MiB, GiB |
spec.containers[].resources.requests | Object | 指定容器啟動和排程時的限制設定 |
spec.containers[].resources.requests.cpu | String | CPU請求, 單位為core數, 容器啟動時初始化可以數量 |
spec.containers[].resources.requests.memory | String | 記憶體請求, 單位為MiB, GiB. 容器啟動的初始化可以數量 |
引數名 | 欄位型別 | 描述 |
spec.restartPolicy | String | 定義Pod的重啟策略, 可選值為Always, OnFailure 預設值為Always 1. Always: Pod一旦終止執行, 則無論容器時如何終止的, kubelet 服務都將重啟 2. OnFailure: 只有Pod以非0退出碼終止才會重啟 3. Never: Pod 終止後,kubelet將退出碼報告給Master,不會重啟該Pod |
spec.nodeSelector | Object | 定義Node的Label過濾標籤 |
spec.imagePullSecrets | Object | 定義pull映象時, 使用的secret名稱 |
spec.hostNetwork | Boolean | 定義是否使用主機網路模式,預設值false |
# 控制器定義
apiVersion: apps/v1 # API版本
kind: Deployment # 資源型別
metadata: # 元資料
name: nginx-deployment
namespace: default
spec: # 資源規格
replicas: 3 # 副本數量
selector: # 標籤選擇
matchLabels:
app: nginx
# 被控制物件
template: # Pod模版
metadata: # Pod元資料
labels:
app: nginx
spec: # Pod規格
containers: # 容器配置
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
快速編寫# kubectl create 試執行生成
kubectl create deployment web --image=nginx -o yaml --dry-run > nginx.yml
# kubectl get 匯出執行的Pod
kubectl get deploy nginx-deployment -o=yaml > nginx-deployment.yml
二. K8S核心技術-Pod
1. Pod 建立時序圖
1. 建立指令傳送至ApiServer,由ApiServer寫入etcd2. Scheduler監聽到有新的Pod建立,根據演算法分配node節點,繫結Pod。返回結果由ApiServer寫入etcd3. Kubelet 監聽到被分配的Pod,執行docker 執行容器。更新狀態返回ApiServer寫入etcd2. Pod 排程策略
1. Pod的資源限制- 在排程過程中根據resources.request的限制找到能夠滿足的節點排程
# 節點新增標籤
kubectl label node node1 env_role=prod
# 檢視節點標籤
kubectl get nodes node1 --show-labels
3. 節點親和性: nodeAffinity,和nodeSelector基本一樣,根據節點標籤的約束來對Pod排程- 硬親和性: 約束條件必須滿足
- 軟親和性: 嘗試滿足
- NoSchedule: 一定不被排程
- PreferNoSchedule: 儘量不被呼叫
- NoExecute: 不會排程,並且還會驅逐已有的Pod
3. Pod 生命週期
Pod能夠具有多個容器,應用執行在容器裡面,但是它也可能有一個或多個先於應用容器啟動的Init容器1. 執行pause基礎容器2. init Container 初始化容器執行(init C可以有多個,序列執行)
- Init 容器總是執行到成功完成為止,如果Init容器失敗,K8S會不斷的重啟該Pod,直到Init 容器成功為止。如果Pod對應的restartPolicy為Never,則不會重新啟動
- 每個Init容器都必須在下一個Init容器啟動之前完成
- start: 在容器啟動時,執行一條命令或指令碼
- liveness: 存活檢測。主要用來確定是否重啟容器
- readless: 就緒檢測。只有當Pod中所有容器都處於就緒狀態,才會作為Service的後端
- stop: 在容器關閉時,執行一條命令或指令碼
1. init C 示例
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
initContainers:
- name: init-myservice
image: busybox:1.32.0
# until: 返回非0, 則進入迴圈. 返回0則退出迴圈
command: ["sh", "-c", "until nslookup myservice;do echo 'waiting for myservice';sleep 2;done;"]
- name: init-mydb
image: busybox:1.32.0
command: ["sh", "-c", "until nslookup mydb;do echo 'waiting for mydb';sleep 2;done;"]
containers:
- name: myapp-container
image: busybox:1.32.0
command: ["sh", "-c", "echo 'The app is running! && sleep 3600'"]
- 檢視日誌(-c 指定pod裡的容器)
kubectl logs myapp-pod -c init-myservice
kubectl logs myapp-pod -c init-myservice -f --tail=10
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
- 在Pod啟動過程中,Init容器會按順序在Pause之後啟動,每個容器必須在下一個容器啟動之前成功推出
- 如果由於執行時失敗退出,它會根據Pod的restartPolicy指定的策略進行重試
- 在所有的Init容器沒有成功之前,Pod將不會變成Ready狀態
- 如果Pod重啟,所有Init容器必須重新執行
- 對Init容器spec的修改被限制在容器image欄位,修改其他欄位都不會生效。更改Init容器的image欄位,等價於重啟該Pod
- Init容器具有應用容器的所有欄位。除了readiness
- 在Pod中的每個app和Init容器的名稱必須唯一
2. 探針
探針是由kubelet 對容器執行的定期診斷。要執行診斷,kubelet呼叫由容器實現的Handler。有三種類型的處理程式:- ExecAction: 在容器內執行指定命令。如果命令退出時返回碼為0則認為診斷成功
- TCPSocketAction: 對指定埠上的容器的IP地址進行TCP檢查。如果埠開啟,則診斷被認為是成功的
- HTTPGetAction: 對指定的埠和路徑上的容器的IP地址執行HTTP Get請求。如果響應的狀態碼大於等於200且小於400,則診斷被認為是成功的
- 成功: 容器通過了檢測
- 失敗: 容器未通過檢測
- 未知: 診斷失敗,因此不會採取任何行動
- readinessProbe: 檢測容器是否準備好服務請求。如果就緒探測失敗,端點控制器將從與Pod匹配的所有Service的端點中刪除該Pod的IP地址。初始延遲之前的就緒狀態預設為Failure。如果容器不提供就緒探針,則預設為Success
apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget-pod
namespace: default
spec:
containers:
- name: readiness-httpget-container
image: nginx:1.19.3
readinessProbe:
httpGet:
port: 80
path: /index1.html
initialDelaySeconds: 1 # 延時, 啟動後多長時間檢測
periodSeconds: 3 # 重試
kubectl get pod readiness-httpget-pod -w -o wide
kubectl describe pod readiness-httpget-pod
--- output
Readiness probe failed: HTTP probe failed with statuscode: 404
# 進入容器, 如果多個容器需 -c 指定
kubectl exec -it readiness-httpget-pod -- /bin/bash
- livenessProbe: 檢測容器是否正在執行。如果存活探測失敗,則kubelet會殺死容器,並且容器將受到其重啟策略的影響。如果容器不提供存活探針,則預設為Success
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod
spec:
containers:
- name: liveness-exec-container
image: busybox:1.32.0
command: ["/bin/sh", "-c", "touch /tmp/live; sleep 60; rm -f /tmp/live;sleep 3600"]
livenessProbe:
exec:
command: ["test", "-e", "/tmp/live"] # test命令檢查某個條件是否成立. -e如果檔案存在, 則為真
initialDelaySeconds: 1 # 延時, 啟動後多長時間檢測
periodSeconds: 3 # 重試
kubectl get pod liveness-exec-pod -w
--- output
NAME READY STATUS RESTARTS AGE
liveness-exec-pod 1/1 Running 0 71s
liveness-exec-pod 1/1 Running 1 104s
3. Start/Stop
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx:1.19.3
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo 'Hello from the postStart handler' > /tmp/message"]
preStop:
exec:
command: ["/bin/sh", "-c", "echo 'Hello from the preStop handler' > /tmp/message"]
4. Pod 執行狀態
- Pending: 掛起,Pod已經被K8S系統接受,但是有容器尚未建立
- Running: 執行,Pod 中所有容器已被建立,至少一個容器正在執行,或處於啟動或重啟狀態
- Succeeded: 成功,Pod中所有容器都被成功終止,並且不會在重啟
- Failed: 失敗,Pod中的所有容器都已經終止,並且至少有一個容器是失敗終止
- Unknown: 未知,因為某些原因無法取得Pod的狀態
三. 控制器-Controller
在叢集上管理和執行容器的物件。用來控制Pod的具體狀態和行為,在控制器的生命週期裡,始終維持Pod的副本數量- Pod是通過Controller實現應用的運維比如伸縮,滾動升級等等
- Pod和Controller之間通過label標籤建立關係