🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 使用MySQL ## 启动MySQL实例 对我个人来说,使用Docker的最大需求就是可以简化一些应用的安装,特别是数据库之类的-_-b。所以,使用Docker的第一个Demo就是启动一个MySQL实例。 ```powershell # 拉取MySQL镜像 docker pull mysql # 启动MySQL实例 # name参数将该Container命名为demo.mysql # p参数将Container内部的3306端口(MySQL的默认端口)映射到本地 # e参数添加环境变量,这里将MySQL的root用户密码设置为password # d参数指定该Container在后台允许,即不会在当前命令行中显示输出 docker run --name demo.mysql -e MYSQL_ROOT_PASSWORD=password -p 3306:3306 -d mysql ``` 如果一切正常的话,命令行中将只输出Container的ID,同时我们也可以通过`docker ps`命令查看到。 ![启动MySQL](https://box.kancloud.cn/e5178f3892a5c8d642383c72ac5928f3_1117x732.png) 如果有更进一步的需要,还可以直接进入Container内部操作(可以视作Lunix环境)。 ```powershell docker exec -it demo.mysql bash ``` ![MySQL命令行](https://box.kancloud.cn/12ddfc0da29575be4f0d021056821dab_1117x732.png) ## 关于数据卷 数据卷(volume)是一个生命周期独立于容器(container)的特殊目录,可以实现数据的持久化储存。 说到这里,想必大家应该都能想到,MySQL这样的数据库应用必然会需要建立数据卷。我们可以用`docker volume ls`来查看一下。 ![数据卷](https://box.kancloud.cn/a80294d60ff17cb00a7595c1d7eaf5b4_1117x732.png) 果然,MySQL镜像在创建实例容器时,会默认创建一个数据卷。 因此,这就涉及到一个坑。 在删除MySQL的实例时,我在一开始就只使用`docker rm demo.mysql`。 但是,这个操作并不会删除与容器相关的数据卷。 所以,这里需要注意,如果确定不再需要了,可以通过`docker rm -v demo.mysql`来彻底删除(包括数据卷)。 当然,对于已经存在的且不再需要的数据卷,我们也可以通过以下方式来删除。 ```powershell # 删除某个数据卷 docker volume rm bb338dbf12e4fff1deae0260ab55089a53555a6e340ae2d2f823920e7be3d725a # 删除所有数据卷 docker volume rm $(docker volume ls -q) ``` 这里稍微解释一下删除所有数据卷的命令。 它其实包括了两部分 1. docker volume ls -q 2. docker volume rm 其中的第一部分可以列出所有数据卷的Id,然后将值传给第二个命令,即起到了删除所有数据卷的作用。 ## 创建MySQL集群 如果觉得只是启动一个MySQL体现不出Docker的优势,那么这边我们来试着用Docker创建一个MySQL集群。 ### 使用命令行创建 首先,自然是[官方文档](https://hub.docker.com/r/mysql/mysql-cluster/)。 因为官方文档已经讲的挺详细的了,所以这边只是单纯的题一下。 ```PowerShell # 创建一个内部网络,命名为cluster docker network create cluster --subnet=192.168.0.0/16 # 创建MySQL管理节点 docker run -d --net=cluster --name=management1 --ip=192.168.0.2 mysql/mysql-cluster ndb_mgmd # 创建两个MySQL数据节点 docker run -d --net=cluster --name=ndb1 --ip=192.168.0.3 mysql/mysql-cluster ndbd docker run -d --net=cluster --name=ndb2 --ip=192.168.0.4 mysql/mysql-cluster ndbd # 创建MySQL查询节点 # 这里和官方文档不同,为了方便直接设置了root密码 docker run -d --net=cluster --name=mysql1 --ip=192.168.0.10 -e MYSQL_ROOT_PASSWORD=password mysql/mysql-cluster mysqld ``` ![MySQL集群](https://box.kancloud.cn/e27f98adc55f18c43f4d701625581e82_1230x514.png) 此时,MySQL集群就已经启动了,我们可以利用`ndb_mgm`来管理集群。 ```PowerShell # 进入交互式的管理命令行 docker run -it --net=cluster mysql/mysql-cluster ndb_mgm ``` 在显示`ndb_mgm>`后键入`show`就可以看到该集群信息。 ![集群信息](https://box.kancloud.cn/1877456666b074eca74f8bff57247b06_1230x514.png) ## 使用Docker Compose创建 和网上那些一大堆的配置教程对比是不是简单很多,但也还是有些不爽,特别是在你要清理资源的时候,你需要手动的删除容器、网络、数据集资源。 显然,我们有更简洁的方式来启动MySQL集群——利用Docker Compose。(懒得换顺序了,本来docker-compose是在下一篇中介绍的) 那首先,我们需要新建一个目录,比如**mysql_cluster**。(目录名称和默认的容器名称有关) 然后,在这个目录中创建一个配置文件`docker-compose.yml`,键入以下内容。 ```yml version: '3' services: # 管理节点 management: image: "mysql/mysql-cluster" command: ndb_mgmd networks: cluster: ipv4_address: 192.168.0.2 # 数据节点1 ndb1: image: "mysql/mysql-cluster" command: ndbd networks: cluster: ipv4_address: 192.168.0.3 # 数据节点2 ndb2: image: "mysql/mysql-cluster" command: ndbd networks: cluster: ipv4_address: 192.168.0.4 # 查询节点 mysql: image: "mysql/mysql-cluster" command: mysqld # 设置root密码 environment: - MYSQL_ROOT_PASSWORD=password # 将3306端口暴露到本地 ports: - "3306:3306" networks: cluster: ipv4_address: 192.168.0.10 # 创建一个B类子网 # 其实改成A类网络应该也可以,这里就按官方文档来配置了。 networks: cluster: driver: bridge ipam: driver: default config: - subnet: 192.168.0.0/16 ``` 最后,在该目录下启动PowerShell,键入`docker-compose up -d`,即可启动MySQL集群。 ### MySQL集群在测试时的一些小问题 在创建MySQL集群后,相信大家肯定会用各种工具去连接测试一下,但往往并不会顺利的连接上。 比如,极有可能碰到的权限问题。 > host ‘192.168.0.1’ is not allowed to connect to this MYSQL server. 这是因为我们的MySQL集群运行在子网中,我们在本地环境中去访问的话,就相当于远程访问。但是MySQL的默认策略是不允许远程登录的,所以我们需要进入MySQL容器,添加远程访问的权限。 首先,利用`docker exec -it mysqlcluster_mysql_1 mysql -uroot -p`进入查询节点。 > **注意**:这里的容器名是根据我创建的目录`mysql-cluster`生成的默认命名。若你创建的目录名和我不同,请使用`docker ps`来查看你自己查询节点的容器名。 然后,在验证密码之后,键入以下内容。 ```sql /* * 这条命令是赋予任何IP的root用户全部权限 * 其中,root用户的密码为password */ GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION; ``` 然后,重新访问就OK了。