tech.guitarrapc.cóm

Technical updates

SQL Server Docker Image のCU12以降でDBがクラッシュする件

SQL Serverは Dockerで動かせるので、いちいちSQL Server をインストールせずともローカル開発をスムーズに回すことができます。

hub.docker.com

そんな SQL Server on Docker ですが、macOS ではホストのDBファイルをボリュームマウントができない制約があります。

Mounting a volume does not work on Docker for Mac

一方で、Windows ではホストのDBファイルをボリュームマウントできるため永続化させたいときとかに便利です。

さて、今回の記事はWindows環境でホストのDBをコンテナでマウントするとクラッシュする件が起こっていることについてです。

目次

TL;DR

CU12*1 以降でホストのDBファイルをボリュームマウントで渡していると、SQL Serverがクラッシュします。

latest でも発生しており、ホストのDBをボリュームマウントする場合は、CU11 に落とすのが暫定対処になりそう。

Issue

CU 12 で問題は発覚しました。

github.com

CU13以降、現在の latest では、このCU13 のクラッシュログが確認できます。

github.com

再現してみよう

とりあえず手元で再現すれば逃げ道も見つかります。試しましょう。

2017-latest (2017-latest-ubuntu)

現在の最新イメージでホストのボリュームをマウントしない場合は、SQL Server が起動できていることがわかります。

docker run -it -e ACCEPT_EULA=Y mcr.microsoft.com/mssql/server:2017-latest

ログを開く

2019-04-26 03:07:27.52 Server      Setup step is copying system data file 'C:\templatedata\master.mdf' to '/var/opt/mssql/data/master.mdf'.
2019-04-26 03:07:27.56 Server      Did not find an existing master data file /var/opt/mssql/data/master.mdf, copying the missing default master and other system database files. If you have moved the database location, but not moved the database files, startup may fail. To repair: shutdown SQL Server, move the master database to configured location, and restart.
2019-04-26 03:07:27.56 Server      Setup step is copying system data file 'C:\templatedata\mastlog.ldf' to '/var/opt/mssql/data/mastlog.ldf'.
2019-04-26 03:07:27.57 Server      Setup step is copying system data file 'C:\templatedata\model.mdf' to '/var/opt/mssql/data/model.mdf'.
2019-04-26 03:07:27.58 Server      Setup step is copying system data file 'C:\templatedata\modellog.ldf' to '/var/opt/mssql/data/modellog.ldf'.
2019-04-26 03:07:27.59 Server      Setup step is copying system data file 'C:\templatedata\msdbdata.mdf' to '/var/opt/mssql/data/msdbdata.mdf'.
2019-04-26 03:07:27.61 Server      Setup step is copying system data file 'C:\templatedata\msdblog.ldf' to '/var/opt/mssql/data/msdblog.ldf'.
2019-04-26 03:07:27.68 Server      Microsoft SQL Server 2017 (RTM-CU14) (KB4484710) - 14.0.3076.1 (X64)
        Mar 12 2019 19:29:19
        Copyright (C) 2017 Microsoft Corporation
        Developer Edition (64-bit) on Linux (Ubuntu 16.04.6 LTS)
2019-04-26 03:07:27.68 Server      UTC adjustment: 0:00
2019-04-26 03:07:27.68 Server      (c) Microsoft Corporation.
2019-04-26 03:07:27.68 Server      All rights reserved.
2019-04-26 03:07:27.68 Server      Server process ID is 28.
2019-04-26 03:07:27.69 Server      Logging SQL Server messages in file '/var/opt/mssql/log/errorlog'.
2019-04-26 03:07:27.69 Server      Registry startup parameters:
         -d /var/opt/mssql/data/master.mdf
         -l /var/opt/mssql/data/mastlog.ldf
         -e /var/opt/mssql/log/errorlog
