ぴねろぐ

日常や趣味、プログラミングについて書いていきたい

SQL ServerをM1 MacのDockerで動かしたい

お久しぶりです。ぱいんです。

今日はタイトルの通り、SQL ServerをM1 Macで動かすためにやったあれこれを書き連ねていきたいと思います。

背景

以前はIntel Macを使ってSQL Serverのコンテナを立てて開発をしていました。ですが弊社の支給PCがM1 Macになったことで、今まで動かしていたSQL Serverが動かなくなってしまいました。そこで何とかM1 MacSQL Serverを使うために色々試してみました。

SQL Serverが動かない

以下の公式の手順に沿って、SQL ServerをDockerで動かしてみます。

Docker:SQL Server on Linux 用のコンテナーのインストール - SQL Server | Microsoft Docs

手順通りにdocker pullと、docker runしてコンテナを表示してみると、コンテナが落ちてしまっています。

$ docker ps -a
CONTAINER ID   IMAGE                                        COMMAND                  CREATED         STATUS                     PORTS     NAMES
4150476cb784   mcr.microsoft.com/mssql/server:2019-latest   "/opt/mssql/bin/perm…"   5 seconds ago   Exited (1) 4 seconds ago             sql1

これだけだと原因がわからないので、ログを表示してみます。

❯ docker logs 4150476cb784
SQL Server 2019 will run as non-root by default.
This container is running as user mssql.
To learn more visit https://go.microsoft.com/fwlink/?linkid=2099216.
/opt/mssql/bin/sqlservr: Invalid mapping of address 0x4003816000 in reserved address space below 0x400000000000. Possible causes:
1) the process (itself, or via a wrapper) starts-up its own running environment sets the stack size limit to unlimited via syscall setrlimit(2);
2) the process (itself, or via a wrapper) adjusts its own execution domain and flag the system its legacy personality via syscall personality(2);
3) sysadmin deliberately sets the system to run on legacy VA layout mode by adjusting a sysctl knob vm.legacy_va_layout.

エラー文で検索してみると、同様の事例がissueとして上がっていました。 https://github.com/microsoft/mssql-docker/issues/668

issueによると、現状M1 MacSQL Serverのコンテナを動かすことは出来ないようです。 しかし、同じMicrosoftが提供するAzure SQL Edgeのimageを使ってSQL Serverを動かしている人がいるようなので試してみます。

Azure SQL Edgeを使ってSQL Serverを動かす

以下のimageを使って、Azure SQL Edgeを動かしてみます。 https://hub.docker.com/_/microsoft-azure-sql-edge

なお、Azure SQL EdgeにはARM用のimageと、x86(AMD64)用のimageが存在しています。 両方のimageが存在している場合に普通にpullすると、実行している環境に対応したimageがpullされます。 自分の場合はM1Macを使用しているため、ARM用imageがpullされます。

❯ docker pull mcr.microsoft.com/azure-sql-edge:latest
latest: Pulling from azure-sql-edge
Digest: sha256:7c203ad8b240ef3bff81ca9794f31936c9b864cc165dd187c23c5bfe06cf0340
Status: Downloaded newer image for mcr.microsoft.com/azure-sql-edge:latest
mcr.microsoft.com/azure-sql-edge:latest

❯ docker image inspect mcr.microsoft.com/azure-sql-edge
[
    {
...
        "Architecture": "arm64",
        "Variant": "v8",
        "Os": "linux",
        "Size": 1831484943,
        "VirtualSize": 1831484943,
...
    }
]

docker image inspectで確認してみると、 "Architecture"で"arm64"が選択されています。

M1 MacでARM用イメージではなく、x86用イメージを使いたい場合は--platform linux/x86_64オプションで明示的に指定する必要があります。

❯ docker pull --platform linux/x86_64 mcr.microsoft.com/azure-sql-edge:latest
latest: Pulling from azure-sql-edge
Digest: sha256:7c203ad8b240ef3bff81ca9794f31936c9b864cc165dd187c23c5bfe06cf0340
Status: Downloaded newer image for mcr.microsoft.com/azure-sql-edge:latest
mcr.microsoft.com/azure-sql-edge:latest

