Deployment 的“应用伸缩”功能就是一种常见的运维操作,在 Kubernetes 里,使用命令 kubectl scale,我们就可以轻松调整 Deployment 下属的 Pod 数量,因为 StatefulSet 是 Deployment 的一种特例,所以它也可以使用 kubectl scale 来实现“应用伸缩”。

除了“应用伸缩”,其他的运维操作比如应用更新、版本回退等工作,该怎么做呢?这些也是我们日常运维中经常会遇到的问题。

在 Kubernetes 里,版本更新使用的不是 API 对象,而是两个命令:kubectl apply 和 kubectl rollout,当然它们也要搭配部署应用所需要的 Deployment、DaemonSet 等 YAML 文件。

在 Kubernetes 里应用都是以 Pod 的形式运行的,而 Pod 通常又会被 Deployment 等对象来管理,所以应用的“版本更新”实际上更新的是整个 Pod。

在 Kubernetes 里应用的版本变化就是 template 里 Pod 的变化,哪怕 template 里只变动了一个字段,那也会形成一个新的版本,也算是版本变化。

 kubectl rollout status 的输出信息,Kubernetes 不是把旧 Pod 全部销毁再一次性创建出新 Pod,而是在逐个地创建新 Pod,同时也在销毁旧 Pod,保证系统里始终有足够数量的 Pod 在运行,不会有“空窗期”中断服务。

新 Pod 数量增加的过程有点像是“滚雪球”,从零开始,越滚越大,所以这就是所谓的“滚动更新”(rolling update)。

在应用更新的过程中,你可以随时使用 kubectl rollout pause 来暂停更新,检查、修改 Pod,或者测试验证,如果确认没问题,再用 kubectl rollout resume 来继续更新。

想要回退到上一个版本,就可以使用命令 kubectl rollout undo,也可以加上参数 --to-revision 回退到任意一个历史版本。

kubectl rollout undo 的操作过程其实和 kubectl apply 是一样的,执行的仍然是“滚动更新”,只不过使用的是旧版本 Pod 模板,把新版本 Pod 数量收缩到 0,同时把老版本 Pod 扩展到指定值。

只需要在 Deployment 的 metadata 里加上一个新的字段 annotations。

annotations 字段的含义是“注解”“注释”,形式上和 labels 一样,都是 Key-Value,也都是给 API 对象附加一些额外的信息,但是用途上区别很大。

  • annotations 添加的信息一般是给 Kubernetes 内部的各种对象使用的,有点像是“扩展属性”;
  • labels 主要面对的是 Kubernetes 外部的用户,用来筛选、过滤对象的。

如果用一个简单的比喻来说呢,annotations 就是包装盒里的产品说明书,而 labels 是包装盒外的标签贴纸。

借助 annotations,Kubernetes 既不破坏对象的结构,也不用新增字段,就能够给 API 对象添加任意的附加信息,这就是面向对象设计中典型的 OCP“开闭原则”,让对象更具扩展性和灵活性。