内容简介:本文风哥教程参考Linux官方文档、Red Hat Enterprise Linux官方文档、Ansible Automation Platform官方文档、Docker官方文档、Kubernetes官方文档和Podman官方文档等内容,详细介绍了相关技术的配置和使用方法。
风哥提示:
本文档介绍Kubernetes数据库集群部署实战案例。
Part01-数据库集群架构
1.1 架构设计
[root@k8s-master ~]# cat > /root/fgedu-database-cluster.txt << 'EOF' FGEDU数据库集群项目 =================== 1. 集群组件 - MySQL主从集群: 数据持久化 - Redis Cluster: 缓存集群 - MongoDB分片集群: 文档存储 2. 高可用设计 - 主从复制 - 自动故障转移 - 数据备份恢复 - 读写分离 3. 存储方案 - PVC持久存储 - 本地存储优化 - 备份策略 4. 监控运维 - Prometheus监控 - 日志收集 - 告警通知 EOF
Part02-MySQL主从集群
2.1 部署MySQL主从
[root@k8s-master ~]# kubectl create namespace fgedu-database
namespace/fgedu-database created
# 创建MySQL配置
[root@k8s-master ~]# cat > fgedu-mysql-config.yaml << 'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: fgedu-mysql-config
namespace: fgedu-database
data:
master.cnf: |
[mysqld]
log-bin=mysql-bin
server-id=1
binlog-format=ROW
gtid-mode=ON
enforce-gtid-consistency=ON
log-slave-updates=ON
slave.cnf: |
[mysqld]
server-id=2
relay-log=relay-bin
read-only=ON
gtid-mode=ON
enforce-gtid-consistency=ON
EOF
[root@k8s-master ~]# kubectl apply -f fgedu-mysql-config.yaml
configmap/fgedu-mysql-config created
# 部署MySQL主节点
[root@k8s-master ~]# cat学习交流加群风哥QQ113257174 > fgedu-mysql-master.yaml << 'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: fgedu-mysql-master-pvc
namespace: fgedu-database
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: fgedu-nfs-storage
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: fgedu-mysql-master
namespace: fgedu-database
spec:
serviceName: fgedu-mysql-master
replicas: 1
selector:
matchLabels:
app: fgedu-mysql
role: master
template:
metadata:
labels:
app: fgedu-mysql
role: master
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "fgedu_root_123"
- name: MYSQL_DATABASE
value: "fgedudb"
- name: MYSQL_USER
value: "fgedu"
- name: MYSQL_PASSWORD
value: "fgedu123"
volumeMounts:
- name: data
mountPath: /var/lib/mysql
- name: config
mountPath: /etc/mysql/conf.d
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 4Gi
livenessProbe:
exec:
command:
- mysqladmin
- ping
- -h
- localhost
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- mysql
- -h
- localhost
- -u
- root
- -pfgedu_root_123
- -e
- SELECT 1
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: config
configMap:
name: fgedu-mysql-config
from PG视频:www.itpux.com items:
- key: master.cnf
path: master.cnf
---
apiVersion: v1
kind: Service
metadata:
name: fgedu-mysql-master
namespace: fgedu-database
spec:
ports:
- port: 3306
targetPort: 3306
clusterIP: None
selector:
app: fgedu-mysql
role: master
EOF
[root@k8s-master ~]# kubectl apply -f fgedu-mysql-master.yaml
persistentvolumeclaim/fgedu-mysql-master-pvc created
statefulset.apps/fgedu-mysql-master created
service/fgedu-mysql-master created
# 部署MySQL从节点
[root@k8s-master ~]# cat > fgedu-mysql-slave.yaml << 'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: fgedu-mysql-slave-pvc
namespace: fgedu-database
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: fgedu-nfs-storage
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: fgedu-mysql-slave
namespace: fgedu-database
spec:
serviceName: fgedu-mysql-slave
replicas: 2
selector:
matchLabels:
app: fgedu-mysql
role: slave
template:
metadata:
labels:
app: fgedu-mysql
role: slave
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "fgedu_root_123"
volumeMounts:
- name: data
mountPath: /var/lib/mysql
- name: config
mountPath: /etc/mysql/conf.d
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 4Gi
volumes:
- name: config
configMap:
name: fgedu-mysql-config
items:
- key: slave.cnf
path: slave.cnf
---
apiVersion: v1
kind: Service
metadata:
name: fgedu-mysql-slave
namespace: fgedu-database
spec:
ports:
- port: 3306
targetPort: 3306
clusterIP: None
selector:
app: fgedu-mysql
role: slave
EOF
[root@k8s-master ~]# kubectl apply -f fgedu-mysql-slave.yaml
persistentvolumeclaim/fgedu-mysql-slave-pvc created
statefulset.apps/fgedu-mysql-slave created
service/fgedu-mysql-slave created
# 配置主从复制
[root@k8s-master ~]# kubectl exec -it fgedu-mysql-master-0 -n fgedu-database -- mysql -uroot -pfgedu_root_123 -e "CREATE USER 'repl'@'%' IDENTIFIED BY 'repl123'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; FLUSH PRIVILEGES;"
mysql: [Warning] Using a password on the command line interface can be insecure.
# 在从节点配置复制
[root@k8s-master ~]# kubectl exec -it fgedu-mysql-slave-0 -n fgedu-database -- mysql -uroot -pfgedu_root_123 -e "CHANGE MASTER TO MASTER_HOST=更多学习教程公众号风哥教程itpux_com'fgedu-mysql-master-0.fgedu-mysql-master.fgedu-database.svc.cluster.local', MASTER_USER='repl', MASTER_PASSWORD='repl123', MASTER_AUTO_POSITION=1; START SLAVE;"
mysql: [Warning] Using a password on the command line interface can be insecure.
# 查看复制状态
[root@k8s-master ~]# kubectl exec -it fgedu-mysql-slave-0 -n fgedu-database -- mysql -uroot -pfgedu_root_123 -e "SHOW SLAVE STATUS\G"
mysql: [Warning] Using a password on the command line interface can be insecure.
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: fgedu-mysql-master-0.fgedu-mysql-master.fgedu-database.svc.cluster.local
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 1234
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 567
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1234
Relay_Log_Space: 789
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Seconds_Behind_Master: 0
Part03-Redis Cluster部署
3.1 Redis集群配置
[root@k8s-master ~]# cat > fgedu-redis-cluster.yaml << 'EOF' apiVersion: apps/v1 kind: StatefulSet metadata: name: fgedu-redis namespace: fgedu-database spec: serviceName: fgedu-redis replicas: 6 selector: matchLabels: app: fgedu-redis template: metadata: labels: app: fgedu-redis spec: containers: - name: redis image: redis:7 ports: - containerPort: 6379 name: client - containerPort: 16379 name: gossip command: - redis-server - --cluster-enabled - "yes" - --cluster-config-file - /data/nodes.conf - --cluster-node-timeout - "5000" - --appendonly - "yes" - --requirepass - "redis123" resources: requests: cpu: 200m memory: 256Mi limits: cpu: 500m memory: 512Mi livenessProbe: exec: command: - redis-cli - -a - redis123 - ping initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: exec: command: - redis-cli - -a - redis123 - ping initialDelaySeconds: 5 periodSeconds: 5 --- apiVersion: v1 kind: Service metadata: name: fgedu-redis namespace: fgedu-database spec: ports: - port: 6379 targetPort: 6379 name: client - port: 16379 targetPort: 16379 name: gossip clusterIP: None selector: app: fgedu-redis EOF [root@k8s-master ~]# kubectl apply -f fgedu-redis-cluster.yaml statefulset.apps/fgedu-redis created service/fgedu-redis created # 查看Redis Pod [root@k8s-master ~]# kubectl get pods -n fgedu-database -l app=fgedu-redis NAME READY STATUS RESTARTS AGE fgedu-redis-0 1/1 Running 0 2m fgedu-redis-1 1/1 Running 0 1m fgedu-redis-2 1/1 Running 0 1m fgedu-redis-3 1/1 Running 0 1m fgedu-redis-4 1/1 Running 0 1m fgedu-redis-5 1/1 Running 0 1m # 创建Redis集群 [root@k8s-master ~]# kubectl exec -it fgedu-redis-0 -n fgedu-database -- redis-cli --cluster create --cluster-replicas 1 \ fgedu-redis-0.fgedu-redis.fgedu-database.svc.cluster.local:6379 \ fgedu-redis-1.fgedu-redis.fgedu-database.svc.cluster.local:6379 \ fgedu-redis-2.fgedu-redis.fgedu-database.svc.cluster.local:6379 \ fgedu-redis-3.fgedu-redis.fgedu-database.svc.cluster.local:6379 \ fgedu-redis-4.fgedu学习交流加群风哥微信: itpux-com-redis.fgedu-database.svc.cluster.local:6379 \ fgedu-redis-5.fgedu-redis.fgedu-database.svc.cluster.local:6379 \ -a redis123 --cluster-yes >>> Performing hash slots allocation on 6 nodes…
Master[0] -> Slots 0 – 5460
Master[1] -> Slots 5461 – 10922
Master[2] -> Slots 10923 – 16383
Adding replica fgedu-redis-3 to fgedu-redis-0
Adding replica fgedu-redis-4 to fgedu-redis-1
Adding replica fgedu-redis-5 to fgedu-redis-2
>>> Trying to optimize slaves allocation for anti-affinity
[OK] Perfect anti-affinity obtained!
>>> Check for open slots…
>>> Check slots coverage…
[OK] All 16384 slots covered.
# 验证集群状态
[root@k8s-master ~]# kubectl exec -it fgedu-redis-0 -n fgedu-database — redis-cli -a redis123 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:6
cluster_my_epoch:1
cluster_stats_messages_sent:1234
cluster_stats_messages_received:1234
Part04-数据库监控
4.1 部署监控
[root@k8s-master ~]# cat > fgedu-mysql-exporter.yaml << 'EOF' apiVersion: apps/v1 kind: Deployment metadata: name: fgedu-mysql-exporter namespace: fgedu-database spec: replicas: 1 selector: matchLabels: app: fgedu-mysql-exporter template: metadata: labels: app: fgedu-mysql-exporter spec: containers: - name: mysql-exporter image: prom/mysqld-exporter:v0.15.0 ports: - containerPort: 9104 env: - name: DATA_SOURCE_NAME value: "root:fgedu_root_123@(fgedu-mysql-master-0.fgedu-mysql-master:3306)/" resources: requests: cpu: 50m memory: 64Mi limits: cpu: 100m memory: 128Mi --- apiVersion: v1 kind: Service metadata: name: fgedu-mysql-exporter namespace: fgedu-database spec: ports: - port: 9104 targetPort: 9104 selector: app: fgedu-mysql-exporter EOF [root@k8s-master ~]# kubectl apply -f fgedu-mysql-exporter.yaml deployment.apps/fgedu-mysql-exporter created service/fgedu-mysql-exporter created # 查看所有数据库资源 [root@k8s-master ~]# kubectl get all -n fgedu-database NAME READY STATUS RESTARTS AGE pod/fgedu-mysql-master-0 1/1 Running 0 15m pod/fgedu-mysql-slave-0 1/1 Running 0 14m pod/fgedu-mysql-slave-1 1/1 Running 0 13m pod/fgedu-redis-0 1/1 Running 0 10m pod/fgedu-redis-1 1/1 Running 0 9m pod/fgedu-redis-2 1/1 Running 0 9m pod/fgedu-redis-3 1/1 Running 0 9m pod/fgedu-redis-4 1/1 Running 0 9m pod/fgedu-redis-5 1/1 Running 0 9m pod/fgedu-mysql-exporter-abc12-xyz789 1/1 Running 0 2m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/fgedu-mysql-master ClusterIP None
service/fgedu-mysql-slave ClusterIP None
service/fgedu-redis ClusterIP None
service/fgedu-mysql-exporter ClusterIP 10.96.100.100
- 使用StatefulSet部署有状态应用
- 配置持久存储保证数据安全
- 设置主从复制实现高可用
- 配置监控告警及时发现问题
- 定期备份数据库数据
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
