Kubernetes上搭建Redis集群的记录
首先
这是2022年KWC圣诞日历的文章。
你好,我是朴亨敬,负责KWC的SRE工作。为了学习K8S,我打算个人开发一个Kubernetes Operator。这篇文章是根据”https://tech.kakao.com/2022/02/09/k8s-redis/”上的内容,实际开发的总结。虽然是韩语文章,但其中记录了将运行在PM(Physical Machine)上的Redis转换为VM(Virtual Machine)并运行在K8S环境中的步骤和问题点。
我开始写这篇文章的原因
由于我从未在实际工作中使用过K8S,所以我自学了相关知识,并创建了这篇文章以提高自己的知识水平。
在文章中,我可能会纠正错误或根据自己的理解进行开发,所以请将这篇文章仅视为参考资料,谢谢。
构成的方法
从结论来看,我们使用了Kubernetes Operator Pattern。为了实现高可用性,我们使用了Pod Affinity,并使用了Redis Exporter、Prometheus和Grafana进行监控。根据韩国的文章,他们使用了Host Network来提高Redis的性能,但是我们没有选择这种方法。
Containers:
Port: 80/TCP
Host Port: 80/TCP
我打算在这篇文章中开发一个使用Ingress Controller与Redis集群进行通信的方法。
-
- Kubernetes Operator Pattern
-
- Ingress Controller
-
- Pod Affinity
- Redis Exporter + Prometheus + Grafana
CRD的动态和详细信息 (CRD’s movements and detailed information)
Redis控制器(协调)
如果添加了CRD。
% kubectl get all -n operator-system
NAME READY STATUS RESTARTS AGE
pod/operator-controller-manager-567b446c69-jrrdx 2/2 Running 0 18s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/operator-controller-manager-metrics-service ClusterIP 10.***.***.*** <none> 8443/TCP 19s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/operator-controller-manager 1/1 1 1 19s
NAME DESIRED CURRENT READY AGE
replicaset.apps/operator-controller-manager-567b446c69 1 1 1 19s
当我使用get命令确认时,我可以看到我创建的控制器已经在名为「deployment.apps/operator-controller-manager」的部署中启动。
通常情况下,生成资源的命名空间将是项目名称。并且,Controller也将成为“Replicas 1、Surge 100%”Deployment资源。
在控制器升高的状态下尝试生成CR。
% kubectl apply -f config/samples/stable_v1_kredis.yaml -n operator-system
kredis.stable.example.com/kredis-sample created
% kubectl get kredis -n operator-system
NAME AGE
kredis-sample 60s
我确认生成的内容无误,并且在使用get命令确认时,可以看到它以”kredis-sample”的名称启动。我也将确认它是否按照我添加的规范进行了设置。
% kubectl describe kredis kredis-sample -n operator-system | grep -A9 "Spec"
Spec:
Base Port: 10000
Image: {AWS ECR}/redis-cluster:latest
Masters: 2
Memory: 1gb
Replicas: 1
Resource:
Requests:
Cpu: 2
Memory: 2000Mi
因为Spec看起来没有问题,所以我会通过Reconcile确认它是否生成了部署。
% kubectl get all -n operator-system | grep -B1 "kredis"
NAME READY STATUS RESTARTS AGE
pod/kredis-sample-7bc8b59fbc-vptdb 1/1 Running 0 7m32s
--
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kredis-sample ClusterIP 10.***.***.*** <none> 6379/TCP 7m33s
--
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/kredis-sample 1/1 1 1 7m33s
--
NAME DESIRED CURRENT READY AGE
replicaset.apps/kredis-sample-7bc8b59fbc 1 1 1 7m33s
部署也已成功启动,我确认能进入”pod/kredis-sample-7bc8b59fbc-vptdb”的Pod并进入Redis控制台。
虽然暂时只完成到这里,但如果以后有时间的话,我打算继续开发剩下的部分。
顺便提一下,要让操作员操作K8S资源,需要将权限(ClusterRole)添加到Service Account中。
如果CRD有更新:(HPA)
如果Cluster已经存在CRD,则执行更新(Reconcile)操作。这个操作也需要在Custom Controller中直接进行开发。←由于CRD添加操作的开发尚未完成,所以更新操作尚未实现。
然后,我们尝试使用常规的kind: HorizontalPodAutoscaler资源来实现HPA,但是常规的HPA会调整Deployment的Replicas,所以这次我想要调整的是
由于不知道如何调整CRD的Spec,所以我们目前正在进行持续调查,以寻找实现它的方法。
https://book.kubebuilder.io/reference/generating-crd.html#scale
通过查看这个链接,似乎在CRD中为了HPA,需要向Operator添加代码并进行配置,因此我们打算以后参考这个进行开发。
Redis 集群的高可用性处理:(故障转移)
当Redis Cluster中的Master节点崩溃时,通过replica配置连接的从节点将自动成为Master节点(进行故障转移)。
Redis的Pod配置
拓扑关键字
为了HA,我们将Master节点和Replica节点的Pod放置在不同的工作节点上。我们会添加标签进行适应。
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
nodeId: "masterNodeId"
topologykey: "kubernetes.io/hostname"
这边的工作也还在开发中。暂且觉得按照上面的规格设定应该可以行,计划等到之前的开发结束后再进行验证。
CRD 规范
以下是CRD的规范。
spec:
masters: 2 # Redis Cluster のMaster Node 数
replicas: 1 # Redis Cluster のReplica Node 数
memory: 1gb # これはRedisのMax Memory
basePort: 10000 # redis port: 10000, redis exporter port: 15000, Cluster bus port: 20000,
image:
resource:
requests:
cpu: '2'
memory: 2000Mi
车队巴士港口 (chē duì bā shì
要改变CRD的Spec,需要修改「{crd}_types.go」文件中的操作符。
https://sdk.operatorframework.io/docs/building-operators/golang/tutorial/#define-the-api 的定义。
// KRedisSpec defines the desired state of KRedis
type KRedisSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Foo is an example field of KRedis. Edit kredis_types.go to remove/update
Image string `json:"image"`
Masters int32 `json:"masters"`
Replicas int32 `json:"replicas"`
Memory string `json:"memory"`
BasePort int32 `json:"basePort"`
Resource map[string]map[string]string `json:"resource"`
}
监控
安装 metrics-server。
要设置监控和水平自动伸缩,请安装metrics-server。
$ kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
现在可以执行kubectl top ~命令了。CPU和内存使用量的指标信息被保存在etcd中,在调度器扩展时或Prometheus进行信息收集时使用。
普罗米修斯和Grafana
我根据这个参考创建了ConfigMap并搭建了Prometheus,还设置了Grafana。但是,由于调查和搭建Redis Exporter需要花费时间,所以我只配置了监控基础设施。
目前,尚未实现的部分。
-
- 監視(Redis Exporter)の設定
-
- CRDの更新やスケールイン・アウト(HPA)の時、追加されたPodをRedis Clusterに追加、削除
-
- Master nodeとReplica nodeのRedis Podを別のワーカーノードに配置されるようにAffinity設定(HA)
-
- Podが落ちて削除された場合、Replica nodeを追加 ← (削除されたら他のPodがMasterに昇格されるので)
-
- (Liveness, Readiness)でPodの状態を確認
-
- Ingress Controllerと紐づいて疎通テスト
-
- Roll Back処理
- 検証
最后
通过在K8S上运行Redis,我们可以获得以下优点:实现了高可用性架构,并且更容易进行扩容和缩容。在本次直接开发Kubernetes的CRD和Custom Controller的过程中,我对K8S有了一定的了解。因此,我建议那些想学习K8S的人尝试直接开发Operator。非常感谢您阅读到这里。由于我在撰写文章的同时也在进行开发,并且还有许多未实现的内容,所以这篇文章基本上是像日记一样的内容。但如果能对大家有所帮助,我将非常高兴。
KWC圣诞节日历2022将继续进行!期待明天的发布!