在容器中部署MySQL
2022-04-30 09:18 abce 阅读(808) 评论(0) 编辑 收藏 举报MySQL的docker镜像是经过优化的代码,只是包含了大多数用户期望的组件。
MySQL的docker安装,相比非容器的安装,区别在以下方面:
·只包含以下的二进制文件:
1 2 3 4 5 6 7 8 9 10 11 12 | /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信息
启动容器的时候,可以通过docker run传递参数给mysql,比如:
1 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | $> 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选项来绑定挂载一个本地主机目录用作数据持久化。比如以下命令会绑定数据目录和配置文件:
1 2 3 4 | 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
1 2 | [mysqld] user =mysql |
·path-on-host-machine/datadir目录必须已经存在。在mysql容器初始化的时候,该目录必须是空的。启动mysql的时候,也可以挂载已经有数据的目录,但是你要确保启动的容器必须和创建该目录的mysql server具有相同的配置,任何文件或目录在启动的时候都要被挂载。
运行其它初始化脚本
如果你想在创建数据库后立即运行任何.sh或.sql脚本,你可以将这些脚本放到本地主机目录,并将本地目录挂载在容器中的/docker-entrypoint-initdb.d/
1 2 3 | 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网络:
1 | docker network create my-custom-net |
然后,当你在创建和启动mysqlserver和客户端容器的时候,使用--network,将这些节点放到容器网络中。比如:
1 2 | 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
1 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | $> 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参数启动,备份结束后容器就会退出,并被移除。一个镜像快照已经被创建,可以在主机目录找到
1 2 | $> ls /tmp/backups db.mbi |
还原的过程
1.关闭mysql容器
1 | docker stop mysqlserver |
2.在主机上,删除绑定目录下的所有内容
1 | rm -rf /path- on -host-machine/datadir/* |
3.启动带有企业备份工具的容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | $> 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容器
1 | docker restart mysqlserver |
或者
1 2 3 | 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 示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | # 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 } } } } ] |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)