Skip to content

Instantly share code, notes, and snippets.

@richlander
Last active March 17, 2023 18:46
Show Gist options
  • Save richlander/2793148e78074b91f810ba1dcdd1fd51 to your computer and use it in GitHub Desktop.
Save richlander/2793148e78074b91f810ba1dcdd1fd51 to your computer and use it in GitHub Desktop.
Inspect MCR Registry Tags for .NET Core

Inspect MCR Registry Tags for .NET Core

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.

Inspect Manifest tag

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",

Inspect Image Digest

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"

Inspect Layer Digest

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&regid=01031d61e1024861afee5d512651eb9f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment