6. kubernetes pod控制器
[TOC]
本文基于马哥的docker和k8s视频总结, 在此致谢马哥.
Pod控制器类型
-
ReplicaSet
(创建并保持指定数量的pod副本, 支持动态扩缩容和滚动更新)- 用户期望的副本数
- 标签选择器
- pod资源模板
Deployment
(建构在ReplicaSet之上, 用来管理无状态应用)-
DaemonSet
(节点级控制器, 确保集群中满足条件的每个节点只运行一个特定pod副本) -
Job
(执行一次性的作业, 确保任务是正常完成而不是异常退出) -
CronJob
(周期性运行作业) -
StatefulSet
(管理有状态应用且每个应用, 每个pod副本都被单独管理)
ReplicaSet
使用rs
示例
生产环境中千万不可随意给pod打标签, 否则有标签重叠时k8s集群可能会随机杀掉正在服务的pod !
kubectl explain rs
apiVersion: app/v1
kind: ReplicaSet
metadata:
name: myapp
namespace: default
spec:
replicas: 2
selector:
matchLabels: # 通过selector, 选择标签为app, 值为myapp且标签为release, 值为canary的pod
app: myapp
release: canary
template: # 定义创建pod的模板
metadata: # 此处指定的是创建出来的pod的元数据
name: myapp-pod # 此处定义的pod名其实没什么用
labels: # 由template中定义的标签一定要符合selector中定义的标准, 否则会一直创建
app: myapp
release: canary
enviroment: qa
spec: # 此处指定的是创建出来的pod的spec
containers:
- name: myapp-container
image: nginx:1.14-alpine
imagePullPolicy: IfNotPresent # 默认值就是IfNotPresent, 此处可省略
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
kubectl create -f replicaset-demo.yml
# 支持动态扩展和滚动更新 (但滚动更新需要手动重启pod)
kubectl edit rs myapp
# 将replicas的值修改为5, 即可实现动态扩容(k8s集群会帮你自动去创建新的3个pod)
# 将image的值改为更高版本, pod所使用的的镜像会更新, 但是pod需要被重启才会使用新的镜像版本
Deployment
能提供滚动式自定义自控制的更新:
Deployment.png Deployment与replicaSet的关系.png能控制更新节奏和更新逻辑: 允许最多(少)存在几个pod和同时更新几个pod
更新时做readiness
特别重要 !!! 因为未ready的不能算更新好.
使用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 # 声明式创建(即能创建, 亦能更新)
kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
myapp-deploy 2/2 2 2 11s
kubectl get rs # 可以发现有rs被创建, 说明Deployment是基于repolicaSet的
NAME DESIRED CURRENT READY AGE
myapp-deploy-fc645b99f 2 2 2 21s
# myapp-deploy-fc645b99f <==> Deployment_name-模板(即deploy-demo.yml)的哈希值
动态扩展
-
Deployment
在实现更新应用时, 可直接编辑记配置文件实现:
# 1. 编辑配置文件deploy-demo.yml, 将replicas值改为3
# 2. 再次应用配置文件deploy-demo.yml
kubectl apply -f deploy-demp.yml # apply可以使用多次
# 3. 每次版本变化都会显示在Annotations的值中
kubectl describe deploy myapp-deploy
滚动更新与回退
# 1. 编辑配置文件deploy-demo.yml, 将image的值改为nginx:1.15-alpine
# 2. 再次应用
kubectl apply -f deploy-demp.yml
# 3. 查看滚动更新时状态信息
kubectl get pods -l app=myapp -w
# 4. 显示历史版本信息, 可用于版本回退 (旧版本模板会被保留, 随时等待回退)
kubectl get rs -o wide
# 5. 查看滚动历史
kubectl rollout history deployment myapp-deploy
# 5.5. 若新版有问题, 可回退到上一版本
kubectl rollout undo deployment myapp-deploy
# 6. 也可使用打补丁的方式更新
kubectl patch deployment myapp-deploy -p '{"spec":{"replicas":5}}'
# -p选项后使用JSON格式数组指明打的补丁, 键需要用引号引起来
更复杂的更新
# 方法一: 打补丁
kubectl patch deployment myapp-deploy -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
# 方法二: 直接交互式编辑
kubectl edit deploy myapp-deploy
- 可以做到更新版本时只更新其中一个, 然后暂停更新 ==> 金丝雀发布:
# 1.
kubectl set image deployment myapp-deploy myapp-container=nginx:1.15-alpine && kubectl rollout pause deployment myapp-deploy
# 2. 监视更新过程
kubectl get pods -l app=myapp -w
kubectl rollout status deployment myapp-deploy
# 3. 若更新没问题, 可以继续更新
kubectl rollout resume deployment myapp-deploy
# 4. 此时也可以看到版本迭代
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: # 可以在容器创建时传入环境变量
- name: REDIS_HOST
value: redis.default.svc.cluster.local # 各pod之间通过service的主机名互相调用, 通信
- name: REDIS_LOG_LEVEL
value: info
kubectl apply -f ds-demo.yml
-
DaemonSet
也支持滚动更新:kubectl set image -h
kubectl set image ds filebeat-ds filebeat:5.6.6-alpine
网友评论