k8s控制器:Replicaset和Deployment
- pod:
那我們在定義pod資源時,可以直接建立一個kind:Pod型別的自主式pod,但是這存在一個問題,假如pod被刪除了,那這個pod就不能自我恢復,就會徹底被刪除,線上這種情況非常危險,所以今天就給大家講解下pod的控制器,所謂控制器就是能夠管理pod,監測pod執行狀況,當pod發生故障,可以自動恢復pod。也就是說能夠代我們去管理pod中間層,並幫助我們確保每一個pod資源始終處於我們所定義或者我們所期望的目標狀態,一旦pod資源出現故障,那麼控制器會嘗試重啟pod或者裡面的容器,如果一直重啟有問題的話那麼它可能會基於某種策略來進行重新布派或者重新編排;如果pod副本數量低於使用者所定義的目標數量,它也會自動補全;如果多餘,也會自動終止pod資源。
-
Replicaset控制器:概念,原理解讀
1.1 Replicaset概述
ReplicaSet是kubernetes中的一種副本控制器,簡稱rs,主要作用是控制由其管理的pod,使pod副本的數量始終維持在預設的個數。它的主要作用就是保證一定數量的Pod能夠在叢集中正常執行,它會持續監聽這些Pod的執行狀態,在Pod發生故障時重啟pod,pod數量減少時重新執行新的 Pod副本。官方推薦不要直接使用ReplicaSet,用Deployments取而代之,Deployments是比ReplicaSet更高階的概念,它會管理ReplicaSet並提供很多其它有用的特性,最重要的是Deployments支援宣告式更新,宣告式更新的好處是不會丟失歷史變更。所以Deployment控制器不直接管理Pod物件,而是由 Deployment 管理ReplicaSet,再由ReplicaSet負責管理Pod物件。
1.2 Replicaset工作原理:如何管理Pod?
Replicaset核心作用在於代使用者建立指定數量的pod副本,並確保pod副本一直處於滿足使用者期望的數量, 起到多退少補的作用,並且還具有自動擴容縮容等機制。
Replicaset控制器主要由三個部分組成:
1、使用者期望的pod副本數:用來定義由這個控制器管控的pod副本有幾個
2、標籤選擇器:選定哪些pod是自己管理的,如果通過標籤選擇器選到的pod副本數量少於我們指定的數量,需要用到下面的元件
3、pod資源模板:如果叢集中現存的pod數量不夠我們定義的副本中期望的數量怎麼辦,需要新建pod,這就需要pod模板,新建的pod是基於模板來建立的。 -
Replicaset資源清單檔案編寫技巧
檢視定義Replicaset資源需要的欄位有哪些?
點選檢視程式碼
[root@master1 ~]# kubectl explain rs
KIND: ReplicaSet
VERSION: apps/v1
DESCRIPTION:
ReplicaSet ensures that a specified number of pod replicas are running at
any given time.
FIELDS:
apiVersion <string> #當前資源使用的api版本,跟VERSION: apps/v1保持一致
kind <string> #資源型別,跟KIND: ReplicaSet保持一致
metadata <Object> #元資料,定義Replicaset名字的
spec <Object> ##定義副本數、定義標籤選擇器、定義Pod模板
status <Object> #狀態資訊,不能改
點選檢視程式碼
[root@master1 ~]# kubectl explain rs.spec
KIND: ReplicaSet
VERSION: apps/v1
RESOURCE: spec <Object>
DESCRIPTION:
Spec defines the specification of the desired behavior of the ReplicaSet.
More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
ReplicaSetSpec is the specification of a ReplicaSet.
FIELDS:
minReadySeconds <integer>
replicas <integer> #定義的pod副本數,根據我們指定的值建立對應數量的pod
selector <Object> -required- #用於匹配pod的標籤選擇器
template <Object> #定義Pod的模板,基於這個模板定義的所有pod是一樣的
點選檢視程式碼
[root@master1 ~]# kubectl explain rs.spec.template
KIND: ReplicaSet
VERSION: apps/v1
RESOURCE: template <Object>
DESCRIPTION:
Template is the object that describes the pod that will be created if
insufficient replicas are detected。PodTemplateSpec describes the data a pod should have when created from a
template
FIELDS:
metadata <Object>
spec <Object>
- Replicaset使用案例:部署Guestbook留言板
把frontend.tar.gz上傳到node1和node2上,解壓,在docker映象網站找
[root@node2]# docker load -i frontend.tar.gz
[root@node1]# docker load -i frontend.tar.gz
包在docker上面找:https://registry.hub.docker.com
編寫一個ReplicaSet資源清單
點選檢視程式碼
[root@master1 ~]# cat replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template: #定義的模板
metadata:
labels:
tier: frontend
spec:
containers: #物件列表下用-線連著
- name: php-redis
image: yecc/gcr.io-google_samples-gb-frontend:v3
imagePullPolicy: IfNotPresent #映象拉取策略
點選檢視程式碼
root@master1 ~]# kubectl apply -f replicaset.yaml
replicaset.apps/frontend created
[root@master1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
frontend 3 3 3 53m
[root@master1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
frontend-82p9b 1/1 Running 0 36m
frontend-j6twz 1/1 Running 0 36m
frontend-lcnq6 1/1 Running 0 36m
#補充:強制刪除pod
kubectl delete pods frontend --force --grace-period=0
點選檢視程式碼
apiVersion: apps/v1 #ReplicaSet 這個控制器屬於的核心群組
kind: ReplicaSet #建立的資源型別
metadata:
name: frontend #控制器的名字
labels:
app: guestbook
tier: frontend
spec:
replicas: 3 #管理的pod副本數量
selector:
matchLabels:
tier: frontend #管理帶有tier=frontend標籤的pod
template: #定義pod的模板
metadata:
labels:
tier: frontend
#pod標籤,一定要有,這樣上面控制器就能找到它要管理的pod是哪些了
spec:
containers: #定義pod裡執行的容器
- name: php-redis #定義容器的名字
image: yecc/gcr.io-google_samples-gb-frontend:v3
ports: #定義埠
- name: http #定義容器的名字
containerPort: 80 #定義容器暴露的埠
- Replicaset管理pod:擴容、縮容、更新
Replicaset實現pod的動態擴容
ReplicaSet最核心的功能是可以動態擴容和回縮,如果我們覺得兩個副本太少了,想要增加,只需要修改配置檔案replicaset.yaml裡的replicas的值即可,原來replicas: 3,現在變成replicaset: 4,修改之後,執行如下命令更新:(如下)
點選檢視程式碼
[root@master1 ~]# kubectl apply -f replicaset.yaml
replicaset.apps/frontend configured
[root@master1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
frontend 4 4 4 62m
[root@master1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
frontend-82p9b 1/1 Running 0 62m
frontend-j6twz 1/1 Running 0 62m
frontend-kzjm7 1/1 Running 0 33s
frontend-lcnq6 1/1 Running 0 62m
#也可以直接編輯控制器實現擴容
kubectl edit rs frontend #這個是我們把請求提交給了apiserver,實時修改
[root@master1 ~]# kubectl edit rs frontend
點選檢視程式碼
把上面的spec下的replicas 後面的值改成5,儲存退出
[root@master1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
frontend 5 5 5 67m
[root@master1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
frontend-82p9b 1/1 Running 0 67m
frontend-j6twz 1/1 Running 0 67m
frontend-kzjm7 1/1 Running 0 5m6s
frontend-lcnq6 1/1 Running 0 67m
frontend-lkl26 1/1 Running 0 13s
點選檢視程式碼
[root@master1 ~]# kubectl apply -f replicaset.yaml
replicaset.apps/frontend configured
[root@master1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
frontend 2 2 2 70m
[root@master1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
frontend-j6twz 1/1 Running 0 70m
frontend-lcnq6 1/1 Running 0 70m
點選檢視程式碼
Replicaset實現pod的更新
#把myapp-v2.tar.gz上傳到node1和node2上,手動解壓
[root@node1 ~]# docker load -i myapp-v2.tar.gz
[root@node2 ~]# docker load -i myapp-v2.tar.gz
[root@master1 ~]# kubectl edit rs frontend
#修改映象image: yecc/gcr.io-google_samples-gb-frontend:v3變成- image: ikubernetes/myapp:v2,修改之後儲存退出
[root@xianchaomaster1 ~]# kubectl get rs -o wide
NAME DESIRED CURRENT READY IMAGES
frontend 2 2 2 ikubernetes/myapp:v2
上面可以看到映象變成了ikubernetes/myapp:v2,說明滾動升級成功了
訪問測試
點選檢視程式碼
[root@master1 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
frontend-glb2c 1/1 Running 0 34s 10.244.209.133 node1
frontend-lck9t 1/1 Running 0 34s 10.244.187.74 node2
[root@master1 ~]# curl 10.244.209.133
div style="width: 50%; margin-left: 20px">
<h2>Guestbook</h2>
[root@master1 ~]# curl 10.244.209.74
div style="width: 50%; margin-left: 20px">
<h2>Guestbook</h2>
#上面可以看到雖然映象已經更新了,但是原來的pod使用的還是之前的映象,新建立的pod才會使用最新的映象
點選檢視程式碼
#10.244.209.133這個ip對應的pod刪除
[root@master1 ~]# kubectl delete pods frontend-glb2c
pod "frontend-glb2c" deleted
[root@master1 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
frontend-hkhdw 1/1 Running 0 15s 10.244.187.75 node2
frontend-lck9t 1/1 Running 0 2m37s 10.244.187.74 node2
#重新生成了一個新的pod:frontend-hkhdw
[root@master1 ~]# curl 10.244.187.75
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
#新生成的pod的映象已經變成了myapp的,說明更新完成了
#如果我們直接修改replicaset.yaml檔案,把image: yecc/gcr.io-google_samples-gb-frontend:v3變成- image: ikubernetes/myapp:v2
kubectl apply -f replicaset.yaml
#發現原來的pod還是用的frontend:v3這個映象,沒有實現自動更新
- 生產環境如果升級,可以刪除一個pod,觀察一段時間之後沒問題再刪除另一個pod,但是這樣需要人工干預多次;實際生產環境一般採用藍綠髮布,原來有一個rs1,再建立一個rs2(控制器),通過修改service標籤,修改service可以匹配到rs2的控制器,這樣才是藍綠髮布,這個也需要我們精心的部署規劃,我們有一個控制器就是建立在rs之上完成的,叫做Deployment
-
Deployment控制器:概念、原理解讀Deployment官方文件:
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
5.1 Deployment概述
Deployment是kubernetes中最常用的資源物件,為ReplicaSet和Pod的建立提供了一種宣告式的定義方法,在Deployment物件中描述一個期望的狀態,Deployment控制器就會按照一定的控制速率把實際狀態改成期望狀態,通過定義一個Deployment控制器會建立一個新的ReplicaSet控制器,通過ReplicaSet建立pod,刪除Deployment控制器,也會刪除Deployment控制器下對應的ReplicaSet控制器和pod資源.
使用Deployment而不直接建立ReplicaSet是因為Deployment物件擁有許多ReplicaSet沒有的特性,例如滾動升級和回滾。
擴充套件:宣告式定義是指直接修改資源清單yaml檔案,然後通過kubectl apply -f 資源清單yaml檔案,就可以更改資源
Deployment控制器是建立在rs之上的一個控制器,可以管理多個rs,每次更新映象版本,都會生成一個新的rs,把舊的rs替換掉,多個rs同時存在,但是隻有一個rs執行。
..
5.2 Deployment工作原理:如何管理rs和Pod?
Deployment可以使用宣告式定義,直接在命令列通過純命令的方式完成對應資源版本的內容的修改,也就是通過打補丁的方式進行修改;Deployment能提供滾動式自定義自控制的更新;對Deployment來講,我們在實現更新時還可以實現控制更新節奏和更新邏輯。
..
什麼叫做更新節奏和更新邏輯呢?
比如說Deployment控制5個pod副本,pod的期望值是5個,但是升級的時候需要額外多幾個pod,那我們控制器可以控制在5個pod副本之外還能再增加幾個pod副本;比方說能多一個,但是不能少,那麼升級的時候就是先增加一個,再刪除一個,增加一個刪除一個,始終保持pod副本數是5個;還有一種情況,最多允許多一個,最少允許少一個,也就是最多6個,最少4個,第一次加一個,刪除兩個,第二次加兩個,刪除兩個,依次類推,可以自己控制更新方式,這種滾動更新需要加readinessProbe和livenessProbe探測,確保pod中容器裡的應用都正常啟動了才刪除之前的pod。
啟動第一步,剛更新第一批就暫停了也可以;假如目標是5個,允許一個也不能少,允許最多可以10個,那一次加5個即可;這就是我們可以自己控制節奏來控制更新的方法。
通過Deployment物件,你可以輕鬆的做到以下事情:
1、建立ReplicaSet和Pod
2、滾動升級(不停止舊服務的狀態下升級)和回滾應用(將應用回滾到之前的版本)
3、平滑地擴容和縮容
4、暫停和繼續Deployment -
Deployment資源清單檔案編寫技巧
檢視Deployment資源物件由哪幾部分組成
點選檢視程式碼
[root@master1 ~]# kubectl explain deployment
KIND: Deployment
VERSION: apps/v1
DESCRIPTION:
Deployment enables declarative updates for Pods and ReplicaSets.
FIELDS:
apiVersion <string> #該資源使用的api版本
kind <string> #建立的資源是什麼?
metadata <Object> #元資料,包括資源的名字和名稱空間
spec <Object> #定義容器的
status <Object> #狀態,不可以修改
點選檢視程式碼
[root@master1 ~]# kubectl explain deployment.spec
KIND: Deployment
VERSION: apps/v1
RESOURCE: spec <Object> #spec是一個物件型別
DESCRIPTION:
Specification of the desired behavior of the Deployment.
DeploymentSpec is the specification of the desired behavior of the
Deployment.
FIELDS:
minReadySeconds <integer>
#Kubernetes在等待設定的時間後才進行升級
#如果沒有設定該值,Kubernetes會假設該容器啟動起來後就提供服務了
paused <boolean> #暫停,當我們更新的時候建立pod先暫停,不是立即更新
progressDeadlineSeconds <integer>
點選檢視程式碼
revisionHistoryLimit <integer> #保留的歷史版本,預設是10
selector <Object> -required- #標籤選擇器,選擇它關聯的pod
strategy <Object> #更新策略
template <Object> -required #定義的pod模板
點選檢視程式碼
[root@master1 ~]# kubectl explain deploy.spec.strategy
KIND: Deployment
VERSION: apps/v1
RESOURCE: strategy <Object>
DESCRIPTION:
The deployment strategy to use to replace existing pods with new ones.
DeploymentStrategy describes how to replace existing pods with new ones.
FIELDS:
rollingUpdate <Object>
type <string>
Type of deployment. Can be "Recreate" or "RollingUpdate". Default is
RollingUpdate.
#支援兩種更新,Recreate和RollingUpdate
#Recreate是重建式更新,刪除一個更新一個
點選檢視程式碼
[root@master1 ~]# kubectl explain deploy.spec.strategy.rollingUpdate
KIND: Deployment
VERSION: apps/v1
RESOURCE: rollingUpdate <Object>
DESCRIPTION:
Rolling update config params. Present only if DeploymentStrategyType =
RollingUpdate.
Spec to control the desired behavior of rolling update.
FIELDS:
maxSurge <string>
#我們更新的過程當中最多允許超出的指定的目標副本數有幾個;
它有兩種取值方式,第一種直接給定數量,第二種根據百分比,百分比表示原本是5個,最多可以超出20%,那就允許多一個,最多可以超過40%,那就允許多兩個
maxUnavailable <string>
#最多允許幾個不可用
假設有5個副本,最多一個不可用,就表示最少有4個可用
點選檢視程式碼
[root@master1 ~]# kubectl explain deploy.spec.template
KIND: Deployment
VERSION: apps/v1
RESOURCE: template <Object>
DESCRIPTION:
Template describes the pods that will be created.
PodTemplateSpec describes the data a pod should have when created from a template
FIELDS:
metadata <Object> #定義模板的名字
spec <Object> #定義容器的屬性資訊
deployment.spec.template為Pod定義的模板,和Pod定義不太一樣,template中不包含apiVersion和Kind屬性,要求必須有metadata。deployment.spec.template.spec為容器的屬性資訊,其他定義內容和Pod一致。
點選檢視程式碼
[root@master1 ~]# kubectl explain deploy.spec.template.spec
KIND: Deployment
VERSION: apps/v1
RESOURCE: spec <Object>
DESCRIPTION:
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
PodSpec is a description of a pod.
FIELDS:
activeDeadlineSeconds <integer>
#activeDeadlineSeconds表示Pod 可以執行的最長時間,達到設定的該值後,Pod 會自動停止。
affinity <Object> #定義親和性,跟直接建立pod時候定義親和性類似
automountServiceAccountToken <boolean> #身份認證相關的
containers <[]Object> -required- #定義容器屬性
tolerations <[]Object> #容忍度
dnsConfig <Object> #設定Pod的DNS
dnsConfig:
nameservers:
- 192.xxx.xxx.6
searches:
- xianchao.svc.cluster.local
- my.dns.search.xianchao
dnsPolicy <string> # dnsPolicy決定Pod 內預設的DNS 配置策略
None 無任何策略:使用自定義的策略
Default 預設:使用宿主機的dns配置,/etc/resolv.conf
ClusterFirst 叢集DNS優先,與 Default 相反,會預先使用 kube-dns (或 CoreDNS ) 的資訊當預設定引數寫入到該 Pod 內的DNS配置。
ClusterFirstWithHostNet 叢集 DNS 優先,並伴隨著使用宿主機網路:同時使用 hostNetwork 與 kube-dns 作為 Pod 預設 DNS 配置。
enableServiceLinks <boolean>
ephemeralContainers <[]Object> #定義臨時容器
臨時容器與其他容器的不同之處在於,它們缺少對資源或執行的保證,並且永遠不會自動重啟,因此不適用於構建應用程式。臨時容器使用與常規容器相同的 ContainerSpec 段進行描述,但許多欄位是不相容且不允許的。
臨時容器沒有埠配置,因此像 ports,livenessProbe,readinessProbe 這樣的欄位是不允許的。
Pod 資源分配是不可變的,因此 resources 配置是不允許的。
臨時容器用途:
當由於容器崩潰或容器映象不包含除錯應用程式而導致 kubectl exec 無用時,臨時容器對於互動式故障排查很有用。
點選檢視程式碼
hostAliases <[]Object> #在pod中增加域名解析的
hostAliases:
– ip: "10.1.2.2"
hostnames:
– "mc.local"
– "rabbitmq.local"
– ip: "10.1.2.3"
hostnames:
– "redis.local"
– "mq.local"
hostIPC <boolean> #使用主機IPC
hostNetwork <boolean> #是否使用宿主機的網路
hostPID <boolean> #可以設定容器裡是否可以看到宿主機上的程序。True可以
hostname <string>
imagePullSecrets <[]Object>
initContainers <[]Object> #定義初始化容器
nodeName <string> #定義pod排程到具體哪個節點上
nodeSelector <map[string]string> #定義節點選擇器
overhead <map[string]string> #overhead是1.16引入的欄位,在沒有引入 Overhead 之前,只要一個節點的資源可用量大於等於 Pod 的 requests 時,這個 Pod 就可以被排程到這個節點上。引入 Overhead 之後,只有節點的資源可用量大於等於 Overhead 加上 requests 的和時才能被排程上來。
preemptionPolicy <string>
priority <integer>
priorityClassName <string>
readinessGates <[]Object>
restartPolicy <string> #Pod重啟策略
runtimeClassName <string>
schedulerName <string>
securityContext <Object> #是否開啟特權模式
serviceAccount <string>
serviceAccountName <string>
setHostnameAsFQDN <boolean>
shareProcessNamespace <boolean>
subdomain <string>
terminationGracePeriodSeconds <integer>
#在真正刪除容器之前,K8S會先發終止訊號(kill -15 {pid})給容器,預設30s
tolerations <[]Object> #定義容忍度
topologySpreadConstraints <[]Object
volumes <[]Object> #掛載儲存卷
- Deployment使用案例:建立一個web站點deployment是一個三級結構,deployment管理replicaset,replicaset管理pod,
例子:用deployment建立一個pod
把myapp-blue-v1.tar.gz和myapp-blue-v2.tar.gz上傳到node1和 node2上,手動解壓:
tar映象包連結https://registry.hub.docker.com/r/janakiramm/myapp
點選檢視程式碼
[root@xianchaonode1 ~]# docker load -i myapp-blue-v1.tar.gz
[root@xianchaonode2 ~]# docker load -i myapp-blue-v1.tar.gz
[root@xianchaonode1 ~]# docker load -i myapp-blue-v2.tar.gz
[root@xianchaonode2 ~]# docker load -i myapp-blue-v2.tar.gz
[root@xianchaomaster1 ~]# cat deploy-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-v1
spec:
replicas: 2
selector:
matchLabels:
app: myapp
version: v1
template:
metadata:
labels:
app: myapp
version: v1
spec:
containers:
- name: myapp
image: janakiramm/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- - containerPort: 80
更新資源清單檔案:
kubectl apply -f deploy-demo.yaml
#kubectl apply:表示宣告式的定義,既可以建立資源,也可以動態更新資源
點選檢視程式碼
kubectl get deploy
顯示如下:
NAME READY UP-TO-DATE AVAILABLE AGE
myapp-v1 2/2 2 2 60s
#建立的控制器名字是myapp-v1
1.NAME :列出名稱空間中deployment的名稱。
2.READY:顯示deployment有多少副本數。它遵循ready/desired的模式。
3.UP-TO-DATE: 顯示已更新到所需狀態的副本數。
4.AVAILABLE: 顯示你的可以使用多少個應用程式副本。
5.AGE :顯示應用程式已執行的時間。
點選檢視程式碼
kubectl get rs
顯示如下:
AME DESIRED CURRENT READY AGE
myapp-v1-67fd9fc9c8 2 2 2 2m35s
#建立deploy的時候也會建立一個rs(replicaset),67fd9fc9c8 這個隨機數字是我們引用pod的模板template的名字的hash值
1.NAME: 列出名稱空間中ReplicaSet資源
2DESIRED:顯示應用程式的所需副本數,這些副本數是在建立時定義的。這是所需的狀態。
3.CURRENT: 顯示當前正在執行多少個副本。
4.READY: 顯示你的使用者可以使用多少個應用程式副本。
5.AGE :顯示應用程式已執行的時間。
點選檢視程式碼
kubectl get pods
顯示如下:
myapp-v1-67fd9fc9c8-fcprr 1/1 Running 0 3s
myapp-v1-67fd9fc9c8-hw4f9 1/1 Running 0 2m21s
[root@xianchaomaster1 ~]# kubectl get pods -o wide | grep myapp
myapp-v1-67fd9fc9c8-fcprr 1/1 Running 0 10.244.187.78 xianchaonode2
myapp-v1-67fd9fc9c8-hw4f9 1/1 Running 0 10.244.209.136 xianchaonode1
點選檢視程式碼
[root@master1 ~]# curl 10.244.187.78
background-color: blue;
[root@master1 ~]# curl 10.244.209.136
background-color: blue;
點選檢視程式碼
apiVersion: apps/v1 #deployment對應的api版本
kind: Deployment #建立的資源是deployment
metadata:
name: myapp-v1 #deployment的名字
spec:
replicas: 2 #deployment管理的pod副本數
selector: #標籤選擇器
matchLabels: # matchLabels下定義的標籤需要跟template.metadata.labels定義的標籤一致
app: myapp
version: v1
template:
metadata:
labels:
app: myapp
version: v1
spec: #定義容器的屬性
containers:
- name: myapp
image: janakiramm/myapp:v1 #容器使用的映象
imagePullPolicy: IfNotPresent #映象拉取策略
ports:
- containerPort: 80 #容器裡的應用的埠
- Deployment管理pod:擴容、縮容、滾動更新、回滾
通過deployment管理應用,實現擴容,把副本數變成3
點選檢視程式碼
[root@master1 ~]# cat deploy-demo.yaml
直接修改replicas數量,如下,變成3
spec:
replicas: 3
修改之後儲存退出,執行
[root@master1 ~]# kubectl apply -f deploy-demo.yaml
注意:apply不同於create,apply可以執行多次;create執行一次,再執行就會報錯復。
kubectl get pods
顯示如下:
NAME READY STATUS RESTARTS AGE
myapp-v1-67fd9fc9c8-fcprr 1/1 Running 0 15m
myapp-v1-67fd9fc9c8-h9js5 1/1 Running 0 11s
myapp-v1-67fd9fc9c8-hw4f9 1/1 Running 0 17m
#上面可以看到pod副本數變成了3個
點選檢視程式碼
[root@master1 ~]# kubectl describe deploy myapp-v1
Name: myapp-v1
Namespace: default
CreationTimestamp: Tue, 30 Mar 2021 12:59:02 +0800
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=myapp,version=v1
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=myapp
version=v1
Containers:
myapp:
Image: janakiramm/myapp:v1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Progressing True NewReplicaSetAvailable
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: myapp-v1-67fd9fc9c8 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 18m deployment-controller Scaled up replica set myapp-v1-67fd9fc9c8 to 2
Normal ScalingReplicaSet 51s deployment-controller Scaled up replica set myapp-v1-67fd9fc9c8 to 3
點選檢視程式碼
[root@master1 ~]# cat deploy-demo.yaml
直接修改replicas數量,如下,變成2
spec:
replicas: 2
修改之後儲存退出,執行
[root@master1 ~]# kubectl apply -f deploy-demo.yaml
[root@master1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-v1-67fd9fc9c8-fcprr 1/1 Running 0 18m
myapp-v1-67fd9fc9c8-hw4f9 1/1 Running 0 20m
點選檢視程式碼
在一個終端視窗執行如下:
[root@xianchaomaster1 ~]# kubectl get pods -l app=myapp -w
NAME READY STATUS RESTARTS AGE
myapp-v1-67fd9fc9c8-fcprr 1/1 Running 0 19m
myapp-v1-67fd9fc9c8-hw4f9 1/1 Running 0 22m
開啟一個新的終端視窗更改映象版本,按如下操作:
[root@xianchaomaster1 ~]# vim deploy-demo.yaml
把image: janakiramm/myapp:v1 變成image: janakiramm/myapp:v2
儲存退出,執行
[root@xianchaomaster1 ~]# kubectl apply -f deploy-demo.yaml
再回到剛才執行監測kubectl get pods -l app=myapp -w的那個視窗,可以看到資訊如下:
NAME READY STATUS RESTARTS AGE
myapp-v1-67fd9fc9c8-fcprr 1/1 Running 0 23m
myapp-v1-67fd9fc9c8-hw4f9 1/1 Running 0 26m
myapp-v1-75fb478d6c-fskpq 0/1 Pending 0 0s
myapp-v1-75fb478d6c-fskpq 0/1 Pending 0 0s
myapp-v1-75fb478d6c-fskpq 0/1 ContainerCreating 0 0s
myapp-v1-75fb478d6c-fskpq 0/1 ContainerCreating 0 1s
myapp-v1-75fb478d6c-fskpq 1/1 Running 0 4s
myapp-v1-67fd9fc9c8-fcprr 1/1 Terminating 0 24m
myapp-v1-75fb478d6c-x8stq 0/1 Pending 0 0s
myapp-v1-75fb478d6c-x8stq 0/1 Pending 0 0s
myapp-v1-75fb478d6c-x8stq 0/1 ContainerCreating 0 0s
myapp-v1-67fd9fc9c8-fcprr 1/1 Terminating 0 24m
myapp-v1-75fb478d6c-x8stq 0/1 ContainerCreating 0 1s
myapp-v1-67fd9fc9c8-fcprr 0/1 Terminating 0 24m
myapp-v1-75fb478d6c-x8stq 1/1 Running 0 1s
myapp-v1-67fd9fc9c8-hw4f9 1/1 Terminating 0 26m
myapp-v1-67fd9fc9c8-hw4f9 1/1 Terminating 0 26m
myapp-v1-67fd9fc9c8-hw4f9 0/1 Terminating 0 26m
myapp-v1-67fd9fc9c8-hw4f9 0/1 Terminating 0 26m
myapp-v1-67fd9fc9c8-hw4f9 0/1 Terminating 0 26m
myapp-v1-67fd9fc9c8-fcprr 0/1 Terminating 0 24m
myapp-v1-67fd9fc9c8-fcprr 0/1 Terminating 0 24m
pending表示正在進行排程,ContainerCreating表示正在建立一個pod,running表示執行一個pod,running起來一個pod之後再Terminating(停掉)一個pod,以此類推,直到所有pod完成滾動升級
Kubectl describe deploy myapp-v1
...
StrategyType:RollirgUpdate #策略型別:滾動更新
RollingUpdateStrategy:25% max unavailable,25% max surge #允許pod超過25%個pod
在另外一個視窗執行
[root@xianchaomaster1 ~]# kubectl get rs
顯示如下:
myapp-v1-67fd9fc9c8 0 0 0 27m
myapp-v1-75fb478d6c 2 2 2 79s
點選檢視程式碼
[root@xianchaomaster1 ~]# kubectl rollout history deployment myapp-v1
deployment.apps/myapp-v1
REVISION CHANGE-CAUSE
1 <none>
2 <none>
#回滾
[root@xianchaomaster1 ~]# kubectl rollout undo deployment myapp-v1 --to-revision=1
deployment.apps/myapp-v1 rolled back
[root@xianchaomaster1 ~]# kubectl rollout history deployment myapp-v1
deployment.apps/myapp-v1
REVISION CHANGE-CAUSE
2 <none>
3 <none>
- 自定義滾動更新策略
maxSurge和maxUnavailable用來控制滾動更新的更新策略
取值範圍
數值 - maxUnavailable: [0, 副本數]
- maxSurge: [0, 副本數]
注意:兩者不能同時為0。
比例 - maxUnavailable: [0%, 100%] 向下取整,比如10個副本,5%的話==0.5個,但計算按照0個;
- maxSurge: [0%, 100%] 向上取整,比如10個副本,5%的話==0.5個,但計算按照1個;
注意:兩者不能同時為0。
建議配置 - maxUnavailable == 0
- 這是我們生產環境提供給使用者的預設配置。即“一上一下,先上後下”最平滑原則:
1個新版本pod ready(結合readiness)後,才銷燬舊版本pod。此配置適用場景是平滑更新、保證服務平穩,但也有缺點,就是“太慢”了。
例子
點選檢視程式碼
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-v1
spec:
replicas: 2
selector:
matchLabels:
app: myqpp
version: v1
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
name: test
labels:
app:myapp
version: v1
spec:
containers:
- name: myapp
image: janakiramm/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
livenessProbe:
httpGet:
port:80
readinessProbe:
httpGet:
Port: 80
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe: #存活性檢查
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
點選檢視程式碼
[root@xianchaomaster1 ~]# kubectl patch deployment myapp-v1 -p '{"spec":{"strategy":{"rollingUpdate": {"maxSurge":1,"maxUnavailable":1}}}}' -n blue-green
檢視myapp-v1這個控制器的詳細資訊
[root@xianchaomaster1 ~]# kubectl describe deployment myapp-v1 -n blue-green
顯示如下:
RollingUpdateStrategy: 1 max unavailable, 1 max surge
上面可以看到RollingUpdateStrategy: 1 max unavailable, 1 max surge
這個rollingUpdate更新策略變成了剛才設定的,因為我們設定的pod副本數是3,1和1表示最少不能少於2個pod,最多不能超過4個pod
這個就是通過控制RollingUpdateStrategy這個欄位來設定滾動更新策略的
- Deployment資源清單詳解
點選檢視程式碼
apiVersion: apps/v1
kind: Deployment
metadata:
name: portal
namespace: ms
spec:
replicas: 1
selector:
matchLabels:
project: ms
app: portal
template: #模板
metadata:
labels:
project: ms
app: portal
spec: #封裝的容器
containers:
- name: portal
image: xianchao/portal:v1
imagePullPolicy: Always #映象拉取策略,生產中使用IfNotPresent較多
ports:
- protocol: TCP
containerPort: 8080 #對映的埠
resources: #資源配額
limits: #資源限制,最多可用的cpu和記憶體
cpu: 1
memory: 1Gi
requests: #最少需要多少資源才可以執行Pod
cpu: 0.5
memory: 1Gi
readinessProbe: #就緒性檢查
tcpSocket:
port: 8080
initialDelaySeconds: 60 #pod開機後60秒檢查
periodSeconds: 10 #隔10秒檢查一次
livenessProbe: #存活性檢查
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
存活性探測
用於判斷容器是否存活,即Pod是否為running狀態,如果LivenessProbe探針探測到容器不健康,則kubelet將kill掉容器,並根據容器的重啟策略是否重啟。如果一個容器不包含LivenessProbe探針,則Kubelet認為容器的LivenessProbe探針的返回值永遠成功。
點選檢視程式碼
tcpSocket:
port: 8080 #檢測8080埠是否存在
initialDelaySeconds: 60 #Pod啟動60s執行第一次檢查
periodSeconds: 10 #第一次檢查後每隔10s檢查一次
readinessProbe: #就緒性探測
有時候應用程式可能暫時無法接受請求,比如Pod已經Running了,但是容器內應用程式尚未啟動成功,在這種情況下,如果沒有ReadinessProbe,則Kubernetes認為它可以處理請求了,然而此時,我們知道程式還沒啟動成功是不能接收使用者請求的,所以不希望kubernetes把請求排程給它,則使用ReadinessProbe探針。
ReadinessProbe和livenessProbe可以使用相同探測方式,只是對Pod的處置方式不同,ReadinessProbe是將Pod IP:Port從對應的EndPoint列表中刪除,而livenessProbe則Kill容器並根據Pod的重啟策略來決定作出對應的措施。
ReadinessProbe探針探測容器是否已準備就緒,如果未準備就緒則kubernetes不會將流量轉發給此Pod。
點選檢視程式碼
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
#在Pod執行過程中,K8S仍然會每隔10s檢測8080埠