一、理论介绍
今天我们来实验 ReplicaSet 控制器(也叫工作负载)。官网描述如下:
![](https://i-blog.csdnimg.cn/direct/55053a49157c4319956641380e1aecb8.png)
1、是什么?
- ReplicaSet 副本集, 维护一组稳定的副本 Pod 集合。
2、为什么需要?
- 解决 pod 被删除了,不能自我恢复问题。
3、缺点
ReplicaSet 无法提供声明式更新,声明式更新的好处,是不会丢失历史版本。
1.1、基础信息
bash
kubectl explain rs
# rs replicaset 的缩写
![](https://i-blog.csdnimg.cn/direct/2227b5e1f15648159b7ff868d840855b.png)
apiVersion :当前资源使用的 api 版本,是 GROUP/VERSION 的组合。官网介绍如下
kind:资源类型,跟 KIND 保持一致。
metadata:元数据。定义资源名称、注解等。
spec :规范、规约。定义 Pod 副本数 、Pod 标签选择器 、Pod 模板。
status:状态信息,只读,一般不会去修改。
1.2、ReplicaSet.spec 规约
bash
kubectl explain rs.spec
# rs replicaset 的缩写
![](https://i-blog.csdnimg.cn/direct/fa7caa9d70cb47159ddb6dc9a61f0175.png)
replica:副本数。定义 ReplicaSet 所管理的 Pod 的副本数,默认是 1。
selector :标签选择器。用于查找一组 Pod 以便于被 ReplicaSet 所管理。它必须跟 Pod 模板的标签(template.metadata.labels)相匹配。否则会报如下错误。
template:Pod 模板。定义 Pod 的模板。
可以看到 template 内部主要就是定义 Pod 的规范(PodSpec)它跟 Pod 定义里的规范(Pod.spec)是同一个类型。
bashkubectl explain rs.spec.template
二、镜像准备
假设有如下三个节点的 K8S 集群:
![](https://i-blog.csdnimg.cn/direct/b18bed6418fe4017b6580385f594fd4d.png)
k8s31master 是控制节点
k8s31node1、k8s31node2 是工作节点
容器运行时是 containerd
使用 springboot 打包两个镜像 hellok8s-1.0.jar.gz 和 hellok8s-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
![](https://i-blog.csdnimg.cn/direct/55417f9e485846d493bdbab0059a21a3.png)
DESIRED 表示期望的副本数是 3。
CURRENT 表示当前在运行的副本数是 3。
READY 表示当前就绪的副本数是 3。
- 查看 Pod
bash
kubectl get pod -owide
![](https://i-blog.csdnimg.cn/direct/d1a8662a5955497183356cf8e9c484e7.png)
从这可以看出来,pod 的名字是由控制器的名字-随机数组成的。
- 访问接口
bash
curl 10.244.9.34:8080/sayHello
![](https://i-blog.csdnimg.cn/direct/56ffb8307c6f40369972affbe67608fd.png)
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
![](https://i-blog.csdnimg.cn/direct/20d41a1323434dffbdd6e53157283388.png)
可以看到 新创建的 pod-single 创建并不成功。
ReplicaSet 控制器,会始终控制标签选择器选中的副本数,是我们设置 replicas: 3 个。
- 删除 ReplicaSet
bash
kubectl delete -f rs-template.yaml
kubectl get rs
kubectl get pod -owide
![](https://i-blog.csdnimg.cn/direct/985510d69860471aa94a044b5cc74e1b.png)
可以看到,删除 ReplicaSet,它所管理的 Pod 资源也会一并被删除。
3.2.2、先有 Pod 后有 ReplicaSet
- 运行 pod
bash
kubectl apply -f pod-single.yaml
kubectl get pod -owide
![](https://i-blog.csdnimg.cn/direct/0fb09a2a8e3a4e9883b192bd3a29e8c4.png)
- 运行 ReplicaSet
bash
kubectl apply -f rs-template.yaml
![](https://i-blog.csdnimg.cn/direct/9a8f08005cb24eab989c9aed6e6c1d60.png)
可以看到,ReplicaSet 只会给我们创建 2 个 Pod。因为已经存在一个 pod-single 它的 label 符合 ReplicaSet 的 标签选择器。
- 删除 ReplicaSet
bash
kubectl delete -f rs-template.yaml
kubectl get pod -owide
![](https://i-blog.csdnimg.cn/direct/176967e459264de3bf43fbef9d3ba7bf.png)
可以看到,删除 ReplicaSet,连同我们单独创建的 pod,也会被一并删除。
四、ReplicaSet 实现 Pod 的动态扩容
假设我们现在有 ReplicaSet 帮我们创建的 3 个 pod。
bash
kubectl apply -f rs-template.yaml
kubectl get pod -owide
![](https://i-blog.csdnimg.cn/direct/c609e77e4cad48d0a4ff28972210a146.png)
倘若现在线上流量激增,我们觉得 3 个 pod 太少了,我们可以动态的扩容。比如我们扩容到 4 个。
只需要修改 rs-template.yaml,replicas: 3 改为 4
![](https://i-blog.csdnimg.cn/direct/dbc8e8a914924ba19febf11264fad7a4.png)
- 重新运行并查看
bash
kubectl apply -f rs-template.yaml
kubectl get pod -owide
![](https://i-blog.csdnimg.cn/direct/8c4763a5beda42fe83b02ca632a7dcc7.png)
可以看到,ReplicaSet 帮我们新拉起了一个 pod。
五、ReplicaSet 实现 Pod 的动态缩容
倘若现在流量高峰过了,我们不需要 4 个那么多 Pod,我们可以恢复回 3 个。
只需要修改 rs-template.yaml,replicas: 4 改为 3
![](https://i-blog.csdnimg.cn/direct/f0be18bfb692495cbe0bc85256151871.png)
- 重新运行并查看
bash
kubectl apply -f rs-template.yaml
kubectl get pod -owide
![](https://i-blog.csdnimg.cn/direct/c5f066f71e0f4957abcedf1ae7c5dba2.png)
可以看到,ReplicaSet 又帮我们恢复回原来的 3 个。
六、ReplicaSet 实现 Pod 的更新
倘若我们现在需要将镜像的版本,从 hellok8s-1.0 升级为 hellok8s-2.0。
修改 rs-template.yaml,image hellok8s:1.0 改为 hellok8s:2.0
![](https://i-blog.csdnimg.cn/direct/289f2986760e43329b400483a0a1f81a.png)
- 运行并查看
bash
kubectl apply -f rs-template.yaml
kubectl get pod -owide
![](https://i-blog.csdnimg.cn/direct/822f39288a9a4312a4197b852ae5cc72.png)
发现 pod 并没有什么变化,我们访问一下接口。
![](https://i-blog.csdnimg.cn/direct/ecd6a66499924f18b132370e5396fe7e.png)
发现接口版本并没有变化。
- 我们随机删除一个 pod
bash
kubectl delete pod rs-template-dtv4d
kubectl get pod -owide
![](https://i-blog.csdnimg.cn/direct/8f2240565bf248d080937fc699b31ad1.png)
ReplicaSet 会帮我们再拉起一个新 Pod rs-template-btfqr,我们访问这个新 Pod 的接口看看。
![](https://i-blog.csdnimg.cn/direct/9953f615bc7e41b9ac70f8917c7118bd.png)
可以发现,新拉起的 pod,已经是新的版本了。
从这,我们发现 ReplicaSet 存在的一个问题:
就是它并不能自动地实现声明式(就只更改镜像版本重新 apply)滚动更新,需要人工地删除旧 Pod,ReplicaSet 再重新拉取一个新 Pod,这个时候的新 Pod,才会是新版本。
这个时候,我们需要一个新的控制器--->Deployment。
七、总结
- Replicaset 核心作用在于代用户创建指定数量的 pod 副本,并确保 pod 副本一直处于满足用户期望的数量,起到多退少补的作用,并且还具有自动扩容缩容等机制。
- 但是它并不能实现声明式更新。