代码改变世界

在容器中部署MySQL

  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信息

配置MySQL Server

启动容器的时候,可以通过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
                }
            }
        }
    }
]

  

 

相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示