前言
上一节我们通过准备好的 docker 环境,使用一个 shell 脚本完成了一键搭建 redis 服务,这节我们通过同样的方式搭建一个mysql服务。
关于 docker 容器启动失败的问题排查
上一篇文章发出以后,有小伙伴反馈自己在搭建 redis 服务的时候出现了创建服务成功,但是连接 redis 服务的时候连接不上,后来发现容器启动起来以后就挂掉了,没有日志,不知道增么排查,因此这里分享一个排查容器启动异常的小技巧。
docker logs
通过 docker logs
命令可以查看容器的日志信息,如果容器启动失败,可以根据提示进行排查。
docker logs 容器id或者id前缀
好了,进入正餐,我们实现一个通过脚本一键启动 mysql
服务。
闲话少说,直接上脚本:
#!/bin/bash
# 服务启动成功,打印参数信息
function printSuccessLog(){
echo "mysql 服务启动完成"
cat <<EOF
容器id: $1
服务名: $2
端口号: $3
数据存储目录: $4
密码: $5
EOF
}
cat <<EOF
###################################################################
本脚本用于基于 docker 一键启动 mysql 服务(前提是机器上已经安装好并
启动了docker服务),部分参数可配置,如果不想配置,可以一路回车,脚本
执行完成可以快速启动一个 mysql 服务。
温馨提示:
本脚本仅仅适用于搭建开发环境,服务稳定以及数据安全性暂不考虑,
不可直接应用于生产环境,切记!
###################################################################
EOF
echo
echo
echo
NOW=`date +"%Y-%m-%d %H:%M:%S"`
echo "准备构建 mysql 服务 $NOW"
echo "请输入服务名,该服务名用于以后快速启动停止或修改该服务,默认为 docker-mysql"
read INPUT_IMAGE_NAME
if [ ! $INPUT_IMAGE_NAME ]
then
IMAGE_NAME=docker-mysql
else
IMAGE_NAME=$INPUT_IMAGE_NAME
fi
echo "请输入端口号,该端口号用于客户端连接该服务,默认为 3306"
read INPUT_PORT
if [ ! $INPUT_PORT ]
then
PORT=3306
else
PORT=$INPUT_PORT
fi
echo "请输入 mysql 的数据存储目录,该目录用于挂载服务的存储数据目录,防止容器重启以后数据丢失,默认为 /usr/local/data/mysql/data"
read INPUT_DATA_LOCATION
if [ ! $INPUT_DATA_LOCATION ]
then
DATA_LOCATION=/usr/local/data/mysql/data
else
DATA_LOCATION=$INPUT_DATA_LOCATION
fi
# 如果目录不存在,则新建该目录
if [ ! -d $DATA_LOCATION ]
then
mkdir -p $DATA_LOCATION
fi
echo "请输入 mysql 的日志目录,该目录用于挂载服务的日志,默认为 /usr/local/data/mysql/log"
read INPUT_LOG_LOCATION
if [ ! $INPUT_LOG_LOCATION ]
then
LOG_LOCATION=/usr/local/data/mysql/log
else
LOG_LOCATION=$INPUT_LOG_LOCATION
fi
# 如果目录不存在,则新建该目录
if [ ! -d $LOG_LOCATION ]
then
mkdir -p $LOG_LOCATION
fi
echo "请输入 mysql root账户的密码,默认为 123456"
read INPUT_PASSWORD
if [ ! $INPUT_PASSWORD ]
then
PASSWORD=123456
else
PASSWORD=$INPUT_PASSWORD
fi
NOW=`date +"%Y-%m-%d %H:%M:%S"`
echo "开始构建 mysql 服务 $NOW"
docker pull mysql
echo "停止旧的 $IMAGE_NAME 服务..."
docker stop $IMAGE_NAME
echo "删除旧的 $IMAGE_NAME 容器..."
docker rm $IMAGE_NAME
echo "开始启动新的 $IMAGE_NAME 服务..."
CONTAINER_ID=`docker run -itd --name $IMAGE_NAME -p $PORT:3306 -v /usr/local/shell/config/mysql/my.cnf:/etc/mysql/my.cnf -v $DATA_LOCATION:/var/lib/mysql -v $LOG_LOCATION:/var/log/mysql -e MYSQL_ROOT_PASSWORD=$PASSWORD mysql`
CONTAINER_ID_PATTERN="^[0-9a-zA-Z]{64}$"
if [[ $CONTAINER_ID =~ $CONTAINER_ID_PATTERN ]]
then
echo "是否把 mysql 服务设为开启自启?[Y/N] ,默认 Y"
read AUTO_START
if [[ $AUTO_START -eq "Y" ]]
then
docker update --restart=always $CONTAINER_ID
fi
printSuccessLog $CONTAINER_ID $IMAGE_NAME $PORT $DATA_LOCATION $PASSWORD
fi
至此,mysql 服务已经起来了,测试:
docker exec -it b6b8 /bin/bash
bash-4.4# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 8.0.30 MySQL Community Server - GPL
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
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> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select user,host,plugin from user;
+------------------+-----------+-----------------------+
| user | host | plugin |
+------------------+-----------+-----------------------+
| root | % | mysql_native_password |
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session | localhost | caching_sha2_password |
| mysql.sys | localhost | caching_sha2_password |
+------------------+-----------+-----------------------+
5 rows in set (0.00 sec)
看起来很完美,但是如果你用远程客户端去连接,你会发现连接不上 mysql 服务器,这是由于 mysql 的安全策略引起的,相信对此有经验的小伙伴都不陌生。主要问题是 mysql8相对之前的版本有了很大变化,笔者也是花费了大量时间来折腾这个事情。