暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

记一次在K8s集群搭建的MySQL主从无法正常启动之数据迁移恢复实践

WeiyiGeek 2022-04-08
1492


本章目录:记一次在K8s集群搭建的MySQL主从无法正常启动之数据迁移恢复实践


描述:在K8s集群中里利用bitnami
提供的mysql:5.7.32-debian-10-r61
镜像并利用helm进行MySQL集群的部署安装, 在进行网络调整后发现mysql-master-0
 pod无法正常启动,导致MySQL数据库无法访问,同时设定的root密码被更改导致无法提取持久化目录中相关数据信息,我们可以依据如下方式进行错误排查以及数据恢复。


前置知识

  • MYSQL介绍安装与运维配置 (https://blog.weiyigeek.top/2019/3/1/80.html)

  • MYSQL容备与入坑 (https://blog.weiyigeek.top/2019/3/26/84.html)


环境说明:

Kubernetes 集群版本: v1.22.2mysql 镜像及其版本: docker.io/bitnami/mysql:5.7.32-debian-10-r61kubectl get pod -n database -l app=mysql  # NAME             READY   STATUS    RESTARTS   AGE  # mysql-master-0   0/0     Error     0          11d  # mysql-slave-0    1/1     Running   0          11d


操作流程:

  • Step 0.操作任何数据之前,第一要务就是必须要进行数据备份,防止在操作的过程中对数据造成破坏。

# 查看 mysql-master 持久化的 PVC 信息$ kubectl get pvc -n database  | grep "mysql"data-mysql-master-0 Bound  pvc-4bef6f99-8a7a-47f4-8517-18721fa5d724  8Gi  RWO  nfs-devops  304ddata-mysql-slave-0  Bound  pvc-2e5de4c5-a1a4-4c79-8e5b-fc21b66d6221  8Gi  RWO  nfs-devops  304d# 进入到持久化目录中$ kubectl describe pv -n database pvc-4bef6f99-8a7a-47f4-8517-18721fa5d724  | grep "Path"Path:      Kubernetes/pvc/devops/database-data-mysql-master-0-pvc-4bef6f99-8a7a-47f4-8517-18721fa5d724# 备份持久化的数据$ cp -a Kubernetes/pvc/devops/database-data-mysql-master-0-pvc-4bef6f99-8a7a-47f4-8517-18721fa5d724 tmp/mysql-backup$ ls tmp/mysql-backup/data | head -n 15auto.cnfca-key.pemca.pemclient-cert.pemclient-key.pemauthib_buffer_poolibdata1ib_logfile0ib_logfile1ibtmp1msgmy_databasemysqlmysql-bin.000001


  • Step 1.K8s中资源服务清单部署的应用无法启动错误信息排查思路。

# sts 资源查看kubectl get sts -n database mysql-master # 查看资源控制器创建的pod日志kubectl logs -f --tail 50 -n database mysql-master-0 # 查看 pod 详细信息以及事件kubectl describe pod -n database mysql-master-0# 查看 pod 启动状态kubectl get pod -n database -l app=mysql


  • Step 2.通过前面错误信息我知道了,mysql-master-0 Pod无法启动的原因是,因为该资源清单了设置Pod健康检查即Liveness
    探针与Readiness
    探针,而正是因为root密码被修改导致Pod无法重新启动,从而导致无法正常提供服务。

# livenessProbe 探针 -- livenessProbe:  exec:    command:    - sh    - -c    - |      password_aux="${MYSQL_ROOT_PASSWORD:-}"      if [ -f "${MYSQL_ROOT_PASSWORD_FILE:-}" ]; then        password_aux=$(cat $MYSQL_ROOT_PASSWORD_FILE)      fi      mysqladmin status -uroot -p$password_aux    failureThreshold: 3       # 失效阈值为3次    initialDelaySeconds: 120  # 初始化延迟时间120s    periodSeconds: 10         # 探测周期,默认情况下是 10 秒。    successThreshold: 1       # 成功阈值为3次    timeoutSeconds: 1         # 超时时间1s# readinessProbe 探针 -- readinessProbe:  exec:    command:    - sh    - -c    - |      password_aux="${MYSQL_ROOT_PASSWORD:-}"      if [ -f "${MYSQL_ROOT_PASSWORD_FILE:-}" ]; then        password_aux=$(cat $MYSQL_ROOT_PASSWORD_FILE)      fi      mysqladmin status -uroot -p$password_aux  failureThreshold: 3  initialDelaySeconds: 30  periodSeconds: 10  successThreshold: 1  timeoutSeconds: 1


  • Step 3.查看database名称空间下的secrets资源中设定的mysql相关凭据(默认以Base64编码)。

$ kubectl get secrets -n database mysql -o yamlapiVersion: v1data:  mysql-password: dXNlcnBhc3N3ZA==              # userpasswd  mysql-replication-password: cmVwbGljYXRpb24=  # replication  mysql-root-password: cm9vdHBhc3N3ZA==         # rootpasswd   由于root密码被其它开发人员进行更改而又忘记导致。.....


  • Step 4.分别查看database名称空间下的mysql-master
    mysql-slave
    的configMap配置文件(实际上配置差不多)。

$ kubectl get cm -n database mysql-master -oyaml$ kubectl get cm -n database mysql-slave -oyamlapiVersion: v1data:  my.cnf: |-    [mysqld]    bind-address=0.0.0.0    port=3306    skip-name-resolve    explicit_defaults_for_timestamp    basedir=/opt/bitnami/mysql    plugin_dir=/opt/bitnami/mysql/plugin    socket=/opt/bitnami/mysql/tmp/mysql.sock    datadir=/bitnami/mysql/data    tmpdir=/opt/bitnami/mysql/tmp    pid-file=/opt/bitnami/mysql/tmp/mysqld.pid    log-error=/opt/bitnami/mysql/logs/mysqld.log    character-set-server=UTF8    collation-server=utf8_general_ci    max_allowed_packet=160M    default_authentication_plugin=mysql_native_password    [client]    port=3306    socket=/opt/bitnami/mysql/tmp/mysql.sock    default-character-set=UTF8    plugin_dir=/opt/bitnami/mysql/plugin    [manager]    port=3306    socket=/opt/bitnami/mysql/tmp/mysql.sock    pid-file=/opt/bitnami/mysql/tmp/mysqld.pid


  • Step 5.前面说到由于mysql数据库的root密码被修改无法通过Pod容器探针检测所以无法启用, 所以我们可以先将资源清单中的livenessProbe与readinessProbe这两部分先停用,以恢复业务正常运行,等待晚上访问流量较小时,关闭应用进行停机维护重置root密码,此时我们可以进行如下操作。

# 编辑 mysql-master 的 configMap 配置文件,在 [mysqld] 行之下加入 skip-grant-tables 字符串, 然后 使用vim 的 :wq 进行保存。kubectl edit cm -n database mysql-master


  • Step 6.等待 mysql-master-0
     Pod运行成功正常后进入到容器内部shell之中,随之执行如下命令。

# 进入 mysql-master-0 Pod 容器内部kubectl exec -it -n database mysql-master-0 bash# 此时我们可以利用root用户以及空密码登陆 MySQL 服务器中,执行如下SQL语句。mysql -u root -pmysql> status;mysql> update mysql.user set authentication_string = password("rootpasswd") where user="root";mysql> update mysql.user set authentication_string = password("userpasswd") where user="user";mysql> update mysql.user set authentication_string = password("replication") where user="replicator";# 刷新用户权限信息必须mysql> flush privileges;# 查看用户信息mysql> select host,user,authentication_string from mysql.user;+-----------+---------------+-------------------------------------------+| host      | user          | authentication_string                     |+-----------+---------------+-------------------------------------------+| %         | user          | *FBBDC6FD2E******A97D36A86BEAC3          || %         | root          | *88CFEE431A******C570D24CEB3C7A167F      || localhost | mysql.sys     | *THISISNOTA******SSWORDTHATCANBEUSEDHERE || %         | replicator    | *32005F59F5******E5AA8898DE51D456CD90    || localhost | mysql.session | *THISISNOTA******ORDTHATCANBEUSEDHERE    |+-----------+---------------+-------------------------------------------+5 rows in set (0.00 sec)


  • Step 7.修改完成后将 mysql-master 的 configMap 设置的 my.cnf 配置文件中的 skip-grant-tables
     字符串去掉,重启Pod即可。

kubectl get pod -n database -l app=mysql  # NAME             READY   STATUS    RESTARTS   AGE  # mysql-master-0   1/1     Running   0          3m12s  # mysql-slave-0    1/1     Running   0          65s

至此, MySQL集群故障恢复完成! 除此之外我们还可以通过独立的Docker容器将其数据备份出来,例如下节的数据迁移恢复


数据迁移恢复

  • Step 1. 准备一份配置文件给docker单独部署的容器进行数据恢复使用,我们需要在配置中加入 skip-grant-tables 参数, 忽略root密码进行登陆到mysql中。

tee tmp/my.cnf <<'EOF'[mysqld]bind-address=0.0.0.0port=3306skip-grant-tablesskip-name-resolveexplicit_defaults_for_timestampbasedir=/opt/bitnami/mysqlsocket=/opt/bitnami/mysql/tmp/mysql.sockdatadir=/bitnami/mysql/datatmpdir=/opt/bitnami/mysql/tmppid-file=/opt/bitnami/mysql/tmp/mysqld.pidlog-error=/opt/bitnami/mysql/logs/mysqld.logcharacter-set-server=UTF8collation-server=utf8_general_cimax_allowed_packet=16Mdefault_authentication_plugin=mysql_native_password[client]port=3306socket=/opt/bitnami/mysql/tmp/mysql.sockdefault-character-set=UTF8[manager]port=3306socket=/opt/bitnami/mysql/tmp/mysql.sockpid-file=/opt/bitnami/mysql/tmp/mysqld.pidEOF


  • Step 2.执行如下命令,并利用前面备份的持久化数据的文件创建一个新的MySQL数据库容器。

# 创建 MySQL 容器docker run -d --name mysql \  -e BITNAMI_DEBUG=true \  -e ALLOW_EMPTY_PASSWORD=yes \  -e MYSQL_AUTHENTICATION_PLUGIN=mysql_native_password \  -e MYSQL_USER=user -e MYSQL_PASSWORD=userpasswd \  -v tmp/mysql-backup/data:/bitnami/mysql/data \  -v tmp/my.cnf:/opt/bitnami/mysql/conf/my.cnf \   -v tmp/logs:/opt/bitnami/mysql/logs \  -p 32160:3306 \  bitnami/mysql:5.7.32-debian-10-r61# 查看 mysql 容器启动日志docker logs -f --tail 50 mysql


  • Step 3.同样进入到mysql容器内部shell中执行如下命令, 查看并导出相应数据库的sql文件。

docker exec -it mysql bashmysql -u root -pmysql> show databases;| auth               || msg                || my_database        |# 解决:终端备份数据库乱码(指定编码以及导出的文件路径)cd opt/bitnami/mysql/logsmysqldump -uroot -p --default-character-set=UTF8 --databases auth --hex-blob --result-file=auth.sql mysqldump -uroot -p --default-character-set=UTF8 --databases msg --hex-blob --result-file=msg.sqlmysqldump -uroot -p --default-character-set=UTF8 --databases my_database --hex-blob --result-file=my_database.sql


  • Step 4.在本机的/tmp/logs
    目录中我们可以查看到mysqldump出的sql文件。

ls tmp/logsauth.sql  msg.sql  my_database.sql  mysqld.log


  • Step 5.如果需要外部使用该Docker搭建的MySQL数据库,你需要更改用户对应的账号密码并刷新权限,在my.cnf配置文件中去除skip-grant-tables
    字段,并重启容器即可。

$ docker restart mysql$ docker ps -aCONTAINER ID        IMAGE                                COMMAND                  CREATED      STATUS                   PORTS        NAMESc72268dc95cf        bitnami/mysql:5.7.32-debian-10-r61   "/opt/bitnami/script…"   11 days ago  Start  (0) 29 hours ago  0.0.0.0:3306 mysql

至此,K8s集群搭建的MySQL数据库迁移恢复实践完毕!

本文至此完毕,更多技术文章,尽情期待下一章节!


欢迎各位志同道合的朋友一起学习交流,如文章有误请在下方留下您宝贵的经验知识,个人邮箱地址【master#weiyigeek.top】
或者个人公众号【WeiyiGeek】
联系我。

更多文章来源于【WeiyiGeek Blog - 为了能到远方,脚下的每一步都不能少 】,个人首页地址https://weiyigeek.top 】


专栏书写不易,如果您觉得这个专栏还不错的,请给这篇专栏 【点个赞、投个币、收个藏、关个注,转个发】(人间五大情),这将对我的肯定,谢谢!。



  • echo  "【点个赞】,动动你那粗壮的拇指或者芊芊玉手,亲!"

  • printf("%s", "【投个币】,万水千山总是情,投个硬币行不行,亲!")

  • fmt.Printf("【收个藏】,阅后即焚不吃灰,亲!")  

  • console.info("【转个发】,让更多的志同道合的朋友一起学习交流,亲!")

  • System.out.println("【关个注】,后续浏览查看不迷路哟,亲!")



 往期相关文章





↓↓↓ 更多文章,请点击下方阅读原文。

文章转载自WeiyiGeek,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论