如何使Mac Docker支持SQL on Linux容器Volume特性

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 这篇文章解决了Docker容器中SQL on Linux实例数据库与容器本身同生死同命运的问题,提出了当Docker容器销毁后,容器中的数据库文件得以保留的方法。

问题引入

这天老鸟火急火燎的找到菜鸟:“鸟儿啊,按照你之前的文章SQL on Linux Run on Docker,当我销毁SQL on Linux Docker容器以后,我容器中的所有数据库数据丢失啦,怎么办,怎么办啊?”。
菜鸟一脸懵逼:“我是参照微软官方文档来的啊?难道这帮XX连这个问题都没有想到?”。于是,菜鸟开始了问题的重现和解决方法。

问题重现

按照上一篇文件启动的Docker容器,SQL on Linux实例中的数据库文件真的会随着Docker容器的销毁而消失,造成数据丢失的灾难吗?这一节进行问题重现和复盘。

启动Docker容器

使用Docker Run命令启动SQL on Linux服务,映射到母体机41433端口上。

$ docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=SQLOnLinux@123' -p 41433:1433 -d microsoft/mssql-server-linux

创建测试对象

使用SSMS连接到Docker母体机41433端口上,执行下面的测试代码:创建测试数据库、创建测试表、初始化两条数据和查询测试表。

IF DB_ID('TestDb') IS NULL
    CREATE DATABASE TestDb;
GO

USE TestDb
GO
IF OBJECT_ID('dbo.Test', 'U') IS NOT NULL
    DROP TABLE dbo.Test
GO

CREATE TABLE dbo.Test(
RowID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY
,Name VARCHAR(20) NOT NULL
);

INSERT INTO dbo.Test
SELECT 'A' UNION ALL SELECT 'B';

SELECT * FROM dbo.Test;

结果如下图展示:
01.png

销毁Docker容器

接下来模拟Docker容器销毁过程:我们需要使用Docker Stop停止SQL on Linux容器,然后使用Docker rm删除这个容器,接下来再次启动Docker容器,最后检查测试数据库、测试表和数据是否存在。如果不存在,说明Docker容器中的数据已经丢失。

$ docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                     NAMES
8c1202ff7a33        microsoft/mssql-server-linux   "/bin/sh -c /opt/m..."   2 minutes ago       Up 2 minutes        0.0.0.0:41433->1433/tcp   suspicious_liskov
...
$ docker stop 8c1202ff7a33
8c1202ff7a33
$ docker rm 8c1202ff7a33
8c1202ff7a33
$ docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=SQLOnLinux@123' -p 41433:1433 -d microsoft/mssql-server-linux
83cd4ca5cdf3d370118c10d8b783b204f86aa7b50fd7e334a27542d2cf7a1230

检查测试对象

再次使用SSMS连接到Docker母体机41433端口,查看测试数据库,展示如下图:
02.png

从这个结果来看,测试数据库已经丢失。说明Docker容器与容器中的数据库是命运共同体、同生死共命运。如果Docker容器销毁,容器中的数据库数据也随之丢失。这个是用户数据的灾难,我们需要迫切解决这个问题。看来老鸟说的大实话啊。

解决问题

SQL on Linux对Mac Docker Volume的限制

要解决这个问题,我们需要引入Docker的Volume技术。简单的说,这个技术的核心思想就是在启动Docker容器的时候,将Docker容器中的目录映射到母体机的目录,Docker容器对这个目录的所有操作会反映到母体机的这个映射目录里面。当Docker容器销毁的时候,母体机的这个映射目录会被保留下来。这样,我们的数据库数据文件不会随着容器的销毁而消失了,继而就解决了这个问题。但是,偏偏目前SQL on Linux不支持Mac操作系统的Docker Volume特性。详情参见微软官方文档:Run the SQL Server Docker image on Linux, Mac, or Windows
关键的地方,截图如下展示:
03.png
Mac系统Docker就真的不支持SQL on Linux Docker容器的Volume吗?让我们来试试看:

$ docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=SQLOnLinux@123' -p 41433:1433 -v /Users/cherish/Downloads/linuxsqldata:/var/opt/mssql -it microsoft/mssql-server-linux
Configuring Microsoft(R) SQL Server(R)...
Microsoft(R) SQL Server(R) setup failed with error code 1. Please check the setup log in /var/opt/mssql/log for more information.

的确启动Docker容器的过程中就会报告错误,详细的错误日志信息如下:

$ cat ~/Downloads/linuxsqldata/log/errorlog
2017-02-09 13:20:06.62 Server      Microsoft SQL Server vNext (CTP1.2) - 14.0.200.24 (X64) 
    Jan 10 2017 19:15:28 
    Copyright (C) 2016 Microsoft Corporation. All rights reserved.
    on Linux (Ubuntu 16.04.1 LTS)
