专题合集

《云原生系列专题分享合集》

目录

ReplicaSet

前面讲到,Container 类似进程的概念,而 Pod 类似进程组的概念。

那么 Controller 就是管理 Pod 这样的进程组的存在,Deployment 就是一种常见的 Controller。

现在我们来看一个常见的 Deployment 部署文件。

kind: Deployment
apiVersion: apps/v1
metadata:
  name: jmeter
  namespace: default
  labels:
    k8s-app: jmeter
spec:
  selector:
    matchLabels:
      k8s-app: jmeter
  replicas: 2
  template:
    metadata:
      labels:
        k8s-app: jmeter
        name: jmeter
    spec:
      containers:
        - name: jmeter
          image: shaonianyr/jmeter:demo
          imagePullPolicy: Always
          ports:
            - name: port
              containerPort: 60000
              protocol: TCP

我们使用这个 Deployment Controller,使得 Jmeter App 保持在两个 Pod 副本数,开启了 ImagePullPolicy Always 的策略,并暴露了 60000 端口。

Always 会保证,就算 Image 不发生更改,也会强制拉取同步一次最新的镜像,相应的代价就是让容器重启的时间变得更长。

一般看到这个 Deployment 我们脑子里的画面是这样的:

然而 Deployment 操作的对象并不是 Pod,而是 ReplicaSet,所以对应关系其实是这样的。

Deployment 通过 ReplicaSet 间接去管理每个 Pod 所属的版本,并维护 Pod 的数量。

当 Pod Running 状态的数量与 Replicas 设置不一样时,就会发生对应的水平伸缩。

Rollout

所以,结合上面那张图,我们再来理解 Deployment 的滚动更新就不难了。

Deployment 会新建一个 ReplicaSet 去增加 Pod 的数量,并减少旧 ReplicaSet Pod 的数量。

这个增减的过程会保持总数恒定在 Replicas 的值,也就是我们的滚动更新。

旧的 ReplicaSet 缩减完毕后,并不会删除,方便做回滚。

查看 Deployment 的历史版本:

kubectl rollout history deployment/jmeter

回滚到指定的版本:

kubectl rollout undo deployment/jmeter --to-revision=v1

讲到这里,一个有意思的问题就出现了。

Replicas=1 的 Deployment 跟 1 个 Pod 有什么区别呢?

当 Pod 异常重启的时候,只会在原来被调度的 Node 上重启,哪怕这个 Node 宕机。

而 Deployment 会在 Pod 异常重启的时候,根据策略去选择最优的 Node 节点调度,哪怕 Replicas 只有 1 个。

......

未完待续,有空就开更。


↙↙↙阅读原文可查看相关链接,并与作者交流