Docker 安装与 SQL Server 容器实例

前言

本系列所有关于 Docker 的笔记仅针对 Docker Desktop for Windows 实践。

下载并安装 Docker Desktop for Windows。根据官网提供的信息,Docker Desktop for Windows 仅能在 Windows 10 专业版或企业版上运行,实践表明,教育版 Win10 也能支持,理论上家庭版也能使用,因为新的 Docker 可以使用 WSL 2 引擎,而 WSL 2 支持 Win10 家庭版。有成功运行的同学可以文末留言。

Get Started with Docker | Docker
Docker Desktop for Windows user manual | Docker Documentation

Docker 是一个沙盒性的容器应用引擎,我们将应用程序以及相关的依赖环境打包到容器中,后续就可以简洁快速地进行镜像移植,只要能运行 Docker 的系统就能拉取我们打包的镜像,从而创建容器,而我们的应用程序则运行在该容器中。Docker 就是一个虚拟机,我们打包好的容器是一个虚拟机实例,做到了一次部署处处运行,而与传统的虚拟机相比,Docker 采用了操作系统内核共享机制,显然更省资源。

对我来说,Docker 可以减少在不同机器上部署同一个应用的机械重复工作量,不用每次都要手动安装复杂的环境依赖,即实现了安装运维的自动化。比如对于部分需要使用 SQL Server 的项目,每次在客户机器上从头安装 SQL Server 都是一个繁琐的过程,使用 Docker 则只要几个命令就能安装成功。有的项目也可以 push 到 Docker hub 仓库中,为客户部署时 pull 到本地安装即可。这就是我接触 Docker 的初衷。慢学 Docker 系列将记录这个过程的零碎笔记。

更快的 WSL 2 引擎

WSL 2(Windows Subsystem for Linux 2)是适用于 Linux 的 Windows 子系统,是在 Windows 上的轻量级虚拟机上运行的完整 Linux 内核,从此我们就可以在 Win10 上快速运行 Linux 命令和工具啦。

Docker for Windows 支持基于 WSL 2 或 Hyper -V 的引擎。基于 WSL 2 的 Docker 可以直接利用 Linux 工作区,无须额外维护 Windows 构建脚本,其动态内存分配功能也能够改善资源分配问题,表现在如果你勾选了 WSL 2 引擎,就不用手动为 Docker 分配 CPU 和内存了,Docker 将仅仅使用所需的最优 CPU 和内存资源。

安装好的 Docker 要想使用基于 WSL 2 的引擎而非基于 Hyper-V 的引擎,则要求 Windows 安装 WSL 2 Linux 内核,若未安装会在 Docker 启动时会提醒,根据提示安装即可。

Win10 上安装完 WSL 2 后建议为 Docker 启用基于 WSL 2 的引擎,即勾选 “Settings-General-Use the WSL 2 based engine” 选项。Docker 安装完一般是默认勾选的,可以自己确认一下。

勾选了 WSL 2 系统会自动为 Docker 分配 CPU 内存,而且 Windows 会与容器共享所有文件。同时 Docker 拉取安装的镜像将由 WSL 2 管理,如果需要迁移镜像位置或备份镜像数据,需要通过 wsl 命令进行。

如果勾选 WSL 2 后 Docker 启动失败,可以到 Windows 控制面板的 “启用或关闭 Windows 功能” 中关闭 Hyper-V 功能后重启 Docker。关于该问题可以参考:

System.InvalidOperationException: Failed to deploy distro docker-desktop · Issue #6640 · docker/for-win

先列出已安装的 WSL 发行版及其版本。

可以看到 Docker 为我们安装了 docker-desktop 和 docker-desktop-data 两个发行版,版本是 2,即 WSL 2,其中我们关注的是 docker-desktop-data 发行版,是用于运行 docker images 即镜像,同时存储镜像数据。该发行版默认将数据(运行数据与镜像文件)存储于 C 盘,位置为%LOCALAPPDATA%/Docker/wsl/data/ext4.vhdx,随着镜像数据增加,将占据更多 C 盘空间,这点需要额外注意。如果空间不足,可以迁移位置,迁移命令的搜索关键词为 “wsl –export docker-desktop-data”,可自行查找。

对 WSL 2 CPU 或内存自动分配有疑问或需要手动分配,可以查阅管理 Linux 分发版 | Microsoft Docs

更换镜像源

