02-k8s各應用管理器與pod介紹
前言:Deployment的發展
雖然ReplicaSet可以確保在任何給定時間執行的Pod副本達到指定的數量,但是Deployment(部署)是一個更高階的概念,它管理ReplicaSet併為Pod和ReplicaSet提供宣告性更新以及許多其他有用的功能,所以建議在實際使用中,採用Deployment代替ReplicaSet。
如果在Deployment物件中描述了所需的狀態,Deployment控制器就會以可控制的速率將實際狀態更改為期望狀態。也可以在Deployment中建立新的ReplicaSet,或者刪除現有的Deployment並使用新的Deployment部署所用的資源。
一、無狀態應用管理器Deployment
deployment用於部署無狀態的服務,是k8s中最常用的控制器。管理物件為pod。
一般用於管理維護企業內部無狀態的微服務,比如configserver、zuul、springboot。
deployment可以管理多個副本的Pod實現無縫遷移、自動擴容縮容、自動災難恢復、一鍵回滾等功能。
Deployment管理器基礎操作
建立Deployment
方式1:手動建立
kubectl create deployment {deployment-name} --image=nginx
方式2:以yaml格式或json格式建立Deployment
kubectl create -f test-nginx.yaml
查詢deployment狀態
檢視指定deployment的詳細資訊
kubectl describe deployment {deployment-name} -n {namespace-name}
kubectl get deployments -o wide
解析:-o wide 檢視全部詳情
匯出deployment配置
匯出已建立的deployment配置檔案至指定路徑:
kubectl get deployments test-nginx -o yaml >/data1/k8s-app/deploy/test-nginx.yaml
檢視指定某一pod下的日誌
kubectl logs {pod-name} -n {namespace-name}
修改deployment配置
修改某個指定deployment配置
kubectl edit deployment {deployment-name} -n {namespace-name}
kubectl apply -f xxx.yaml -n {namespace-name}
kubectl replace -f xxx.yaml -n {namespace-name}
版本升級操作:
手動改映象並記錄:
kubectl set image deploy {deployment-name} -n {namespace-name} XXX=xx(版本資訊) --record
解析:
--record 表示記錄本次修改
檢視部署歷史:
kubectl rollout history deploy {deployment-name} -n {namespace-name}
更新多次,需要檢視某次更新的詳細資訊:
kubectl rollout history deploy {deployment-name} -n {namespace-name} --revision=3
解析:
--revision 指定版本號
回滾到上一個版本:
kubectl rollout undo deploy {deployment-name} -n {namespace-name}
回滾到指定版本:
kubectl rollout undo deploy {deployment-name} -n {namespace-name} --to-revision=2
解析:
--to-revision=2 表示回滾到更新的第2個版本
擴容與縮容
動態調整Pod的副本數:
kubectl scale deploy {deployment-name} -n {namespace-name} --replicas=5
解析:
--replicas=5 將原有副本數修改為5,若原有為2個,將擴容3個副本;若原有為10個,將縮容
注意:這裡的擴容縮容,不會修改原有rs
Deployment更新的暫停與恢復(用set 修改多處更新)
暫停Deployment更新
kubectl rollout pause deploy {deployment-name} -n {namespace-name}
set修改deployment資源
kubectl set image ......
kubectl set resources deploy {deployment-name} -c {container-name}(指定容器) --limits=cpu=200m,memory=128Mi --requests=cpu=10m,memory=16Mi
恢復Deployment更新:
kubectl rollout resume {deployment-name} -n {namespace-name}
注意:恢復更新的Deployment建立了一個新的RS(複製集)
注意事項:
可修改yaml格式來更新Deployment,其中在spec下的幾個引數配置解析為:
- replicas: 4 表示副本數,4為4個副本
- revisionHistoryLimit:設定保留RS舊的revision的個數,設定為0的話,不保留歷史資料;
- minReadySeconds:可選引數,指定新建立的Pod在沒有任何容器崩潰的情況下視為Ready最小的秒數,預設為0,即一旦被建立就視為可用。
關於滾動更新的策略引數解析:
strategy.type:更新deployment的方式,預設是RollingUpdate;
- RollingUpdate表示滾動更新,可以指定maxSurge和maxUnavailable
- maxUnavailable:指定在回滾或更新時最大不可用的Pod的數量,可選欄位,預設25%,可以設定成數字或百分比,如果該值為0,那麼maxSurge就不能0
- maxSurge:可以超過期望值的最大Pod數,可選欄位,預設為25%,可以設定成數字或百分比,如果該值為0,那麼maxUnavailable不能為0
- Recreate:重建,先刪除舊的Pod,在建立新的Pod
示例:
# kubectl get deploy nginx -oyaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "12"
kubernetes.io/change-cause: kubectl set image deploy nginx nginx=nginx:1.15.3
--record=true
creationTimestamp: "2020-09-19T02:41:11Z"
generation: 19
labels:
app: nginx
name: nginx
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 2
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.15.3
imagePullPolicy: IfNotPresent
name: nginx
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 10m
memory: 16Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
二、有狀態應用管理StatefulSet
StatefulSet(有狀態集,縮寫為sts)主要用於管理有狀態應用程式的工作負載API物件。常用於部署有狀態的且需要有序啟動的應用程式。
和Deployment類似,一個StatefulSet也同樣管理著基於相同容器規範的Pod。不同的是,StatefulSet為每個Pod維護了一個粘性標識。這些Pod是根據相同的規範建立的,但是不可互換,每個Pod都有一個持久的識別符號,在重新排程時也會保留,一般格式為StatefulSetName-Number。比如定義一個名字是Redis-Sentinel的StatefulSet,指定建立三個Pod,那麼創建出來的Pod名字就為Redis-Sentinel-0、Redis-Sentinel-1、Redis-Sentinel-2。
StatefulSet建立的Pod一般使用Headless Service(無頭服務)負責Pod的網路身份和通訊,需要提前建立此服務。和普通的Service的區別在於Headless Service沒有ClusterIP,它使用的是Endpoint進行互相通訊。在刪除一個StatefulSet時,不保證對Pod的終止,要在StatefulSet中實現Pod的有序和正常終止,可以在刪除之前將StatefulSet的副本縮減為0。
Headless一般格式為:
statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local
解析:
- statefulSetName 為StatefulSet的名字;
- 0..N-1 為Pod所在的序號,從0開始到N-1;
- serviceName 為Headless Service的名字,建立StatefulSet時,必須指定Headless Service名稱;
- namespace 為服務所在的名稱空間;
- .cluster.local 為Cluster Domain(叢集域)。
StatefulSet注意事項:
一般StatefulSet用於有以下一個或者多個需求的應用程式:
- 需要穩定的獨一無二的網路識別符號。
- 需要持久化資料。
- 需要有序的、優雅的部署和擴充套件。
- 需要有序的自動滾動更新。
- 如果應用程式不需要任何穩定的識別符號或者有序的部署、刪除或者擴充套件,應該使用無狀態的控制器部署應用程式,比如Deployment或者ReplicaSet。
StatefulSet是Kubernetes 1.9版本之前的beta資源,在1.5版本之前的任何Kubernetes版本都沒有。
Pod所用的儲存必須由PersistentVolume Provisioner(持久化卷配置器)根據請求配置StorageClass,或者由管理員預先配置,當然也可以不配置儲存。
為了確保資料安全,刪除和縮放StatefulSet不會刪除與StatefulSet關聯的卷,可以手動選擇性地刪除PVC和PV(參考PV和PVC節)。
Deployment管理器基礎操作
定義一個StatefulSet資源yaml檔案
定義一個簡單的StatefulSet的示例如下:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
注意:
此示例沒有新增儲存配置
其中:
- kind: Service 定義了一個名字為Nginx的Headless Service,建立的Service格式為nginx-0.nginx.default.svc.cluster.local,其他的類似,因為沒有指定Namespace(名稱空間),所以預設部署在default。
- kind: StatefulSet 定義了一個名字為web的StatefulSet,replicas表示部署Pod的副本數。
- 在StatefulSet中必須設定Pod選擇器(.spec.selector)用來匹配其標籤(.spec.template.metadata.labels)。在1.8版本之前,如果未配置該欄位(.spec.selector),將被設定為預設值,在1.8版本之後,如果未指定匹配Pod Selector,則會導致StatefulSet建立錯誤。
- 當StatefulSet控制器建立Pod時,它會新增一個標籤statefulset.kubernetes.io/pod-name,該標籤的值為Pod的名稱,用於匹配Service。
檢視更新過程
kubuctl rollout status sts {statefulset-name} -n {namespace-name}
過濾檢視pod配置中某一資訊
kubectl get pod {pod-name} -n {namespace-name} -oyaml | grep image
kubectl get po -l app=nginx -w
-w 引數表示動態檢視pod的更新過程
在pod的配置中,updateStrategy 表示更新策略,其中若type: RollingUpdate 表示滾動更新,修改pod配置後會根據建立順序更新,配置為:
updateStrategy:
rollingUpdate:
partition: 0
type: RollingUpdate
解析:
partition: 0 表示分段更新,0表示小於0的pod不更新(即更新所有pod);其中數字表示更新的分段(pod)數;舉例:若StatefulSet的pod數有5個,現在partition: 2;那麼pod2前面的pod不會更新(pod0、pod1),更新的pod為pod2、pod3、pod4。多用於灰度釋出(先讓指定pod更新,在更新其它pod)
若type: OnDelete 表示只有刪除pod時,才會更新修改的配置,且配置應為:
updateStrategy:
type: RollingUpdate
StatefulSet的刪除
一般情況,刪除sts時,pod會被重建
涉及概念:級聯刪除與非級聯刪除
- 級聯刪除:刪除StatefulSet時同時刪除pod,若不指定,預設為級聯刪除
- 非級聯刪除:刪除StatefulSet時不刪除pod,但刪除sts後,pod變成“孤兒”,此時刪除pod不會被重建
設定級聯刪除或非級聯刪除
非級聯刪除:
kubectl delete sts {statefulset-name} -n {namespace-name} --cascade=false
三、守護程序服務DaemonSet
DaemonSet 是守護程序集,縮寫為ds,在所有節點或者是匹配條件的節點(通過打標籤形式)上都部署一個Pod。
使用DaemonSet的場景
- 執行叢集儲存的daemon,比如ceph或者glusterd
- 節點的CNI網路外掛,calico
- 節點日誌的收集:fluentd或者是filebeat
- 節點的監控:node exporter
- 服務暴露:部署一個ingress-nginx
建立DaemonSet
kubectl create -f nginx-ds.yaml
示例:
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app: nginx
name: nginx
spec:
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
updateStrategy:
rollingUpdate:
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.15.2
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
設定匹配條件的node部署pod
方法1命令部署:
kubectl label nodeXX(節點名稱) nodeXX(節點名稱-多個節點) ... ds=true
檢視標籤
kubectl get node --show-labels
方法2修改yaml檔案:(注意,若replace YAML檔案,會更新配置)
在spec下,新增
......
nodeSelector:
ds: "ture"
......
另外,若需要新增或刪除ds節點,需進行label新增或刪除即可
DaemonSet更新配置
......
updateStrategy:
rollingUpdate:
maxUnavailable: 1 ###最大不可用範圍,建議設為1
......
注意:在DaemonSet的生產環境中,建議更新策略採用OnDelete,避免影響所有節點上的pod,可用幾個不重要的pod做測試用
......
updateStrategy:
type: RollingUpdate
......
四、Label與Selector
Label:對k8s中各種資源進行分類、分組,新增一個具有特別屬性的一個標籤。
Selector:通過一個過濾的語法進行查詢到對應標籤的資源
刪除label
kubectl label node {node-name} app- -n {namespace-name}
修改label
kubectl label pod {pod-name} app=xx(新名稱) -n {namespace-name} --overwrite
檢視所有ns下符合條件的標籤
kubectl get svc -A --show-labels
kubectl get pod -A --show-labels
kubectl get node -A --show-labels
根據需求檢視匹配條件的多種標籤表達示例:
所有ns下,標籤包含metrics-server和kubernetes-dashboad的pod
kubectl get po -A -l 'k8s-app in (metrics-server, kubernetes-dashboad)'
標籤為nginx,但不包含v1版本的pod
kubectl get po -l version!=v1,app=nginx
所有ns下,標籤為nginx,但不包含v1版本的pod
kubectl get po -A -l version!=v1,'app02 in (nginx,busybox)'
未完待續。。。。