资源调度
- 发现对Pod操作不方便,不能直接操作,而且不能直接编辑,需要对原来的配置文件进行操作,而且需要删除之后再创建Pod,不方便,更多是通过控制器来操作。
Label和Selector
- 通过设置标签和选择器来确定需要的资源,如果是kubectl get po,就是Pod,这里的po可以替换成其他资源,如deploy。
Label
- label,标签可以在配置文件或者命令行kubectl中设置
- 命令行中,有下面的命令:
# 创建临时label
kubectl label po <资源名称> app=hello
# 修改已经存在的标签
kubectl label po <资源名称> app=hello2 --overwrite
# 查看label
# selector 按照 label 单值查找节点
kubectl get po -A -l app=hello
# selector 按照 label 多值查找节点,也可以不等查找
kubectl get po -A -l test=1.0.0,type=app
kubectl get po -A -l test=1.0.0,app!=hello
# selector 按照 label 选择多值查找节点,引号必须有,避免歧义
kubectl get po -A -l 'test in (1.0.0,1.0.1),type=app'
# 查看所有节点的 labels
kubectl get po --show-labels
# selector 按照 label 综合查找节点
kubectl get po -A -l app=hello --show-labels
# - 是 -- 命令的缩写,例如,-l 是 --label 的缩写,-A 是 --all-namespaces 的缩写。
Selector
- 进行选择对应的资源
- 可以在配置文件中配置,在各对象的配置 spec.selector 或其他可以写 selector 的属性中编写
- 也可以在kubectl命令中:
# 匹配单个值,查找 app=hello 的 pod
kubectl get po -A -l app=hello
# 匹配多个值
kubectl get po -A -l 'k8s-app in (metrics-server, kubernetes-dashboard)'
# 查找 version!=1 and app=nginx 的 pod 信息
kubectl get po -l version!=1,app=nginx
# 不等值 + 语句
kubectl get po -A -l version!=1,'app in (busybox, nginx)'
- 一些命令演示如下:
Deployment(无状态)
-
deployment的嵌套关系如下:
-
这里replicationcontroller已经逐步被替代,因为replicaset可以用selector来选择。
功能
创建
-
先用命令行创建一个nginx的deployment,运行
kubectl create deploy nginx-deploy --image=nginx:1.7.9
-
然后查看deploy,replicaset和Pod,会发现像上面介绍的是一层一层嵌套关系,如下:-
-
执行kubectl get po,rs,deploy --show-labels得到:
-
创建的yaml文件:
apiVersion: apps/v1 # deployment api版本
kind: Deployment # 资源类型为deployment
metadata: # 元信息
labels: # deploy标签
app: nginx-deploy
name: nginx-deploy # deploy的名字
namespace: default # 所在的命名空间
spec:
replicas: 1 # 期望的副本数
revisionHistoryLimit: 10 # 进行滚动更新后,保留的历史版本数
selector: # 选择器,用于找到匹配的RS
matchLabels: # 按照标签匹配
app: nginx-deploy # 匹配的标签
strategy: # 更新策略
rollingUpdate: # 滚动更新配置
maxSurge: 25% # 进行滚动更新时,最多可以启动25%的新实例
maxUnavailable: 25% # 进行滚动更新时,最多可以同时停止25%的旧实例
type: RollingUpdate # 更新类型,采用滚动更新
template: # Pod模板
metadata: # Pod的元信息
labels: # Pod标签
app: nginx-deploy
spec: # Pod期望信息
containers: # Pod容器
- image: nginx:1.7.9 # 镜像
imagePullPolicy: IfNotPresent # 拉取策略
name: nginx # 容器名称
restartPolicy: Always # 重启策略
terminationGracePeriodSeconds: 30 # 删除操作最多宽限多长时间
- deploy和statefulset可能用到matchLabels
滚动更新
-
只有修改了 deployment 配置文件中的 template 中的属性后,才会触发更新操作
-
通过 kubectl edit deployment nginx-deploy 进行修改
-
下面先修改非template,看看是否更新
-
进入修改之后,在label中新加入标签:
-
查看是否更新,发现确实没有更新
-
然后修改副本数为3,方便后面看滚动更新进行查看
-
也不是更新,发现deploy,rs都是一个,然后管理着3个Pod
-
注:这是因为create的模板edit后直接生效了,要是自己定义的yaml文件,记得重新apply
-
下面将template里面的nginx镜像版本号修改之后保存退出,发现在滚动更新
-
具体查看信息用
kubectl rollout status deploy nginx-deploy
-
这次用命令行的方式进行设置,执行
kkubectl set image deployment/nginx-deploy nginx=nginx:1.7.9
-
进入deploy查看信息
kubectl describe deploy nginx-deploy
-
可以看出是replicaset是不断变化的,大概意思是创建一个新的replicaset,然后更新一个Pod,更新好后,停止原来rs的旧Pod,然后再更新另一个新Pod,然后再停掉原来rs的旧Pod,直至完成。如下图:
-
再次看信息会发现,新的Pod已经和新的RS关联,如下图:
-
注:可能会出现并行的状态,就是修改之后,生成一个新的RS来更新,还没完成的时候,又进行了修改,然后就会停止之前的更新,创建新的RS来进行这次更新
回滚
-
有时候你可能想回退一个Deployment,例如,当Deployment不稳定时,比如一直crash looping。
-
默认情况下,kubernetes会在系统中保存前两次的Deploymentrollout历史记录,以便你可以随时会退(你可以修改revision history limit来更改保存的revision数)。
-
假如更新 deployment 时参数不小心写错,如 nginx:1.9.1 写成了 nginx:1.91
kubectl set image deployment/nginx-deploy nginx=nginx:1.91
-
监控滚动升级状态,由于镜像名称错误,下载镜像失败,因此更新过程会卡住
kubectl rollout status deployments nginx-deploy
-
结束监听后,获取 rs 信息,我们可以看到新增的 rs 副本数是 2 个
kubectl get rs
-
通过 kubectl get pods 获取 pods 信息,我们可以看到关联到新的 rs 的 pod,状态处于 ImagePullBackOff 状态
-
为了修复这个问题,我们需要找到需要回退的 revision 进行回退 通过
kubectl rollout history deployment/nginx-deploy
可以获取 revison 的列表 -
通过
kubectl rollout history deployment/nginx-deploy --revision=2
可以查看详细信息 -
确认要回退的版本后,可以通过
kubectl rollout undo deployment/nginx-deploy
可以回退到上一个版本 -
也可以回退到指定的 revision
kubectl rollout undo deployment/nginx-deploy --to-revision=2
-
再次通过
kubectl get deployment
和kubectl describe deployment
可以看到,我们的版本已经回退到对应的 revison 上了 -
注:可以通过设置 .spec.revisonHistoryLimit 来指定 deployment 保留多少 revison,如果设置为 0,则不允许 deployment 回退了。
-
命令结果如下:
- 下面这个是旧rs里面之前创建Pod和删除Pod
扩容缩容
- 扩容与缩容只是直接创建副本数,没有更新 pod template 因此不会创建新的 rs
- 通过 kube scale 命令可以进行自动扩容/缩容,以及通过 kube edit 编辑 replicas 也可以实现扩容/缩容
# 通过 kube edit 编辑,就是通过kubectl edit deploy nginx-deploy命令进去之后修改replicas
#通过 kube scale 命令可以进行自动扩容/缩容
kubectl scale --replicas=6 deploy nginx-deploy
- 缩容同理,只不过把数字变小就行
暂停与恢复
-
由于每次对 pod template 中的信息发生修改后,都会触发更新 deployment 操作,那么此时如果频繁修改信息,就会产生多次更新,而实际上只需要执行最后一次更新即可,当出现此类情况时我们就可以暂停 deployment 的 rollout
-
通过
kubectl rollout pause deployment <name>
就可以实现暂停,直到你下次恢复后才会继续进行滚动更新 -
尝试对容器进行修改,然后查看是否发生更新操作了
kubectl set image deploy <name> nginx=nginx:1.17.9
kubectl get po
- 通过以上操作可以看到实际并没有发生修改,此时我们再次进行修改一些属性,如限制 nginx 容器的最大cpu为 0.2 核,最大内存为 128M,最小内存为 64M,最小 cpu 为 0.1 核
kubectl set resources deploy <deploy_name> -c <container_name> --limits=cpu=200m,memory=128Mi --requests=cpu100m,memory=64Mi
-
通过格式化输出
kubectl get deploy <name> -o yaml
,可以看到配置确实发生了修改,再通过 kubectl get po 可以看到 pod 没有被更新 -
那么此时我们再恢复 rollout,通过命令
kubectl rollout resume deploy <name>
-
恢复后,我们再次查看 rs 和 po 信息,我们可以看到就开始进行滚动更新操作了
kubectl get rs
kubectl get po
- 修改内容
-
pause之后,修改不会更新
-
resume之后,更新。