2019-04-26 03:07:27.69 Server      SQL Server detected 1 sockets with 1 cores per socket and 2 logical processors per socket, 2 total logical processors; using 2 logical processors based on SQL Server licensing. This is an informational message; no user action is required.
2019-04-26 03:07:27.69 Server      SQL Server is starting at normal priority base (=7). This is an informational message only. No user action is required.
2019-04-26 03:07:27.70 Server      Detected 1584 MB of RAM. This is an informational message; no user action is required.
2019-04-26 03:07:27.70 Server      Using conventional memory in the memory manager.
2019-04-26 03:07:27.84 Server      Buffer pool extension is already disabled. No action is necessary.
2019-04-26 03:07:27.94 Server      InitializeExternalUserGroupSid failed. Implied authentication will be disabled.
2019-04-26 03:07:27.94 Server      Implied authentication manager initialization failed. Implied authentication will be disabled.
2019-04-26 03:07:27.94 Server      Successfully initialized the TLS configuration. Allowed TLS protocol versions are ['1.0 1.1 1.2']. Allowed TLS ciphers are ['ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:!DHE-RSA-AES256-GCM-SHA384:!DHE-RSA-AES128-GCM-SHA256:!DHE-RSA-AES256-SHA:!DHE-RSA-AES128-SHA'].
2019-04-26 03:07:27.98 Server      The maximum number of dedicated administrator connections for this instance is '1'
2019-04-26 03:07:27.98 Server      Node configuration: node 0: CPU mask: 0x0000000000000003:0 Active CPU mask: 0x0000000000000003:0. This message provides a description of the NUMA configuration for this computer. This is an
informational message only. No user action is required.
2019-04-26 03:07:27.99 Server      Using dynamic lock allocation.  Initial allocation of 2500 Lock blocks and 5000 Lock Owner blocks per node.  This is an informational message only.  No user action is required.
2019-04-26 03:07:27.99 Server      In-Memory OLTP initialized on lowend machine.
2019-04-26 03:07:28.02 Server      Database Instant File Initialization: enabled. For security and performance considerations see the topic 'Database Instant File Initialization' in SQL Server Books Online. This is an informational message only. No user action is required.
ForceFlush is enabled for this instance.
2019-04-26 03:07:28.03 Server      Query Store settings initialized with enabled = 1,
2019-04-26 03:07:28.03 Server      Software Usage Metrics is disabled.
2019-04-26 03:07:28.04 spid6s      Starting up database 'master'.
ForceFlush feature is enabled for log durability.
2019-04-26 03:07:28.16 spid6s      The tail of the log for database master is being rewritten to match the new sector size of 4096 bytes.  3072 bytes at offset 418816 in file /var/opt/mssql/data/mastlog.ldf will be written.
2019-04-26 03:07:28.27 spid6s      Converting database 'master' from version 862 to the current version 869.
2019-04-26 03:07:28.27 spid6s      Database 'master' running the upgrade step from version 862 to version 863.
2019-04-26 03:07:28.30 spid6s      Database 'master' running the upgrade step from version 863 to version 864.
2019-04-26 03:07:28.33 spid6s      Database 'master' running the upgrade step from version 864 to version 865.
2019-04-26 03:07:28.35 spid6s      Database 'master' running the upgrade step from version 865 to version 866.
2019-04-26 03:07:28.36 spid6s      Database 'master' running the upgrade step from version 866 to version 867.
2019-04-26 03:07:28.37 spid6s      Database 'master' running the upgrade step from version 867 to version 868.
2019-04-26 03:07:28.38 spid6s      Database 'master' running the upgrade step from version 868 to version 869.
2019-04-26 03:07:28.47 Server      Failed to verify the Authenticode signature of 'C:\binn\secforwarder.dll'. Signature verification of SQL Server DLLs will be skipped. Genuine copies of SQL Server are signed. Failure to verify the Authenticode signature might indicate that this is not an authentic release of SQL Server. Install a genuine copy of SQL Server or contact customer support.
2019-04-26 03:07:28.58 spid6s      Resource governor reconfiguration succeeded.
2019-04-26 03:07:28.58 spid6s      SQL Server Audit is starting the audits. This is an informational message. No user action is required.
2019-04-26 03:07:28.59 spid6s      SQL Server Audit has started the audits. This is an informational message. No user action is required.
2019-04-26 03:07:28.62 spid6s      SQL Trace ID 1 was started by login "sa".
2019-04-26 03:07:28.64 spid6s      Server name is '4200ec551fc5'. This is an informational message only. No user action is required.
2019-04-26 03:07:28.65 spid19s     Password policy update was successful.
2019-04-26 03:07:28.66 spid22s     Always On: The availability replica manager is starting. This is an informational message only. No user action is required.
2019-04-26 03:07:28.66 spid6s      Starting up database 'msdb'.
2019-04-26 03:07:28.67 spid22s     Always On: The availability replica manager is waiting for the instance of SQL Server to allow client connections. This is an informational message only. No user action is required.
2019-04-26 03:07:28.67 spid11s     Starting up database 'mssqlsystemresource'.
2019-04-26 03:07:28.67 spid11s     The resource database build version is 14.00.3076. This is an informational message only. No user action is required.
2019-04-26 03:07:28.70 spid11s     Starting up database 'model'.
2019-04-26 03:07:28.85 spid19s     A self-generated certificate was successfully loaded for encryption.
2019-04-26 03:07:28.86 spid19s     Server is listening on [ 'any' <ipv6> 1433].
2019-04-26 03:07:28.86 spid19s     Server is listening on [ 'any' <ipv4> 1433].
2019-04-26 03:07:28.86 spid11s     The tail of the log for database model is being rewritten to match the new sector size of 4096 bytes.  2048 bytes at offset 75776 in file /var/opt/mssql/data/modellog.ldf will be written.
2019-04-26 03:07:28.87 Server      Server is listening on [ ::1 <ipv6> 1434].
2019-04-26 03:07:28.87 Server      Server is listening on [ 127.0.0.1 <ipv4> 1434].
2019-04-26 03:07:28.87 Server      Dedicated admin connection support was established for listening locally on port 1434.
2019-04-26 03:07:28.87 spid19s     SQL Server is now ready for client connections. This is an informational message; no user action is required.
2019-04-26 03:07:28.87 spid6s      The tail of the log for database msdb is being rewritten to match the new sector size of 4096 bytes.  512 bytes at offset 306688 in file /var/opt/mssql/data/MSDBLog.ldf will be written.
2019-04-26 03:07:28.99 spid11s     Converting database 'model' from version 862 to the current version 869.
2019-04-26 03:07:28.99 spid11s     Database 'model' running the upgrade step from version 862 to version 863.
2019-04-26 03:07:29.00 spid6s      Converting database 'msdb' from version 862 to the current version 869.
2019-04-26 03:07:29.00 spid6s      Database 'msdb' running the upgrade step from version 862 to version 863.
2019-04-26 03:07:29.06 spid11s     Database 'model' running the upgrade step from version 863 to version 864.
2019-04-26 03:07:29.10 spid6s      Database 'msdb' running the upgrade step from version 863 to version 864.
2019-04-26 03:07:29.10 spid11s     Database 'model' running the upgrade step from version 864 to version 865.
2019-04-26 03:07:29.12 spid11s     Database 'model' running the upgrade step from version 865 to version 866.
2019-04-26 03:07:29.12 spid6s      Database 'msdb' running the upgrade step from version 864 to version 865.
2019-04-26 03:07:29.13 spid11s     Database 'model' running the upgrade step from version 866 to version 867.
2019-04-26 03:07:29.13 spid6s      Database 'msdb' running the upgrade step from version 865 to version 866.
2019-04-26 03:07:29.14 spid11s     Database 'model' running the upgrade step from version 867 to version 868.
2019-04-26 03:07:29.15 spid6s      Database 'msdb' running the upgrade step from version 866 to version 867.
2019-04-26 03:07:29.16 spid6s      Database 'msdb' running the upgrade step from version 867 to version 868.
2019-04-26 03:07:29.16 spid11s     Database 'model' running the upgrade step from version 868 to version 869.
2019-04-26 03:07:29.17 spid6s      Database 'msdb' running the upgrade step from version 868 to version 869.
2019-04-26 03:07:29.29 spid11s     Polybase feature disabled.
2019-04-26 03:07:29.29 spid11s     Clearing tempdb database.
2019-04-26 03:07:29.63 spid11s     Starting up database 'tempdb'.
2019-04-26 03:07:29.82 spid11s     The tempdb database has 1 data file(s).
2019-04-26 03:07:29.83 spid22s     The Service Broker endpoint is in disabled or stopped state.
2019-04-26 03:07:29.83 spid22s     The Database Mirroring endpoint is in disabled or stopped state.
2019-04-26 03:07:29.84 spid22s     Service Broker manager has started.
2019-04-26 03:07:29.96 spid6s      Recovery is complete. This is an informational message only. No user action is required.
2019-04-26 03:07:29.98 spid24s     The default language (LCID 0) has been set for engine and full-text services.
2019-04-26 03:07:33.03 spid35s     The activated proc '[dbo].[sp_syspolicy_events_reader]' running on queue 'msdb.dbo.syspolicy_event_queue' output the following:  'Transaction (Process ID 35) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction

では、適当にフォルダを掘ってからDBフォルダにマウントしましょう。

mkdir c:\db
docker run -it -e ACCEPT_EULA=Y -v C:\db:/var/opt/mssql mcr.microsoft.com/mssql/server:2017-latest-ubuntu

見事にクラッシュしています。

This program has encountered a fatal error and cannot continue running at Fri Apr 26 03:14:04 2019
The following diagnostic information is available:

       Reason: 0x00000006
       Status: 0x40000015
      Message: Kernel bug check
      Address: 0x6a844180
   Parameters: 0x10861f680
   Stacktrace: 000000006a92fc73 000000006a8441db 000000006a831422
               000000006a83fe62 000000006a92e08a 000000006a92cb8d
               000000006a96c0d2 000000006acac000 000000006ac38000
               000000006ac40000 0000000000000001
      Process: 7 - sqlservr
       Thread: 11 (application thread 0x4)
  Instance Id: 72388ba8-dd88-4469-b1fe-c4794d04ff54
     Crash Id: 3593f479-5b4f-4ef6-ad74-b70a3bda2756
  Build stamp: b2ce95e3a6684060d1d3bb1264841a1a8fc1d501ed6d1cfdb89cfcdde8048253
 Distribution: Ubuntu 16.04.6 LTS
   Processors: 2
 Total Memory: 2076528640 bytes
    Timestamp: Fri Apr 26 03:14:04 2019

Ubuntu 16.04.6 LTS
Capturing core dump and information to /var/opt/mssql/log...
dmesg: read kernel buffer failed: Operation not permitted
No journal files were found.
No journal files were found.
Attempting to capture a dump with paldumper
WARNING: Capture attempt failure detected
Attempting to capture a filtered dump with paldumper
WARNING: Attempt to capture dump failed.  Reference /var/opt/mssql/log/core.sqlservr.7.temp/log/paldumper-debug.log for details
Attempting to capture a dump with gdb
WARNING: Unable to capture crash dump with GDB. You may need to
allow ptrace debugging, enable the CAP_SYS_PTRACE capability, or
run as root.

クラッシュログ置いておきます。

crash.txt

This program has encountered a fatal error and cannot continue running at Fri Apr 26 03:40:08 2019
The following diagnostic information is available:

       Reason: 0x00000006
       Status: 0x40000015
      Message: Kernel bug check
      Address: 0x6c244180
   Parameters: 0x10861f680
   Stacktrace: 000000006c32fc73 000000006c2441db 000000006c231422 
               000000006c23fe62 000000006c32e08a 000000006c32cb8d 
               000000006c36c0d2 000000006c6ac000 000000006c638000 
               000000006c640000 0000000000000001 
      Process: 7 - sqlservr
       Thread: 11 (application thread 0x4)
  Instance Id: e467da02-a594-4124-93cb-c8eb2415c65a
     Crash Id: e751eea3-120c-448b-92c5-dc0b370c783d
  Build stamp: b2ce95e3a6684060d1d3bb1264841a1a8fc1d501ed6d1cfdb89cfcdde8048253
 Distribution: Ubuntu 16.04.6 LTS
   Processors: 2
 Total Memory: 2076528640 bytes
    Timestamp: Fri Apr 26 03:40:08 2019

crash.json

{
    "reason": "0x00000006",
    "processName": "sqlservr",
    "pid": "7",
    "instanceId": "e467da02-a594-4124-93cb-c8eb2415c65a",
    "crashId": "e751eea3-120c-448b-92c5-dc0b370c783d",
    "threadId": "11",
    "libosThreadId": "0x4",
    "buildStamp": "b2ce95e3a6684060d1d3bb1264841a1a8fc1d501ed6d1cfdb89cfcdde8048253",
    "status": "0x40000015",
    "message": "Kernel bug check",
    "address": "0x6c244180",
    "parameters": [
        {
            "value": "0x41"
        },
        {
            "value": "0xffffffffc0000034"
        },
        {
            "value": "0x5"
        },
        {
            "value": "0x0"
        },
        {
            "value": "0x0"
        }
    ],
    "libosStack": [
        "0x000000006c32fc73",
        "0x000000006c2441db",
        "0x000000006c231422",
        "0x000000006c23fe62",
        "0x000000006c32e08a",
        "0x000000006c32cb8d",
        "0x000000006c36c0d2",
        "0x000000006c6ac000",
        "0x000000006c638000",
        "0x000000006c640000",
        "0x0000000000000001"
    ],
    "last_errno": "2",
    "last_errno_text": "No such file or directory",
    "distribution": "Ubuntu 16.04.6 LTS",
    "processors": "2",
    "total_memory": "2076528640",
    "timestamp": "Fri Apr 26 03:40:08 2019"
}

No such file or directory.....

2017-CU11-ubuntu

CU11 まで落とすとマウントできています。

mkdir c:\db
docker run -it -e ACCEPT_EULA=Y -v C:\db:/var/opt/mssql mcr.microsoft.com/mssql/server:2017-CU11-ubuntu

ログを開く

2019-04-26 03:18:07.29 Server      Setup step is copying system data file 'C:\templatedata\master.mdf' to '/var/opt/mssql/data/master.mdf'.
2019-04-26 03:18:08.13 Server      Did not find an existing master data file /var/opt/mssql/data/master.mdf, copying the missing default master and other system database files. If you have moved the database location, but not moved the database files, startup may fail. To repair: shutdown SQL Server, move the master database to configured location, and restart.
2019-04-26 03:18:08.15 Server      Setup step is copying system data file 'C:\templatedata\mastlog.ldf' to '/var/opt/mssql/data/mastlog.ldf'.
2019-04-26 03:18:08.19 Server      Setup step is copying system data file 'C:\templatedata\model.mdf' to '/var/opt/mssql/data/model.mdf'.
2019-04-26 03:18:08.34 Server      Setup step is copying system data file 'C:\templatedata\modellog.ldf' to '/var/opt/mssql/data/modellog.ldf'.
2019-04-26 03:18:08.49 Server      Setup step is copying system data file 'C:\templatedata\msdbdata.mdf' to '/var/opt/mssql/data/msdbdata.mdf'.
2019-04-26 03:18:08.69 Server      Setup step is copying system data file 'C:\templatedata\msdblog.ldf' to '/var/opt/mssql/data/msdblog.ldf'.
2019-04-26 03:18:09.69 Server      Microsoft SQL Server 2017 (RTM-CU11) (KB4462262) - 14.0.3038.14 (X64)
        Sep 14 2018 13:53:44
        Copyright (C) 2017 Microsoft Corporation
        Developer Edition (64-bit) on Linux (Ubuntu 16.04.5 LTS)
2019-04-26 03:18:09.70 Server      UTC adjustment: 0:00
2019-04-26 03:18:09.70 Server      (c) Microsoft Corporation.
2019-04-26 03:18:09.70 Server      All rights reserved.
2019-04-26 03:18:09.70 Server      Server process ID is 4120.
2019-04-26 03:18:09.70 Server      Logging SQL Server messages in file '/var/opt/mssql/log/errorlog'.
2019-04-26 03:18:09.70 Server      Registry startup parameters:
         -d /var/opt/mssql/data/master.mdf
         -l /var/opt/mssql/data/mastlog.ldf
         -e /var/opt/mssql/log/errorlog
2019-04-26 03:18:09.72 Server      SQL Server detected 1 sockets with 1 cores per socket and 2 logical processors per socket, 2 total logical processors; using 2 logical processors based on SQL Server licensing. This is an informational message; no user action is required.
2019-04-26 03:18:09.72 Server      SQL Server is starting at normal priority base (=7). This is an informational message only. No user action is required.
2019-04-26 03:18:09.72 Server      Detected 1584 MB of RAM. This is an informational message; no user action is required.
2019-04-26 03:18:09.72 Server      Using conventional memory in the memory manager.
2019-04-26 03:18:12.56 Server      Buffer pool extension is already disabled. No action is necessary.
2019-04-26 03:18:13.80 Server      InitializeExternalUserGroupSid failed. Implied authentication will be disabled.
2019-04-26 03:18:13.80 Server      Implied authentication manager initialization failed. Implied authentication will be disabled.
2019-04-26 03:18:13.81 Server      Successfully initialized the TLS configuration. Allowed TLS protocol versions are ['1.0 1.1 1.2']. Allowed TLS ciphers are ['ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:!DHE-RSA-AES256-GCM-SHA384:!DHE-RSA-AES128-GCM-SHA256:!DHE-RSA-AES256-SHA:!DHE-RSA-AES128-SHA'].
2019-04-26 03:18:13.98 Server      Node configuration: node 0: CPU mask: 0x0000000000000003:0 Active CPU mask: 0x0000000000000003:0. This message provides a description of the NUMA configuration for this computer. This is an
informational message only. No user action is required.
2019-04-26 03:18:13.99 Server      The maximum number of dedicated administrator connections for this instance is '1'
2019-04-26 03:18:13.99 Server      Using dynamic lock allocation.  Initial allocation of 2500 Lock blocks and 5000 Lock Owner blocks per node.  This is an informational message only.  No user action is required.
2019-04-26 03:18:13.99 Server      In-Memory OLTP initialized on lowend machine.
2019-04-26 03:18:14.24 Server      Database Instant File Initialization: enabled. For security and performance considerations see the topic 'Database Instant File Initialization' in SQL Server Books Online. This is an informational message only. No user action is required.
ForceFlush is enabled for this instance.
2019-04-26 03:18:14.24 Server      Query Store settings initialized with enabled = 1,
2019-04-26 03:18:14.25 spid6s      Starting up database 'master'.
2019-04-26 03:18:14.28 Server      Software Usage Metrics is disabled.
ForceFlush feature is enabled for log durability.
2019-04-26 03:18:15.76 spid6s      The tail of the log for database master is being rewritten to match the new sector size of 4096 bytes.  3072 bytes at offset 418816 in file /var/opt/mssql/data/mastlog.ldf will be written.
2019-04-26 03:18:16.63 spid6s      Converting database 'master' from version 862 to the current version 869.
2019-04-26 03:18:16.63 spid6s      Database 'master' running the upgrade step from version 862 to version 863.
2019-04-26 03:18:16.65 spid6s      Database 'master' running the upgrade step from version 863 to version 864.
2019-04-26 03:18:16.82 spid6s      Database 'master' running the upgrade step from version 864 to version 865.
2019-04-26 03:18:16.84 spid6s      Database 'master' running the upgrade step from version 865 to version 866.
2019-04-26 03:18:16.85 spid6s      Database 'master' running the upgrade step from version 866 to version 867.
2019-04-26 03:18:16.85 spid6s      Database 'master' running the upgrade step from version 867 to version 868.
2019-04-26 03:18:16.87 spid6s      Database 'master' running the upgrade step from version 868 to version 869.
2019-04-26 03:18:18.14 spid6s      Resource governor reconfiguration succeeded.
2019-04-26 03:18:18.14 spid6s      SQL Server Audit is starting the audits. This is an informational message. No user action is required.
2019-04-26 03:18:18.14 spid6s      SQL Server Audit has started the audits. This is an informational message. No user action is required.
2019-04-26 03:18:18.47 spid6s      SQL Trace ID 1 was started by login "sa".
2019-04-26 03:18:18.48 spid18s     Password policy update was successful.
2019-04-26 03:18:18.49 spid6s      Server name is 'f16aca2a7c35'. This is an informational message only. No user action is required.
2019-04-26 03:18:18.49 spid21s     Always On: The availability replica manager is starting. This is an informational message only. No user action is required.
2019-04-26 03:18:18.50 spid21s     Always On: The availability replica manager is waiting for the instance of SQL Server to allow client connections. This is an informational message only. No user action is required.
2019-04-26 03:18:18.50 spid8s      Starting up database 'mssqlsystemresource'.
2019-04-26 03:18:18.50 spid6s      Starting up database 'msdb'.
2019-04-26 03:18:18.51 spid8s      The resource database build version is 14.00.3038. This is an informational message only. No user action is required.
2019-04-26 03:18:18.53 spid8s      Starting up database 'model'.
2019-04-26 03:18:20.73 spid6s      The tail of the log for database msdb is being rewritten to match the new sector size of 4096 bytes.  512 bytes at offset 306688 in file /var/opt/mssql/data/MSDBLog.ldf will be written.
2019-04-26 03:18:20.77 spid6s      Converting database 'msdb' from version 862 to the current version 869.
2019-04-26 03:18:20.77 spid6s      Database 'msdb' running the upgrade step from version 862 to version 863.
2019-04-26 03:18:20.78 spid8s      The tail of the log for database model is being rewritten to match the new sector size of 4096 bytes.  2048 bytes at offset 75776 in file /var/opt/mssql/data/modellog.ldf will be written.
2019-04-26 03:18:20.81 spid8s      Converting database 'model' from version 862 to the current version 869.
2019-04-26 03:18:20.81 spid8s      Database 'model' running the upgrade step from version 862 to version 863.
2019-04-26 03:18:20.82 spid6s      Database 'msdb' running the upgrade step from version 863 to version 864.
2019-04-26 03:18:20.84 spid8s      Database 'model' running the upgrade step from version 863 to version 864.
2019-04-26 03:18:20.84 spid6s      Database 'msdb' running the upgrade step from version 864 to version 865.
2019-04-26 03:18:20.86 spid6s      Database 'msdb' running the upgrade step from version 865 to version 866.
2019-04-26 03:18:20.86 spid8s      Database 'model' running the upgrade step from version 864 to version 865.
2019-04-26 03:18:20.87 spid6s      Database 'msdb' running the upgrade step from version 866 to version 867.
2019-04-26 03:18:20.87 spid8s      Database 'model' running the upgrade step from version 865 to version 866.
2019-04-26 03:18:20.88 spid8s      Database 'model' running the upgrade step from version 866 to version 867.
2019-04-26 03:18:20.88 spid6s      Database 'msdb' running the upgrade step from version 867 to version 868.
2019-04-26 03:18:20.90 spid8s      Database 'model' running the upgrade step from version 867 to version 868.
2019-04-26 03:18:20.90 spid6s      Database 'msdb' running the upgrade step from version 868 to version 869.
2019-04-26 03:18:20.92 spid8s      Database 'model' running the upgrade step from version 868 to version 869.
2019-04-26 03:18:21.05 spid8s      Polybase feature disabled.
2019-04-26 03:18:21.05 spid8s      Clearing tempdb database.
2019-04-26 03:18:24.70 spid18s     A self-generated certificate was successfully loaded for encryption.
2019-04-26 03:18:24.73 spid18s     Server is listening on [ 'any' <ipv4> 1433].
2019-04-26 03:18:24.74 Server      Server is listening on [ 127.0.0.1 <ipv4> 1434].
2019-04-26 03:18:24.74 Server      Dedicated admin connection support was established for listening locally on port 1434.
2019-04-26 03:18:24.75 spid18s     SQL Server is now ready for client connections. This is an informational message; no user action is required.
2019-04-26 03:18:25.93 spid8s      Starting up database 'tempdb'.
2019-04-26 03:18:27.55 spid8s      The tempdb database has 1 data file(s).
2019-04-26 03:18:27.55 spid21s     The Service Broker endpoint is in disabled or stopped state.
2019-04-26 03:18:27.56 spid21s     The Database Mirroring endpoint is in disabled or stopped state.
2019-04-26 03:18:27.57 spid21s     Service Broker manager has started.
2019-04-26 03:18:27.68 spid6s      Recovery is complete. This is an informational message only. No user action is required.
2019-04-26 03:18:33.21 spid10s     The default language (LCID 0) has been set for engine and full-text services.

対処方法

CU11 まで落とすと、問題は発生しません。 Microsoftの反応がないので、どうするのか悩ましいですがいったんCU11 で固定しておくとよさそうです。

余談

自分でDockerfile 書いてSQL Server (Linux) をインストールして利用という手もあります。

が、試しに CU12 のイメージをもとにDockerfile を書くと面白いログが出ています。(CU12+ からapt-get で sql-server を入れてないため)

The following additional packages will be installed:

mssql-server

gist.github.com

どんな対応がいいのかしらの反応が待ち遠しいですね。

エラーログ

おいておきます。

2019-04-26 03:18:09.69 Server      Microsoft SQL Server 2017 (RTM-CU11) (KB4462262) - 14.0.3038.14 (X64) 
    Sep 14 2018 13:53:44 
    Copyright (C) 2017 Microsoft Corporation
    Developer Edition (64-bit) on Linux (Ubuntu 16.04.5 LTS)
2019-04-26 03:18:09.70 Server      UTC adjustment: 0:00
2019-04-26 03:18:09.70 Server      (c) Microsoft Corporation.
2019-04-26 03:18:09.70 Server      All rights reserved.
2019-04-26 03:18:09.70 Server      Server process ID is 4120.
2019-04-26 03:18:09.70 Server      Logging SQL Server messages in file '/var/opt/mssql/log/errorlog'.
2019-04-26 03:18:09.70 Server      Registry startup parameters: 
     -d /var/opt/mssql/data/master.mdf
     -l /var/opt/mssql/data/mastlog.ldf
     -e /var/opt/mssql/log/errorlog
2019-04-26 03:18:09.72 Server      SQL Server detected 1 sockets with 1 cores per socket and 2 logical processors per socket, 2 total logical processors; using 2 logical processors based on SQL Server licensing. This is an informational message; no user action is required.
2019-04-26 03:18:09.72 Server      SQL Server is starting at normal priority base (=7). This is an informational message only. No user action is required.
2019-04-26 03:18:09.72 Server      Detected 1584 MB of RAM. This is an informational message; no user action is required.
2019-04-26 03:18:09.72 Server      Using conventional memory in the memory manager.
2019-04-26 03:18:12.56 Server      Buffer pool extension is already disabled. No action is necessary. 
2019-04-26 03:18:13.80 Server      InitializeExternalUserGroupSid failed. Implied authentication will be disabled.
2019-04-26 03:18:13.80 Server      Implied authentication manager initialization failed. Implied authentication will be disabled.
2019-04-26 03:18:13.81 Server      Successfully initialized the TLS configuration. Allowed TLS protocol versions are ['1.0 1.1 1.2']. Allowed TLS ciphers are ['ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:!DHE-RSA-AES256-GCM-SHA384:!DHE-RSA-AES128-GCM-SHA256:!DHE-RSA-AES256-SHA:!DHE-RSA-AES128-SHA'].
2019-04-26 03:18:13.98 Server      Node configuration: node 0: CPU mask: 0x0000000000000003:0 Active CPU mask: 0x0000000000000003:0. This message provides a description of the NUMA configuration for this computer. This is an informational message only. No user action is required.
2019-04-26 03:18:13.99 Server      The maximum number of dedicated administrator connections for this instance is '1'
2019-04-26 03:18:13.99 Server      Using dynamic lock allocation.  Initial allocation of 2500 Lock blocks and 5000 Lock Owner blocks per node.  This is an informational message only.  No user action is required.
2019-04-26 03:18:13.99 Server      In-Memory OLTP initialized on lowend machine.
2019-04-26 03:18:14.24 Server      Database Instant File Initialization: enabled. For security and performance considerations see the topic 'Database Instant File Initialization' in SQL Server Books Online. This is an informational message only. No user action is required.
2019-04-26 03:18:14.25 spid6s      Starting up database 'master'.
2019-04-26 03:18:14.24 Server      Query Store settings initialized with enabled = 1, 
2019-04-26 03:18:14.28 Server      Software Usage Metrics is disabled.
2019-04-26 03:18:15.76 spid6s      The tail of the log for database master is being rewritten to match the new sector size of 4096 bytes.  3072 bytes at offset 418816 in file /var/opt/mssql/data/mastlog.ldf will be written.
2019-04-26 03:18:16.63 spid6s      Converting database 'master' from version 862 to the current version 869.
2019-04-26 03:18:16.63 spid6s      Database 'master' running the upgrade step from version 862 to version 863.
2019-04-26 03:18:16.65 spid6s      Database 'master' running the upgrade step from version 863 to version 864.
2019-04-26 03:18:16.82 spid6s      Database 'master' running the upgrade step from version 864 to version 865.
2019-04-26 03:18:16.84 spid6s      Database 'master' running the upgrade step from version 865 to version 866.
2019-04-26 03:18:16.85 spid6s      Database 'master' running the upgrade step from version 866 to version 867.
2019-04-26 03:18:16.85 spid6s      Database 'master' running the upgrade step from version 867 to version 868.
2019-04-26 03:18:16.87 spid6s      Database 'master' running the upgrade step from version 868 to version 869.
2019-04-26 03:18:18.14 spid6s      Resource governor reconfiguration succeeded.
2019-04-26 03:18:18.14 spid6s      SQL Server Audit is starting the audits. This is an informational message. No user action is required.
2019-04-26 03:18:18.14 spid6s      SQL Server Audit has started the audits. This is an informational message. No user action is required.
2019-04-26 03:18:18.47 spid6s      SQL Trace ID 1 was started by login "sa".
2019-04-26 03:18:18.48 spid18s     Password policy update was successful.
2019-04-26 03:18:18.49 spid6s      Server name is 'f16aca2a7c35'. This is an informational message only. No user action is required.
2019-04-26 03:18:18.49 spid21s     Always On: The availability replica manager is starting. This is an informational message only. No user action is required.
2019-04-26 03:18:18.50 spid21s     Always On: The availability replica manager is waiting for the instance of SQL Server to allow client connections. This is an informational message only. No user action is required.
2019-04-26 03:18:18.50 spid8s      Starting up database 'mssqlsystemresource'.
2019-04-26 03:18:18.50 spid6s      Starting up database 'msdb'.
2019-04-26 03:18:18.51 spid8s      The resource database build version is 14.00.3038. This is an informational message only. No user action is required.
2019-04-26 03:18:18.53 spid8s      Starting up database 'model'.
2019-04-26 03:18:20.73 spid6s      The tail of the log for database msdb is being rewritten to match the new sector size of 4096 bytes.  512 bytes at offset 306688 in file /var/opt/mssql/data/MSDBLog.ldf will be written.
2019-04-26 03:18:20.77 spid6s      Converting database 'msdb' from version 862 to the current version 869.
2019-04-26 03:18:20.77 spid6s      Database 'msdb' running the upgrade step from version 862 to version 863.
2019-04-26 03:18:20.78 spid8s      The tail of the log for database model is being rewritten to match the new sector size of 4096 bytes.  2048 bytes at offset 75776 in file /var/opt/mssql/data/modellog.ldf will be written.
2019-04-26 03:18:20.81 spid8s      Converting database 'model' from version 862 to the current version 869.
2019-04-26 03:18:20.81 spid8s      Database 'model' running the upgrade step from version 862 to version 863.
2019-04-26 03:18:20.82 spid6s      Database 'msdb' running the upgrade step from version 863 to version 864.
2019-04-26 03:18:20.84 spid8s      Database 'model' running the upgrade step from version 863 to version 864.
2019-04-26 03:18:20.84 spid6s      Database 'msdb' running the upgrade step from version 864 to version 865.
2019-04-26 03:18:20.86 spid6s      Database 'msdb' running the upgrade step from version 865 to version 866.
2019-04-26 03:18:20.86 spid8s      Database 'model' running the upgrade step from version 864 to version 865.
2019-04-26 03:18:20.87 spid6s      Database 'msdb' running the upgrade step from version 866 to version 867.
2019-04-26 03:18:20.87 spid8s      Database 'model' running the upgrade step from version 865 to version 866.
2019-04-26 03:18:20.88 spid8s      Database 'model' running the upgrade step from version 866 to version 867.
2019-04-26 03:18:20.88 spid6s      Database 'msdb' running the upgrade step from version 867 to version 868.
2019-04-26 03:18:20.90 spid8s      Database 'model' running the upgrade step from version 867 to version 868.
2019-04-26 03:18:20.90 spid6s      Database 'msdb' running the upgrade step from version 868 to version 869.
2019-04-26 03:18:20.92 spid8s      Database 'model' running the upgrade step from version 868 to version 869.
2019-04-26 03:18:21.05 spid8s      Polybase feature disabled.
2019-04-26 03:18:21.05 spid8s      Clearing tempdb database.
2019-04-26 03:18:24.70 spid18s     A self-generated certificate was successfully loaded for encryption.
2019-04-26 03:18:24.73 spid18s     Server is listening on [ 'any' <ipv4> 1433].
2019-04-26 03:18:24.74 Server      Server is listening on [ 127.0.0.1 <ipv4> 1434].
2019-04-26 03:18:24.74 Server      Dedicated admin connection support was established for listening locally on port 1434.
2019-04-26 03:18:24.75 spid18s     SQL Server is now ready for client connections. This is an informational message; no user action is required.
2019-04-26 03:18:25.93 spid8s      Starting up database 'tempdb'.
2019-04-26 03:18:27.55 spid8s      The tempdb database has 1 data file(s).
2019-04-26 03:18:27.55 spid21s     The Service Broker endpoint is in disabled or stopped state.
2019-04-26 03:18:27.56 spid21s     The Database Mirroring endpoint is in disabled or stopped state.
2019-04-26 03:18:27.57 spid21s     Service Broker manager has started.
2019-04-26 03:18:27.68 spid6s      Recovery is complete. This is an informational message only. No user action is required.
2019-04-26 03:18:33.21 spid10s     The default language (LCID 0) has been set for engine and full-text services.
2019-04-26 03:20:54.61 spid6s      Always On: The availability replica manager is going offline because SQL Server is shutting down. This is an informational message only. No user action is required.
2019-04-26 03:20:54.61 spid6s      SQL Server shutdown due to Ctrl-C or Ctrl-Break signal. This is an informational message only. No user action is required.
2019-04-26 03:20:54.61 spid6s      SQL Trace was stopped due to server shutdown. Trace ID = '1'. This is an informational message only; no user action is required.

*1:CU = Cumulative Update - a periodic release that includes bug fixes, security fixes, and occasionally a small feature.

.NET Core Global Tools のインストールとアップグレードを状態に応じて行う

.NET Core Global Tools は.NET Core SDKがインストールされている環境でdotnet系cliツールをlist/install/upgrade/uninstall を行う仕組みです。

docs.microsoft.com

この仕組みがでたことで、少なくとも dotnet core製のCLIツールの配布はnugetを経由することで統合的に行うことができるようになりました。 おおむねnpmと同様の感覚で使えるため、npmが入っておらず dotnet だけがはいった環境で便利です。

例えば、CI環境では.NET Coreビルド時に .NET Core SDK は入っているけどnpmはない、など特定のシーンで強力に機能します。 さて、今回はこのインストール、アップグレードに関してみてみましょう。

目次

インストールとアップグレードをまとめて行いたい

.NET Core Global Toolsは、インストールに dotnet tool install、アップグレードに dotnet tool upgrade とそれぞれ別のコマンドを用います。 dockerなど、環境が使い捨ての場合はこれで十分なのでシンプルさはとてもいいことです。

一方で、すでにツールxxxx がインストールされている環境で dotnet tool install --global xxxx を行うと exit code 1 が生じ、インストールされていない環境で dotnet tool upgrade xxxx を行うと exit code 1 が生じます。 つまり、ホスト環境など「すでにツールがインストールされている環境」に対してツールのインストールを保証するシーンではひと手間加える必要があります。

ではUnityBuildRunnerを例にサクッと書いてみましょう。

www.nuget.org

サンプルはリポジトリに置いておきます。

github.com

cmd (Windows環境)

もし bash が使えないgowなども利用できないWindows環境の場合、batで保証するように書いてみましょう。 よくあるコマンドの存在を確認して切り替えれば十分でしょう。

dotnet tool list -g | findstr unitybuildrunner 
if ('%errorlevel%' == '1') ( 
    dotnet tool install --global UnityBuildRunner --version 1.1.5 
) else ( 
    dotnet tool update --global UnityBuildRunner 
) 

bash

linux 環境では command を使って探したいところですが、dotnet 自体は成功してしまうので list から grep してお茶を濁します。

if dotnet tool list -g | grep unitybuildrunner; 
then 
    dotnet tool update --global UnityBuildRunner 
else 
    dotnet tool install --global UnityBuildRunner --version 1.1.5 
fi 

まとめ

dotnet コマンドで保証してくれてもいい気もしつつ、まぁ仕方ない。

Ref

解消するっぽい....? 未インストール状態で、dotnet tool update -g unitybuildrunner は今のところだめっぽい。

github.com

AzureDevOpsPipeline/Azure DevOps Pipeline で docker build と Azure Container Repository への push を行う

Azure Pipeline を使っているとタスクによせたくなるのですが、あんまりそういうのもアレなのでほどほどにというのはもうちょっと言われてもいい気がします。 Docker はその最たる例で コマンドで3行で済むようなものがDockerタスクを使うといたずらに時間を取られる傾向にあります。

今回は Azure DevOps Pipeline でDocker ビルドを行って、Azure Container Repository に push する流れを見てみましょう。 Azure DevOps Pipeline を使っていないなら、これでやるメリットはアカウント統合程度で特にない感じです。(アカウント統合も統合できていない感がつよい)

目次

[:contents:]

TL;DR

ビルドマシンは hosted が楽でよい。 docker build は、dockerタスクではなく docker コマンドでやるほうがいい docker push は、docker タスクを使って認証を透過的に行おう。

何をDockerで動かすの

ASP.NET Core 2.2 を対象にdockerで動かしてみましょう。 例えばAzure Container Instance で動かすのもいいのです。 しかし、container じゃなくてもAzure Web Apps for Linux にデプロイすれば たいがいはいいのでWebアプリのdocker展開はポータビリティをどこまで担保したいか、どう動かしたいかの相談なのでほどほどに。

Azure DevOps Pipeline の Docker タスク

Docker Module は、0 と 1と2があります。

0 を利用するのがおすすめです。

f:id:guitarrapc_tech:20190416104133p:plain
Docker タスク0.*

1 は妙な挙動をして不安定なためお勧めしません。

f:id:guitarrapc_tech:20190416104152p:plain
Dockerタスク 1.*

2 は、コンセプトが変わっててACRで使うならあんまりいらなさそう。というか、余計な手間が増えてて微妙。

f:id:guitarrapc_tech:20190416104215p:plain
Dockerタスク2.*

ローカルでの docker build

なにはともあれlocal で通しておきましょう。 これがCIで通るようにします。

適当にこんな構成とします。 ASPNETCOREにcsprojの名前を、YOUR_PROJECT_DIR にプロジェクトのフォルダ名を指定しておきます。

.
└ src
  └ YOUR_PROJECT_DIR 
      ├ Dockerfile
      └ ASPNETCORE.csproj

Dockerfileはこのような感じになるかと思います。

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
WORKDIR /src/YOUR_PROJECT_DIR
COPY ["YOUR_PROJECT_DIR/ASPNETCORE.csproj", "ASPNETCORE.csproj"]
RUN dotnet restore "ASPNETCORE.csproj"
WORKDIR /src
COPY . .
WORKDIR /src/YOUR_PROJECT_DIR
ARG conf="Debug"
RUN dotnet build "ASPNETCORE.csproj" -c $conf -o /app
RUN dotnet publish "ASPNETCORE.csproj" -c $conf -o /app

FROM base AS final
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "ASPNETCORE.dll"]

あとは実行時に ASPNETCORE_ENVIRONMENT を Development | Staging | Production で指定すれば挙動が切り替わるのでokですね。

docker build

特にWindows系のhosted|private agent がそうですが、build をする場合、Dockerタスクではなく docker コマンドをたたくほうが安定します。 dockerタスクで行おうとすると、docker build中にイメージが見つかったり見つからなかったり、COPYが実行できたりできなかったり構成を変えていないのに実行ごとに挙動が変わりました。(これでDockerfile や設定がおかしいかと思って試行錯誤で数時間消費した)

variables:
  BuildConfiguration: Debug
  DockerImageName: ASPNETCORE
  DockerFile: YOUR_PROJECT_DIR/Dockerfile

steps:
- bash: 'docker build -t youraspnetcoreregistry.azurecr.io/$(DockerImageName):$(Build.SourceVersion)_$(Build.BuildId) -t $(Registry).azurecr.io/$(DockerImageName):latest -f YOUR_PROJECT_DIR/Dockerfile .'
  displayName: 'docker build'

これでビルドが実行できます。 ACRに挙げるにあたって、ビルドごとにバージョンが一意に特定できる必要があるので、git hash + build id で毎ビルドで一意にしています。

docker push

push は簡単です。 local でいうところの、docker login しておいて docker push です。 ただし、CIでやるに伴ってレジストリのログインを認証情報を出さずに透過的に行いたいでしょう。

docker@0 タスク を使うと ACRへの認証情報を事前に解決しておけるので便利です。

先ほど docker build で指定した tag を指定してpush してあげましょう。 この時、ACRを対象にしている場合、ACRのアドレス "youraspnetcoreregistry.azurecr.io" 部分は自動的に解決されるため、tagで指定する必要がありません。docker build でyouraspnetcoreregistry.azurecr.io/$(DockerImageName):$(Build.SourceVersion)_$(Build.BuildId) と指定した場合、$(DockerImageName):$(Build.SourceVersion)_$(Build.BuildId) でokです。(.... なんと余計なことを)

- task: Docker@0
  displayName: 'Push an image'
  inputs:
    azureSubscription: YOUR_SUBSCRIPTION
    azureContainerRegistry: '{"loginServer":"youraspnetcoreregistry.azurecr.io", "id" : "/subscriptions/abcdefg-1234-abcd-56789ghijklmn/resourceGroups/AWESOME-RESOURCE/providers/Microsoft.ContainerRegistry/registries/youraspnetcoreregistry"}'
    action: 'Push an image'
    imageName: '$(DockerImageName):$(Build.SourceVersion)_$(Build.BuildId)'
    includeLatestTag: true

これで無事にdocker build -> push ができるでしょう。

CircleCI のOrb をPull Request を通じて学ぶ

エンジニア同士で話していると、CIどうしよう、今何がいいかなぁという話にたびたびなります。

CIサービスは複数ありますが、サーバーサイドビルドでSaaS 型CI なら CircleCI が今のところいいい感じです。(2.1を前提とする)

circleci.com

あるいはGitHub Actions もとてもいい感触です。 現状Beta で push イベント駆動なのでlintやビルドにはいい感じで利用できます。他のTagなどのイベントを利用できるようになるのが楽しみです。

github.com

今回は、CircleCI 2.1 で利用できる Orb についてPR送ることを通して学んでみます。

目次

TL;DR

PRを出したくて仕組みを理解していくと何かと捗るのでいいですよ。 実情は、適切に動かすためにコンセプトと仕様を理解することに徹するだけです。 モチベーションだいじ。

Orb とは

CircleCI 2.1 から利用できる機能で、JobsやCommand に定義していた処理を公開し、それを利用できる機能です。

circleci.com

利用方法はいたって簡単です。

circleci.com

YAML で version: 2.1 を宣言し、orbs で利用するorbを定義、command/jobs/workflow のいずれかでOrbに定義されたcommandやjob を namespace/コマンド のような記述で利用するだけです。 ドキュメントにあるミニマムな例が分かりやすいでしょう。

version: 2.1

orbs:
    hello: circleci/hello-build@0.0.5

workflows:
    "Hello Workflow":
        jobs:
          - hello/hello-build

いざ使うときに気になる「どんな Orbがあるのか、使い方は?」は、Orb Explorer を使うことで探すことができます。

circleci.com

f:id:guitarrapc_tech:20190414070527p:plain
Orbレジストリから検索

Orbを利用するにあたり困らない例と困る例

さて公開されているOrbですが、いい感じで使える一方であと一歩これが足りない、というケースがあります。

例えば、circleci/aws-s3@1.0.6 を見てみましょう。

https://circleci.com/orbs/registry/orb/circleci/aws-s3

このOrbがよく考えられているのが、arguments パラメーターを公開しておりOrbに定義がないパラメーターを受付可能にしていることです。 このパラメーターがあるおかげで、aws cli にOrbが想定していないパラメーターを渡すことができます。

version: 2.1
orbs:
  aws-s3: circleci/aws-s3@1.0.0
jobs:
  build:
    docker:
      - image: 'circleci/python:2.7'
    steps:
      - checkout
      - run: mkdir bucket && echo "lorum ipsum" > bucket/build_asset.txt
      - aws-s3/sync:
          from: bucket
          to: 's3://my-s3-bucket-name/prefix'
          arguments: |
            --acl public-read \
            --cache-control "max-age=86400"
          overwrite: true
      - aws-s3/copy:
          from: bucket/build_asset.txt
          to: 's3://my-s3-bucket-name'
          arguments: '--dryrun'

一方で、circleci/aws-code-deploy@0.0.7 を見るとこの arguments パラメーターがないために、ごにょごにょできません。

version: 2.1
orbs:
  aws-code-deploy: circleci/aws-code-deploy@1.0.0
workflows:
  deploy_application:
    jobs:
      - aws-code-deploy/deploy:
          application-name: myApplication
          deployment-group: myDeploymentGroup
          service-role-arn: myDeploymentGroupRoleARN
          bundle-bucket: myApplicationS3Bucket
          bundle-key: myS3BucketKey

AWS CLI を Circle CI で使うときの注意

aws関連のOrbに arguments を渡す口がなくて困る例として、aws cliの処理を assume role による認証で行いたい場合があります。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-role.htmldocs.aws.amazon.com

assume role を使うことで、認証は一つで、assume 先のrole定義でアクセス先を切り替えることができます。 また、アクセス先の認証も assume role の policy で縛ることができるため、AWS のアクセス制御的にも相性が良くなっています。 assume role を利用するには、そのプロファイル定義と role_arnsource_profile を定義します。

[profile marketingadmin]
role_arn = arn:aws:iam::123456789012:role/marketingadmin
source_profile = user1

あとは、環境変数でAWS_DEFAULT_PROFILE を定義するかAWS_PROFILE で暗黙的に解決させる、あるいはコマンド実行時に --profile プロファイル名 が必要です。

aws s3 cp .... s3://.... --marketingadmin

CircleCIの事情を考えると、circleci の aws 系のOrbは circleci/aws-cli を必ず利用しています。

https://circleci.com/orbs/registry/orb/circleci/aws-cli

この Orbは非常に使い勝手が良く、AWS_ACCESS_KEYAWS_SECRET_ACCESS_KEYAWS_DEFAULT_REGION をCircle CI のProject にあるEnvironment Variable に定義しておくだけで aws configure が行われます。

一方で、このOrbは default profile を使う前提であるため任意の Profile を追加で生成できません。そのためassume role を使うときには別途プロファイルを追加する必要があります。

      - run: 
          command: |
            mkdir -p ~/.aws
            echo "[assume_role]" >> ~/.aws/credentials
            echo "source_profile = default" >> ~/.aws/credentials
            echo "role_arn = << parameters.role_arn >>" >> ~/.aws/credentials

circleci/aws-cli を自分で実行しない場合は、事前に ~/.awsを作ってあげましょう。もしcircleci/aws-cli/installcircleci/aws-cli/configure を自分で実行するなら不要です。 あとはコマンドに Profile を渡せばいいです。 で、前節のcircleci/aws-s3 の場合は、arguments: '--profile assume_role' とOrb実行時に渡せばいいのでok、となります。

余談ですがcircle ci のaws-cli/configureを使うなら、AWS_DEFAULT_PROFILEAWS_PROFILE は使えません。 これらを定義しているとaws-cli/configure でコケます、AWS_DEFAULT_PROFILEaws configureが終わっている前提なのでまぁシカタナイ。

Traceback (most recent call last):
  File "/usr/local/bin/aws", line 27, in <module>
    sys.exit(main())
  File "/usr/local/bin/aws", line 23, in main
    return awscli.clidriver.main()
  File "/usr/local/lib/python2.7/site-packages/awscli/clidriver.py", line 59, in main
    rc = driver.main()
  File "/usr/local/lib/python2.7/site-packages/awscli/clidriver.py", line 193, in main
    command_table = self._get_command_table()
  File "/usr/local/lib/python2.7/site-packages/awscli/clidriver.py", line 102, in _get_command_table
    self._command_table = self._build_command_table()
  File "/usr/local/lib/python2.7/site-packages/awscli/clidriver.py", line 122, in _build_command_table
    command_object=self)
  File "/usr/local/lib/python2.7/site-packages/botocore/session.py", line 671, in emit
    return self._events.emit(event_name, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/botocore/hooks.py", line 356, in emit
    return self._emitter.emit(aliased_event_name, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/botocore/hooks.py", line 228, in emit
    return self._emit(event_name, kwargs)
  File "/usr/local/lib/python2.7/site-packages/botocore/hooks.py", line 211, in _emit
    response = handler(**kwargs)
  File "/usr/local/lib/python2.7/site-packages/awscli/customizations/preview.py", line 69, in mark_as_preview
    service_name=original_command.service_model.service_name,
  File "/usr/local/lib/python2.7/site-packages/awscli/clidriver.py", line 318, in service_model
    return self._get_service_model()
  File "/usr/local/lib/python2.7/site-packages/awscli/clidriver.py", line 335, in _get_service_model
    api_version = self.session.get_config_variable('api_versions').get(
  File "/usr/local/lib/python2.7/site-packages/botocore/session.py", line 233, in get_config_variable
    logical_name)
  File "/usr/local/lib/python2.7/site-packages/botocore/configprovider.py", line 226, in get_config_variable
    return provider.provide()
  File "/usr/local/lib/python2.7/site-packages/botocore/configprovider.py", line 323, in provide
    value = provider.provide()
  File "/usr/local/lib/python2.7/site-packages/botocore/configprovider.py", line 382, in provide
    config = self._session.get_scoped_config()
  File "/usr/local/lib/python2.7/site-packages/botocore/session.py", line 334, in get_scoped_config
    raise ProfileNotFound(profile=profile_name)
botocore.exceptions.ProfileNotFound: The config profile (assume_role) could not be found
Exited with code 1

circleci/aws-code-deploy で arguments 対応をPRする

このあたりを理解した上で、一時対処として自分の Commands で対応していたのですが、公式にあった方がいいので対応しました。

circleci/aws-code-deploy@0.0.9 から arguments が利用できます。

github.com

なお、#140 で対応漏れがあったので #144 をすぐに出しましたが... はずかしい、Orbのテストがないと厳しいですね。

github.com

対応は単純で arguments パラメーターをつけて回るだけです。この時、when が string型に対しては '' をfalse と認識することを利用しています。

Empty strings are treated as a falsy value in evaluation of when clauses, and all other strings are treated as truthy. Using an unquoted string value that YAML interprets as a boolean will result in a type error.

circleci.com

加えて、<<# parameters.xxxxx >> <</parameters.xxxxx>> によってパラメーターが true の場合にのみ埋め込まれるのを使うとこう書けばいいことが分かります。

<<# parameters.arguments >> << parameters.arguments >><</parameters.arguments >>

これで、argument を使って --profile を指定可能になりましたとさ、めでたしめでたし。

version: 2.1
orbs:
  aws-code-deploy: circleci/aws-code-deploy@1.0.0
workflows:
  deploy_application:
    jobs:
      - aws-code-deploy/deploy:
          application-name: myApplication
          deployment-group: myDeploymentGroup
          service-role-arn: myDeploymentGroupRoleARN
          bundle-bucket: myApplicationS3Bucket
          bundle-key: myS3BucketKey
          arguments: '--profile assume_role'

Google Analytics やGoogle Adsを使っていることの対応

このサイトでは、Google Analytics を使っています。これは、アクセスに対してどういう動きをしているのか、どんな興味を持たれているのかのサイトの改善を意図しています。あとはGoogle Analyticsがどんどん変化するので手元で確認できるサイトを持っておきたいからです。

一昨年から、Google Adsense をいれています。これは、広告を普段使っていなかったので、どういう設定でどういう埋め込みや見た目、Rewardがあるのかを確認し、それをこのサイトの運営に充てるためです。

さて、ということはクッキーポリシーに対応しないといけないわけで、怠っていたので対応を進めることにしました。

目次

対応が必要なのか

Google Analytics と Google Adsense それぞれの利用規約を見ます。

www.google.com

お客様は適切なプライバシー ポリシーを用意および遵守し、訪問者からの情報を収集するうえで、適用されるすべての法律、ポリシー、規制を遵守するものとします。お客様はプライバシー ポリシーを公開し、そのプライバシー ポリシーで、お客様がデータ収集のために Cookie を使用していることを必ず通知するものとします。また、Google アナリティクスを使用していること、および Google アナリティクスでデータが収集、処理される仕組みについても必ず開示するものとします。

Google Adsense は次がオンライン利用規約ですが、ここではポリシーの設定については記載がありません。

www.google.com

Google Adsenseはコンテンツポリシーにもう少し細かくあります。

support.google.com

サイトのプライバシー ポリシーについて プライバシー ポリシーには次の情報を記載する必要があります。

Google などの第三者配信事業者が Cookie を使用して、ユーザーがそのウェブサイトや他のウェブサイトに過去にアクセスした際の情報に基づいて広告を配信すること。 Google が広告 Cookie を使用することにより、ユーザーがそのサイトや他のサイトにアクセスした際の情報に基づいて、Google やそのパートナーが適切な広告をユーザーに表示できること。 ユーザーは、広告設定でパーソナライズ広告を無効にできること(または、www.aboutads.info にアクセスすれば、パーソナライズ広告に使われる第三者配信事業者の Cookie を無効にできること)。 第三者配信による広告掲載を無効にしていない場合、広告の配信時に第三者配信事業者や広告ネットワークの Cookie が使用される可能性があります。その点についても、次の方法でサイトのプライバシー ポリシーに明示してください。

会社、個人に関わらず利用者はなので対応します。

どう対応するのか

前提として、個人を識別する情報は取得していません。そこで、追加で必要となる「必須コンテンツの記載にある3つ」を対応します。

  • Google などの第三者配信事業者が Cookie を使用して、ユーザーがそのウェブサイトや他のウェブサイトに過去にアクセスした際の情報に基づいて広告を配信すること。

  • Google が広告 Cookie を使用することにより、ユーザーがそのサイトや他のサイトにアクセスした際の情報に基づいて、Google やそのパートナーが適切な広告をユーザーに表示できること。

  • ユーザーは、広告設定でパーソナライズ広告を無効にできること(または、www.aboutads.info にアクセスすれば、パーソナライズ広告に使われる第三者配信事業者の Cookie を無効にできること)。

上から順に、次の対応を取ります。

  • 利用サービスの記載とアクセス情報に基づいた広告配信を行うことを示した、クッキーポリシーのページを配置
  • クッキーを利用することの通知
  • オプトアウト方法の提供

GDPRの内容からいくと、「広告表示を行うことの通知」ではたりず、初アクセス時点ではAnalyticsは無効にしておいてクッキー同意の通知でon/offの切り替えが必要そうです。このサイトは日本語配信しており、アクセス動向からも閲覧者は99.99%日本であると判明しているのでGDPRに沿った有効化/無効化対応はまた今度にします。

hyper-text.org

クッキーポリシーの配置

プライバシーポリシーが望ましいと思いますが、今このサイトではクッキーの利用のみに関してトラッキング、広告配信を行っています。そこで、まずはクッキーポリシーを配置することにします。

tech.guitarrapc.com

このクッキーポリシーは、Cookie Policy Generator: Create your Cookies Policy を用いて生成したものに、Google Analytics/Ads のコンテンツポリシーにあった Google の Policyへのリンクを載せています。

policies.google.com

policies.google.com

また、クッキーポリシーはサイトのLinks 内にアクセスするためのリンクを張っておいていつでも確認できるようにしておきます。

クッキーを利用することの通知

どのような内容にするかわからず調べました。情報があまり一貫性がないようですが、GDPRに対応するなら同意をとってから取得するためのバナー対応に踏み込んでおく方がよさそうです。*1

どんな表示がいいのかGoogleの解説を見ます。

サイト運営者様のサイトや法律は国ごとに異なるため、Google でプライバシー ポリシーに関する具体的な文面を提案することはできません。サイトのプライバシー ポリシーを作成する際には、Network Advertising Initiative などのリソースを参考にされることをおすすめします。Cookie 使用の同意を得るための情報通知に関する詳細については、cookiechoices.org をご覧ください。

クッキーの同意に関しては、cookiechoices.org を見るのが良いとあります。

www.cookiechoices.org

この中で、「自社サイトへのアクセスデータを別の場所での広告配信に利用しない場合は、次のような通知が適するかもしれません。」があります。

f:id:guitarrapc_tech:20190408043256p:plain
自社サイトへのアクセスデータを別の場所での広告配信に利用しない場合の通知例

幸い、本サイトはあくまでも自分の勉強結果を載せているだけでこのサイトから他のサイトに連携したり、別の場所での広告配信に利用することはありません。クッキーの利用を通知するの通知 + 先ほど設置したクッキーポリシーへの誘導でよさそうです。

このような勉強目的の情報だけ載せているサイトで、全画面で同意をとったりしてみるものが見えないのは最悪だと思います。そこで、画面下にバナー通知を出すことにします。この通知は Cookie Concent と呼ばれ、書く方法や生成サイトが複数あります。今回は、デモが自分の希望する体験に近く、コードも小さいinsites が提供するものを利用します。

cookieconsent.insites.com

表示方法や配色、リンク先を調整したら、コードをデザイン画面で配置します。

オプトアウト方法の提供

先ほどのクッキーポリシーですが、生成した時点ではOpt Out がついていません。 Required content - AdSense Help に基づくと、オプトアウト提供方法について記載があります。

ユーザーは、広告設定でパーソナライズ広告を無効にできること(または、www.aboutads.info にアクセスすれば、パーソナライズ広告に使われる第三者配信事業者の Cookie を無効にできること)。

これをクッキーポリシーに提示しておけば広告の除外、オプトアウトがユーザーそれぞれが希望に応じて設定できます。

adssettings.google.com

WebChoices: Digital Advertising Alliance's Consumer Choice Tool for Web US

結果確認

次の結果になればよさそうです。

  • プライベートブラウズでアクセスしたときに、サイト下部にクッキーに関するバナーが表示される
  • バナーのリンクからクッキーポリシーにアクセスできる
  • クッキーポリシーのOpt out リンクからGoogle の広告設定ページやWebChoices にアクセスできる

クッキーはPC、スマホともに問題なさそうです。

f:id:guitarrapc_tech:20190408044445p:plain
PCのプライベートブラウズでクッキーに関するバナーが表示される

f:id:guitarrapc_tech:20190408044746p:plain
スマホでもクッキーに関するバナーが表示される

バナーのリンクも無事に遷移しました。

f:id:guitarrapc_tech:20190408044902p:plain
Learn more から Cookie Policyページへ遷移

Opt out も遷移しました。

f:id:guitarrapc_tech:20190408045010p:plain
optout.aboutads.info への遷移

f:id:guitarrapc_tech:20190408045048p:plain
Your Adchoiceの確認

今後

クッキーポリシーが英語なのは、結局それでいいかなぁという怠りなので、日本語にするか考えます。やらない気もします。

GDPRに対応したり、ほか媒体で利用するようなケースはECサイトなど企業での利用ではありそうです。Google アナリティクスの広告向け機能に関するポリシー要件には、欧州連合対応があり同意をもとめるかの商業的対応が必要とあるのでこのあたりを使うなら必須ですね。

support.google.com

Google Analytics は、UAの有効化/無効化対応でもよさそうですがGoogle Ads はどうするのが適切なんですかね? というあたりがよくわからない感じです。

このあたり、まとめがほしい。

余談

今回このような表示を行うにあたって、バナー通知を目立たせるために記事とバナーだけを表示できるワンカラムへの変更、バナーがマテリアル風だったのでサイトのみため調整もしてみました。

たまった記事かかなきゃ。

*1:クリック回数的にも読むのにつらくない