需求分析
团队的项目中,一部分使用3306作为Mysql端口,另一部分,则是使用3307。
而一般情况下,直接安装的Mysql只能服务一个端口。
这样,遇到不同的项目,要么改Mysql的服务,要么改项目的数据库端口。然而,这两种方法都不方便...
Docker可以完美解决这个问题。
使用Docker可以实现:在一台设备上,同时运行多个Mysql实例,并且这些实例之间不会互相干扰。
下面我们从理论、操作两方面来看。
什么是Docker?
不需要理解“虚拟化技术”,只要用过虚拟机,就可以理解Docker。
虚拟机
先说什么是虚拟机:
就是在现有的系统中,模拟一组“虚拟的”硬件,然后在这个硬件上,再安装一套操作系统。
虚拟机中的系统和宿主机的系统,是互相隔离的。
除了虚拟机的硬件是模拟出来的以外,其他方面,虚拟机和真实的系统没有区别。
虚拟机有自己的文件系统、自己的线程、自己的网卡、自己的IP、自己的端口......它什么都有。
比如,物理机中的3306端口,不会影响虚拟机的3306端口;
再比如,如果在虚拟机的80端口开启Http服务,这和宿主机的80端口没有什么关系...
但是,如果想让虚拟机为宿主机提供服务端口,怎么办呢?
- 端口映射。
端口映射
不用懂概念,举个例子就明白了。
假设物理机的主机名是localhost,虚拟机的IP是192.168.1.100
正常情况下,如果我们通过localhost域名,只能访问宿主机的端口,不能直接访问虚拟机的端口。
但如果把虚拟机的3306映射到物理机的3307,会出现什么呢?
当我们再输入localhost:3307的时候,就等价于访问192.168.1.100:3306,
甚至我们都不需要知道虚拟机的地址,直接通过映射,就能访问到虚拟机的端口了。
Docker
如果我们把“虚拟系统”这个词换成“容器”
把虚拟机的“安装盘”换成“镜像”
那么,这样的“虚拟机”,就是Docker!
Docker不是虚拟机,但虚拟机的大多数特性,Docker都有。
所以我们没必要研究它俩有什么区别,而是通过研究它俩的共性,来迁移我们已有的知识。
看了刚才虚拟机的介绍,我们即使用脚丫子想,也能想明白:Docker也是有独立端口的。
实现Mysql“双开”
有了上面的理论,想创建多个运行在不同端口上的Mysql,就轻而易举了。
我们使用Docker容器,可以创建无限个一模一样的Mysql。
再使用端口映射,分别映射到宿主机的不同端口上,达到“双开”的效果。
(需要注意的是,这些容器之间是独立的,更改容器1不会影响容器2)
操作
安装Docker
无论你是Mac,还是Linux,还是Windows,都可以通过终端,快速的安装Docker。
(建议使用最简单的方式安装Docker,不用在安装时耽误太多时间,装好后可以不用登录)
拉取镜像
什么是“镜像”?
刚才说了,相当于安装系统的“光盘”。我们可以通过这张光盘,在许多电脑上,安装许多一模一样的系统。
而镜像呢?通过这个镜像,可以创建许多一模一样的容器,也相当于安装了许多一模一样的系统。
在终端中输入:
// 拉取mysql5.7镜像
docker pull mysql:5.7
// 或者拉取最新的mysql镜像
docker pull mysql
等待读条完成,这个Mysql的“安装盘”就下载到我们的电脑上了。
建立容器
刚才也说了,一个容器就相当于一个虚拟机系统。所以建立容器,就是在“装系统”,既然是装系统,就需要用到刚才的“安装盘”。
终端输入:
// 把各种属性替换成自己的!
docker run -id --name=[容器名称] -p [主机端口]:[容器端口] -e MYSQL\_ROOT\_PASSWORD=[Mysql密码] [镜像名称]
// 示例代码
docker run -id --name=mysql3307 -p 3307:3306 -e MYSQL\_ROOT\_PASSWORD=123456 mysql:5.7
值得注意的是,命令中的3307:3306就是“端口映射”,也就是把容器的3306映射到本机的3307,注意千万不要写反!!
修改Mysql登录密码
许多测试环境都是使用root空密码登录,所以我们把容器中的Mysql也改成空密码。
由于容器是独立的环境,它有自己的终端,因此我们需要从本机的终端,切换到容器的终端。
终端中输入,进入容器:
// 容器名改成自己的
docker exec -it [容器名] bash
// 示例代码
docker exec -it mysql3307 bash
输完之后,可以发现终端的前缀发生了变化:
说明已经进入了容器的终端。
接下来进入Mysql环境:
// 老规矩,换成自己的
mysql -u[用户名] -p[密码]
// 实例代码
mysql -uroot -p123456
我们发现,终端的前缀又发生了变化:
此时,输入:
// 运行root用户 使用空密码登录
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '' WITH GRANT OPTION; FLUSH PRIVILEGES; EXIT;
看到下图,说明设置成功,此时你的数据库已经可以使用root空密码访问localhost:3307了。
输入exit,退出容器,返回本机的终端:
开启第二个容器
刚才启动的容器,使用了3307端口。那么如果我们还想再开一个3306端口,怎么操作呢?——重复一遍就可以了。
// 建立容器
docker run -id --name=mysql3306 -p 3306:3306 -e MYSQL\_ROOT\_PASSWORD=123456 mysql:5.7
// 进入容器
docker exec -it mysql3306 bash
// 进入mysql
mysql -uroot -p123456
// 允许root从任意位置登录
GRANT ALL PRIVILEGES ON \*.\* TO 'root'@'%' IDENTIFIED BY '' WITH GRANT OPTION; FLUSH PRIVILEGES; EXIT;
一通操作之后,我们就获得了两个Mysql,除了端口,其他一模一样。
扩展
以后就可以通过自己的需求,动态的启动不同端口的Mysql了。
比如,示例代码中,可以使用docker start mysql3306启动3306的Mysql,通过docker start mysql3307启动3307的Mysql。
不用的时候,就可以docker stop mysql3307把它关掉,非常灵活。
总结
Docker是个好东西!