前几天,我软发布跨平台的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
出现如下页面就好了:
数据持久化测试
先用ubuntu测试。可以先将ubuntu镜像下载(没加版本参数会下载最新版):
sudo docker pull ubuntu
Tips
国内可能下载速度很慢,可以通过镜像加速,方法是:
打开DaoCloud网站注册一个账户并登陆:
进入个人主页后可以看到右上角有个加速器的火箭图标:
点击图标,得到一个脚本,将国内镜像加入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):
进入家目录,并生成一个文件:
cd
touch test001
退出容器:
exit
运行如下命令检查系统的容器列表:
sudo docker ps
可以看到输出是空的:
因为这个容器没有任何后台进程,所以退出容器后,容器就结束了。
现在加上-a参数:
sudo docker ps -a
可以看到之前运行的容器出现了,状态是退出:
重新启动此容器并附着到此容器:
sudo docker start docker01
sudo docker attach docker01
运行后进入家目录检查生成的文件:
现在生成一个容器docker02,然后去检查家目录的文件:
可以发现找不到新生成的文件。
发生这个问题的原因是由于镜像是只读的,通过镜像生成的容器里的写操作只在容器里起作用,用镜像生成的新容器不受影响,如下图:
如果容器的数据有持久化要求,启动时加载已有数据,就要通过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
检查文件系统挂载情况:
可以看到/mnt/temp下被挂载了一个新分区,大小即主机/mnt所在分区的大小。
到此目录创建一个文件:
坑爹的事情发生了,没有权限。经过修改主机、容器内的宿主、权限都不能解决此问题,后来在万能的google帮助下才发现是docker启动时启动了selinux,找到原因就简单了,修改/etc/sysconfig/docker文件:
删除高亮部分并重启docker服务即可。
删除并重新运行docker03,再进入/mnt/temp下,可正常生成文件,并且在主机的/mnt目录下也可看到新生成的文件:
SQL on Docker的数据持久化#
SQL on Docker的配置使用
今天还在网上看到有人问如何将SQL Server安装到容器里,其实我软早已做好,直接使用即可。
先查找在docker.io的官方SQL Server 镜像:
可以看到第一个就是官方版的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的容器:
现在用ssms去连接SQL(不要忘了打开nsg的对应端口):
可见,顺利登陆。
检查数据库属性的文件,可以发现文件位置位于容器的/var/opt/mssql目录:
所以如果要将容器的数据库持久化,需要将此目录持久化,即映射到主机的目录里。
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
可以看到sql02正常启动,并且在主机对应目录生成了数据库文件。
登录到sql02并创建一个新数据库demodb:
现在关闭sql02,创建sql03,并将~/mssql目录mount到sql03:
现在通过ssms登录sql03:
可以看到sql02创建的demodb也出现了,说明数据文件的持久化成功。
另外,在运行sql03时,没有通过-e参数指定sa的密码,因为sa的密码记录在数据库里,数据文件持久化后,密码保持不变。
以上就是简单的SQL on Docker数据文件持久化测试。相信随着SQL的发展,SQL on Docker会功能越来越完善。