摘要:结论本文结合了多种技术来构建一个复杂的生产就绪示例。 当然,这个库是一个单实例数据库。 如果您需要构建高可用的数据库解决方案,则需要部署自动化操作的集群。 虽然备份示例中仅使用了备份,但在生产环境中不太实用。 您应该考虑使用备份和备份日志。
文档说明
本文适用于容器初学者。 作者首先使用官方 MySQL 镜像构建一个可运行的容器。 创建一个单实例数据库,然后考虑您的生产环境或实际需求,逐步完善和结合多种K8S技术,创建一个复杂的、可用于生产的 >MySQL构建一个单实例库。 。
轻松部署
只需设置root用户密码(环境变量MYSQL_ROOT_PASSWORD),如下所示。 您可以使用MySQL官方镜像轻松构建MySQL数据库。
# kubectl create -f - <<EOFapiVersion:extensions/v1beta1kind:Deploymentmetadata:labels:app:mysql name:mysqlspec:replicas:1 选择器:matchLabels:app:mysql template:metadata:标签:应用程序:mysql 规范:容器:- 映像:mysql 名称:mysql imagePullPolicy:IfNotPresent 环境:- 名称:MYSQL_ROOT_PASSWORD值:ChangemeEOF
注意:如果K8S集群是minishift,则openshift 和 origin 不支持以 root 用户和官方 MySQL 身份运行容器。 t。 但是,它需要root权限,因此您必须将anyuid scc分配给默认服务帐户才能使其顺利运行。
# oc admpolicy add-scc-to-user anyuid -z default
启用数据库以服务创建。 集群内部和外部都可以访问。 集群外部的访问必须通过nodePort配置的30006端口进行。
# kubectl create -f - <<EOFapiVersion: v1kind: Servicemetadata:labels: app: mysql name: mysqlspec: type: NodePort ports: - port: 3306 nodePort: 30006 Protocol: TCP targetPort: 3306 选择器: app: mysqlEOF
接下来访问数据库并验证是否运行成功:
# kubectl get pod # 当前 Pod 名称 NAME就绪状态重启 AGEmysql-5b5668c448-t44ml 1/1 Running 0 3h# 通过本机访问# kubectl exec -it mysql-5b5668c448-t44ml -[ k4] mysql -uroot -pChangememysql> select 1;+---+| 1 |+---+| 1 |+-- -+# 访问集群内 mysql 服务: # kubectl exec -it mysql-5b5668c448-t44ml -- mysql -uroot [ k4]pChangeme -hmysqlmysql> select now();+[ k4] ---------------- ----+| 现在() |+----------[ k4] ----------+| 2018-05-21 07:19:14 |+ ----------------[k4 ][ k4]---+# 在集群外,可以通过任意K8S节点访问数据库。 # mysql - uroot -pChangeme -horigin-lb-01 -P30006mysql> 显示数据库;+----------[ k4 ]---------+| 数据库 |+-----[ k4 ]---------- ]----+| 信息架构 | mysql | | 系统 |+------------[ k4][ k4][k4 ]----+
扩展部署保护持久存储
因此,数据即使在 > 之后也存在。 MySQL 将重新启动。 必须配置持久存储。 作者的实验环境由支持K8S的GlusterFS分布式存储组成。 该功能是动态提供的,因此您可以运行以下命令来创建PVC。 :
# kubectl create -f - <<EOFkind:持久VolumeClaimapiVersion:v1metadata:名称:mysqlspec:accessModes:- ReadOnlyMany资源:请求:存储:1Gi storageClassName:glusterfs - raid0EOF
接下来,调整部署并挂载卷:
spec:containers:- image:mysql...volumeMounts:- name:mysql[ k4]data mountPath : /var/lib/mysql 卷: - name: mysql-datapersistentVolumeClaim:claimName: mysql
自定义配置文件
cm一旦安装到容器中,您就可以自定义MySQL配置文件。 名为 mysql-config 的 cm 包含一个 custom.cnf 文件,如下所示。
apiVersion: v1metadata : 名称: mysql-configdata:custom.cnf: | [mysqld]default_storage_engine=innodb Skip_external_locking lower_case_table_names=1 Skip_host_cache Skip_name_resolvekind: 容器中的 ConfigMap
cm 安装内部:
规格:...容器:- 图像:mysql...volumeMounts:-名称:mysql-config 挂载路径:/etc/mysql/conf.d/... 卷:-名称:mysql-config configMap:名称:mysql-config...
加密的 MingSense 数据
用户密码和其他 MingSense 数据被加密并存储在 Secret 和 Deploy em> 通行证中 。 卷挂载或引用环境变量。 如本示例所示,创建 root、app 和 test 用户并对 3 个人的密码进行加密并保存。它。 > 用户:
# echo -n Changeme | base64Q2hhbmdlbWU=# kubectl create -f - <<EOFapiVersion: v1kind: Secretmetadata: name: mysql-user-pwddata: mysql-root-pwd: Q2hhbmdlbWU= mysql-app[ k4]user-pwd: Q2hhbmdlbWU= mysql-test-user-pwd: Q2hhbmdlbWU=EOF
创建秘密后,从部署检索用户的明文密码,并使用环境变量存储秘密浏览数据。 请参阅下面的 Yaml。 更改为3。 > 调整:
MYSQL_DATABASE环境变量是在镜像初始化时自动创建的。数据库配置为 1。
当镜像初始化时,MYSQL_DATABASE数据库被分配给MYSQL_USER user;
p>
root 用户和 MYSQL_USER 用户可以通过secret输入密码得到它。 SecretKeyRef; p>
规范:... 容器:- 映像:mysql 名称:mysql imagePullPolicy:IfNotPresent 环境:- 名称:MYSQL_ROOT_PASSWORD valueFrom:SecretKeyRef:名称:mysql[ k4]user-pwd 密钥:mysql -root-pwd - 名称:MYSQL_PASSWORD valueFrom:SecretKeyRef:名称:mysql-user-pwd 密钥:mysql-app-user -pwd -名称:MYSQL_USER 值:app -名称:MYSQL_DATABASE 值:appdb
容器健康检查
K8S镜像控制器可以通过利文ssProbe判断容器是否不健康并决定是否重建容器。 Service服务还通过readinessProbe判断容器服务是否健康,以保证服务可用性。
在这个例子中,作者配置的livenessProbe和readinessProbe是相同的。 也就是说,如果对数据库的查询在一次执行中失败了 3 次。 行被定义为例外。 livenessProbe 和 readinessProbe 的详细用法超出了本文的范围。 请参阅 K8S 官方文档:
配置 Liveness 和 Readiness Probes
Pod 生命周期
规范:容器:- 图像:mysql... livenessProbe:exec:命令:- /bin/sh - "-c" - MYSQL_PWD ="${ MYSQL_ROOT_PASSWORD} “ - mysql -h 127.0.0.1 -u root -e “ SELECT 1”InitialDelaySeconds: 30 timeoutSeconds: 5 successThreshold: 1 FailureThreshold: 3 readinessProbe: exec:命令: - /bin/sh - "-c" - MYSQL_PWD="${MYSQL_ROOT_PASSWORD}" - mysql -h 127.0.0.1 -u root -e " SELECT 1"InitialDelaySeconds: 10 timeoutSeconds: 1 successThreshold: 1 FailureThreshold: 3...
容器初始化
假设您有以下需求: “MySQL 的初始部署包含MySQL 官方映像中应用程序所需的数据库、用户、权限、表结构和数据。”检查,你会看到目录/docker-entrypoint-initdb.d中的文件是在数据库初始化时创建的。 将自动执行。 考虑到 .sh、.sql 和 .sql.gz 文件,有两种可能性:
根据官方镜像重写Dockerfile,并将脚本粘贴到新镜像中/docker-entrypoint-initdb.d复制 em> 目录。 这种方法不灵活,因为它需要编译新图像。
初始化容器 (initContainers) 在常规容器 (containers),因此在初始化容器内,您可以将脚本复制到共享目录并将MySQL映像挂载到该目录中的/docker-entrypoint-。]initdb.d,这个方法比较灵活。
在这个例子中,作者使用了一个初始化容器的方案,其功能如下:
初始化共享一个名为mysql-initdb的emptyDir。 所有内容,包括常规容器,都安装在 /docker-entrypoint-initdb.d 目录中。
初始化容器是放置在共享/docker-entrypoint-initdb.d目录中的 >.sql文件。 该目录包含初始化的testdb和appdb数据库;数据库目录中的p>
MySQL丢失。数据库中删除+found目录,初始化容器。 规范:initContainers:-名称:mysql-init image:busybox imagePullPolicy:IfNotPresent env:-名称:MYSQL_TEST_USER_PASSWORD valueFrom:SecretKeyRef:名称:mysql-user-pwd键:mysql-test -user-pwd 命令:- sh - "-c" - | set -ex rm -fr /var/lib/mysql /洛斯t+found cat > /docker-entrypoint-initdb.d/mysql-testdb-init.sql < /docker-entrypoint-initdb.d/mysql-appdb-init.sql <<EOF 创建表 app(id int ); 插入 app value(1); : - 名称: mysql-data 挂载路径: /var/lib/mysql - 名称: mysql-initdb 挂载路径: /docker- 入口点 -initdb.d 容器: [ k4 ] 图片:mysql volumeMounts:- 名称:mysql-initdb 挂载路径:/docker-entrypoint-initdb.d... 卷:- 名称:mysql-datapersistentVolumeClaim:claimName: mysql - 名称:mysql-initdb emptyDir: {}...完成 > 部署
通过上述多个阶段的协调,MySQL数据库的部署将如下所示:
apiVersion:扩展/v1beta1kind:部署元数据:标签:应用程序:mysql名称:mysqlspec:副本:1选择器:matchLabels:应用程序:mysql模板:元数据:标签:应用程序:mysql规范:initContainers : - 名称 : mysql-init 映像:busybox imagePullPolicy:IfNotPresent env:- 名称:MYSQL_TEST_USER_PASSWORD valueFrom:secretKeyRef:名称:mysql-user-pwd 密钥:mysql-test- user-pwd 使用说明:- sh - "-c" - | set -ex rm -fr /var/lib/mysql/lost+found cat > /docker-entrypoint-initdb. d/mysql-testdb-init.sql < /docker-entrypoint-initdb.d/mysql-appdb-init.sql <<EOF 创建表 app(id int); 插入到 app value(1); : [ k4] 名称: mysql-data 挂载路径: /var/lib/mysql - 名称: mysql-initdb 挂载路径: /docker-entrypoint-initdb.d 容器: -] 图像:mysql 名称:mysql imagePullPolicy:IfNotPresent env:- 名称:MYSQL_ROOT_PASSWORD valueFrom:SecretKeyRef:名称:mysql-user-pwd 密钥:mysql-root-pwd - 名称:MYSQL_PASSWORD valueFrom: SecretKeyRef: 名称:mysql-user-pwd 键:mysql-app-user-pwd - 名称:MYSQL_USER 值:app - 名称:MYSQL_DATABASE 值:appdb 卷挂载: -名称:mysql-data 挂载路径:/var/lib/mysql -名称:mysql-initdb 挂载路径:/docker-entrypoint-initdb.d -名称:mysql - ]config 挂载路径:/etc/mysql/conf.d/ 端口:- 名称:mysql容器端口:3306 命令:- /bin/sh - "-c" - MYSQL_PWD="${MYSQL_ROOT_PASSWORD}" - mysql -h 127.0.0.1 -u root [ k4] ]e "SELECT 1"InitialDelaySeconds: 30 timeoutSeconds: 5 successThreshold: 1 FailureThreshold: 3 readinessProbe: exec: 命令: - /bin/sh - "-c" - MYSQL_PWD="${ MYSQL_ROOT_PASSWORD} " - mysql -h 127.0.0.1 -u root -e "SELECT 1"InitialDelaySeconds: 10 timeoutSeconds: 1 successThreshold: 1 FailureThreshold: 3 卷: - 名称: mysql- datapersistentVolumeClaim :声明名称:mysql - 名称:mysql-initdb emptyDir: {} - name: mysql-config configMap: name: mysql-config
创建此部署会产生以下组件。
# kubectl get all,pvc,cm,secret# MySQL Deployment: NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEdeploy/mysql 1 1 1 1 1m# RS 由 Deployment 调用。 自动生成的 NAME DESIRED CURRENT READY AGErs/mysql-998977cdd 1 1 1 1m# Pod: NAME READY STATUS RESTARTS AGEpo/mysql-998977cdd-v2ks2 1/1 Running 1 1m# Service: NAME TYPE CLUSTER [k4 ] IP 外部 - IP 端口 AGEsvc/mysql 节点端口 172.30.3.200 3306:30006/TCP 8h# Pvc: 名称状态卷容量访问模式存储类 AGEpvc/mysql 绑定 pvc-fe.. 1Gi ROX glusterfs-raid0 2m# Configmap: NAME DATA AGEcm/mysql-config 1 6h# Secret: NAME TYPE DATA AGEsecrets/mysql[ k4 ]user-pwd Opaque 3 1h
定期自动备份
定期备份数据库,确保数据安全。 在K8S集群上,您可以配置CronJob来实现自动备份作业。 首先,为您的备份创建持久存储。
# kubectl create -f - <<EOFkind: PersistentVolumeClaimapiVersion: v1metadata: name: mysql-backupspec: accessModes: - ReadWriteOnce Resource: requests: storage: 2Gi storageClassName: glusterfs[ k4]raid0EOF
接下来,设置每天早上的实际自动作业任务0,如下所示。>Point 使用mysqldump 来备份appdb 数据库。
# kubectl create -f - < /mysql-backup/mysql-`date +"%Y%m%d"`.sql 卷挂载:-名称:mysql-备份挂载路径:/mysql[ k4]backup restartPolicy: OnFailure volume: - name: mysql-backuppersistentVolumeClaim:claimName: mysql-backupEOF
结论
这篇文章结合K8S的东西。 许多技术已被用来构建复杂的、可用于生产的范例。 当然,这个库是一个单实例数据库。 如果您需要为数据库构建高可用性解决方案,您应该部署类似MySQL HA的东西。 对于PXC集群,自动作业备份示例仅使用。 mysqldump用于备份目的,但在生产环境中不太实用。 您应该使用xtrabackup进行备份,并考虑使用mysqlbinlog。m> 备份日志。
请参阅docker-entrypoint.sh。 ↩
评论前必须登录!
注册