Kubernetes Operator开发与StatefulSet有状态应用管理
背景与挑战
在Kubernetes生态中,有状态应用(如数据库、消息队列、缓存系统)的管理一直是最具挑战性的领域之一。与传统无状态应用相比,有状态应用需要确保:
- 数据持久性:确保数据不因Pod重启或迁移而丢失
- 稳定标识:维护固定的网络标识和存储映射关系
- 有序操作:部署、扩展、升级等操作需要严格的顺序控制
- 状态一致性:保证集群状态的一致性和数据完整性
以MySQL数据库集群为例,传统Deployment无法满足以下需求:
- 主从节点的有序启动和配置
- 自动故障转移和数据同步
- 备份恢复的自动化管理
- 配置变更的滚动更新
实现方案
基于Operator模式我们开发了MySQL集群管理Operator,实现有状态应用的自动化管理
- CRD(CustomResourceDefinition):定义MySQLCluster资源类型,封装集群规格、备份策略等配置
- 控制器逻辑:持续调和实际状态与期望状态,处理节点故障转移、数据备份等复杂操作
- 初始化与配置管理:自动处理MySQL系统初始化、主从复制配置和参数优化
apiVersion: mysql.oracle.com/v2kind: InnoDBClustermetadata: name: myclusterspec: instances: 3 secretName: my-secret tlsUseSelfSigned: true router: instances: 1 podSpec: resources: requests: memory: "2Gi" cpu: "1000m" limits: memory: "4Gi" cpu: "2000m" # 关键:Pod反亲和性确保节点分布 affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution:
1. Storm集群组件
Storm集群中包含两类节点:主控节点(Master Node)和工作节点(Work Node)。其分别对应的角色如下:
- 主控节点(Master Node)上运行一个被称为Nimbus的后台程序,它负责在Storm集群内分发代码,分配任务给工作机器,并且负责监控集群运行状态。Nimbus的作用类似于Hadoop中JobTracker的角色。
- 每个工作节点(Work Node)上运行一个被称为Supervisor的后台程序。Supervisor负责监听从Nimbus分配给它执行的任务,据此启动或停止执行任务的工作进程。每一个工作进程执行一个Topology的子集;一个运行中的Topology由分布在不同工作节点上的多个工作进程组成。

Storm集群组件
Nimbus和Supervisor节点之间所有的协调工作是通过Zookeeper集群来实现的。此外,Nimbus和Supervisor进程都是快速失败(fail-fast)和无状态(stateless)的;Storm集群所有的状态要么在Zookeeper集群中,要么存储在本地磁盘上。这意味着你可以用kill -9来杀死Nimbus和Supervisor进程,它们在重启后可以继续工作。这个设计使得Storm集群拥有不可思议的稳定性。
2. 安装Storm集群
2.1 搭建Zookeeper集群
参考zookeeper集群搭建
2.2 安装Jdk 7
1. 下载并安装JDK 7;
2. 配置JAVA_HOME环境变量;
3. 运行java、javac命令,测试java正常安装。
2.3 下载并解压Storm发布版本
下一步,需要在Nimbus和Supervisor机器上安装Storm发行版本。
1. 下载Storm发行版本,推荐使用Storm0.10.0:
2. 解压到安装目录下(/home/ipms/storm-0.10.0)
3. 修改storm.yaml配置文件
1) storm.zookeeper.servers: Storm集群使用的Zookeeper集群地址,其格式如下:
storm.zookeeper.servers:
- "111.222.333.444"
- "555.666.777.888"
如果Zookeeper集群使用的不是默认端口,那么还需要storm.zookeeper.port选项。
2
# Building Heron on CentOS 7
## Step 1 - Install the required dependencies
sudo yum install gcc gcc-c++ kernel-devel wget unzip zlib-devel zip git automake cmake patch libtool -y
yum install
由于单台redis服务器的计算和内存管理能力有限,使用过大内存redis服务器的性能急剧下降。为了获取更好的缓存性能及扩展型,我们需要搭建redis集群来满足需求。因redis 3.0 beta支持的集群功能不适合生产环境的使用,所以我们采用twitter的twemproxy来搭建redis缓存服务器集群.
Twemproxy是memcached和redis协议的代理服务器,并能有效减少大量连接对redis服务器的性能影响.
安装步骤:
1. 下载编译redis
推荐版本2.8及以上
2. 修改redis配置文件
修改端口(可在启动时指定)
port 6379
采用纯内存模式,注释掉save指令.
#save 900 1
#save 300 10
#save 60 10000
#save 900 1000
调整内存大小
maxmemory 8g
设置密码(可在启动时指定)
requirepass foobared
3.启动redis服务
redis-server ../conf/masters/redis.conf --logfile ../logs/masters/master-01.log --requirepass 'stream!23$' --port 6301
4.下载编译Twemproxy
推荐使用 0.4.1 release
5.修改twemproxy配置
修改监听端口
listen: 0.0.0.0:6401
禁用自动剔除,保持hash一致性
auto_eject_hosts: false
设置redis超时
timeout: 2000
redis: true
设置redis密码
redis_auth: stream!23$
配置redis服务地址(集群中所有redis都要添加上)
servers:
- 10.221.247.5:6301:1 server01
- 10.221.247.5:6302:1 server02
- 10.221.247.5:6303:1 server03
- 10.221.247.5:6304:1 server04
- 10.221.247.5:6305:1 server05
- 10.221.247.5:6306:1 server06
- 10.221.247.5:6307:1 server07
- 10.221.247.5
Storm使用Zookeeper协调集群,由于Zookeeper并不用于消息传递,所以Storm给Zookeeper带来的压力相当低。大多数情况下,单个节点的Zookeeper集群足够胜任,不过为了确保故障恢复或者部署大规模Storm集群,可能需要更大规模节点的Zookeeper集群(对于Zookeeper集群的话,官方推荐的最小节点数为3个)。在Zookeeper集群的每台机器上完成以下安装部署步骤:
1)下载安装Java JDK.
2)根据Zookeeper集群的负载情况,合理设置Java堆大小,尽可能避免发生swap,导致Zookeeper性能下降。
3)下载后解压安装Zookeeper包.
4)根据Zookeeper集群节点情况,创建如下格式的Zookeeper配置文件zoo.cfg:
tickTime=2000
dataDir=/var/zookeeper/
clientPort=2181
initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888
其中:
- dataDir指定Zookeeper的数据文件目录;
- server.id=host:port:port,id是为每个Zookeeper节点的编号,保存在dataDir目录下的myid文件中;
- zoo1~zoo3表示各个Zookeeper节点的hostname;
- 第一个port是用于连接leader的端口,第二个port是用于leader选举的端口。
5)在dataDir目录下创建myid文件,文件中只包含一行,且内容为该节点对应的server.id中的id编号。
6)启动Zookeeper服务:
可以通过bin/zkServer.sh脚本启动Zookeeper服务。
7)通过Zookeeper客户端测试服务是否可用:
通过bin/zkCli.sh脚本启动Zookeeper Java客户端。
配置文件参考: