当前位置: 首页 > news >正文

十三、K8s自定义资源Operator

十三、K8s自定义资源Operator

文章目录

  • 十三、K8s自定义资源Operator
    • 1、什么是Operator
      • 1.1 Operator定义
      • 1.2 Operator使用场景:
      • 1.3 Operator组成
      • 1.4 Operator和Helm对比
    • 2、在 K8s 集群中安装 Redis 集群
      • 2.1 安装 Operator 和 CRD
      • 2.2 安装集群
      • 2.3 设置 Redis 集群密码
      • 2.4 在 K8s 外部访问 Redis 集群
      • 2.5 卸载集群
    • 3、使用 Operator 安装 MySQL 集群
      • 3.1 安装 Operator 和 CRD
      • 3.2 创建 NDB Cluster
      • 3.3 访问测试
      • 3.4 集群外部访问
      • 3.5 删除集群

1、什么是Operator

1.1 Operator定义

Operator是一种用于扩展K8s API的自定义控制器,可以实现在原生资源对象上进行自定义资源类型。通过Operator,也可以实现将复杂的任务转化对K8s资源的操作,让应用程序的管理和维护更加简单和规范。

1.2 Operator使用场景:

  • 简化复杂应用的管理:像管理K8s资源一样管理复杂的系统
  • 一致性操作:通过资源定义决定行为,各个环境可以统一配置
  • 扩展集群能力:自定义资源类型,扩展集群的调度能力

1.3 Operator组成

  • CRD:Custom Resource Definitions,Operator使用k8s的CRD来定义新的资源类型,新的类型可像核心资源被管理,比如定义一个叫做Database的CRD,可以用于一键启动一个数据库实例。
  • Controller:Operator控制器,该控制器监视自定义资源的状态,并根据用户的配置自动执行相应的操作,比如创建一个数据库,执行一次备份任务等。

1.4 Operator和Helm对比

  • Helm:
  • 适合简单的应用程序或微服务,尤其是那些不需要复杂运维任务的应用
  • 开发简单,无需深入了解开发知识
  • Operator:
    • 适合复杂的应用程序(如数据库、消息队列、缓存系统等),除部署外,也需要一些额外任务的应用,比如备份等
    • 开发稍微复杂,需要了解相关开发知识

2、在 K8s 集群中安装 Redis 集群

Redis Cluster 是 Redis 的分布式部署模式,可以让多个 Redis 实例以集群的方式运行,从而提供高可用性、水平扩展和数据冗余的能力。Redis Cluster 通过分片(Sharding)和复制(Replication)技术,确保数据可以在多个节点之间分布,并且在节点故障时能够自动恢复。

推荐 Operator:https://operatorhub.io/operator/redis-operator
仓库地址:https://github.com/OT-CONTAINER-KIT/redis-operator
国内仓库:https://gitee.com/dukuan/redis-operator
官方文档:https://ot-redis-operator.netlify.app/docs/

架构

在这里插入图片描述

2.1 安装 Operator 和 CRD

# 添加 Operator 的 Helm 仓库:
[root@k8s-master01 ~]# helm repo add ot-helm https://ot-container-kit.github.io/helm-charts/# 安装 Operator 和 CRD:
[root@k8s-master01 ~]# helm install redis-operator ot-helm/redis-operator --namespace ot-operators --create-namespace
NAME: redis-operator
LAST DEPLOYED: Sun Jun 29 08:16:50 2025
NAMESPACE: ot-operators
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Thank you for installing redis-operator.Your release is named redis-operator.To learn more about the release, try:$ helm status redis-operator$ helm get all redis-operator# 查看创建的 CRD:
[root@k8s-master01 ~]# kubectl get crd | grep redis
redis.redis.redis.opstreelabs.in                      2025-06-29T00:16:46Z
redisclusters.redis.redis.opstreelabs.in              2025-06-29T00:16:47Z
redisreplications.redis.redis.opstreelabs.in          2025-06-29T00:16:47Z
redissentinels.redis.redis.opstreelabs.in             2025-06-29T00:16:48Z# 查看 Pod:
[root@k8s-master01 ~]# kubectl get po -n ot-operators
NAME                              READY   STATUS    RESTARTS   AGE
redis-operator-68b7b4c9f8-dtjrr   1/1     Running   0          3m40s# 如果无法连外网,可以使用国内的仓库进行离线安装,已同步国内的镜像仓库
# crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/redis-operator:v0.20.2

2.2 安装集群

# 创建 Redis 集群的资源文件:
[root@k8s-master01 ~]# vim redis-cluster.yaml 
[root@k8s-master01 ~]# cat redis-cluster.yaml 
apiVersion: redis.redis.opstreelabs.in/v1beta2
kind: RedisCluster
metadata:name: redis-cluster
spec:clusterSize: 3clusterVersion: v7persistenceEnabled: truekubernetesConfig:image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/redis:v7.0.15imagePullPolicy: IfNotPresentstorage:volumeClaimTemplate:spec:storageClassName: nfs-csi       # 生产上不建议使用NFSaccessModes: ["ReadWriteOnce"]resources:requests:storage: 1Gi[root@k8s-master01 ~]# kubectl create -f redis-cluster.yaml -n public-service# 查看pod状态
[root@k8s-master01 ~]# kubectl get po -n public-service
NAME                       READY   STATUS    RESTARTS      AGE
redis-cluster-follower-0   1/1     Running   0             33s
redis-cluster-follower-1   1/1     Running   0             26s
redis-cluster-follower-2   1/1     Running   0             20s
redis-cluster-leader-0     1/1     Running   2 (83s ago)   89s
redis-cluster-leader-1     1/1     Running   0             60s
redis-cluster-leader-2     1/1     Running   0             39s# 查看 RedisCluster 状态:
[root@k8s-master01 ~]# kubectl get rediscluster -n public-service
NAME            CLUSTERSIZE   READYLEADERREPLICAS   READYFOLLOWERREPLICAS
redis-cluster   3             3                     3
# 查看 Redis 集群状态:
[root@k8s-master01 ~]# kubectl exec -ti redis-cluster-leader-0 -n public-service -- bash
redis-cluster-leader-0:/data$ redis-cli
127.0.0.1:6379> CLUSTER info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:3
cluster_my_epoch:1
cluster_stats_messages_ping_sent:274
cluster_stats_messages_pong_sent:271
cluster_stats_messages_sent:545
cluster_stats_messages_ping_received:268
cluster_stats_messages_pong_received:274
cluster_stats_messages_meet_received:3
cluster_stats_messages_received:545
total_cluster_links_buffer_limit_exceeded:0# 查看集群节点状态:
127.0.0.1:6379> CLUSTER NODES
e7f1e66cd4f329292494b180eef228544a6173d5 172.16.85.199:6379@16379,redis-cluster-leader-0 myself,master - 0 1751207832000 1 connected 0-5460
5513c90d5bfc92e29400207f2892d546950e9056 172.16.58.226:6379@16379,redis-cluster-follower-1 slave efb4a3641bb8b244a020a49741da746e406d7c9a 0 1751207832000 2 connected
540db0e0a90acfb0a334beef8bb28ed72a3b9a26 172.16.85.202:6379@16379,redis-cluster-follower-2 slave 96d23f632eb74396ccbe6cd100461e7fc8a466c2 0 1751207832749 3 connected
01c8b60089fc8807e579aa704c95be98774e5a4d 172.16.85.201:6379@16379,redis-cluster-follower-0 slave e7f1e66cd4f329292494b180eef228544a6173d5 0 1751207831739 1 connected
96d23f632eb74396ccbe6cd100461e7fc8a466c2 172.16.85.200:6379@16379,redis-cluster-leader-2 master - 0 1751207833762 3 connected 10923-16383
efb4a3641bb8b244a020a49741da746e406d7c9a 172.16.58.225:6379@16379,redis-cluster-leader-1 master - 0 1751207833000 2 connected 5461-10922# 创建 Redis Key 测试
redis-cluster-leader-0:/data$ redis-cli -c
127.0.0.1:6379> set a test
-> Redirected to slot [15495] located at 172.16.85.200:6379
OK
172.16.85.200:6379> get a
"test"

2.3 设置 Redis 集群密码

# 使用 Secret 存储 Redis 密码
[root@k8s-master01 ~]# vim secret.yaml
[root@k8s-master01 ~]# cat secret.yaml 
---
apiVersion: v1
kind: Secret
metadata:name: redis-secret
stringData:password: yunwei
type: Opaque[root@k8s-master01 ~]# kubectl create -f secret.yaml -n public-service
# 更新 Redis 集群配置:
[root@k8s-master01 ~]# vim redis-cluster.yaml 
[root@k8s-master01 ~]# cat redis-cluster.yaml 
....kubernetesConfig:image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/redis:v7.0.15imagePullPolicy: IfNotPresentredisSecret:name: redis-secretkey: password
....# 重新创建集群(删除重建才会生效)
[root@k8s-master01 ~]# kubectl delete -f redis-cluster.yaml -n public-service
[root@k8s-master01 ~]# kubectl create -f redis-cluster.yaml -n public-service# 查看pod
[root@k8s-master01 ~]# kubectl get po -n public-service
NAME                       READY   STATUS    RESTARTS   AGE
redis-cluster-follower-0   1/1     Running   0          17s
redis-cluster-follower-1   1/1     Running   0          12s
redis-cluster-follower-2   1/1     Running   0          6s
redis-cluster-leader-0     1/1     Running   0          33s
redis-cluster-leader-1     1/1     Running   0          28s
redis-cluster-leader-2     1/1     Running   0          22s
# 登录测试:
[root@k8s-master01 ~]# kubectl exec -ti redis-cluster-follower-0 -n public-service -- bash
redis-cluster-follower-0:/data$ redis-cli -c -a yunwei
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> CLUSTER INFO
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:3
cluster_my_epoch:1
cluster_stats_messages_ping_sent:91
cluster_stats_messages_pong_sent:96
cluster_stats_messages_meet_sent:1
cluster_stats_messages_sent:188
cluster_stats_messages_ping_received:96
cluster_stats_messages_pong_received:92
cluster_stats_messages_received:188
total_cluster_links_buffer_limit_exceeded:0

2.4 在 K8s 外部访问 Redis 集群

如果需要在 K8s 外部访问 Redis 集群(生产环境不推荐),就要把 Redis 集群暴露出去,此时可以把 Service 更改为 NodePort:

[root@k8s-master01 ~]# cat redis-cluster.yaml 
....kubernetesConfig:service:serviceType: NodePort  # 改成NodePort即可image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/redis:v7.0.15imagePullPolicy: IfNotPresentredisSecret:name: redis-secretkey: password

2.5 卸载集群

# 直接通过 yaml 文件删除即可:[root@k8s-master01 ~]# kubectl delete -f redis-cluster.yaml -n public-service

3、使用 Operator 安装 MySQL 集群

MySQL NDB Cluster 是一个分布式、高可用的数据库系统,适用于需要高并发读写、低延迟和高可用性的应用场景。MySQL NDB Cluster 基于 NDB(Network Database)存储引擎,并通过多个节点协同工作来提供数据的分布存储和故障恢复能力。

MySQL 集群安装推荐 Operator:https://operatorhub.io/operator/ndb-operator
官方文档:https://dev.mysql.com/doc/ndb-operator/8.4/en/
仓库地址:https://github.com/mysql/mysql-ndb-operator
国内仓库:https://gitee.com/dukuan/mysql-ndb-operator

架构
在这里插入图片描述

组件介绍:

  • 管理节点:Management Node,负责管理和配置整个 NDB Cluster。保存了 NDB 集群的配置信息,包括 Data Node、SQL Node。管理节点不直接参与数据存储或事务处理,主要负责集群的管理和监控,确保集群的正常运行。
  • 数据节点:Data Node,数据节点是集群中实际存储数据的节点,负责存储一部分数据,并且数据会在多个 Data Node 之间进行分区和复制,以实现高可用性和负载均衡。
  • SQL 节点:SQL Node,SQL Node 是用户与 NDB Cluster 交互的主要入口,提供了标准的 MySQL SQL 接口,允许用户通过 SQL 查询、插入、更新和删除数据。
  • NDBAPI:可以直接与 NDB 存储引擎进行交互的接口。

3.1 安装 Operator 和 CRD

# 下载部署文件:
[root@k8s-master01 ~]# git clone https://gitee.com/dukuan/mysql-ndb-operator.git# 创建 Operator:
[root@k8s-master01 ~]# cd mysql-ndb-operator/
[root@k8s-master01 mysql-ndb-operator]# kubectl apply -f deploy/manifests/ndb-operator.yaml -n ndb-operator# 查看 Pod
[root@k8s-master01 mysql-ndb-operator]# kubectl get po -n ndb-operator
NAME                                           READY   STATUS    RESTARTS   AGE
ndb-operator-app-5f8547d4b-hps2g               1/1     Running   0          8m35s
ndb-operator-webhook-server-78d5d44bb5-92c77   1/1     Running   0          8m35s# 如果无法连外网,可以使用国内的仓库进行离线安装,已同步国内的镜像仓库
# crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/community-ndb-operator:9.1.0-1.6.0

3.2 创建 NDB Cluster

# 创建一个 NDB Cluster:
[root@k8s-master01 ~]# vim ndb-cluster.yaml
[root@k8s-master01 ~]# cat ndb-cluster.yaml 
apiVersion: mysql.oracle.com/v1
kind: NdbCluster
metadata:name: example-ndb
spec:image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/community-cluster:9.1.0redundancyLevel: 1        # 指定数据副本的数量,生产环境大于等于 2dataNode:nodeCount: 1            # 指定数据副本的数量,生产环境大于等于 2pvcSpec:storageClassName: nfs-csiaccessModes: ["ReadWriteOnce"]resources:requests:storage: 10GimysqlNode:nodeCount: 1            # 指定数据副本的数量,生产环境大于等于 2pvcSpec:storageClassName: nfs-csiaccessModes: ["ReadWriteOnce"]resources:requests:storage: 10Gi
# 创建集群:
[root@k8s-master01 ~]# kubectl create ns ndb-cluster[root@k8s-master01 ~]# kubectl create -f ndb-cluster.yaml -n ndb-cluster# 查看 Pod 状态:
[root@k8s-master01 ~]# kubectl get po -n ndb-cluster
NAME                   READY   STATUS    RESTARTS   AGE
example-ndb-mgmd-0     1/1     Running   0          4m57s
example-ndb-mysqld-0   1/1     Running   0          75s
example-ndb-ndbmtd-0   1/1     Running   0          4m48s# 查看集群状态:
[root@k8s-master01 ~]# kubectl get ndbcluster -n ndb-cluster
NAME          REPLICA   MANAGEMENT NODES   DATA NODES   MYSQL SERVERS   AGE    UP-TO-DATE
example-ndb   1         Ready:1/1          Ready:1/1    Ready:1/1       5m2s   True

3.3 访问测试

# 集群创建后,会有一些 Service 可以访问到集群内部:
[root@k8s-master01 ~]# kubectl get svc -n ndb-cluster
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
example-ndb-mgmd     ClusterIP   10.104.25.157   <none>        1186/TCP   5m37s
example-ndb-mysqld   ClusterIP   10.101.140.23   <none>        3306/TCP   115s
example-ndb-ndbmtd   ClusterIP   None            <none>        1186/TCP   5m28s
# 首先登录到 SQL 节点,然后使用 ndb_mgm 查看集群状态
[root@k8s-master01 ~]# kubectl exec -ti example-ndb-mysqld-0 -n ndb-cluster -- bash
Defaulted container "mysqld-container" out of: mysqld-container, ndb-pod-init-container (init), mysqld-init-container (init)
bash-5.1# ndb_mgm -c example-ndb-mgmd
-- NDB Cluster -- Management Client --
ndb_mgm> SHOW
Connected to management server at example-ndb-mgmd port 1186 (using cleartext)
Cluster Configuration
---------------------
[ndbd(NDB)]	1 node(s)
id=2	@172.16.58.230  (mysql-9.1.0 ndb-9.1.0, Nodegroup: 0, *)[ndb_mgmd(MGM)]	1 node(s)
id=1	@172.16.85.210  (mysql-9.1.0 ndb-9.1.0)[mysqld(API)]	6 node(s)
id=147 (not connected, accepting connect from any host)
id=148	@172.16.85.211  (mysql-9.1.0 ndb-9.1.0)
id=149 (not connected, accepting connect from example-ndb-mysqld-1.example-ndb-mysqld.ndb-cluster.svc.cluster.local)
id=150 (not connected, accepting connect from example-ndb-mysqld-2.example-ndb-mysqld.ndb-cluster.svc.cluster.local)
id=151 (not connected, accepting connect from any host)
id=152 (not connected, accepting connect from any host)
# 也可以通过 MySQL 客户端链接集群,首先查看集群的访问密码:
[root@k8s-master01 ~]# base64 -d <<< $(kubectl -n ndb-cluster get secret example-ndb-mysqld-root-password -o jsonpath={.data.password})
pFWE8AwPocQ5qiGR# 登录 MySQL:
bash-5.1# mysql -h example-ndb-mysqld -uroot -ppFWE8AwPocQ5qiGR
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 111
Server version: 9.1.0-cluster MySQL Cluster Community Server - GPLCopyright (c) 2000, 2024, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| ndbinfo            |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)mysql> 

