This workflow explores the 3.0
manifest-based tag in the mcr.microsoft.com/v2/dotnet/core/runtime repo on MCR as an example. It uses curl
to call a set of container registry APIs to find image digests, layer digests, and layer location. This example is intended to show the separation between MCR as a image manifest service and Azure CDN as an image layer service.
This pattern can be used on any operating system, but the specific commands are OS-specific. curl
is included in the latest versions of Windows and is also in most Linux and macOS distributions. findstr
is part of Windows, however, grep
can be used on Linux or macOS instead.
The 3.0
tag is a manifest tag. It represents a set of potential candidate images, for various operating systems and operating systems versions. When a manifest tag is pulled by a docker client, the client picks the best image for the host operating system if one is compatible. There is no guarantee that there will be a compatible image.
The following curl command requests the manifest digest list for the 3.0
tag in the mcr.microsoft.com/v2/dotnet/core/runtime
repo. It lists all of the supported images, their digests, and their associated configurations.
C:\>curl -s -H "Accept: application/vnd.docker.distribution.manifest.list.v2+json" https://mcr.microsoft.com/v2/dotnet/core/runtime/manifests/3.0
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 1164,
"digest": "sha256:9455ca49f5a77ada94eea95dc3cbe86d608ced5efbaa9dcbb9778fcfa6cd0b90",
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 1164,
"digest": "sha256:0e81282177c75266af08d2b536dadf1fd7cff08d5ff444310753eb296f8cd780",
"platform": {
"architecture": "arm",
"os": "linux",
"variant": "v7"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 1164,
"digest": "sha256:84662fc278c8595651064cf500c414f46680ccd1184d1f39efe42f384dcaaae8",
"platform": {
"architecture": "arm64",
"os": "linux",
"variant": "v8"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 1984,
"digest": "sha256:937717ad9363ddc0c2a9b9018c595a7f7454f5a112cfa0a52952da6325a18b03",
"platform": {
"architecture": "amd64",
"os": "windows",
"os.version": "10.0.16299.1029"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 1984,
"digest": "sha256:0899a6a5917a0a969eb60064444fda1a2c12aacb1dea5060f3a93c2d8aedfcaf",
"platform": {
"architecture": "amd64",
"os": "windows",
"os.version": "10.0.17134.648"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 1672,
"digest": "sha256:187a51f5662abbe7360022a15f6416e16ba3af32ca68e645067a43fdf9f38fbf",
"platform": {
"architecture": "amd64",
"os": "windows",
"os.version": "10.0.17763.379"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 1879,
"digest": "sha256:b833e669819836f729b04381f9e48fdc8361fe7d4abee14d0afc5f1a34d1ebed",
"platform": {
"architecture": "arm",
"os": "windows",
"os.version": "10.0.17763.379"
}
}
]
}
The following command is the same as the one above, but also uses findstr
to print only the image digests. We'll arbitrarily take the first one for our next command.
C:\>curl -s -H "Accept: application/vnd.docker.distribution.manifest.list.v2+json" https://mcr.microsoft.com/v2/dotnet/core/runtime/manifests/3.0 | findstr digest
"digest": "sha256:9455ca49f5a77ada94eea95dc3cbe86d608ced5efbaa9dcbb9778fcfa6cd0b90",
"digest": "sha256:0e81282177c75266af08d2b536dadf1fd7cff08d5ff444310753eb296f8cd780",
"digest": "sha256:84662fc278c8595651064cf500c414f46680ccd1184d1f39efe42f384dcaaae8",
"digest": "sha256:937717ad9363ddc0c2a9b9018c595a7f7454f5a112cfa0a52952da6325a18b03",
"digest": "sha256:0899a6a5917a0a969eb60064444fda1a2c12aacb1dea5060f3a93c2d8aedfcaf",
"digest": "sha256:187a51f5662abbe7360022a15f6416e16ba3af32ca68e645067a43fdf9f38fbf",
"digest": "sha256:b833e669819836f729b04381f9e48fdc8361fe7d4abee14d0afc5f1a34d1ebed",
The following curl command requests the layer list for the first image digest that we saw above, which happens to be the Linux AMD64. Docker containers are made up of layers, that are downloaded and composed separately.
C:\>curl -s -H "Accept: application/vnd.docker.distribution.manifest.v2+json" https://mcr.microsoft.com/v2/dotnet/core/runtime/manifests/sha256:9455ca49f5a77ada94eea95dc3cbe86d608ced5efbaa9dcbb9778fcfa6cd0b90
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 3996,
"digest": "sha256:8beba8202d12f505d397e712636474f42f61042e573133a4ab5d6465c2e8c015"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 22496034,
"digest": "sha256:f7e2b70d04ae3f516c08c24d88de0f82699aaf3ee98af6eb208bd234136142b4"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 15873239,
"digest": "sha256:870473edacef1683171081f690c1807fed922948b6e5565ae4d9a523250352f7"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 4818840,
"digest": "sha256:e4558dcdf53c558bbbedae24383483f6bf1745283bb67591c18900f596eeca82"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 30396005,
"digest": "sha256:e2c6398c75f168d934150eacee8b4209998c13c6b034fdf6f038c1496948f2ff"
}
]
}
The following command is the same as the one above, but also uses findstr
to print only the layer digests. We'll arbitrarily take the first one for our next command.
C:\>curl -s -H "Accept: application/vnd.docker.distribution.manifest.v2+json" https://mcr.microsoft.com/v2/dotnet/core/runtime/manifests/sha256:9455ca49f5a77ada94eea95dc3cbe86d608ced5efbaa9dcbb9778fcfa6cd0b90 | findstr digest
"digest": "sha256:8beba8202d12f505d397e712636474f42f61042e573133a4ab5d6465c2e8c015"
"digest": "sha256:f7e2b70d04ae3f516c08c24d88de0f82699aaf3ee98af6eb208bd234136142b4"
"digest": "sha256:870473edacef1683171081f690c1807fed922948b6e5565ae4d9a523250352f7"
"digest": "sha256:e4558dcdf53c558bbbedae24383483f6bf1745283bb67591c18900f596eeca82"
"digest": "sha256:e2c6398c75f168d934150eacee8b4209998c13c6b034fdf6f038c1496948f2ff"
The following curl command requests the layer location for the first layer digest seen in the previous command. A docker client would then download this and the remaining layers. In this case, the location is an Azure CDN provided URL.
C:\>curl -s -i https://mcr.microsoft.com/v2/dotnet/core/runtime/blobs/sha256:f7e2b70d04ae3f516c08c24d88de0f82699aaf3ee98af6eb208bd234136142b4 | findstr Location
Location: https://mcrwus20.cdn.mscr.io/01031d61e1024861afee5d512651eb9f-h36fskt2ei//docker/registry/v2/blobs/sha256/f7/f7e2b70d04ae3f516c08c24d88de0f82699aaf3ee98af6eb208bd234136142b4/data?P1=1552609781&P2=1&P3=1&P4=n1w%2Fe17blh2wFTEYuTIm8PSRjTNuRq%2BzW7GLdsN54MM%3D&se=2019-03-15T00%3A29%3A41Z&sig=yFwxgqllToxef2euF8VwX3CKPv1KSqwMA41EaZ1c7%2Fc%3D&sp=r&sr=b&sv=2016-05-31®id=01031d61e1024861afee5d512651eb9f