使用 mariadb-operator 在 Kubernetes 中运行和操作 MariaDB

StatefulSet
资源的引入是 Kubernetes 中运行有状态工作负载的重大变革,它引入了一系列特性,包括
- 每个
Pod
的可预测 DNS 名称,允许在网络中单独寻址它们。 - 每个
Pod
的稳定持久存储,确保每个 Pod 都绑定到同一个PersistentVolumeClaim
。 - 有序的优雅部署和自动滚动更新。
然而,这对于在 Kubernetes 中以可靠方式运行数据库来说还不够。我们缺少日间操作(Day 1 operations)和日常维护操作(Day 2 operations),例如配置高可用性和安排备份,这些是原生 Kubernetes 不管理的。通常,DBA(也就是人工操作员)是执行这些操作的指定人员,他们遵循操作手册并利用他们的专业知识,但归根结底他们是人类,能力有限,尤其是在维护大量数据库集群时。
为了解决这个问题,mariadb-operator
通过提供 MariaDB
自定义资源来扩展 Kubernetes API,该资源封装了在 Kubernetes 中轻松运行和操作 MariaDB 的操作专业知识。在这篇博客中,我们将安装 mariadb-operator
并配置它提供的一些自定义资源。
安装 mariadb-operator
您可以通过 Helm 轻松地在 Kubernetes 集群中安装 mariadb-operator
。这将安装所需的自定义资源和操作符本身。
helm repo add mariadb-operator https://mariadb-operator.github.io/mariadb-operator
helm install mariadb-operator mariadb-operator/mariadb-operator
配置 MariaDB 服务器
首先,我们需要创建一个包含 root 凭据的 Kubernetes Secret
kubectl create secret generic mariadb --from-literal=root-password=mariadb
然后,我们可以引用它并创建 MariaDB
资源
kubectl apply -f - <<EOF
apiVersion: mariadb.mmontes.io/v1alpha1
kind: MariaDB
metadata:
name: mariadb
spec:
rootPasswordSecretKeyRef:
name: mariadb
key: root-password
image:
repository: mariadb
tag: "10.11.3"
pullPolicy: IfNotPresent
port: 3306
volumeClaimTemplate:
resources:
requests:
storage: 100Mi
accessModes:
- ReadWriteOnce
myCnf: |
[mariadb]
bind-address=0.0.0.0
default_storage_engine=InnoDB
binlog_format=row
innodb_autoinc_lock_mode=2
max_allowed_packet=256M
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 300m
memory: 512Mi
EOF
操作符将监视 MariaDB
资源并最终将它们协调为 StatefulSets
kubectl get mariadbs
NAME READY STATUS PRIMARY POD AGE
mariadb True Running mariadb-0 4m43s
kubectl get statefulsets
NAME READY AGE
mariadb 1/1 4m48s
kubectl get pods
NAME READY STATUS RESTARTS AGE
mariadb-0 1/1 Running 0 4m52s
配置数据库、用户和授权
MariaDB 实例成功部署并运行后,下一步是配置 Databases
并授予 Grant
权限给 Users
kubectl apply -f - <<EOF
apiVersion: mariadb.mmontes.io/v1alpha1
kind: Database
metadata:
name: data-test
spec:
mariaDbRef:
name: mariadb
characterSet: utf8mb4
collate: uca1400_ai_ci
EOF
kubectl create secret generic user --from-literal=password=mariadb
kubectl apply -f - <<EOF
apiVersion: mariadb.mmontes.io/v1alpha1
kind: User
metadata:
name: user
spec:
mariaDbRef:
name: mariadb
passwordSecretKeyRef:
name: user
key: password
maxUserConnections: 20
EOF
kubectl apply -f - <<EOF
apiVersion: mariadb.mmontes.io/v1alpha1
kind: Grant
metadata:
name: grant
spec:
mariaDbRef:
name: mariadb
privileges:
- "CREATE"
- "SELECT"
- "INSERT"
- "UPDATE"
database: "*"
table: "*"
username: user
grantOption: false
EOF
应用上述清单后,操作符将在 MariaDB 中创建相应的 SQL 资源
kubectl get databases
NAME READY STATUS CHARSET COLLATE MARIADB AGE
data-test True Created utf8 utf8_general_ci mariadb 45s
kubectl get users
NAME READY STATUS MAXCONNS MARIADB AGE
user True Created 20 mariadb 25s
kubectl get grants
NAME READY STATUS DATABASE TABLE USERNAME GRANTOPT MARIADB AGE
grant True Created * * user true mariadb 20s
为应用程序配置连接
在此阶段,我们可以声明式地创建 Connections
,让应用程序只需挂载操作符创建的 Secret
即可无缝连接到 MariaDB
kubectl apply -f - <<EOF
apiVersion: mariadb.mmontes.io/v1alpha1
kind: Connection
metadata:
name: connection
spec:
mariaDbRef:
name: mariadb
username: user
passwordSecretKeyRef:
name: user
key: password
database: data-test
secretName: connection
secretTemplate:
key: dsn
EOF
kubectl get connections
NAME READY STATUS SECRET MARIADB AGE
connection True Healthy connection mariadb 6s
kubectl get secret connection -o jsonpath="{.data.dsn}" | base64 -d
user:mariadb@tcp(mariadb.default.svc.cluster.local:3306)/data-test
编排和调度 SQL 脚本
既然应用程序可以成功建立连接,下一个考虑因素是数据库模式的管理。 SqlJob
资源允许在 Kubernetes Jobs
中执行 SQL 脚本。通过利用此资源,您可以通过执行 SQL 脚本来灵活地定义数据库模式或执行迁移。
kubectl apply -f - <<EOF
apiVersion: mariadb.mmontes.io/v1alpha1
kind: SqlJob
metadata:
name: 01-users
spec:
mariaDbRef:
name: mariadb
username: user
passwordSecretKeyRef:
name: user
key: password
database: data-test
sql: |
CREATE TABLE IF NOT EXISTS users (
id bigint PRIMARY KEY AUTO_INCREMENT,
username varchar(255) NOT NULL,
UNIQUE KEY name__unique_idx (username)
);
INSERT INTO users(username) VALUES('mmontes11');
EOF
kubectl get sqljobs
NAME COMPLETE STATUS MARIADB AGE
01-users True Success mariadb 42s
kubectl get jobs
NAME COMPLETIONS DURATION AGE
01-users 1/1 10s 49s
kubectl exec -it mariadb-0 -- mariadb -u user -pmariadb -D data-test -e "SELECT * FROM users;"
+----+-----------+
| id | username |
+----+-----------+
| 1 | mmontes11 |
+----+-----------+
备份和恢复
数据库初始化后,定期安排备份以防止数据丢失至关重要。您可以通过创建 Backup
资源来做到这一点。
kubectl apply -f - <<EOF
apiVersion: mariadb.mmontes.io/v1alpha1
kind: Backup
metadata:
name: backup-scheduled
spec:
mariaDbRef:
name: mariadb
schedule:
cron: "*/5 * * * *"
maxRetentionDays: 30
storage:
persistentVolumeClaim:
resources:
requests:
storage: 100Mi
accessModes:
- ReadWriteOnce
EOF
此资源将被协调为 CronJob
,它会定期调度 Jobs
来执行备份。
kubectl get backups
NAME COMPLETE STATUS MARIADB AGE
backup-scheduled True Success mariadb 24s
kubectl get cronjobs
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
backup-scheduled */5 * * * * False 0 28s 29s
类似地,我们可以创建 Restore
资源来恢复 Backup
。
kubectl apply -f - <<EOF
apiVersion: mariadb.mmontes.io/v1alpha1
kind: Restore
metadata:
name: restore
spec:
mariaDbRef:
name: mariadb
backupRef:
name: backup-scheduled
EOF
kubectl get restores
NAME COMPLETE STATUS MARIADB AGE
restore True Success mariadb 11s
kubectl get jobs
NAME COMPLETIONS DURATION AGE
restore 1/1 10s 23s
从备份启动新的 MariaDB 实例
为了方便起见,可以从现有的 Backup
创建一个新的 MariaDB 实例。通过利用此功能,您可以根据需要启动新实例并快速从备份中恢复数据。操作符将在新实例准备就绪后立即执行恢复操作来处理此过程。
kubectl apply -f - <<EOF
apiVersion: mariadb.mmontes.io/v1alpha1
kind: MariaDB
metadata:
name: mariadb-from-backup
spec:
bootstrapFrom:
backupRef:
name: backup-scheduled
rootPasswordSecretKeyRef:
name: mariadb
key: root-password
image:
repository: mariadb
tag: "10.11.3"
pullPolicy: IfNotPresent
port: 3306
volumeClaimTemplate:
resources:
requests:
storage: 100Mi
accessModes:
- ReadWriteOnce
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 300m
memory: 512Mi
EOF
kubectl get mariadbs
NAME READY STATUS PRIMARY POD AGE
mariadb-from-backup True Running mariadb-from-backup-0 1m
kubectl get pods
NAME READY STATUS RESTARTS AGE
mariadb-from-backup-0 1/1 Running 0 1m
kubectl exec -it mariadb-from-backup-0 -- mariadb -u root -pmariadb -D data-test -e "SELECT * FROM users;"
+----+-----------+
| id | username |
+----+-----------+
| 1 | mmontes11 |
+----+-----------+
总结
本博客演示了如何有效利用 mariadb-operator
通过自定义资源管理 Kubernetes 中的 MariaDB 实例,推广了声明式方法,而不是依赖于命令式命令。欢迎查看文档,如有任何疑问,请加入 mariadb-operator Slack 频道!
Martin,这是一篇很棒的文章!您关于使用 mariadb-operator 在 Kubernetes 中管理 MariaDB 的全面指南非常有启发性。我很欣赏关于设置、配置,尤其是备份和恢复的详细步骤。从现有备份启动新的 MariaDB 实例是一个游戏规则改变者。感谢分享您的见解!
非常感谢 Noman 的积极反馈!
请问,为什么 MariaDB 要使用 storageClass?