2017-02-09 13:20:06.76 Server      UTC adjustment: 0:00
2017-02-09 13:20:06.80 Server      (c) Microsoft Corporation.
2017-02-09 13:20:06.84 Server      All rights reserved.
2017-02-09 13:20:06.88 Server      Server process ID is 4116.
2017-02-09 13:20:06.92 Server      Logging SQL Server messages in file 'C:\var\opt\mssql\log\errorlog'.
2017-02-09 13:20:06.98 Server      Registry startup parameters: 
     -d C:\var\opt\mssql\data\master.mdf
     -l C:\var\opt\mssql\data\mastlog.ldf
     -e C:\var\opt\mssql\log\errorlog
2017-02-09 13:20:07.09 Server      Command Line Startup Parameters:
     --setup
     --sa-password
2017-02-09 13:20:07.58 Server      Error: 17113, Severity: 16, State: 1.
2017-02-09 13:20:07.58 Server      Error 87(The parameter is incorrect.) occurred while opening file 'C:\var\opt\mssql\data\master.mdf' to obtain configuration information at startup. An invalid startup option might have caused the error. Verify your startup options, and correct or remove them if necessary.

解决方案

巴嘎,这里就又引入了另外一个问题,如何解决Mac系统上SQL on Linux的Docker容器不支持Volume的问题?不要惊慌,淡定,当然是有办法的,这个解决方法便是这篇文章存在的意义。解决方法如下:

$ docker create -v /var/opt/mssql --name sql41433data microsoft/mssql-server-linux
2e1deac3c2bffa5f6cd97dfdc3683c59628538550ea9010d16214906c299cf54

$ docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=SQLOnLinux@123' -p 41433:1433 --volumes-from sql41433data -it --name linuxsql41433 microsoft/mssql-server-linux

大概30秒后,Docker容器中的SQL实例服务起来以后,首先,参照问题重现中创建测试对象,然后销毁Docker容器,接下来再次启动Docker容器。

$ docker ps 
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                     NAMES
596f3bfebb8a        microsoft/mssql-server-linux   "/bin/sh -c /opt/m..."   57 seconds ago      Up 56 seconds       0.0.0.0:41433->1433/tcp   linuxsql41433
...
$ docker stop 596f3bfebb8a
596f3bfebb8a
$ docker rm 596f3bfebb8a
596f3bfebb8a
$ docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=SQLOnLinux@123' -p 41433:1433 --volumes-from sql41433data -it --name linuxsql41433 microsoft/mssql-server-linux

最后检查测试对象,截图如下:
04.png
其实,从启动过程的日志,我们也可以看到TestDb已经启动。
05.png
说明这个解决方法切实有效。

最后总结

这篇文章解决了Docker容器中SQL on Linux实例数据库与容器本身同生死同命运的问题,使得用户数据在容器被销毁时得以保留。更加详细的过程和步骤,可以参看youku视频:
11_SQLOnLinux_MacDockerVolumes

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
21天前
|
Docker 容器
进入Docker容器中
进入Docker容器中
34 2
|
1月前
|
Java Go 开发者
Docker容器技术简介及其与Go语言的结合点
【2月更文挑战第23天】本文首先概述了Docker容器技术的核心概念和优势,接着探讨了Go语言与Docker容器技术的结合点。通过阐述Docker的轻量级、可移植性和版本控制等特性,以及Go语言在容器化应用中的优势,本文旨在说明两者结合能够实现更高效、灵活的应用开发和部署。
|
1月前
|
Oracle 关系型数据库 数据库
|
1天前
|
存储 运维 监控
构建高效稳定的Docker容器监控体系
【4月更文挑战第18天】 在现代微服务架构中,Docker容器已成为部署和运行应用的标准环境。随之而来的挑战是如何有效监控这些容器的性能与健康状况,确保系统的稳定性和可靠性。本文将探讨构建一个高效稳定的Docker容器监控体系的关键技术和方法,包括日志管理、性能指标收集以及异常检测机制,旨在为运维人员提供实用的指导和建议。
6 0
|
10天前
|
Linux Docker 容器
docker 容器常用命令
docker 容器常用命令
12 0
|
10天前
|
Linux Shell 虚拟化
linux 部署docker容器虚拟化平台(二)--------docker 镜像制作方法
linux 部署docker容器虚拟化平台(二)--------docker 镜像制作方法
14 0
|
10天前
|
存储 Linux Shell
centos 部署docker容器 安装 、基本使用方法(一)
centos 部署docker容器 安装 、基本使用方法(一)
19 0
|
18天前
|
Kubernetes 网络协议 Docker
Docker 容器的DNS
Docker 容器的DNS
23 1
|
21天前
|
关系型数据库 MySQL Nacos
【深入浅出Nacos原理及调优】「实战开发专题」采用Docker容器进行部署和搭建Nacos服务以及“坑点”
【深入浅出Nacos原理及调优】「实战开发专题」采用Docker容器进行部署和搭建Nacos服务以及“坑点”
45 1
|
22天前
|
NoSQL 关系型数据库 MySQL
安装Docker&镜像容器操作&使用Docker安装部署MySQL,Redis,RabbitMQ,Nacos,Seata,Minio
安装Docker&镜像容器操作&使用Docker安装部署MySQL,Redis,RabbitMQ,Nacos,Seata,Minio
99 1