K8S ReplicaSet 控制器

一、理论介绍

今天我们来实验 ReplicaSet 控制器(也叫工作负载)。官网描述如下:

1、是什么?

  • ReplicaSet 副本集, 维护一组稳定的副本 Pod 集合。

2、为什么需要?

  • 解决 pod 被删除了,不能自我恢复问题。

3、缺点

ReplicaSet 无法提供声明式更新,声明式更新的好处,是不会丢失历史版本。

1.1、基础信息

bash 复制代码
kubectl explain rs
# rs replicaset 的缩写

apiVersion :当前资源使用的 api 版本,是 GROUP/VERSION 的组合。官网介绍如下

kind:资源类型,跟 KIND 保持一致。

metadata:元数据。定义资源名称、注解等。

spec :规范、规约。定义 Pod 副本数Pod 标签选择器Pod 模板

status:状态信息,只读,一般不会去修改。

1.2、ReplicaSet.spec 规约

bash 复制代码
kubectl explain rs.spec
# rs replicaset 的缩写

replica:副本数。定义 ReplicaSet 所管理的 Pod 的副本数,默认是 1。

selector :标签选择器。用于查找一组 Pod 以便于被 ReplicaSet 所管理。它必须跟 Pod 模板的标签(template.metadata.labels)相匹配。否则会报如下错误。

template:Pod 模板。定义 Pod 的模板。

可以看到 template 内部主要就是定义 Pod 的规范(PodSpec)它跟 Pod 定义里的规范(Pod.spec)是同一个类型。

bash 复制代码
kubectl explain rs.spec.template

二、镜像准备

假设有如下三个节点的 K8S 集群:

k8s31master 是控制节点

k8s31node1、k8s31node2 是工作节点

容器运行时是 containerd

使用 springboot 打包两个镜像 hellok8s-1.0.jar.gzhellok8s-2.0.jar.gz

hellok8s:1.0

bash 复制代码
@RestController
public class HelloController {

    @GetMapping("/sayHello")
    @ResponseBody
    public String sayHello() {
        # 蓝
        return "Hello,I am Blue";
    }
}

hellok8s:2.0

bash 复制代码
@RestController
public class HelloController {

    @GetMapping("/sayHello")
    @ResponseBody
    public String sayHello() {
        # 绿
        return "Hello,I am Green";
    }
}

它们的区别仅在输出的问候信息不同,一个 Blue、一个 Green.

  • 导入镜像
bash 复制代码
# node1 执行
[root@k8s31node1 ~]# ctr -n=k8s.io images import hellok8s-1.0.jar.gz
[root@k8s31node1 ~]# ctr -n=k8s.io images import hellok8s-2.0.jar.gz
# node2 执行
[root@k8s31node2 ~]# ctr -n=k8s.io images import hellok8s-1.0.jar.gz
[root@k8s31node2 ~]# ctr -n=k8s.io images import hellok8s-2.0.jar.gz

三、管理 Pod

3.1、管理 template 定义的 Pod

rs-template.yaml

bash 复制代码
apiVersion: apps/v1
kind: ReplicaSet
metadata: 
  name: rs-template
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hellok8s-v1
  template:
    metadata:
      labels:
        app: hellok8s-v1
    spec:
      containers:
      - name: hellok8s
        image: hellok8s:1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

replicas: 3 副本为3

image: hellok8s:1.0 镜像的版本是 1.0

selector.matchLabels 必须跟 template.metadata.labels 相匹配。

  • 执行并查看
bash 复制代码
kubectl apply -f rs-template.yaml
# 查看 rs
kubectl get rs

DESIRED 表示期望的副本数是 3。

CURRENT 表示当前在运行的副本数是 3。

READY 表示当前就绪的副本数是 3。

  • 查看 Pod
bash 复制代码
kubectl get pod -owide

从这可以看出来,pod 的名字是由控制器的名字-随机数组成的。

  • 访问接口
bash 复制代码
curl 10.244.9.34:8080/sayHello

3.2、管理 非 template 定义的 Pod

3.2.1、先有 ReplicaSet 后有 Pod

假设在刚才已经存在 3 个 Pod 的基础上,我们再新增一个 Pod,看看会发生什么?

pod-single.yaml

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-single
  labels:
    app: hellok8s-v1
spec:
  containers:
  - name: hellok8s
    image: hellok8s:1.0
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 8080

特意设置 metadata.labels 跟 ReplicaSet 的 template.metadata.labels 相匹配。

让 ReplicaSet 能通过标签选择器查询到这个 Pod。

  • 运行并监控
bash 复制代码
kubectl apply -f pod-single.yaml
kubectl get pod -w

可以看到 新创建的 pod-single 创建并不成功。

ReplicaSet 控制器,会始终控制标签选择器选中的副本数,是我们设置 replicas: 3 个。

  • 删除 ReplicaSet
bash 复制代码
kubectl delete -f rs-template.yaml
kubectl get rs
kubectl get pod -owide

可以看到,删除 ReplicaSet,它所管理的 Pod 资源也会一并被删除。

3.2.2、先有 Pod 后有 ReplicaSet

  • 运行 pod
bash 复制代码
kubectl apply -f pod-single.yaml
kubectl get pod -owide
  • 运行 ReplicaSet
bash 复制代码
kubectl apply -f rs-template.yaml

可以看到,ReplicaSet 只会给我们创建 2 个 Pod。因为已经存在一个 pod-single 它的 label 符合 ReplicaSet 的 标签选择器。

  • 删除 ReplicaSet
bash 复制代码
kubectl delete -f rs-template.yaml
kubectl get pod -owide

可以看到,删除 ReplicaSet,连同我们单独创建的 pod,也会被一并删除。

四、ReplicaSet 实现 Pod 的动态扩容

假设我们现在有 ReplicaSet 帮我们创建的 3 个 pod。

bash 复制代码
kubectl apply -f rs-template.yaml
kubectl get pod -owide

倘若现在线上流量激增,我们觉得 3 个 pod 太少了,我们可以动态的扩容。比如我们扩容到 4 个。

只需要修改 rs-template.yaml,replicas: 3 改为 4

  • 重新运行并查看
bash 复制代码
kubectl apply -f rs-template.yaml
kubectl get pod -owide

可以看到,ReplicaSet 帮我们新拉起了一个 pod。

五、ReplicaSet 实现 Pod 的动态缩容

倘若现在流量高峰过了,我们不需要 4 个那么多 Pod,我们可以恢复回 3 个。

只需要修改 rs-template.yaml,replicas: 4 改为 3

  • 重新运行并查看
bash 复制代码
kubectl apply -f rs-template.yaml
kubectl get pod -owide

可以看到,ReplicaSet 又帮我们恢复回原来的 3 个。

六、ReplicaSet 实现 Pod 的更新

倘若我们现在需要将镜像的版本,从 hellok8s-1.0 升级为 hellok8s-2.0。

修改 rs-template.yaml,image hellok8s:1.0 改为 hellok8s:2.0

  • 运行并查看
bash 复制代码
kubectl apply -f rs-template.yaml
kubectl get pod -owide

发现 pod 并没有什么变化,我们访问一下接口。

发现接口版本并没有变化。

  • 我们随机删除一个 pod
bash 复制代码
kubectl delete pod rs-template-dtv4d
kubectl get pod -owide

ReplicaSet 会帮我们再拉起一个新 Pod rs-template-btfqr,我们访问这个新 Pod 的接口看看。

可以发现,新拉起的 pod,已经是新的版本了。

从这,我们发现 ReplicaSet 存在的一个问题:

就是它并不能自动地实现声明式(就只更改镜像版本重新 apply)滚动更新,需要人工地删除旧 Pod,ReplicaSet 再重新拉取一个新 Pod,这个时候的新 Pod,才会是新版本。

这个时候,我们需要一个新的控制器--->Deployment。

七、总结

  • Replicaset 核心作用在于代用户创建指定数量的 pod 副本,并确保 pod 副本一直处于满足用户期望的数量,起到多退少补的作用,并且还具有自动扩容缩容等机制。
  • 但是它并不能实现声明式更新。
相关推荐
armcsdn2 小时前
基于Docker Compose部署Traccar容器与主机MySQL的完整指南
mysql·docker·容器
铅笔侠_小龙虾4 小时前
Docker 实战 -- Mysql
mysql·docker·容器
阿里云云原生4 小时前
Higress MCP 服务管理,助力构建私有 MCP 市场
云原生
IvanCodes4 小时前
三、Docker常用命令
docker·容器
zzywxc7875 小时前
云原生 Serverless 架构下的智能弹性伸缩与成本优化实践
云原生·架构·serverless
海星船长丶6 小时前
基于docker进行渗透测试环境的快速搭建(在ubantu中docker设置代理)
运维·docker·容器
KubeSphere 云原生6 小时前
Higress 上架 KubeSphere Marketplace,助力企业构建云原生流量入口
云原生
AKAMAI11 小时前
在Akamai平台上进行VOD转码的参考架构
后端·云原生·云计算