在容器中部署MySQL

2022/4/30 19:15:48

本文主要是介绍在容器中部署MySQL,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

 

MySQL的docker镜像是经过优化的代码,只是包含了大多数用户期望的组件。

MySQL的docker安装,相比非容器的安装,区别在以下方面:

·只包含以下的二进制文件:

/usr/bin/my_print_defaults
/usr/bin/mysql
/usr/bin/mysql_config
/usr/bin/mysql_install_db
/usr/bin/mysql_tzinfo_to_sql
/usr/bin/mysql_upgrade
/usr/bin/mysqladmin
/usr/bin/mysqlcheck
/usr/bin/mysqldump
/usr/bin/mysqlpump
/usr/bin/mysqlbackup (for MySQL Enterprise Edition 8.0 only)
/usr/sbin/mysqld

  

·所有的二级制文件都是被修剪过的,不包含debug信息

配置MySQL Server

启动容器的时候,可以通过docker run传递参数给mysql,比如:

docker run --name mysql1 -d mysql/mysql-server:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_col

持久化数据和配置的修改

容器被删除或损坏,任何数据和配置就丢失了。docker volumes为容器内数据持久化提供了一种机制。

在初始化容器的时候,MySQL Server容器创建一个docker卷作为数据目录。可以通过docker inspect命令来查看容器的挂载点,查找关键字mount

