6. kubernetes pod控制器
[TOC]
本文基于馬哥的docker和k8s視頻總結(jié), 在此致謝馬哥.
Pod控制器類(lèi)型
-
ReplicaSet
(創(chuàng)建并保持指定數(shù)量的pod副本, 支持動(dòng)態(tài)擴(kuò)縮容和滾動(dòng)更新)- 用戶期望的副本數(shù)
- 標(biāo)簽選擇器
- pod資源模板
Deployment
(建構(gòu)在ReplicaSet之上, 用來(lái)管理無(wú)狀態(tài)應(yīng)用)-
DaemonSet
(節(jié)點(diǎn)級(jí)控制器, 確保集群中滿足條件的每個(gè)節(jié)點(diǎn)只運(yùn)行一個(gè)特定pod副本) -
Job
(執(zhí)行一次性的作業(yè), 確保任務(wù)是正常完成而不是異常退出) -
CronJob
(周期性運(yùn)行作業(yè)) -
StatefulSet
(管理有狀態(tài)應(yīng)用且每個(gè)應(yīng)用, 每個(gè)pod副本都被單獨(dú)管理)
ReplicaSet
使用rs
示例
生產(chǎn)環(huán)境中千萬(wàn)不可隨意給pod打標(biāo)簽, 否則有標(biāo)簽重疊時(shí)k8s集群可能會(huì)隨機(jī)殺掉正在服務(wù)的pod !
kubectl explain rs
apiVersion: app/v1
kind: ReplicaSet
metadata:
name: myapp
namespace: default
spec:
replicas: 2
selector:
matchLabels: # 通過(guò)selector, 選擇標(biāo)簽為app, 值為myapp且標(biāo)簽為release, 值為canary的pod
app: myapp
release: canary
template: # 定義創(chuàng)建pod的模板
metadata: # 此處指定的是創(chuàng)建出來(lái)的pod的元數(shù)據(jù)
name: myapp-pod # 此處定義的pod名其實(shí)沒(méi)什么用
labels: # 由template中定義的標(biāo)簽一定要符合selector中定義的標(biāo)準(zhǔn), 否則會(huì)一直創(chuàng)建
app: myapp
release: canary
enviroment: qa
spec: # 此處指定的是創(chuàng)建出來(lái)的pod的spec
containers:
- name: myapp-container
image: nginx:1.14-alpine
imagePullPolicy: IfNotPresent # 默認(rèn)值就是IfNotPresent, 此處可省略
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
kubectl create -f replicaset-demo.yml
# 支持動(dòng)態(tài)擴(kuò)展和滾動(dòng)更新 (但滾動(dòng)更新需要手動(dòng)重啟pod)
kubectl edit rs myapp
# 將replicas的值修改為5, 即可實(shí)現(xiàn)動(dòng)態(tài)擴(kuò)容(k8s集群會(huì)幫你自動(dòng)去創(chuàng)建新的3個(gè)pod)
# 將image的值改為更高版本, pod所使用的的鏡像會(huì)更新, 但是pod需要被重啟才會(huì)使用新的鏡像版本
Deployment
能提供滾動(dòng)式自定義自控制的更新:
能控制更新節(jié)奏和更新邏輯: 允許最多(少)存在幾個(gè)pod和同時(shí)更新幾個(gè)pod
更新時(shí)做readiness
特別重要 !!! 因?yàn)槲磖eady的不能算更新好.
使用Deployment
示例
kubectl explain deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: myapp
release: canary
template:
metadata:
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp-container
image: nginx:1.14-alpine
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
kubectl apply -f deploy-demo.yml # 聲明式創(chuàng)建(即能創(chuàng)建, 亦能更新)
kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
myapp-deploy 2/2 2 2 11s
kubectl get rs # 可以發(fā)現(xiàn)有rs被創(chuàng)建, 說(shuō)明Deployment是基于repolicaSet的
NAME DESIRED CURRENT READY AGE
myapp-deploy-fc645b99f 2 2 2 21s
# myapp-deploy-fc645b99f <==> Deployment_name-模板(即deploy-demo.yml)的哈希值
動(dòng)態(tài)擴(kuò)展
-
Deployment
在實(shí)現(xiàn)更新應(yīng)用時(shí), 可直接編輯記配置文件實(shí)現(xiàn):
# 1. 編輯配置文件deploy-demo.yml, 將replicas值改為3
# 2. 再次應(yīng)用配置文件deploy-demo.yml
kubectl apply -f deploy-demp.yml # apply可以使用多次
# 3. 每次版本變化都會(huì)顯示在Annotations的值中
kubectl describe deploy myapp-deploy
滾動(dòng)更新與回退
# 1. 編輯配置文件deploy-demo.yml, 將image的值改為nginx:1.15-alpine
# 2. 再次應(yīng)用
kubectl apply -f deploy-demp.yml
# 3. 查看滾動(dòng)更新時(shí)狀態(tài)信息
kubectl get pods -l app=myapp -w
# 4. 顯示歷史版本信息, 可用于版本回退 (舊版本模板會(huì)被保留, 隨時(shí)等待回退)
kubectl get rs -o wide
# 5. 查看滾動(dòng)歷史
kubectl rollout history deployment myapp-deploy
# 5.5. 若新版有問(wèn)題, 可回退到上一版本
kubectl rollout undo deployment myapp-deploy
# 6. 也可使用打補(bǔ)丁的方式更新
kubectl patch deployment myapp-deploy -p '{"spec":{"replicas":5}}'
# -p選項(xiàng)后使用JSON格式數(shù)組指明打的補(bǔ)丁, 鍵需要用引號(hào)引起來(lái)
更復(fù)雜的更新
# 方法一: 打補(bǔ)丁
kubectl patch deployment myapp-deploy -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
# 方法二: 直接交互式編輯
kubectl edit deploy myapp-deploy
- 可以做到更新版本時(shí)只更新其中一個(gè), 然后暫停更新 ==> 金絲雀發(fā)布:
# 1.
kubectl set image deployment myapp-deploy myapp-container=nginx:1.15-alpine && kubectl rollout pause deployment myapp-deploy
# 2. 監(jiān)視更新過(guò)程
kubectl get pods -l app=myapp -w
kubectl rollout status deployment myapp-deploy
# 3. 若更新沒(méi)問(wèn)題, 可以繼續(xù)更新
kubectl rollout resume deployment myapp-deploy
# 4. 此時(shí)也可以看到版本迭代
kubectl get rs -o wide
# 5. 可回滾到指定版本
kubectl rollout undo deployment myapp-deploy --to-revision=1
DaementSet
使用ds
示例
kubectl explain ds
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: redis
role: logstore
template:
metadata:
labels:
app: redis
role: logstore
spec:
containers:
- name: redis
image: redis:4.0-alpine
imagePullPolicy: IfNotPresent
ports:
- name: redis
containerPort: 6379
protocol: TCP
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat-ds
namespace: default
spec:
selector:
matchLabels:
app: filebeat
release: stable
template:
metadata:
label:
app: filebeat
release: stable
spec:
containers:
- name: filebeat-container
image: filebeat:5.6.5-alpine
imagePullPolicy: IfNotPresent
env: # 可以在容器創(chuàng)建時(shí)傳入環(huán)境變量
- name: REDIS_HOST
value: redis.default.svc.cluster.local # 各pod之間通過(guò)service的主機(jī)名互相調(diào)用, 通信
- name: REDIS_LOG_LEVEL
value: info
kubectl apply -f ds-demo.yml
-
DaemonSet
也支持滾動(dòng)更新:kubectl set image -h
kubectl set image ds filebeat-ds filebeat:5.6.6-alpine