scoefield

V1

2022/04/13阅读:15主题:橙心

还在手动管理pod?别逗了,看看k8s的资源对象RS和RC是怎么管理的吧

RS&RC 的引入

相信大家刚开始了解 Pod 的时候,是学习它的一些基本使用方法,以及是干什么用的,而且前面我们讲 pod 的时候,也都是直接来操作 Pod 来说明的。

如果我们现在有一个商城项目,上线后由 Pod 提供的服务,我们来想象下可能会遇到的一些场景:

  • 场景一:由于 520 临近,我们搞活动,商城网站访问量突然暴增
  • 场景二:提供当前 Pod 运行的机器(节点)发生了故障,此时 Pod 也挂掉了,不能正常提供服务

对于场景一的情况,或许好处理些,因为一般搞活动之前,我们都会跟进以往的经验大概计算下会有多大的访问量,提前多启动几个 Pod,等活动结束后,再把多加的 Pod 干掉,虽然有点繁琐,但是应对这种情况还是没问题的。

对于场景二的情况,可能某天晚上收到大量告警信息说服务挂了,最直接的就是影响正常业务,此时老大坐不住了,就会电话打过来,然后你会屁颠屁颠的从床上爬起来默默打开电脑操作一波,在另外的节点上重新启动一个新的 Pod,问题也就引刃而解了。

可想而知,如果我们都是人工的去维护 pod,和解决遇到的这些问题,似乎又回到了以前刀耕火种的时代了。此时,你会不会在想是否有一种工具能够来帮助我们管理 Pod?比如 Pod 挂了一个,会不会自动帮我们新拉起一个,或者 Pod 在这个节点挂了在另外合适的节点上重新启动一个 Pod,这样上面遇到的问题都无需我们手动去处理解决了。

是的,Kubernetes 就为我们提供了这样的资源对象(管理工具):

  • Replication Controller:简单来熟就是用来部署和升级 Pod 的;
  • Replica Set:下一代的 Replication Controller(RC 的 Pro 版本);
  • Deployment:可以更加方便而且灵活的管理 Pod 和 Replica Set;

Replication Controller(RC)

Replication Controller 简称 RC,RC 是 Kubernetes 系统中的核心概念之一,简单来说,RC 可以保证在任意时间运行 Pod 的副本数量,能够保证 Pod 总是可用的。

如果实际 Pod 数量比指定的多那就结束掉多余的,如果实际数量比指定的少就新启动一些 Pod,当 Pod 失败、被删除或者挂掉后,RC 都会去自动创建新的 Pod 来保证副本数量,所以即使只有一个 Pod,我们也应该使用 RC 来管理我们的 Pod。

我们想想如果现在我们遇到上面的问题的话,可能除了第一个不能做到完全自动化,其余的我们是不是都不用担心了,运行 Pod 的节点挂了,RC 检测到 Pod 失败了,就会去合适的节点重新启动一个 Pod 就行,不需要我们手动去新建一个 Pod 了。

如果是第一种情况的话在活动开始之前我们给 Pod 指定 15 个副本,结束后将副本数量改成 5,这样是不是也远比我们手动去启动、手动去关闭要好得多,而且我们后面还会给大家介绍另外一种资源对象 HPA 可以根据资源的使用情况来进行自动扩缩容,这样以后遇到这种情况,我们就真的可以安心的去睡觉了。

下面我们使用 RC 来管理一个 Nginx 的 Pod,YAML 文件如下:

apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx-rc-demo
  labels:
    name: rc
spec:
  replicas: 2
  selector:
    name: rc
  template:
    metadata:
     labels:
       name: rc
    spec:
     containers:
     - name: nginx-demo
       image: nginx
       ports:
       - containerPort: 80

上面的 YAML 文件相对于我们之前的 Pod 的格式:

  • kind:资源对象的种类,这里创建的是 RC
  • spec.replicas: 指定 Pod 的副本数量,默认为 1,此处为 2
  • spec.selector: RC 通过该属性来筛选要控制的 Pod,可以理解为筛选对应标签
  • spec.template: 这里就是我们之前的 Pod 的定义的模块,容器镜像用的是 nginx
  • spec.template.metadata.labels: 注意这里的 Pod 的 labels 要和 spec.selector 相同,这样 RC 就可以来控制当前这个 Pod 了。

这个 YAML 文件中的意思就是定义了一个 RC 资源对象,它的名字叫 nginx-rc-demo,保证一直会有 2 个 Pod 运行。

注意 spec.selector 和 spec.template.metadata.labels 这两个字段必须相同,否则会创建失败的,当然我们也可以不写 spec.selector,这样就默认与 Pod 模板中的 metadata.labels 相同了。所以为了避免不必要的错误的话,不写为好。

然后我们来创建上面的 RC 对象(保存为 nginx-rc-demo.yaml):

$ kubectl create -f nginx-rc-demo.yaml
或者
$ kubectl apply -f nginx-rc-demo.yaml

查看 RC:

$ kubectl get rc

查看详细的描述信息:

$ kubectl describe rc nginx-rc-demo

接下来我们再通过 RC 来修改下 Pod 的副本数量为 3:

$ kubectl apply -f nginx-rc-demo.yaml

或者执行下面的命令编辑 RC 也可以

$ kubectl edit rc nginx-rc-demo

还可以用 RC 来进行滚动升级,比如我们将镜像版本更改为 nginx:1.6.9:

$ kubectl rolling-update nginx-rc-demo --image=nginx:1.6.9

但是如果我们的 Pod 中多个容器的话,就需要通过修改 YAML 文件来进行修改了:

$ kubectl rolling-update nginx-rc-demo -f nginx-rc-demo.yaml

如果升级完成后出现了新的问题,想要一键回滚到上一个版本的话,使用 RC 只能用同样的方法把镜像地址替换成之前的,然后重新滚动升级。

详细操作命令可参考:http://docs.kubernetes.org.cn/683.html

Replication Set(RS)

Replication Set 简称 RS,随着 Kubernetes 的高速发展,官方已经推荐我们使用 RS 和 Deployment 来代替 RC 了,实际上 RS 和 RC 的功能基本一致,目前唯一的一个区别就是 RC 只支持基于等式的 selector(env=dev 或 environment!=qa),但 RS 还支持基于集合的 selector(version in (v1.0, v2.0)),这对复杂的运维管理就非常方便了。

kubectl 命令行工具中关于 RC 的大部分命令同样适用于我们的 RS 资源对象。不过我们也很少会去单独使用 RS,它主要被 Deployment 这个更加高层的资源对象使用,除非用户需要自定义升级功能或根本不需要升级 Pod,在一般情况下,我们推荐使用 Deployment 而不直接使用 Replica Set。

RS 资源对象的创建跟 RC 的创建方法大同小异,这里就不再举例了。

总结

最后我们总结下关于 RC/RS 的一些特性和作用吧:

  • 大部分情况下,我们可以通过定义一个 RC 实现的 Pod 的创建和副本数量的控制
  • RC 中包含一个完整的 Pod 定义模块(不包含 apiversion 和 kind)
  • RC 是通过 label selector 机制来实现对 Pod 副本的控制的
  • 通过改变 RC 里面的 Pod 副本数量,可以实现 Pod 的扩缩容功能
  • 通过改变 RC 里面的 Pod 模板中镜像版本,可以实现 Pod 的滚动升级功能(但是不支持一键回滚,需要用相同的方法去修改镜像地址)

后续会给大家介绍另外一种更加高级也是现在官方推荐使用的一个资源对象 Deployment

分类:

后端

标签:

后端

作者介绍

scoefield
V1