$> docker inspect mysql1
...
 "Mounts": [
            {
                "Type": "volume",
                "Name": "4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652",
                "Source": "/var/lib/docker/volumes/4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652/_data",
                "Destination": "/var/lib/mysql",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
...

结果显示,源目录是/var/lib/docker/volumes/4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652/_data

这就是本地主机上数据持久化的目录。在容器内被挂载在/var/lib/mysql

另一种持久化的方法是在创建容器的时候,通过--mount选项来绑定挂载一个本地主机目录用作数据持久化。比如以下命令会绑定数据目录和配置文件:

docker run --name=mysql1 \
--mount type=bind,src=/path-on-host-machine/my.cnf,dst=/etc/my.cnf \
--mount type=bind,src=/path-on-host-machine/datadir,dst=/var/lib/mysql \
-d mysql/mysql-server:tag

这里的mount命令会将path-on-host-machine/my.cnf挂载到/etc/my.cnf;将path-on-host-machine/datadir挂载到/var/lib/mysql。

绑定挂载必须满足以下条件:

·path-on-host-machine/my.cnf文件必须已经存在,必须包含以下内容用于启动mysql

[mysqld]
user=mysql

·path-on-host-machine/datadir目录必须已经存在。在mysql容器初始化的时候,该目录必须是空的。启动mysql的时候,也可以挂载已经有数据的目录,但是你要确保启动的容器必须和创建该目录的mysql server具有相同的配置,任何文件或目录在启动的时候都要被挂载。

运行其它初始化脚本

如果你想在创建数据库后立即运行任何.sh或.sql脚本,你可以将这些脚本放到本地主机目录,并将本地目录挂载在容器中的/docker-entrypoint-initdb.d/

docker run --name=mysql1 \
--mount type=bind,src=/path-on-host-machine/scripts/,dst=/docker-entrypoint-initdb.d/ \
-d mysql/mysql-server:tag

从应用容器连接容器中的mysql

创建docker网络,你可以让容器互相通信,这样另一个容器中的客户端应用可以访问容器中的mysql server。

首先,创建docker网络:

docker network create my-custom-net

然后,当你在创建和启动mysqlserver和客户端容器的时候,使用--network,将这些节点放到容器网络中。比如:

docker run --name=mysql1 --network=my-custom-net -d mysql/mysql-server
docker run --name=myapp1 --network=my-custom-net -d myapp

这样容器myapp1可以连接到mysql1,通过mysql1主机名;反过来也可以连接。因为docker会自动为给定的容器名创建dns。

在下面的例子中,我们从myapp1中运行mysql客户端连接到mysql1

docker exec -it myapp1 mysql --host=mysql1 --user=myuser --password

错误日志

首次使用服务器容器启动 MySQL 服务器时,如果以下任一条件为真,则不会生成服务器错误日志

·主机上的配置文件已经被挂载,但是变量中没有包含参数log_error

·主机上的配置文件没有被挂载,但是容器环境变量mysql_log_console被设置为true(mysql8容器中是默认设置)。这样mysql错误日志被打印到stderr,日志就被记录在容器的log中,可以通过docker logs mysqld-container命令查看。

要想以上任何一个条件为真时,能生成错误日志,可以使用--log-error参数配置mysqlserver,在容器中指定位置生成错误日志。

要想持久化错误日志,可以像上面提到的那样配置持久化。但是,你必须要保证你的mysql在容器内具有对挂载点文件的读写权限。

使用基于容器的mysql企业版备份工具进行备份

要想备份,必须有对数据目录的访问权限。

 

使用容器版的mysql企业版备份工具备份容器中的mysql,要遵循以下步骤:

1.在mysql容器所在的主机上启动另一个备份工具容器来执行备份。使用关键字backup-to-image

$> docker run \
--mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \
--mount type=bind,src=/path-on-host-machine/backups/,dst=/data/backups \
--rm mysql/enterprise-server:8.0 \
mysqlbackup -umysqlbackup -ppassword --backup-dir=/tmp/backup-tmp --with-timestamp \
--backup-image=/data/backups/db.mbi backup-to-image
[Entrypoint] MySQL Docker Image 8.0.11-1.1.5
MySQL Enterprise Backup version 8.0.11 Linux-4.1.12-61.1.16.el7uek.x86_64-x86_64 [2018-04-08  07:06:45]
Copyright (c) 2003, 2018, Oracle and/or its affiliates. All Rights Reserved.
180921 17:27:25 MAIN    INFO: A thread created with Id '140594390935680'
180921 17:27:25 MAIN    INFO: Starting with following command line ...
...
-------------------------------------------------------------
   Parameters Summary
-------------------------------------------------------------
   Start LSN                  : 29615616
   End LSN                    : 29651854
-------------------------------------------------------------
mysqlbackup completed OK!

2.使用--rm参数启动,备份结束后容器就会退出,并被移除。一个镜像快照已经被创建,可以在主机目录找到

$> ls /tmp/backups
db.mbi

  

 

还原的过程

1.关闭mysql容器

docker stop mysqlserver

2.在主机上,删除绑定目录下的所有内容

rm -rf /path-on-host-machine/datadir/*

3.启动带有企业备份工具的容器

$> docker run \
--mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \
--mount type=bind,src=/path-on-host-machine/backups/,dst=/data/backups \
--rm mysql/enterprise-server:8.0 \
mysqlbackup --backup-dir=/tmp/backup-tmp --with-timestamp \
--datadir=/var/lib/mysql --backup-image=/data/backups/db.mbi copy-back-and-apply-log
[Entrypoint] MySQL Docker Image 8.0.11-1.1.5
MySQL Enterprise Backup version 8.0.11 Linux-4.1.12-61.1.16.el7uek.x86_64-x86_64 [2018-04-08  07:06:45]
Copyright (c) 2003, 2018, Oracle and/or its affiliates. All Rights Reserved.
180921 22:06:52 MAIN    INFO: A thread created with Id '139768047519872'
180921 22:06:52 MAIN    INFO: Starting with following command line ...
...
180921 22:06:52 PCR1    INFO: We were able to parse ibbackup_logfile up to
          lsn 29680612.
180921 22:06:52 PCR1    INFO: Last MySQL binlog file position 0 155, file name binlog.000003
180921 22:06:52 PCR1    INFO: The first data file is '/var/lib/mysql/ibdata1'
                              and the new created log files are at '/var/lib/mysql'
180921 22:06:52 MAIN    INFO: No Keyring file to process.
180921 22:06:52 MAIN    INFO: Apply-log operation completed successfully.
180921 22:06:52 MAIN    INFO: Full Backup has been restored successfully.
mysqlbackup completed OK! with 3 warnings

4.重启mysql容器

docker restart mysqlserver

或者

docker run --name=mysqlserver2 \
--mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \
-d mysql/enterprise-server:8.0

docker环境变量

当创建mysql容器实例的时候,可以通过参数--env(缩写是-e)来指定一个或多个参数。如果挂载的数据目录不为空,初始化就会失败,设置变量也就无效。

·布尔变量

  MYSQL_RANDOM_ROOT_PASSWORD, MYSQL_ONETIME_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD, MYSQL_LOG_CONSOLE

  如果给这些变量设置任何非0长度的字符串,变量值就为true。

·MYSQL_RANDOM_ROOT_PASSWORD默认值为true(除非MYSQL_ROOT_PASSWORD或MYSQL_ALLOW_EMPTY_PASSWORD被设置为true),容器启动的时候给root用户生成一个随机密码。密码被打印在容器的stdout,可以通过查看容器的日志来发现

·MYSQL_ONETIME_PASSWORD默认值为true(除非MYSQL_ROOT_PASSWORD或MYSQL_ALLOW_EMPTY_PASSWORD被设置为true),会给root设置过期,必须修改密码才能使用

·MYSQL_DATABASE指定数据库名。如果提供了MYSQL_USER、MYSQL_PASSWORD,创建的用户就会被授予访问该数据库的超级权限(grant all)

·MYSQL_USER、MYSQL_PASSWORD。如果用户创建的时候没有指定关键MYSQL_DATABASE,就默认不授予任何权限

·MYSQL_HOST,默认创建的用户是‘root’@'localhost'

·MYSQL_LOG_CONSOLE:如果设置为true,错误日志被重定向到stderr,可用通过docker logs mysql-container查看

·MYSQL_ROOT_PASSWORD ·MYSQL_ALLOW_EMPTY_PASSWORD

 

 

docker inspect 示例

# docker inspect d4a31e9e36a6
[
    {
        "Id": "d4a31e9e36a609c1df6b61f36be6da4ee31993042fd166669c234d2fddcb7699",
        "Created": "2019-12-03T11:04:26.399766499Z",
        "Path": "docker-entrypoint.sh",
        "Args": [
            "mysqld"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 71169,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2019-12-03T11:04:36.393621191Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha266:bddaf69df77093d9669a7b3277f6ff04bd966b0d0dc634a9b0bdfd006693ef6d",
        "ResolvConfPath": "/var/lib/docker/containers/d4a31e9e36a609c1df6b61f36be6da4ee31993042fd166669c234d2fddcb7699/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/d4a31e9e36a609c1df6b61f36be6da4ee31993042fd166669c234d2fddcb7699/hostname",
        "HostsPath": "/var/lib/docker/containers/d4a31e9e36a609c1df6b61f36be6da4ee31993042fd166669c234d2fddcb7699/hosts",
        "LogPath": "/var/lib/docker/containers/d4a31e9e36a609c1df6b61f36be6da4ee31993042fd166669c234d2fddcb7699/d4a31e9e36a609c1df6b61f36be6da4ee31993042fd166669c234d2fddcb7699-json.log",
        "Name": "/abce",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": [
            "3c2e2066e2fc99cb69b236f6903cbadca3396c20b7bfe7337aa279226a7bcbf6",
            "993c1f9416d6beb919f6c660e64f2666a3ac6b0e9b7bd7eb61d6793c42239966",
            "fd6c9f93e9b1f1160a639d992e03696644e026dc6420ef0b9997907071d733b9",
            "d26946cc167da1999096c316b6269a4401ffb24bdf963d764b6f0f3aa93f09c0",
            "4667c02dc20fc6b4e6f342e6499c9dae96a76c6fee9c7d226f966e60f99fcfd9",
            "97a379c43660f699cf26b9bd2d1329f30ed4f29b737a9c3990c1a06a4269a623",
            "134a97dd9c34247aac979f7a417b41473b600996e970091da1a064317ac7ded0",
            "16b46d6671befcb6463ea96971b93e6efb9d9617997437933b96317476c9009a",
            "6f06471d7a69179d9cd36ca299d6033331e1ad3c676f1964f2a306e40eccca2e"
        ],
        "HostConfig": {
            "Binds": [
                "/root/test/data/mariadb:/var/lib/mysql"
            ],
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {
                    "max-file": "3",
                    "max-size": "1g"
                }
            },
            "NetworkMode": "default",
            "PortBindings": {
                "3306/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "3306"
                    }
                ]
            },
            "RestartPolicy": {
                "Name": "always",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Capabilities": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": true,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": [
                "label=disable"
            ],
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67109964,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": null,
            "ReadonlyPaths": null
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/9c6b99c3d399aed0136d206be94f7e197c369efabcc4c991246e64cad9699393-init/diff:/var/lib/docker/overlay2/f63999479d9b7c440bd46696326a7e6792cf6b6cd491e2090bd6c042aaae91cc/diff:/var/lib/docker/overlay2/df3aa0ee0d40c1df7cad9bae013c9693caa44fb99c1f9a3a334cb0f039b76c23/diff:/var/lib/docker/overlay2/669f3969cb3e0daf3afbd6f7abf39dba640bbac3694d3aa626b6e6baaf9d6f6a/diff:/var/lib/docker/overlay2/0cc6eab39b7e36d16ba9b11ad37b44c0fa49f9677c99caf11940a4ef6c9ab6f0/diff:/var/lib/docker/overlay2/9041baa60966c293343699677da90d3ed1b09b7ec4ba94db966ffcf929baac9a/diff:/var/lib/docker/overlay2/76079077609ffc4de620229be23967c1f499e7b0676960cb711f3b477901ab40/diff:/var/lib/docker/overlay2/60477a4697dec3f7a93796d3d0396e6091add1fc14c0cbe327929bb12d3bad43/diff:/var/lib/docker/overlay2/79cae3146de3414934b0e9696066b6ed6e7d7cc0ab62ff1cbff7fffc462ece76/diff:/var/lib/docker/overlay2/ba4c19ce6d3ef7c623627c2e4d769afe316b326d0991fc7e6e99cce69dac44e4/diff:/var/lib/docker/overlay2/fdbf036fa609629b03919f466129c2d1161a7b2140beac69d6679ee49a7e66dc/diff:/var/lib/docker/overlay2/7a34ab43a76c0bf6f6e39961c66fe7f9edad67296f96e914f79f614aa6fea091/diff:/var/lib/docker/overlay2/c22a9966c30ae9fdfca2666d6031940e316694619cbec24936b29a31be111ac6/diff:/var/lib/docker/overlay2/b42092cffe9796196dda94316e34d9d66d2bd4e4ef0b7af3466306c676a91726/diff:/var/lib/docker/overlay2/6edb02afa6d461db16b6fa93ff1991496dcefbc91916601d3dca930e36ae33ac/diff:/var/lib/docker/overlay2/6662e3d9fddc96e003276ebe7723dc3249c90960296a6ee96b2064c926999f60/diff:/var/lib/docker/overlay2/7c21bc2fed92c43af76224b90caf29bd04172a6d6fd2b44fe71679ea9ab4e7dc/diff:/var/lib/docker/overlay2/971c69a1919e1e4a10cadc19071ad46ada7c6af2fbda761c4f1d96706f63b1f6/diff:/var/lib/docker/overlay2/430341b6ae26699411d7bd6ce9bb43604979e76e66406bfd6e29aa0a74ad620a/diff:/var/lib/docker/overlay2/c1e77dcfe7e626669d6b6a3776e6b4006ad67a4fb3f9334a9e01e4ec4d209db7/diff",
                "MergedDir": "/var/lib/docker/overlay2/9c6b99c3d399aed0136d206be94f7e197c369efabcc4c991246e64cad9699393/merged",
                "UpperDir": "/var/lib/docker/overlay2/9c6b99c3d399aed0136d206be94f7e197c369efabcc4c991246e64cad9699393/diff",
                "WorkDir": "/var/lib/docker/overlay2/9c6b99c3d399aed0136d206be94f7e197c369efabcc4c991246e64cad9699393/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/root/test/data/mariadb",
                "Destination": "/var/lib/mysql",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
        "Config": {
            "Hostname": "d4a31e9e36a6",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "3306/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "MYSQL_ROOT_PASSWORD=P@ssW0rd",
                "TZ=Asia/Shanghai",
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.10",
                "GPG_KEYS=177F4010FE66CA3336300306F1666F24C74CD1D9",
                "MARIADB_MAJOR=10.4",
                "MARIADB_VERSION=1:10.4.11+maria~bionic",
                "AUTO_RUN_DIR=/docker-entrypoint-initdb.d",
                "INSTALL_DB_SQL=test_0_efv_init.sql"
            ],
            "Cmd": [
                "mysqld"
            ],
            "Image": "test_0_efv:10.4.11",
            "Volumes": {
                "/var/lib/mysql": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {}
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "d1fa9c90777010769f9c2f6766732a0a72e0aa1477242203cee6f64966bee947",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "3306/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "3306"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/d1fa9c907770",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "139c9639f3d413ec9cff69f71eaf6f06f7617627746a1ba939c9f604eb96eb39",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "aa026c39aa6f9bdb46d3d1c49ffd4e16bbeab4ea79627d2cfcbfbddce6261c29",
                    "EndpointID": "139c9639f3d413ec9cff69f71eaf6f06f7617627746a1ba939c9f604eb96eb39",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

  

 



这篇关于在容器中部署MySQL的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程