SQL,到容器里来

前几天,我软发布跨平台的SQL2017的消息刷屏了朋友圈。各位吃瓜群众纷纷发来贺电的同时,也提出了不少疑问,其中很重要一点就是如何实现SQL在容器里的数据持久化?今天就来聊聊这个问题。

容器数据持久化

环境准备

测试环境使用Azure上的CentOS7.3,安装完成首先升级所有软件到最新版:

sudo yum update

然后安装docker:

sudo yum install docker* -y

设置开机启动docker,并启动docker:

sudo systemctl enable docker

sudo systemctl start docker

然后检查docker运行状态:

sudo docker info

出现如下页面就好了:

mark

数据持久化测试

先用ubuntu测试。可以先将ubuntu镜像下载(没加版本参数会下载最新版):

sudo docker pull ubuntu


Tips

​ 国内可能下载速度很慢,可以通过镜像加速,方法是:

  • 打开DaoCloud网站注册一个账户并登陆:

    DaoCloud

  • 进入个人主页后可以看到右上角有个加速器的火箭图标:

    mark

  • 点击图标,得到一个脚本,将国内镜像加入docker配置的json脚本

    curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://416d59dc.m.daocloud.io

  • 重启docker服务生效:

    sudo systemctl restart docker


镜像下载完成,运行基于此镜像的第一个容器:

sudo docker run --name docker01 -i -t ubuntu /bin/bash


解释一下几个参数:

​ 1、run:运行一个容器

​ 2、–name:给运行的容器取个名字(如果忽略,会随机给出一个)

3、-i:启用标准stdin

​ 4、-t:启用一个伪tty终端(才能登陆进去)

​ 5、ubuntu:运行容器的基础镜像,如果本地没有,直接从仓库里拉一个

​ 6、/bin/bash:进入容器tty后的sh


现在就进入了运行的容器(一个极小化的ubuntu):

mark

进入家目录,并生成一个文件:

cd

touch test001

退出容器:

exit

运行如下命令检查系统的容器列表:

sudo docker ps

可以看到输出是空的:

mark

因为这个容器没有任何后台进程,所以退出容器后,容器就结束了。

现在加上-a参数:

sudo docker ps -a

可以看到之前运行的容器出现了,状态是退出:

mark

重新启动此容器并附着到此容器:

sudo docker start docker01

sudo docker attach docker01

运行后进入家目录检查生成的文件:

mark

现在生成一个容器docker02,然后去检查家目录的文件:

mark

可以发现找不到新生成的文件。

发生这个问题的原因是由于镜像是只读的,通过镜像生成的容器里的写操作只在容器里起作用,用镜像生成的新容器不受影响,如下图:

mark

如果容器的数据有持久化要求,启动时加载已有数据,就要通过Data Volume来解决。

Data Volume有Bind Mount(将host指定目录映射到容器)和Docker Managed Volume(Docker自行管理目录两种方式),各有用途。这里讨论一下Bind Mount方式。

Blind Mount很简单,只需运行容器时加上如下参数:

-v HostDir:DockerDir

现在将主机的/mnt目录映射到新容器docker03的/mnt/temp目录下:

sudo docker run --name docker03 -i -t -v /mnt:/mnt/temp ubuntu /bin/bash

检查文件系统挂载情况:

mark

可以看到/mnt/temp下被挂载了一个新分区,大小即主机/mnt所在分区的大小。

到此目录创建一个文件:

mark

坑爹的事情发生了,没有权限。经过修改主机、容器内的宿主、权限都不能解决此问题,后来在万能的google帮助下才发现是docker启动时启动了selinux,找到原因就简单了,修改/etc/sysconfig/docker文件:

mark

删除高亮部分并重启docker服务即可。

删除并重新运行docker03,再进入/mnt/temp下,可正常生成文件,并且在主机的/mnt目录下也可看到新生成的文件:

mark

SQL on Docker的数据持久化

SQL on Docker的配置使用

今天还在网上看到有人问如何将SQL Server安装到容器里,其实我软早已做好,直接使用即可。

先查找在docker.io的官方SQL Server 镜像:

mark

可以看到第一个就是官方版的mssql-linux的容器镜像。先拉回本地:

sudo docker pull microsoft/mssql-server-linux

SQL on Docker的运行很简单:

sudo docker run -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=<YourStrong!Passw0rd>' -p 1401:1433 --name sql01 -d microsoft/mssql-server-linux

和之前比,不同之处在

​ -e参数传递环境变量(这里包含同意许可和SA密码设置)

​ -p端口映射(将主机的1401映射到sql的监听端口1433,可根据实际情况选择主机端口)

​ -d说明作为守护进程运行

运行后tty停留在主机,检查状态,多出一个sql01的容器:

mark

现在用ssms去连接SQL(不要忘了打开nsg的对应端口):

mark

mark

可见,顺利登陆。

检查数据库属性的文件,可以发现文件位置位于容器的/var/opt/mssql目录:

mark

所以如果要将容器的数据库持久化,需要将此目录持久化,即映射到主机的目录里。

SQL on Docker数据持久化

接下来就简单了,运行一个容器sql02,并将主机的新建目录~/mssql映射给容器(注意不要端口冲突):

sudo docker run -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=<YourStrong!Passw0rd>' -p 1402:1433 -v ~/mssql:/var/opt/mssql --name sql02 -d microsoft/mssql-server-linux

mark

可以看到sql02正常启动,并且在主机对应目录生成了数据库文件。

登录到sql02并创建一个新数据库demodb:

mark

现在关闭sql02,创建sql03,并将~/mssql目录mount到sql03:

mark

现在通过ssms登录sql03:

mark

可以看到sql02创建的demodb也出现了,说明数据文件的持久化成功。

另外,在运行sql03时,没有通过-e参数指定sa的密码,因为sa的密码记录在数据库里,数据文件持久化后,密码保持不变。

以上就是简单的SQL on Docker数据文件持久化测试。相信随着SQL的发展,SQL on Docker会功能越来越完善。