mysql docker 制作_MySQL的Docker镜像制作详解

一、环境描述

1. 宿主机

CPU:双核

内存:4 GB

硬盘:120 GB

IP地址:192.168.190.128

操作系统:CentOS 7.4 x86_64 Minimal

2. Docker

3. 基础镜像

操作系统:CentOS 6.9 x86_64

4. MySQL

版本:5.7.21

安装方式:YUM Repo

二、创建必要的文件

1. 创建服务启动脚本

当MySQL容器启动时,便会运行该脚本,启动MySQL服务。在shell中运行以下命令,创建start.sh脚本:

cat > /root/Downloads/start.sh << "EOF"

#! /bin/bash

# Source function library.

. /etc/rc.d/init.d/functions

# Source networking configuration.

. /etc/sysconfig/network

exec="/usr/bin/mysqld_safe"

prog="mysqld"

# Set timeouts here so they can be overridden from /etc/sysconfig/mysqld

STARTTIMEOUT=120

# Set in /etc/sysconfig/mysqld, will be passed to mysqld_safe

MYSQLD_OPTS=

[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog

lockfile=/var/lock/subsys/$prog

# Support for extra options passed to mysqld

command=$1 && shift

extra_opts="$@"

# Extract value of a MySQL option from config files

# Usage: get_mysql_option OPTION DEFAULT SECTION1 SECTION2 SECTIONN

# Result is returned in $result

# We use my_print_defaults which prints all options from multiple files,

# with the more specific ones later; hence take the last match.

get_mysql_option () {

option=$1

default=$2

shift 2

result=$(/usr/bin/my_print_defaults "$@" | sed -n "s/^--${option}=//p" | tail -n 1)

if [ -z "$result" ]; then

# not found, use default

result="${default}"

fi

}

get_mysql_option datadir "/var/lib/mysql" mysqld

datadir="$result"

get_mysql_option socket "$datadir/mysql.sock" mysqld

socketfile="$result"

get_mysql_option log-error "/var/log/mysqld.log" mysqld mysqld_safe

errlogfile="$result"

get_mysql_option pid-file "/var/run/mysqld/mysqld.pid" mysqld mysqld_safe

mypidfile="$result"

case $socketfile in

/*) adminsocket="$socketfile" ;;

*) adminsocket="$datadir/$socketfile" ;;

esac

install_validate_password_sql_file () {

local initfile

initfile="$(mktemp /var/lib/mysql-files/install-validate-password-plugin.XXXXXX.sql)"

chmod a+r "$initfile"

echo "SET @@SESSION.SQL_LOG_BIN=0;" > "$initfile"

echo "INSERT INTO mysql.plugin (name, dl) VALUES ('validate_password', 'validate_password.so');" >> "$initfile"

echo "$initfile"

}

start(){

[ -x $exec ] || exit 5

# check to see if it's already running

RESPONSE=$(/usr/bin/mysqladmin --no-defaults --socket="$adminsocket" --user=UNKNOWN_MYSQL_USER ping 2>&1)

if [ $? = 0 ]; then

# already running, do nothing

action $"Starting $prog: " /bin/true

ret=0

elif echo "$RESPONSE" | grep -q "Access denied for user"

then

# already running, do nothing

action $"Starting $prog: " /bin/true

ret=0

else

# prepare for start

if [ ! -e "$errlogfile" -a ! -h "$errlogfile" -a "x$(dirname "$errlogfile")" = "x/var/log" ]; then

install /dev/null -m0640 -omysql -gmysql "$errlogfile"

fi

[ -x /sbin/restorecon ] && /sbin/restorecon "$errlogfile"

if [ ! -d "$datadir/mysql" ] ; then

# First, make sure $datadir is there with correct permissions

if [ ! -d "$datadir" -a ! -h "$datadir" -a "x$(dirname "$datadir")" = "x/var/lib" ]; then

install -d -m0751 -omysql -gmysql "$datadir" || exit 1

fi

if [ ! -h "$datadir" -a "x$(dirname "$datadir")" = "x/var/lib" ]; then

chown mysql:mysql "$datadir"

chmod 0751 "$datadir"

fi

if [ -x /sbin/restorecon ]; then

/sbin/restorecon "$datadir"

for dir in /var/lib/mysql-files /var/lib/mysql-keyring ; do

if [ -x /usr/sbin/semanage -a -d /var/lib/mysql -a -d $dir ] ; then

/usr/sbin/semanage fcontext -a -e /var/lib/mysql $dir >/dev/null 2>&1

/sbin/restorecon -r $dir

fi

done

fi

# Now create the database

initfile="$(install_validate_password_sql_file)"

action $"Initializing MySQL database: " /usr/sbin/mysqld --initialize --datadir="$datadir" --user=mysql --init-file="$initfile"

ret=$?

rm -f "$initfile"

[ $ret -ne 0 ] && return $ret

# Generate certs if needed

if [ -x /usr/bin/mysql_ssl_rsa_setup -a ! -e "${datadir}/server-key.pem" ] ; then

/usr/bin/mysql_ssl_rsa_setup --datadir="$datadir" --uid=mysql >/dev/null 2>&1

fi

fi

if [ ! -h "$datadir" -a "x$(dirname "$datadir")" = "x/var/lib" ]; then

chown mysql:mysql "$datadir"

chmod 0751 "$datadir"

fi

# Pass all the options determined above, to ensure consistent behavior.

# In many cases mysqld_safe would arrive at the same conclusions anyway

# but we need to be sure. (An exception is that we don't force the

# log-error setting, since this script doesn't really depend on that,

# and some users might prefer to configure logging to syslog.)

# Note: set --basedir to prevent probes that might trigger SELinux

# alarms, per bug #547485

$exec $MYSQLD_OPTS --datadir="$datadir" --socket="$socketfile" \

--pid-file="$mypidfile" \

--basedir=/usr --user=mysql $extra_opts >/dev/null &

safe_pid=$!

# Spin for a maximum of N seconds waiting for the server to come up;

# exit the loop immediately if mysqld_safe process disappears.

# Rather than assuming we know a valid username, accept an "access

# denied" response as meaning the server is functioning.

ret=0

TIMEOUT="$STARTTIMEOUT"

while [ $TIMEOUT -gt 0 ]; do

RESPONSE=$(/usr/bin/mysqladmin --no-defaults --socket="$adminsocket" --user=UNKNOWN_MYSQL_USER ping 2>&1) && break

echo "$RESPONSE" | grep -q "Access denied for user" && break

if ! /bin/kill -0 $safe_pid 2>/dev/null; then

echo "MySQL Daemon failed to start."

ret=1

break

fi

sleep 1

let TIMEOUT=${TIMEOUT}-1

done

if [ $TIMEOUT -eq 0 ]; then

echo "Timeout error occurred trying to start MySQL Daemon."

ret=1

fi

if [ $ret -eq 0 ]; then

action $"Starting $prog: " /bin/true

touch $lockfile

else

action $"Starting $prog: " /bin/false

fi

fi

return $ret

}

start

EOF

2. 创建MySQL配置文件

MySQL容器的配置文件存放在宿主机中,便于调整MySQL服务的配置项。在shell中运行以下命令,创建my.cnf文件:

cat > /root/Downloads/my.cnf << "EOF"

# For advice on how to change settings please see

# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html

[mysqld]

#

# Remove leading # and set to the amount of RAM for the most important data

# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.

# innodb_buffer_pool_size = 128M

#

# Remove leading # to turn on a very important data integrity option: logging

# changes to the binary log between backups.

# log_bin

#

# Remove leading # to set options mainly useful for reporting servers.

# The server defaults are faster for transactions and fast SELECTs.

# Adjust sizes as needed, experiment to find the optimal values.

# join_buffer_size = 128M

# sort_buffer_size = 2M

# read_rnd_buffer_size = 2M

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks

symbolic-links=0

log-error=/var/log/mysqld.log

pid-file=/var/run/mysqld/mysqld.pid

EOF

3. 创建supervisor配置文件

supervisor是一种Linux的进程管理工具,MySQL容器会用其管理自身的后台服务。在shell中运行以下命令,创建supervisord.conf文件:

cat > /root/Downloads/supervisord.conf << "EOF"

[supervisord]

nodaemon=true

[program:mysql]

command=/bin/bash start.sh

EOF

三、制作MySQL镜像

1. 创建Dockerfile文件

在shell中运行以下命令,创建Dockerfile文件:

cat > /root/Downloads/Dockerfile << "EOF"

# 使用自建的CentOS 6.9基础镜像

FROM registry.cn-hangzhou.aliyuncs.com/ghoulich-centos/centos:6.9

# 镜像维护者

MAINTAINER ghoulich@aliyun.com

# 安装MySQL

RUN rpm -ivh https://repo.mysql.com//mysql57-community-release-el6-11.noarch.rpm

RUN yum install -y mysql-community-server

COPY start.sh /

# 安装supervisor

RUN yum install -y epel-release

RUN rpm --rebuilddb && yum install -y supervisor

# 复制supervisor配置文件

RUN rm -rf /etc/supervisord.conf

COPY supervisord.conf /etc/supervisord.conf

# 清理系统

RUN yum clean all

# 开放3306端口

EXPOSE 3306

# 挂载数据、配置和日志目录

RUN rm -rf /etc/my.cnf /var/log/mysqld.log

VOLUME ["/var/lib/mysql", "/etc/my.cnf", "/var/log/mysqld.log"]

# 自启动supervisor

CMD ["/usr/bin/supervisord"]

EOF

上述文件有两点需要注意:

公开3306端口,这是MySQL的默认服务端口。

创建数据、配置和日志目录的挂载点,这样便可以通过宿主机直接编辑和查看MySQL容器的数据、配置和日志,即使删除容器,这些数据也不会丢失。

2. 创建MySQL镜像

在shell中执行以下命令,创建镜像(耗时较长):

cd /root/Downloads

docker build -t mysql:latest .

3. 查看镜像

在shell中查看镜像信息,若如下图所示,则表示镜像创建成功:

ea3c8b5e69aad4fc1c3ca8ad8eee7bfe.png

四、上传镜像

1. 登录阿里云镜像库

在shell中运行以下命令:

docker login --username=ghoulich@aliyun.com registry.cn-hangzhou.aliyuncs.com

请根据实际情况,使用真实的用户名和密码。

2. 创建镜像标签

在shell中运行以下命令:

docker tag mysql:latest registry.cn-hangzhou.aliyuncs.com/ghoulich-centos/centos-6.9-mysql:5.7.21

3. 推送镜像

在shell中运行以下命令:

docker push registry.cn-hangzhou.aliyuncs.com/ghoulich-centos/centos-6.9-mysql:5.7.21

五、使用方法

1. 创建目录和文件

在shell中运行以下命令,在宿主机上创建MySQL的数据、配置和日志目录,并且修改访问权限:

mkdir -p /usr/local/mysql/{data,log,config}

touch /usr/local/mysql/log/mysqld.log

cp /root/Downloads/my.cnf /usr/local/mysql/config/

chown -R 27:27 /usr/local/mysql

注意,27:27是MySQL容器中的mysql用户的UID和GID,宿主机中没有这个用户。

2. 启动容器

在shell中运行以下命令,启动MySQL容器:

docker run --detach \

--name mysql \

--hostname mysql \

--volume /usr/local/mysql/log/mysqld.log:/var/log/mysqld.log \

--volume /usr/local/mysql/config/my.cnf:/etc/my.cnf \

--volume /usr/local/mysql/data:/var/lib/mysql \

--publish 3306:3306 \

registry.cn-hangzhou.aliyuncs.com/ghoulich-centos/centos-6.9-mysql:5.7.21

有几个选项需要说明:

--volume:将MySQL容器的数据、配置和日志目录映射至宿主机的相应目录;

--publish:将MySQL容器的3306端口映射至宿主机的3306端口。

3. 修改初始密码

MySQL服务初次启动时,会自动生成一个随机密码,存放在mysqld.log日志文件中。在shell中运行以下命令,首先提取初始密码,其次修改root密码,然后启用远程连接权限,最后刷新权限:

init_passwd=$(sed -rn 's/^(.*)(root@localhost: )(.*)$/\3/p' /usr/local/mysql/log/mysqld.log)

docker exec -it mysql mysql --user=root --password=${init_passwd} --connect-expired-password --execute="ALTER USER 'root'@'localhost' IDENTIFIED BY '123.Org$%^';"

docker exec -it mysql mysql --user=root --password=123.Org$%^ --execute="GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123.Org$%^' WITH GRANT OPTION;"

docker exec -it mysql mysql --user=root --password=123.Org$%^ --execute="FLUSH PRIVILEGES;"

4. 验证测试

通过telnet验证宿主机的3306端口,若结果如下图所示,则表示MySQL容器启动成功:

7094638c881b70b2f4785205fc65606d.png

5. 常用命令

在修改配置文件之后,需要重启MySQL服务才能生效,可以通过以下命令启动、停止和重启容器,也能达到同样的效果:

# 启动容器

docker start mysql

# 停止容器

docker stop mysql

# 重启容器

docker restart mysql

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值