個人的に見落としていたWindows コンテナの変更点

本投稿はAWS Containers Advent Calendar 2023の10日目の記事です。投稿時間的にギリギリ間に合ったはず。きっと。多分。


今回は個人的にウォッチ出来ていなかった Windows Container Image に関する変更について簡単にまとめてみます。


## 2023-05-10 頃？以前のWindows servercore Image (2019) の mediaType

Docker Image Manifest には レイヤーや容量、ダイジェスト値といった Image に関する情報が含まれています。
例えば、Manifest を確認することで、Image 名や、アーキテクチャ、OS 情報等も取得可能です。
Manifest の記載内容は以下の様なコマンドで確認できます。

```bash

 % docker manifest inspect --verbose mcr.microsoft.com/windows/servercore:10.0.17763.4377
[
	{
		"Ref": "mcr.microsoft.com/windows/servercore:10.0.17763.4377@sha256:c80f3eb3fddc3cacc5d779de0135906842a7195c21ba8cdefc373e2e548eeeaf",
		"Descriptor": {
			"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
			"digest": "sha256:c80f3eb3fddc3cacc5d779de0135906842a7195c21ba8cdefc373e2e548eeeaf",
			"size": 886,
			"platform": {
				"architecture": "amd64",
				"os": "windows",
				"os.version": "10.0.17763.4377",
				"os.features": [
					"win32k"
				]
			}
		},
		"SchemaV2Manifest": {
			"schemaVersion": 2,
			"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
			"config": {
				"mediaType": "application/vnd.docker.container.image.v1+json",
				"size": 788,
				"digest": "sha256:66a1a48cbc112ec01f8af22153b50e4d1a0e8b74e190594222ef9d3b0d4a7b9b"
			},
			"layers": [
				{
					"mediaType": "application/vnd.docker.image.rootfs.foreign.diff.tar.gzip",
					"size": 1660377526,
					"digest": "sha256:8185ee4ed6467d79d4c69f02fe3902311ba84777802d459dcd99869f603b161f",
					"urls": [
						"https://mcr.microsoft.com/v2/windows/servercore/blobs/sha256:8185ee4ed6467d79d4c69f02fe3902311ba84777802d459dcd99869f603b161f"
					]
				},
				{
					"mediaType": "application/vnd.docker.image.rootfs.foreign.diff.tar.gzip",
					"size": 356019256,
					"digest": "sha256:d1629109497f302d0776ee05c686b635ce10daa442b8fe27777aa7e7f3f4c685",
					"urls": [
						"https://mcr.microsoft.com/v2/windows/servercore/blobs/sha256:d1629109497f302d0776ee05c686b635ce10daa442b8fe27777aa7e7f3f4c685"
					]
				}
			]
		}
	}
]

```
Image Manifest V2 に関するshemaについては、[こちら](https://matsuand.github.io/docs.docker.jp.onthefly/registry/spec/manifest-v2-2/)も確認してみてください。上記のImage は 2023-05-10に公開されたものです。

Windows Image の場合、特徴的だったのは、layers 以下の部分で、

```
			"layers": [
				{
					"mediaType": "application/vnd.docker.image.rootfs.foreign.diff.tar.gzip",
					"size": 1660377526,
					"digest": "sha256:8185ee4ed6467d79d4c69f02fe3902311ba84777802d459dcd99869f603b161f",
					"urls": [
						"https://mcr.microsoft.com/v2/windows/servercore/blobs/sha256:8185ee4ed6467d79d4c69f02fe3902311ba84777802d459dcd99869f603b161f"
					]
				},
   
    <snip>
```

`mediaType` の部分です。上記の場合、`application/vnd.docker.image.rootfs.foreign.diff.tar.gzip`　となっていて、これは、当該 Layer が gzip された tar であり、レジストリにプッシュされないという動作になります。
その為、この Layer は取得する場合、 `ulrs` に記載されたアドレスからダウンロードする(例だと `mcr.microsoft.com`)からダウンロードしなくてはなりません。

例えば、開発したアプリケーションを含めたWindows イメージを ECR に push した場合でも、上記のmediaTypeが設定された Layer は ECR には通常、pushされません。 その為、自身で build したコンテナイメージを利用したい場合でも

* Base Image部分 は MS社のレジストリからダウンロード
* カスタマイズした部分は ECRからダウンロード

といった様な動きになります。(コンテナホストにキャッシュがない場合)

## 最近の Image 

2023-06-23頃に公開された Image の Manifestでは、以下の様になっていました。

```bash
 docker manifest inspect --verbose mcr.microsoft.com/windows/servercore:10.0.17763.4499
[
	{
		"Ref": "mcr.microsoft.com/windows/servercore:10.0.17763.4499@sha256:169e0b6968015a6ce48ade6c7aa4fc9375c18f9581dc47bfbb296c2b61747c73",
		"Descriptor": {
			"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
			"digest": "sha256:169e0b6968015a6ce48ade6c7aa4fc9375c18f9581dc47bfbb296c2b61747c73",
			"size": 430,
			"platform": {
				"architecture": "amd64",
				"os": "windows",
				"os.version": "10.0.17763.4499",
				"os.features": [
					"win32k"
				]
			}
		},
		"SchemaV2Manifest": {
			"schemaVersion": 2,
			"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
			"config": {
				"mediaType": "application/vnd.docker.container.image.v1+json",
				"size": 625,
				"digest": "sha256:0e4e89ebdca4bd921242bbc5f428cbf50d82b4e0886b59045f85bf9ad6e68bff"
			},
			"layers": [
				{
					"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
					"size": 1604146467,
					"digest": "sha256:0aff88f72bd4668c33a9d95992707d5c4cb00d125d4bce7e5879f35cb935a756"
				}
			]
		}
	}
]
```

こちらでは、layersに記載されているmediaTypeが`application/vnd.docker.image.rootfs.diff.tar.gzip`に変わってますね。この場合、自身でbuildしたコンテナイメージをECRにpushすると全てのLayerがECRにpushされる様になります。


## 何故変わったのか？

実は、[こちらの](https://techcommunity.microsoft.com/t5/containers/announcing-windows-container-base-image-redistribution-rights/ba-p/3645201
)ブログで、Base Image の再配布に関する権利が変更になった事がアナウンスされていました。公開されたのは2022年10月頃の様なので、結構前の事ですね。

どうやら、インターネットアクセスが無い環境でも Windows コンテナを使いやすくする事を目的とした変更だった様です。この変更を受けて、OCI Image Specでも` "Layer" with distribution restrictions`が[deprecated になった](https://github.com/opencontainers/image-spec/pull/965)様です。

## Foreign Layer を ECR　に push する方法
以前から、Foreign Layer を push　することも可能で、dockerdの設定として、deamon.jsonに以下の様な記述をすれば、以前からECRにpushすることは可能でした。

```json
{
    "allow-nondistributable-artifacts": ["<account_id>.dkr.ecr.<region>.amazonaws.com"]
}
```

最近の Image では、`Foreign Layer`自体が使われていない様なので、上記の設定は不要になります。


## AWS　上で Windows コンテナを動かすのに嬉しいことあるの？
ぱっと思いつくところだと、
* 全てのLayerが ECR 上 からダウンロードすることになるので、Image　を pull するのが早くなるかも？
* 全ての Layerが ECR 上 に保持されるので、 保存サイズが大きくなる

という変化はありそうです。 嬉しいかどうかは、ユースケース次第でしょうか。