国内网络用户安装完 Docker 后建议更换下镜像源的地址,否则拉取镜像的速度可能会慢得令人发指。

镜像加速地址

截至目前(2020-10)可用性较高的是 阿里云容器镜像加速 和 DaoCloud 的 Docker 镜像站 。阿里云需要登录后才能获取镜像加速地址,不想注册的可以使用我的地址:https://7mvpvz9f.mirror.aliyuncs.com。DaoCloud 直接访问镜像站获取地址即可。个人使用下来感觉阿里云的加速效果更胜一筹。

配置镜像加速

在系统右下角右键 Docker 菜单,选择 Settings,在设置中选择 Docker Engine 配置项,在编辑窗口中填写加速地址:

{
  "registry-mirrors": ["https://7mvpvz9f.mirror.aliyuncs.com"]
}

编辑完成后点击 Apply & Restart,等待 Docker 重启后新的镜像地址即可生效。

Docker 在 Win10 上有 Linux containers 和 Windows containers 两种运行模式,二者取其一,在其中一种模式上安装的镜像无法在另一个模式中使用,除非有特殊需求,否则为获得最佳的文件系统性能,一般使用 Linux containers 模式。

实例-Docker 部署 SQL Server 镜像

本节将通过创建一个 SQL Server 容器,演示 Docker 部署一个镜像的常用操作。

拉取 SQL Server 镜像

SQL Server 只有 2017 及以上版本支持以容器运行

以下命令拉取最新版本的 SQL Server 镜像:

docker pull mcr.microsoft.com/mssql/server

也可以拉取特定版本的镜像:

  • 2017-latest
    docker pull mcr.microsoft.com/mssql/server:2017-latest
  • 2019-latest
    docker pull mcr.microsoft.com/mssql/server:2019-latest

创建 SQL Server 容器

建议通过命令行运行 SQL Server 镜像,从而创建一个容器,通过 Docker for Windows 客户端运行镜像创建 sqlserver 容器的功能有 bug,会导致创建的容器运行不起来。

docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=844e#6a3d73" \
   -p 1433:1433 --name la-sqlserver -h sqlserver \
   --env LC_ALL=C.UTF-8 \
   -d mcr.microsoft.com/mssql/server

这里的命令基于我们前面拉取的 mcr.microsoft.com/mssql/server 镜像创建一个名为 la-sqlserver 的 SQLServer 容器。其中 –env 参数为容器指定系统编码,这样才支持 Unicode 显示。

运行的同时必须设置 sa 密码,否则 SQL Server 无法成功启动。要求的密码策略为:长度至少 8 位,必须同时包含字母、数字和特殊符号。

下表对前一个 docker run  示例中的参数进行说明:

参数说明
-e “ACCEPT_EULA=Y”将 ACCEPT_EULA  变量设置为任意值,以确认接受最终用户许可协议。 SQL Server 映像的必需设置。
-e “SA_PASSWORD=<YourStrong@Passw0rd\>”指定 SQL Server 的 sa 密码
-p 1433:1433将主机环境中的 TCP 端口(第一个值)映射到容器中的 TCP 端口(第二个值)。  在此示例中,SQL Server 侦听容器中的 TCP 1433,并对主机上的端口 1433 公开。
–name sqlserver为容器指定一个自定义名称,而不是使用随机生成的名称。  如果运行多个容器,则无法重复使用相同的名称。
-h sqlserver用于显式设置容器主机名,如果不指定它,则默认为容器 ID,该 ID 是随机生成的系统 GUID。
mcr.microsoft.com/mssql/server指定 SQL Server 镜像。

运行命令无报错后通过 docker ps -a 可以列出已经运行的容器。

连接到 SQL Server

更多关于 SQL Server 容器连接参考 Microsoft Docs:部署并连接到 SQL Server Docker 容器 – SQL Server | Microsoft Docs

成功创建运行容器后可以在 Docker 客户端查看容器状态。

这里我使用 SSMS 工具从容器外连接 SQL Server,连接成功后就可以按照 SQL Server 的普通操作对容器 SQL Server 进行操作。

附加 SQL Server 数据库文件

由于启用了 WSL 2,我们可以直接把数据库文件从 Windows 主机复制到容器内,之后就可以执行附加命令。

1、将文件复制到容器中

