Kubernetes教程FG063-Kubernetes状态集(StatefulSet)配置与实战
内容简介
本篇文章主要介绍Kubernetes中状态集(StatefulSet)的配置与使用方法。风哥教程参考Kubernetes官方文档StatefulSet相关内容,结合生产环境实际操作场景,详细讲解StatefulSet的配置方法、特性和最佳实践。
目录大纲
Part01-基础概念与理论知识
1.1 StatefulSet概述
StatefulSet是Kubernetes中用于管理有状态应用的控制器,它可以:
- 管理有状态应用:如数据库、缓存等需要持久化状态的应用
- 保证Pod的顺序和唯一性:Pod有固定的名称和网络标识
- 持久化存储:为每个Pod创建独立的持久化存储
- 有序部署和扩缩容:按照顺序部署和扩缩容Pod
1.2 StatefulSet的特性
StatefulSet具有以下特性:
- 稳定的网络标识:每个Pod有固定的主机名和DNS记录
- 稳定的存储:每个Pod有独立的PersistentVolumeClaim
- 有序部署:按照顺序创建Pod,先创建0号Pod,再创建1号Pod,以此类推
- 有序删除:按照逆序删除Pod,先删除n-1号Pod,再删除n-2号Pod,以此类推
- 有序扩缩容:扩缩容时保持Pod的顺序
Part02-生产环境规划与建议
2.1 StatefulSet应用场景
- 数据库集群:如MySQL主从复制、PostgreSQL集群等
- 缓存集群:如Redis集群、Memcached集群等
- 分布式系统:如ZooKeeper、Kafka等
- 有状态服务:需要保存状态的应用,如游戏服务器、会话存储等
,风哥提示:。
2.2 StatefulSet设计原则
- 使用Headless Service:为StatefulSet创建Headless Service,用于提供稳定的网络标识
- 配置持久化存储:为每个Pod配置独立的PersistentVolumeClaim
- 合理设置更新策略:选择合适的更新策略,如OnDelete或RollingUpdate
- 考虑高可用性:部署多个副本,确保应用的高可用性
- 配置健康检查:为Pod配置liveness和readiness探针
Part03-生产环境项目实施方案
3.1 StatefulSet配置
配置StatefulSet,风哥提示:。
创建Headless Service
# 创建Headless Service配置文件
[root@fgedu-master ~]# cat > headless-service.yaml << EOF apiVersion: v1 kind: Service metadata: name: fgedu-statefulset-service namespace: default spec: clusterIP: None selector: app: fgedu-statefulset ports: - port: 80 name: http EOF
[root@fgedu-master ~]# cat > headless-service.yaml << EOF apiVersion: v1 kind: Service metadata: name: fgedu-statefulset-service namespace: default spec: clusterIP: None selector: app: fgedu-statefulset ports: - port: 80 name: http EOF
# 应用Service配置
[root@fgedu-master ~]# kubectl apply -f headless-service.yaml
[root@fgedu-master ~]# kubectl apply -f headless-service.yaml
service/fgedu-statefulset-service created
创建StatefulSet
# 创建StatefulSet配置文件
[root@fgedu-master ~]# cat > statefulset.yaml << EOF apiVersion: apps/v1 kind: StatefulSet metadata: name: fgedu-statefulset namespace: default spec: serviceName: "fgedu-statefulset-service" replicas: 3 selector: matchLabels: app: fgedu-statefulset template: metadata: labels: app: fgedu-statefulset spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 name: http,学习交流加群风哥微信: itpux-com。 volumeMounts: - name: nginx-data mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: nginx-data spec:accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 1Gi EOF
[root@fgedu-master ~]# cat > statefulset.yaml << EOF apiVersion: apps/v1 kind: StatefulSet metadata: name: fgedu-statefulset namespace: default spec: serviceName: "fgedu-statefulset-service" replicas: 3 selector: matchLabels: app: fgedu-statefulset template: metadata: labels: app: fgedu-statefulset spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 name: http,学习交流加群风哥微信: itpux-com。 volumeMounts: - name: nginx-data mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: nginx-data spec:accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 1Gi EOF
# 应用StatefulSet配置
[root@fgedu-master ~]# kubectl apply -f statefulset.yaml
[root@fgedu-master ~]# kubectl apply -f statefulset.yaml
statefulset.apps/fgedu-statefulset created
查看StatefulSet状态
# 查看StatefulSet状态
[root@fgedu-master ~]# kubectl get statefulset
[root@fgedu-master ~]# kubectl get statefulset
NAME READY AGE
fgedu-statefulset 3/3 1m
fgedu-statefulset 3/3 1m
# 查看Pod状态
[root@fgedu-master ~]# kubectl get pods -l app=fgedu-statefulset
[root@fgedu-master ~]# kubectl get pods -l app=fgedu-statefulset
NAME READY STATUS RESTARTS AGE
fgedu-statefulset-0 1/1 Running 0 1m
fgedu-statefulset-1 1/1 Running 0 50s
fgedu-statefulset-2 1/1 Running 0 30s
fgedu-statefulset-0 1/1 Running 0 1m
fgedu-statefulset-1 1/1 Running 0 50s
fgedu-statefulset-2 1/1 Running 0 30s
3.2 持久化存储配置
为StatefulSet配置持久化存储。
查看PVC状态
# 查看PVC状态
[root@fgedu-master ~]# kubectl get pvc
[root@fgedu-master ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nginx-data-fgedu-statefulset-0 Bound pvc-12345678-1234-1234-1234-1234567890ab 1Gi RWO standard 1m
nginx-data-fgedu-statefulset-1 Bound pvc-87654321-4321-4321-4321-ba0987654321 1Gi RWO standard 50s
nginx-data-fgedu-statefulset-2 Bound pvc-abcdef12-3456-7890-abcd-ef1234567890 1Gi RWO standard 30s
nginx-data-fgedu-statefulset-0 Bound pvc-12345678-1234-1234-1234-1234567890ab 1Gi RWO standard 1m
nginx-data-fgedu-statefulset-1 Bound pvc-87654321-4321-4321-4321-ba0987654321 1Gi RWO standard 50s
nginx-data-fgedu-statefulset-2 Bound pvc-abcdef12-3456-7890-abcd-ef1234567890 1Gi RWO standard 30s
3.3 StatefulSet管理
管理StatefulSet。
扩缩容StatefulSet
# 扩缩容StatefulSet
[root@fgedu-master ~]# kubectl scale statefulset fgedu-statefulset –replicas=5
[root@fgedu-master ~]# kubectl scale statefulset fgedu-statefulset –replicas=5
statefulset.apps/fgedu-statefulset scaled,学习交流加群风哥QQ113257174。
# 查看扩缩容后的Pod状态
[root@fgedu-master ~]# kubectl get pods -l app=fgedu-statefulset
[root@fgedu-master ~]# kubectl get pods -l app=fgedu-statefulset
NAME READY STATUS RESTARTS AGE
fgedu-statefulset-0 1/1 Running 0 5m
fgedu-statefulset-1 1/1 Running 0 4m
fgedu-statefulset-2 1/1 Running 0 4m
fgedu-statefulset-3 1/1 Running 0 1m
fgedu-statefulset-4 1/1 Running 0 30s
fgedu-statefulset-0 1/1 Running 0 5m
fgedu-statefulset-1 1/1 Running 0 4m
fgedu-statefulset-2 1/1 Running 0 4m
fgedu-statefulset-3 1/1 Running 0 1m
fgedu-statefulset-4 1/1 Running 0 30s
更新StatefulSet
# 更新StatefulSet镜像
[root@fgedu-master ~]# kubectl patch statefulset fgedu-statefulset -p ‘{“spec”:{“template”:{“spec”:{“containers”:[{“name”:”nginx”,”image”:”nginx:1.21.6″}]}}}’
[root@fgedu-master ~]# kubectl patch statefulset fgedu-statefulset -p ‘{“spec”:{“template”:{“spec”:{“containers”:[{“name”:”nginx”,”image”:”nginx:1.21.6″}]}}}’
statefulset.apps/fgedu-statefulset patched
# 查看更新状态
[root@fgedu-master ~]# kubectl rollout status statefulset fgedu-statefulset
[root@fgedu-master ~]# kubectl rollout status statefulset fgedu-statefulset
statefulset rolling update complete 5 pods at revision fgedu-statefulset-789d765432
Part04-生产案例与实战讲解
4.1 数据库集群部署
某企业需要在Kubernetes中部署MySQL主从复制集群。
案例背景
- 应用:MySQL 8.0主从复制
- 节点数量:1主2从
- 存储需求:每个节点需要20GB存储
- 高可用:主节点故障时,从节点可以晋升为主节点
部署方案
# 1. 创建Headless Service
cat > mysql-service.yaml << EOF apiVersion: v1 kind: Service metadata: name: mysql namespace: fgedu-production spec: clusterIP: None selector: app: mysql ports: - port: 3306 name: mysql EOF # 应用Service配置 kubectl apply -f mysql-service.yaml # 2. 创建StatefulSet cat > mysql-statefulset.yaml << EOF,更多视频教程www.fgedu.net.cn。 apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql namespace: fgedu-production spec: serviceName: "mysql" replicas: 3 selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:8.0 env: - name: MYSQL_ROOT_PASSWORD value: "fgedu123" - name: MYSQL_DATABASE value: "fgedudb" - name: MYSQL_USER value: "fgedu" - name: MYSQL_PASSWORD value: "fgedu123" ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-data mountPath: /var/lib/mysql volumeClaimTemplates: - metadata: name: mysql-data spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 20Gi storageClassName: high-performance EOF # 应用StatefulSet配置 kubectl apply -f mysql-statefulset.yaml # 3. 配置主从复制 # 连接到主节点 kubectl exec -it mysql-0 -n fgedu-production -- mysql -uroot -pfgedu123 # 在主节点上创建复制用户 CREATE USER 'replicator'@'%' IDENTIFIED BY 'replicator123'; GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%'; FLUSH PRIVILEGES; # 查看主节点状态 SHOW MASTER STATUS; # 连接到从节点 kubectl exec -it mysql-1 -n fgedu-production -- mysql -uroot -pfgedu123 # 在从节点上配置复制 CHANGE MASTER TO MASTER_HOST='mysql-0.mysql.fgedu-production.svc.cluster.local', MASTER_USER='replicator', MASTER_PASSWORD='replicator123', MASTER_LOG_FILE='binlog.000001', MASTER_LOG_POS=123456; # 启动复制 START SLAVE; # 查看复制状态 SHOW SLAVE STATUS\G; # 对第二个从节点执行相同操作 kubectl exec -it mysql-2 -n fgedu-production -- mysql -uroot -pfgedu123 CHANGE MASTER TO MASTER_HOST='mysql-0.mysql.fgedu-production.svc.cluster.local',更多学习教程公众号风哥教程itpux_com。 MASTER_USER='replicator', MASTER_PASSWORD='replicator123', MASTER_LOG_FILE='binlog.000001', MASTER_LOG_POS=123456; START SLAVE; SHOW SLAVE STATUS\G;
cat > mysql-service.yaml << EOF apiVersion: v1 kind: Service metadata: name: mysql namespace: fgedu-production spec: clusterIP: None selector: app: mysql ports: - port: 3306 name: mysql EOF # 应用Service配置 kubectl apply -f mysql-service.yaml # 2. 创建StatefulSet cat > mysql-statefulset.yaml << EOF,更多视频教程www.fgedu.net.cn。 apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql namespace: fgedu-production spec: serviceName: "mysql" replicas: 3 selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:8.0 env: - name: MYSQL_ROOT_PASSWORD value: "fgedu123" - name: MYSQL_DATABASE value: "fgedudb" - name: MYSQL_USER value: "fgedu" - name: MYSQL_PASSWORD value: "fgedu123" ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-data mountPath: /var/lib/mysql volumeClaimTemplates: - metadata: name: mysql-data spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 20Gi storageClassName: high-performance EOF # 应用StatefulSet配置 kubectl apply -f mysql-statefulset.yaml # 3. 配置主从复制 # 连接到主节点 kubectl exec -it mysql-0 -n fgedu-production -- mysql -uroot -pfgedu123 # 在主节点上创建复制用户 CREATE USER 'replicator'@'%' IDENTIFIED BY 'replicator123'; GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%'; FLUSH PRIVILEGES; # 查看主节点状态 SHOW MASTER STATUS; # 连接到从节点 kubectl exec -it mysql-1 -n fgedu-production -- mysql -uroot -pfgedu123 # 在从节点上配置复制 CHANGE MASTER TO MASTER_HOST='mysql-0.mysql.fgedu-production.svc.cluster.local', MASTER_USER='replicator', MASTER_PASSWORD='replicator123', MASTER_LOG_FILE='binlog.000001', MASTER_LOG_POS=123456; # 启动复制 START SLAVE; # 查看复制状态 SHOW SLAVE STATUS\G; # 对第二个从节点执行相同操作 kubectl exec -it mysql-2 -n fgedu-production -- mysql -uroot -pfgedu123 CHANGE MASTER TO MASTER_HOST='mysql-0.mysql.fgedu-production.svc.cluster.local',更多学习教程公众号风哥教程itpux_com。 MASTER_USER='replicator', MASTER_PASSWORD='replicator123', MASTER_LOG_FILE='binlog.000001', MASTER_LOG_POS=123456; START SLAVE; SHOW SLAVE STATUS\G;
4.2 有状态应用管理实战
某企业需要在Kubernetes中部署一个有状态的应用,需要保证Pod的顺序和持久化存储。。
案例背景
- 应用:ZooKeeper集群
- 节点数量:3个
- 存储需求:每个节点需要10GB存储
- 要求:保证节点的顺序和网络标识
管理方案
# 1. 创建ZooKeeper StatefulSet
[root@fgedu-master ~]# cat > zookeeper-statefulset.yaml << EOF apiVersion: apps/v1 kind: StatefulSet metadata: name: zookeeper namespace: fgedu-production spec: serviceName: "zookeeper" replicas: 3 selector: matchLabels: app: zookeeper template: metadata: labels: app: zookeeper spec: containers: - name: zookeeper image: zookeeper:3.7 ports: - containerPort: 2181 name: client - containerPort: 2888 name: peer - containerPort: 3888 name: leader-election env: - name: ZOO_MY_ID valueFrom: fieldRef: fieldPath: metadata.name - name: ZOO_SERVERS value: server.1=zookeeper-0.zookeeper.fgedu-production.svc.cluster.local:2888:3888 server.2=zookeeper-1.zookeeper.fgedu-production.svc.cluster.local:2888:3888 server.3=zookeeper-2.zookeeper.fgedu-production.svc.cluster.local:2888:3888 volumeMounts: - name: zookeeper-data mountPath: /data volumeClaimTemplates: - metadata: name: zookeeper-data spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 10Gi EOF
[root@fgedu-master ~]# cat > zookeeper-statefulset.yaml << EOF apiVersion: apps/v1 kind: StatefulSet metadata: name: zookeeper namespace: fgedu-production spec: serviceName: "zookeeper" replicas: 3 selector: matchLabels: app: zookeeper template: metadata: labels: app: zookeeper spec: containers: - name: zookeeper image: zookeeper:3.7 ports: - containerPort: 2181 name: client - containerPort: 2888 name: peer - containerPort: 3888 name: leader-election env: - name: ZOO_MY_ID valueFrom: fieldRef: fieldPath: metadata.name - name: ZOO_SERVERS value: server.1=zookeeper-0.zookeeper.fgedu-production.svc.cluster.local:2888:3888 server.2=zookeeper-1.zookeeper.fgedu-production.svc.cluster.local:2888:3888 server.3=zookeeper-2.zookeeper.fgedu-production.svc.cluster.local:2888:3888 volumeMounts: - name: zookeeper-data mountPath: /data volumeClaimTemplates: - metadata: name: zookeeper-data spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 10Gi EOF
。
,from K8S+DB视频:www.itpux.com。
# 应用StatefulSet配置
[root@fgedu-master ~]# kubectl apply -f zookeeper-statefulset.yaml
# 应用StatefulSet配置
[root@fgedu-master ~]# kubectl apply -f zookeeper-statefulset.yaml
# 查看ZooKeeper集群状态
[root@fgedu-master ~]# kubectl exec -it zookeeper-0 -n fgedu-production — zkServer.sh status
[root@fgedu-master ~]# kubectl exec -it zookeeper-0 -n fgedu-production — zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
Mode: leader
Using config: /conf/zoo.cfg
Mode: leader
# 查看ZooKeeper-1状态
[root@fgedu-master ~]# kubectl exec -it zookeeper-1 -n fgedu-production — zkServer.sh status
[root@fgedu-master ~]# kubectl exec -it zookeeper-1 -n fgedu-production — zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
Mode: follower
Using config: /conf/zoo.cfg
Mode: follower
Part05-风哥经验总结与分享
5.1 StatefulSet配置最佳实践
- 使用Headless Service:为StatefulSet创建Headless Service,确保稳定的网络标识
- 配置持久化存储:使用volumeClaimTemplates为每个Pod创建独立的存储
- 合理设置更新策略:
- OnDelete:手动删除Pod后更新
- RollingUpdate:滚动更新,默认策略
- 考虑Pod亲和性和反亲和性:确保Pod分布在不同的节点上,提高可用性
- 配置健康检查:为Pod配置liveness和readiness探针,确保应用健康
- 设置资源限制:为容器设置合理的资源限制,避免资源竞争
- 备份数据:定期备份StatefulSet的数据,确保数据安全
5.2 常见问题与解决方案
问题 原因 解决方案
StatefulSet创建失败 配置错误 检查StatefulSet配置
Pod创建顺序问题 依赖关系错误 确保Headless Service正确配置
存储挂载失败 PVC配置错误 检查PVC配置和存储后端
StatefulSet扩缩容失败 资源不足或配置错误 检查集群资源和配置
Pod网络标识问题 DNS配置错误 检查集群DNS配置
StatefulSet创建失败 配置错误 检查StatefulSet配置
Pod创建顺序问题 依赖关系错误 确保Headless Service正确配置
存储挂载失败 PVC配置错误 检查PVC配置和存储后端
StatefulSet扩缩容失败 资源不足或配置错误 检查集群资源和配置
Pod网络标识问题 DNS配置错误 检查集群DNS配置
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