❯ docker image inspect mcr.microsoft.com/azure-sql-edge
[
    {
...
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 1133716277,
        "VirtualSize": 1133716277,
...
    }
]

"Architecture"で"arm64"ではなく"amd64"になっています。

まずはx86用のイメージで動かしてみます。

❯ docker run --cap-add SYS_PTRACE -e 'ACCEPT_EULA=1' -e 'MSSQL_SA_PASSWORD='passw0rd' -p 1433:1433 --name azuresqledge -d mcr.microsoft.com/azure-sql-edge:latest
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
88dcadd90e3d139f3079dd075a8216e1dc0a98f91612a9d51e874cbf8a4e82cf

❯ docker ps -a
CONTAINER ID   IMAGE                              COMMAND                  CREATED         STATUS                     PORTS     NAMES
88dcadd90e3d   mcr.microsoft.com/azure-sql-edge   "/opt/mssql/bin/perm…"   3 seconds ago   Exited (1) 2 seconds ago             azuresqledge

こちらだとコンテナが落ちてしまいます。logを見てみるとmssqlと同じエラーが出ています。

❯ docker logs 88dcadd90e3d
Azure SQL Edge will run as non-root by default.
This container is running as user mssql.
To learn more visit https://go.microsoft.com/fwlink/?linkid=2140520.
/opt/mssql/bin/sqlservr: Invalid mapping of address 0x40092f5000 in reserved address space below 0x400000000000. Possible causes:
1) the process (itself, or via a wrapper) starts-up its own running environment sets the stack size limit to unlimited via syscall setrlimit(2);
2) the process (itself, or via a wrapper) adjusts its own execution domain and flag the system its legacy personality via syscall personality(2);
3) sysadmin deliberately sets the system to run on legacy VA layout mode by adjusting a sysctl knob vm.legacy_va_layout.

次に、ARM用イメージで動かしてみます。 image名は事前にdocker tagを使って変更しています。

❯ docker run --cap-add SYS_PTRACE -e 'ACCEPT_EULA=1' -e 'MSSQL_SA_PASSWORD=passw0rd' -p 1433:1433 --name azuresqledge -d mcr.microsoft.com/azure-sql-edge:latest
066e3272b85227f6f29e1a2083f2794e2e3faca41ef07600aa2275c98513d5cb
❯ docker ps -a
CONTAINER ID   IMAGE                COMMAND                  CREATED         STATUS         PORTS                              NAMES
066e3272b852   azure-sql-edge-arm   "/opt/mssql/bin/perm…"   3 seconds ago   Up 2 seconds   1401/tcp, 0.0.0.0:1433->1433/tcp   azuresqledge

こちらのイメージは正常に動いてそうです。 M1 MacSQL Serverが動くことが確認できました。

注意点

sqlcmdが無い

ARM用imageだとsqlcmdが入ってないので別途sqlcmdを動かす方法を考える必要があります。

[!NOTE] sqlcmd tool is not available inside the ARM64 version of SQL Edge containers. https://hub.docker.com/_/microsoft-azure-sql-edge

azure-sql-edgeの関連リポジトリとしてmssql-toolsがあります。 このmssql-toolsにsqlcmdが入っているので、sqlcmdを使って初期化用SQLを流したいといった場合には、azure-sql-edgeでSQL Server用コンテナを立て、mssql-toolsで別途コンテナを立てて別コンテナからsqlcmdでSQLを流すという方法を取る必要があります。

Azure SQL Edgeでサポートされていない機能がある

Azure SQL Edgeのイメージで一応SQL Serverを動かせることができますが、元のmssqlイメージとは別物であるため、サポートされていない機能もあります。 詳しくは下記のドキュメントにサポートされていない機能についての記述があります。

Azure SQL Edge でサポートされる機能 | Microsoft Docs

まとめ

とりあえずM1でSQL Serverを動かしてみただけなので、業務などで使う場合には本当にこのAzure SQL Edgeで大丈夫なのかというのは確認が必要だと思います。 mssqlイメージがM1対応してくれると嬉しいんですけどね。

https://hub.docker.com/_/microsoft-mssql-server

M1が出てから結構な期間が経って、様々なライブラリやツールがM1に対応してきていますが、中には未だに対応していないものもあるため遭遇した際には中々辛いものがあります。。。