命令格式为:docker cp <Host path> <Container Name/ID>:<Container path>,其中容器 name 或容器 ID 可以通过 docker ps --no-trunc 命令查询得到,注意查询容器 ID 的话不要使用 docker ps -a 命令,该命令查询显示的容器 ID 不是完整的。

将宿主机 E:\program_data\mssql\data 下的 lahotel.mdf 文件和 lahotel.ldf 文件复制到容器内的/var/opt/mssql/data 目录下,在宿主机执行命令如下:

docker cp /E/program_data/mssql/data/lahotel.mdf la-sqlserver:/var/opt/mssql/data
docker cp /E/program_data/mssql/data/lahotel.ldf la-sqlserver:/var/opt/mssql/data

命令中的 la-sqlserver 是我们前面创建的 SQL Server 容器的名字,可以通过 docker ps -a 命令查询到。

2、执行复制命令后我们登陆到容器中查看是否有复制成功

在宿主机执行命令如下,以 root 身份登录容器:

winpty docker exec -ti --user root la-sqlserver bash

进入容器后执行命令查看目录下是否存在前面复制过来的文件

cd /var/opt/mssql/data
ls

注意以上是要进入容器内执行的命令。

3、为复制的文件授予写权限

文件复制到文件后只有读权限,在执行数据库附加命令时将报错,需要给.mdf 和.ldf 文件授予写权限。以 root 身份进入 la-sqlserver 容器(见步骤 2),执行以下命令:

chmod 777 /var/opt/mssql/data/lahotel.mdf
chmod 777 /var/opt/mssql/data/lahotel.ldf

4、附加数据库

使用 SSMS 连接容器中的 SQL Server,新建查询执行 SQL 命令,附加我们的 lahotel 数据库文件:

EXEC sp_attach_db @dbname = 'lahotel',
@filename1 = '/var/opt/mssql/data/lahotel.mdf',
@filename2 = '/var/opt/mssql/data/lahotel.ldf'

以上 4 个步骤的命令执行结果如下述 A、B 截图。

A、复制文件到容器内并授予写权限:

B、SQL Server 数据库附加结果:

5、从容器复制(备份)文件

对于容器内的数据库文件 mdf 来说,当容器删除之后数据也随之丢失,有时候需要手动备份数据到宿主机中,最原始的备份方法是从容器中将数据复制出来。

5.1 可以直接从容器内复制整个目录:

docker cp la-sqlserver:/var/opt/mssql/data /E/program_data/mssql/data/backup
docker cp la-sqlserver:/var/opt/mssql/data /E/program_data/mssql/data/backup

以上命令将 la-sqlserver 容器的/var/opt/mssql/data 目录复制到宿主机的 E:\program_data\mssql\data\backup 文件夹

5.2 也可以复制指定文件

docker cp la-sqlserver:/var/opt/mssql/data/lahotel.ldf /E/program_data/mssql/data/backup/
docker cp la-sqlserver:/var/opt/mssql/data/lahotel.mdf /E/program_data/mssql/data/backup/

以上命令将 la-sqlserver 容器内的 lahotel.mdf 和 lahotel.ldf 文件复制到宿主机的 backup 文件夹内。

话外:Docker 数据保留

在保留数据方面,除了手动复制备份外,Dcoker 推荐的方法是使用数据卷绑定挂载(bind mount)或数据卷容器(Volume)的方案。前者是在主机上将目录作为容器中的数据卷装载,后者是使用一个容器共享的数据卷,指定容器的某个目录数据持久化到数据卷中,且数据卷的内容独立于容器的声明周期之外,除非手动删除卷。这样就可以在不同容器间共享数据卷,在新容器指定数据卷,从而达到数据持久化。

关于两种数据管理方法的区别:

1、bing mount 方法更为简单,设置后将在主机上的 Docker 的存储目录中创建一个新目录,并且由 Docker 管理该目录的内容,但是其依赖于具有特定目录结构可用的主机文件系统,在不同宿主机(相同系统)或不同系统之间兼容性较低。/2、

2、Volume 方法更为灵活,兼容性最高,也是 Docker 首先推荐的方法。相比 bind mount 方法,数据备份或迁移更方便,可以在不同容器之间共享数据,删除容器后卷的数据仍然留存。

更多的 Docker 数据管理参考以下文档:

配置和自定义 SQL Server Docker 容器 – SQL Server | Microsoft Docs

Use volumes | Docker Documentation

暂无评论

发送评论 编辑评论


				
上一篇
下一篇