MySQL 是我们常用的关系型数据库,在项目开发、测试、部署到生成环境时,经常需要部署一套 MySQL 来对数据进行缓存。这里介绍下如何在 Kubernetes 环境中部署用于开发、测试的环境的 MySQL 数据库,当然,部署的是单节点模式,并非用于生产环境的主从或集群模式。单节点的 MySQL 部署简单,且配置存活探针,能保证快速检测 MySQL 是否可用,当不可用时快速进行重启。
在使用 Kubernetes 部署应用后,一般会习惯于将应用的配置文件外置,用 ConfigMap 存储,然后挂载进入镜像内部。这样,只要修改 ConfigMap 里面的配置,再重启应用就能很方便就能够使应用重新加载新的配置,很方便。
创建 Kubernetes 的 ConfigMap 资源,用于存储 MySQL 的配置文件 mysql.conf 内容:
「mysql-config.yaml:」
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-shadow-config
labels:
app: mysql-shadow
data:
my.cnf: |-
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
max_connections = 2000
secure_file_priv=/var/lib/mysql
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
通过 kubectl 工具部署 Kubernetes ConfigMap 资源,命令如下:
$ kubectl create -f mysql-config.yaml\
Kubernetes 部署的应用一般都是无状态应用,部署后下次重启很可能会漂移到不同节点上,所以不能使用节点上的本地存储,而是网络存储对应用数据持久化,PV 和 PVC 是 Kubernetes 用于与储空关联的资源,可与不同的存储驱动建立连接,存储应用数据,所以接下来我们要创建 Kubernetes PV、PVC 资源。
PV 支持多种存储驱动,不同存储驱动的 PV 配置方式是不同的,需要根据你的存储系统来配置 PV 参数。这里用的是 NFS 存储(共享网络文件存储系统),直接使用前面创建的 StorageClass 即可。
具体参考:
「mysql-storage.yaml:」
## PVC
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mysql-shadow
spec:
storageClassName: nfs-storage #---指定StorageClass
resources:
requests:
storage: 5Gi #设置 pvc 存储资源大小
accessModes:
- ReadWriteOnce
通过 kubectl 工具部署 Kubernetes PV、PVC 资源,命令如下:
$ kubectl create -f mysql-storage.yaml
MySQL 没有自带 /metrics
接口供 Prometheus 使用,在这种情况下,我们也需要利用 exporter 服务来为 Prometheus 提供指标数据了。Prometheus 官方为许多应用就提供了对应的 exporter 应用,也有许多第三方的实现,我们可以前往官方网站进行查看:https://prometheus.io/docs/instrumenting/exporters/。
这里我们选择官方的 mysqld_exporter:
mysqld_exporter 其支持的版本:
这里通过 mysqld_exporter 的服务来监控 MySQL 服务,我们以 sidecar 的形式和主应用部署在同一个 Pod 中,比如我们这里来部署一个 MySQL,并用 mysqld_exporter 的方式来采集监控数据供 Prometheus 使用,如下资源清单文件:「promethues-mysql-deploy.yaml」
创建用于 Kubernetes Deployment 来配置部署 MySQL 的参数:
## Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: db-mysql-shadow
labels:
app: mysql-shadow
spec:
replicas: 1
selector:
matchLabels:
app: mysql-shadow
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9104"
labels:
app: mysql-shadow
spec:
containers:
- name: mysql-shadow
image: centos/mysql-57-centos7:latest
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD ## 配置Root用户默认密码
value: "123456"
resources:
limits:
cpu: 2000m
memory: 512Mi
requests:
cpu: 2000m
memory: 512Mi
volumeMounts:
- name: data
mountPath: /var/lib/mysql
- name: config
mountPath: /etc/mysql/conf.d/my.cnf
subPath: my.cnf
- name: localtime
readOnly: true
mountPath: /etc/localtime
- name: mysql-exporter-shadow
image: prom/mysqld-exporter:latest
env:
- name: DATA_SOURCE_NAME
value: "root:123456@(db-mysql-produce:3306)/"
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 9104
volumes:
- name: data
persistentVolumeClaim:
claimName: mysql-shadow
- name: config
configMap:
name: mysql-shadow-config
- name: localtime
hostPath:
type: File
path: /etc/localtime
---
## Service
apiVersion: v1
kind: Service
metadata:
name: db-mysql-shadow
labels:
app: mysql-shadow
spec:
type: NodePort
ports:
- name: mysql
port: 3306
targetPort: 3306
nodePort: 30338
- name: prom
port: 9104
targetPort: 9104
selector:
app: mysql-produce
「参数简介:」
-VolumeMounts
进行绑定。通过 kubectl 工具部署 Deployment 来创建 MySQL ,命令如下:
$ kubectl create -f mysql-deploy.yaml
进入MySQL 使用命令进行连接:
$ kubectl exec -ti db-mysql-shadow-6b69bdddd6-7crqg -- /bin/bash
root@db-mall-mysql-6b69bdddd6-7crqg:/# mysql -uroot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 423
Server version: 5.7.26 MySQL Community Server (GPL)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases
-> ;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mall |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
可以看到,已经成功连接数据库,说明数据库能正常使用。
创建完成后,我们可以看到 MySQL 的 Pod 里面包含有两个容器:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
db-mysql- shadow-6b69bdddd6-7crqg 2/2 Running 0 4d20h
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
db-mysql- shadow NodePort 10.96.106.73 <none> 3306:30338/TCP,9104:30602/TCP 4d20h
我们可以通过 9104 端口来校验是否能够采集到数据:
$ curl 10.96.106.73:9104/metrics
TYPE mysql_global_variables_ft_query_expansion_limit gauge
mysql_global_variables_ft_query_expansion_limit 20
# HELP mysql_global_variables_general_log Generic gauge metric from SHOW GLOBAL VARIABLES.
# TYPE mysql_global_variables_general_log gauge
mysql_global_variables_general_log 0
# HELP mysql_global_variables_group_concat_max_len Generic gauge metric from SHOW GLOBAL VARIABLES.
# TYPE mysql_global_variables_group_concat_max_len gauge
mysql_global_variables_group_concat_max_len 1024
# HELP mysql_global_variables_gtid_executed_compression_period Generic gauge metric from SHOW GLOBAL VARIABLES.
# TYPE mysql_global_variables_gtid_executed_compression_period gauge
mysql_global_variables_gtid_executed_compression_period 1000
# HELP mysql_global_variables_gtid_mode Generic gauge metric from SHOW GLOBAL VARIABLES.
# TYPE mysql_global_variables_gtid_mode gauge
......
源码文件: