ECS Windows コンテナにカルチャー設定をしてみた

2023.05.17

こんにちは。
ご機嫌いかがでしょうか。
"No human labor is no human error" が大好きな吉井 亮です。

Windows コンテナ使っていますか?
Windows コンテナを用いてアプリケーションを開発しているケースで、カルチャー設定を日本(ja-JP)にしたい要望はあると思います。
そのやり方を調べましたのでブログに残したいと思います。

やり方

結論を書きます。 Set-Culture ja-JP 実行済みの Docker イメージを作成する必要があります。
ECS タスク定義の command で Set-Culture ja-JP を実行しても期待の動作にはなりませんでした。

手順

ECR リポジトリ作成

Set-Culture ja-JP 実行済みのイメージを格納する ECR プライベートリポジトリを作成します。
手順は割愛します。Amazon ECR private repositories を参照ください。
本エントリでは、「windows-japanese」という名称で作成しています。

コンテナビルド環境の用意

Windows コンテナをビルドする環境を用意します。
手元に適当なマシンが無かったので、今回は EC2 を新規起動します。AMI は amazon/Windows_Server-2022-English-Core-ECS_Optimized-2023.04.18 を使用しました。
これは Amazon ECS に最適化された AMI と呼ばれる AMI で Docker がインストールされています。
執筆日時点では Windows Server 2022/2019/2016/20H2 の AMI が用意されています。ECS 最適化 AMI を使う場合は、ベースイメージのバージョンを合わせた AMI を選択ください。

セッションマネージャーでインスタンスへログオンする場合はインスタンスプロファイルを適切に設定ください。
セッションマネージャーを使って鍵ストレスの無いEC2アクセス!

Docker イメージ作成

それでは Docker イメージを作ります。
以下のコマンドはセッションマネージャーでログオン後に実行しています。

ベースイメージは servercore:ltsc2022 を選びました。Set-Culture ja-JP を実行してカルチャー設定を日本にします。

docker run --name temp-container --user "NT AUTHORITY\SYSTEM" --isolation=process mcr.microsoft.com/windows/servercore:ltsc2022 powershell -Command "Set-Culture ja-JP"

カルチャー設定を変更した temp-container に Microsoft Log Monitor を配置します。 Log Monitor を配置することでログやコマンド結果を標準出力に出す狙いです。
バイナリ を予め作業インスタンスにダウンロードしておきます。
※ セッションマネージャーで curl 等を打つとブラウザの初期設定ができてないエラーが出てダウンロードできません。S3 を経由するなどの代替策でダウンロードしましょう。

docker cp C:\LogMonitor temp-container:c:\Logmonitor

カルチャー設定と Log Monitor の配置が完了したイメージを docker commit で作成します。
コマンド例にある URI をご自身の環境に置き換えください。また、 05160941 はタグです。任意の文字列に置き換えて実行ください。

docker commit temp-container your_aws_account.dkr.ecr.us-west-2.amazonaws.com/windows-japanese:05160941

念のため動作確認します。作成したばかりのイメージでコンテナを起動します。
コマンド例にある URI をご自身の環境に置き換えください。また、 05160941 はタグです。任意の文字列に置き換えて実行ください。

docker run -it your_aws_account.dkr.ecr.us-west-2.amazonaws.com/windows-japanese:05160941 powershell

コンテナ内で get-culture を実行してみましょう。

PS C:\> get-culture

LCID             Name             DisplayName
----             ----             -----------
1041             ja-JP            Japanese (Japan)

無事に日本(ja-JP)になっています。
イメージを ECR リポジトリに push します。まずは認証です。マネジメントコンソールの ECR 画面からプッシュコマンドを表示できるので、確実に実施したい方はそちらをコピペしてください。
コマンド例にある URI をご自身の環境に置き換えください。

(Get-ECRLoginCommand).Password | docker login --username AWS --password-stdin your_aws_account.dkr.ecr.us-west-2.amazonaws.com

WARNING! Your password will be stored unencrypted in C:\Windows\system32\config\systemprofile\.docker\config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

Login Succeeded と表示されば成功です。ECR にプッシュします。
コマンド例にある URI をご自身の環境に置き換えください。また、 05160941 はタグです。任意の文字列に置き換えて実行ください。

docker push your_aws_account.dkr.ecr.us-west-2.amazonaws.com/windows-japanese:05160941

CloudWatch ロググループの作成

コンテナログを保管する用途の CloudWatch ロググループを作成しておきます。
本エントリでは「/ecs/windows-fargate」という名称にしています。任意に置き換えてください。
ロググループを作成する手順は割愛します。CloudWatch Logs にロググループを作成します。 を参照ください。

ECS クラスターの作成

ECR にイメージがプッシュし終わったら ECS クラスターを作成します。
データプレーンが Fargate であっても EC2 であってもカルチャー設定に違いはありません。手順が簡単なので Fargate でクラスターを作ります。 手順は割愛します。AWS Fargate の Windows コンテナによるコンソールの使用開始 を参照ください。

動作確認用のタスク定義を貼り付けておきます。各種値はご自身の環境に合わせて修正ください。

{
    "family": "windows-fargate",
    "containerDefinitions": [
        {
            "name": "windows-fargate",
            "image": "your_aws_account.dkr.ecr.us-west-2.amazonaws.com/windows-japanese:05160941",
            "cpu": 0,
            "portMappings": [],
            "essential": true,
            "entryPoint": [
                "C:\\LogMonitor\\LogMonitor.exe",
                "powershell",
                "-Command"
            ],
            "command": [
                "get-culture; exit"
            ],
            "environment": [],
            "mountPoints": [],
            "volumesFrom": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/windows-fargate",
                    "awslogs-region": "us-west-2",
                    "awslogs-stream-prefix": "ecs"
                }
            }
        }
    ],
    "taskRoleArn": "arn:aws:iam::your_aws_account:role/ecsTaskRole",
    "executionRoleArn": "arn:aws:iam::your_aws_account:role/ecsTaskExecutionRole",
    "networkMode": "awsvpc",
    "requiresCompatibilities": [
        "FARGATE"
    ],
    "cpu": "1024",
    "memory": "2048",
    "runtimePlatform": {
        "operatingSystemFamily": "WINDOWS_SERVER_2022_CORE"
    }
}

タスク実行

ECS クラスターとタスク定義作成が完了しました。
それではタスクを実行してみます。get-culture を打っているだけの単純なコンテナです。

実行後に CloudWatch Logs を見てみましょう。

1041             ja-JP            Japanese (Japan)

出てます。ja-JP になっています。

まとめ

最初はタスク定義に command に Set-Culture ja-JP を書いておけば大丈夫だと考えていましたが、そんな単純ではなく予めイメージ作成が必要だということに気がつきました。 もしかしたら他の方法もあるかもしれませんが、この方法でカルチャー設定をすることができそうで安心しました。

参考

以上、吉井 亮 がお届けしました。