3.4 集群外部访问

如果想要在集群外部访问,可以创建一个 SQL Node NodePort 类型的 Service:

[root@k8s-master01 ~]# vim ndbcluster-svc-nodeport.yaml
[root@k8s-master01 ~]# cat ndbcluster-svc-nodeport.yaml 
apiVersion: v1
kind: Service
metadata:name: example-ndb-mysqld-nodeportnamespace: ndb-cluster
spec:ports:- name: mysqld-service-port-0port: 3306protocol: TCPtargetPort: 3306selector:mysql.oracle.com/node-type: mysqldmysql.oracle.com/v1: example-ndbsessionAffinity: Nonetype: NodePort# 创建该 Service:
[root@k8s-master01 ~]# kubectl create -f ndbcluster-svc-nodeport.yaml# 查看端口:
[root@k8s-master01 ~]# kubectl get -f ndbcluster-svc-nodeport.yaml
NAME                          TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
example-ndb-mysqld-nodeport   NodePort   10.110.189.195   <none>        3306:30314/TCP   11s

接下来即可通过节点 IP:30314 访问该集群。

3.5 删除集群

# 直接删除资源即可:
[root@k8s-master01 ~]# kubectl delete -f ndb-cluster.yaml -n ndb-cluster

此博客来源于:https://edu.51cto.com/lecturer/11062970.html

http://www.dtcms.com/a/276765.html

相关文章:

  • 客户资源被挖?营销方案泄露?企业经营信息保护避坑指南
  • Python Day11
  • Agent任务规划
  • 【PMP备考】敏捷思维:驾驭不确定性的项目管理之道
  • QT中设计qss字体样式但是没有用【已解决】
  • 文件系统(精讲)
  • JVM与系统性能监控工具实战指南:从JVM到系统的全链路分析
  • 【每日刷题】阶乘后的零
  • SOEM build on ubuntu
  • Golang实战:使用 Goroutine 实现数字与字母的交叉打印
  • 使用bp爆破模块破解pikachu登录密码
  • 使用frp内网穿透:将本地服务暴露到公网
  • 张量类型转换
  • 深入探讨Java的ZGC垃圾收集器:原理、实战与优缺点
  • 格密码--数学基础--08最近向量问题(CVP)与格陪集
  • Mentor软件模块复杂,如何分角色授权最合理?
  • 【PTA数据结构 | C语言版】阶乘的递归实现
  • 串口屏的小记哦
  • 鸿蒙进程通信的坑之ServiceExtensionAbility
  • Datomic数据库简介(TBC)
  • Ntfs!LfsFlushLfcb函数分析之Ntfs!_LFCB->LbcbWorkque的背景分析3个restart页面一个普通页面的一个例子
  • 如何在IEEETrans格式的latex标题页插入图像
  • CCS-MSPM0G3507-4-基础篇-串口通讯-实现收和发
  • Java SE--抽象类和接口
  • 面试150 对称二叉树
  • Waiting for server response 和 Content Download
  • 嵌入式程序调试工具
  • 《人件》阅读笔记
  • 【Flask】基础入门
  • 华为业务变革项目IPD基本知识