导读:在本分步教程中了解如何在 Kubernetes 上运行 MySQL、PostgreSQL、MongoDB 和其他有状态应用程序。
尽管如今几乎没有人质疑使用 Kubernetes (K8s) 来管理容器应用程序,但很多工程师(包括我自己)仍然对在 Kubernetes 上运行数据库持怀疑态度。
由于数据库通常是有状态的应用程序,它们需要持久的数据存储和一致性,而 Kubernetes 是靠无状态应用程序建立起来的。因此,要在 Kubernetes 上运行数据库,您需要确保它可以提供持久存储、备份和恢复以及高可用性和故障转移。
在本教程中,我将使用在 Kubernetes 上创建和运行 MySQL 数据库的示例来演示如何在 Kubernetes 中管理有状态应用程序。
我将深入探讨 StatefulSet、PersistentVolumes (PV)、PersistentVolumeClaims (PVC) 和 StorageClasses 等关键概念。这里将假设你已经了解数据库和Kubernetes。
在开始之前,了解无状态和有状态应用程序之间的区别特别重要。
无状态应用程序不会在请求之间保留数据;每个请求单独处理数据,无需担心共享数据。有状态应用程序会在请求之间保留数据,并在会话或 pod 之间共享数据。数据库等工作负载需要数据持久化。
持久存储: StatefulSet 利用 PV,确保每个 pod 都有专用的、稳定的存储,即使在 pod 重新启动后也能保持完整。
稳定的网络标识符: StatefulSet 中的每个单独的 pod 都会收到一个唯一且一致的名称,即使在部署后也保持不变;例如:mypod-0,mypod-1,mypod-2。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/aws-ebs # Use the correct provisioner for your cloud provider (AWS, GCP, Azure, etc.)
parameters:
type: gp3
reclaimPolicy: Retain
通过运行以下命令创建存储类:
kubectl apply -f storage-class.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 10Gi
accessModes:
ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: standard
hostPath:
path: /mnt/data # Specify a path in the host for storage
PV 是 Kubernetes 集群中分配的存储。如果启用了动态配置,Kubernetes 将自动创建 PV。
否则,需要手动创建一个。
步骤 3:创建持久卷声明 (PVC)
PVC 充当应用程序与请求的存储之间的接口。PVC 允许您的应用程序从可用的 PV 中请求存储。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: standard
步骤 4:部署 MySQL StatefulSet
此代码片段为 MySQL 创建了一个 StatefulSet,这确保每个 MySQL pod(实例)都有自己的唯一标识符、持久存储和稳定的网络身份。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: "mysql"
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
name: mysql
image: mysql:5.7
ports:
containerPort: 3306
name: mysql
env:
name: MYSQL_ROOT_PASSWORD
value: "your_password"
volumeMounts:
name: mysql-storage
mountPath: /var/lib/mysql
volumeClaimTemplates:
metadata:
name: mysql-storage
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi
storageClassName: standard
步骤 5:为 MySQL 创建无头服务
创建 MySQL StatefulSets 无头服务,以使 Pod 能够在 Kubernetes 集群中相互通信。
以下示例中的无头服务名为mysql。可以使用名称在集群内访问 MySQL Pod,该名称
# Headless service
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
ports:
name: mysql
port: 3306
selector:
app: mysql
步骤 6:将 MySQL 日志传输到监控工具
监控MySQL 对于识别数据库性能、瓶颈和错误以及确保数据库健康非常重要。MySQL StatefulSets 的日志可以路由到监控工具,例如Datadog、Grafana、Prometheus 和 ElasticSearch(ELK Stack),以全面了解数据库的性能和健康状况。
需要配置 MySQL 以将日志传输到您的监控工具。常见的监控日志包括:
慢查询日志识别运行缓慢的日志
错误日志跟踪错误和警告
通用查询日志跟踪所有 MySQL 查询
步骤 7:执行定期备份和常规恢复
定期备份以确保 Kubernetes 工作负载的可用性以及例行恢复以验证数据库的完整性非常重要。
Velero是一款开源工具,旨在安全地备份和恢复 Kubernetes 集群和 PV 上的资源。
它是确保你的应用程序或数据库不会丢失任何数据的绝佳解决方案。
Velero 提供 Kubernetes 集群备份、恢复、灾难恢复和计划备份等基本功能。有关更多信息,请查看Velero 的文档(https://velero.io/docs/v1.15/)。
步骤 8:配置数据库警报
在运行数据库和其他 StatefulSet 应用程序的 Kubernetes 环境中,设置警报通知以持续监控并避免性能下降、服务中断、停机或数据损坏至关重要。
可以使用 Datadog、Nagios、Prometheus 和 Grafana 等监控工具来监控和检查数据库的运行状况。
它们可以与 Slack 和PagerDuty等警报通知平台集成,因此每当服务出现问题或数据库出现其他问题时,工程师都会收到通知(通常是电话通知)。
结论
在 Kubernetes 中运行数据库会带来独特的挑战,包括状态管理、持久存储和网络稳定性。
管理员现在就可以轻松地在 Kubernetes 中管理数据库工作负载,通过利用 PersistentVolumes、StorageClasses、StatefulSets 和 PersistentVolumeClaims 等 Kubernetes 工具来确保数据库的完整性与可用性。
随着 Kubernetes 的不断发展,它对 StatefulSets 的支持将会增加,使得在 Kubernetes 中运行数据库成为现代基础设施的强大解决方案。
作者:场长
本文为 @ 场长 创作并授权 21CTO 发布,未经许可,请勿转载。
内容授权事宜请您联系 webmaster@21cto.com或关注 21CTO 公众号。
该文观点仅代表作者本人,21CTO 平台仅提供信息存储空间服务。