diff --git a/content/install-guides/skopeo.md b/content/install-guides/skopeo.md new file mode 100644 index 000000000..47ece28ae --- /dev/null +++ b/content/install-guides/skopeo.md @@ -0,0 +1,390 @@ +--- +title: Skopeo + +draft: true + +author_primary: Jason Andrews +minutes_to_complete: 10 +official_docs: https://github.com/containers/skopeo + +additional_search_terms: +- containers +- images +- registry + +layout: installtoolsall +multi_install: false +multitool_install_part: false +test_images: +- ubuntu:latest +test_maintenance: false +tool_install: true +weight: 1 +--- + +Skopeo is a command-line utility that performs various operations on container images and image repositories. It does not require a daemon to be running on your computer. + +This article explains how to install Skopeo for Ubuntu on Arm. + +Skopeo is available for Windows, macOS, and Linux and supports the Arm architecture. Refer to [Installing Skopeo](https://github.com/containers/skopeo/blob/main/install.md) for information about other operating systems and architectures. + +## What should I consider before installing Skopeo on Arm? + +Confirm you are using an Arm machine by running: + +```bash +uname -m +``` + +The output should be: +```output +aarch64 +``` + +If you see a different result, you are not using an Arm computer running 64-bit Linux. + +## How do I download and Install Skopeo for Ubuntu on Arm? + +The easiest way to install Skopeo is to use the package manager: + +```bash +sudo apt update +sudo apt install -y skopeo +``` + +Confirm the installation by checking the version: + +```bash +skopeo --version +``` + +To see the help message: + +```bash +skopeo --help +``` + +The output is: + +```output +Various operations with container images and container image registries + +Usage: + skopeo [flags] + skopeo [command] + +Available Commands: + copy Copy an IMAGE-NAME from one location to another + delete Delete image IMAGE-NAME + generate-sigstore-key Generate a sigstore public/private key pair + help Help about any command + inspect Inspect image IMAGE-NAME + list-tags List tags in the transport/repository specified by the SOURCE-IMAGE + login Login to a container registry + logout Logout of a container registry + manifest-digest Compute a manifest digest of a file + standalone-sign Create a signature using local files + standalone-verify Verify a signature using local files + sync Synchronize one or more images from one location to another + +Flags: + --command-timeout duration timeout for the command execution + --debug enable debug output + -h, --help help for skopeo + --insecure-policy run the tool without any policy check + --override-arch ARCH use ARCH instead of the architecture of the machine for choosing images + --override-os OS use OS instead of the running OS for choosing images + --override-variant VARIANT use VARIANT instead of the running architecture variant for choosing images + --policy string Path to a trust policy file + --registries.d DIR use registry configuration files in DIR (e.g. for container signature storage) + --tmpdir string directory used to store temporary files + -v, --version Version for Skopeo + +Use "skopeo [command] --help" for more information about a command. +``` + +## How do I get started with Skopeo? + +Some commands to get you started with Skopeo are demonstrated below. + +### How can I check if a container image supports Arm? + +To find out if an image is multi-architecture, including Arm, you can inspect the image's manifest. + +For example, to check if the dev container available for creating Arm Learning Paths supports the Arm architecture run: + +```bash +skopeo inspect --raw docker://docker.io/armswdev/learn-dev-container:latest | jq '.manifests[] | select(.platform.architecture == "arm64")' +``` + +The output is similar to: + +```output +{ + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "size": 1574, + "digest": "sha256:b7abfdc06d4cb06dfbb644f0d7c50202f99f83298da7903ea6463de23b55fb10", + "platform": { + "architecture": "arm64", + "os": "linux" + } +} +``` + +If the command returns a result for an image, the image supports the `arm64` architecture. + +### How can I check if a container image supports multiple architectures? + +To find out if an image supports both `arm64` and `amd64` architectures, you can inspect the image's manifest for both architectures. + +For example, to check if the same dev container supports both architectures run: + +```bash +skopeo inspect --raw docker://docker.io/armswdev/learn-dev-container:latest | jq '.manifests[] | select(.platform.architecture == "arm64" or .platform.architecture == "amd64")' +``` + +The output confirms that both `arm64` and `amd64` are supported architectures as shown below: + +```output +{ + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "size": 1574, + "digest": "sha256:15fe2dc0925c6e5da27048edcd034660f51216ad700cb7cf12cb7779c16e9bce", + "platform": { + "architecture": "amd64", + "os": "linux" + } +} +{ + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "size": 1574, + "digest": "sha256:b7abfdc06d4cb06dfbb644f0d7c50202f99f83298da7903ea6463de23b55fb10", + "platform": { + "architecture": "arm64", + "os": "linux" + } +} +``` + +### Can I use a script to check if a container image supports the Arm architecture? + +You can run a script to check container images for `arm64` support. + +The script performs the following tasks: +- Get a token for the repository +- Read the image manifest +- Check the manifest for architecture support + +Make sure Python3 is installed on your computer. + +Use a text editor to copy the Python code below to a file named `check-image.py`. + +```python +import requests +import sys +import os +import argparse +from typing import List, Dict, Tuple + +# Target architectures to check +TARGET_ARCHITECTURES = {'amd64', 'arm64'} +TIMEOUT_SECONDS = 10 + +def get_auth_token(repository: str) -> str: + """Get Docker Hub authentication token.""" + url = "https://auth.docker.io/token" + params = { + "service": "registry.docker.io", + "scope": f"repository:{repository}:pull" + } + try: + response = requests.get(url, params=params, timeout=TIMEOUT_SECONDS) + response.raise_for_status() + return response.json()['token'] + except requests.exceptions.RequestException as e: + print(f"Failed to get auth token: {e}", file=sys.stderr) + sys.exit(1) + +def get_manifest(repository: str, tag: str, token: str) -> Dict: + """Fetch manifest for specified image.""" + headers = { + 'Accept': 'application/vnd.docker.distribution.manifest.list.v2+json', + 'Authorization': f'Bearer {token}' + } + url = f"https://registry-1.docker.io/v2/{repository}/manifests/{tag}" + try: + response = requests.get(url, headers=headers, timeout=TIMEOUT_SECONDS) + response.raise_for_status() + return response.json() + except requests.exceptions.RequestException as e: + print(f"Failed to get manifest: {e}", file=sys.stderr) + sys.exit(1) + +def check_architectures(manifest: Dict) -> List[str]: + """Check available architectures in the manifest.""" + if manifest.get('manifests'): + archs = [m['platform']['architecture'] for m in manifest['manifests']] + return archs + else: + return [] + +def parse_image_spec(image: str) -> Tuple[str, str]: + """Parse image specification into repository and tag.""" + if ':' in image: + repository, tag = image.split(':', 1) + else: + repository, tag = image, 'latest' + + if '/' not in repository: + repository = f'library/{repository}' + return repository.lower(), tag + +def parse_args(): + """Parse command line arguments.""" + parser = argparse.ArgumentParser(description='Check Docker image architectures') + parser.add_argument('image', help='Docker image name (format: name:tag)') + return parser.parse_args() + +if __name__ == "__main__": + args = parse_args() + repository, tag = parse_image_spec(args.image) + + token = get_auth_token(repository) + manifest = get_manifest(repository, tag, token) + architectures = check_architectures(manifest) + + if not architectures: + print(f"No architectures found for {args.image}", file=sys.stderr) + sys.exit(1) + + available_targets = TARGET_ARCHITECTURES.intersection(architectures) + missing_targets = TARGET_ARCHITECTURES - set(architectures) + + if not missing_targets: + print(f"✓ Image {args.image} supports all required architectures") + else: + print(f"✗ Image {args.image} is missing architectures: {', '.join(missing_targets)}") + print(f"Available architectures: {', '.join(architectures)}") +``` + +The script queries Docker Hub. If needed, you can change the registry and the architecture list to meet your needs. + +Run the script asking about Alpine Linux: + +```bash +python3 ./check-image.py alpine:3.21.0 +``` + +The output indicates that the image supports both `arm64` and `amd64`: + +```output +✓ Image alpine:3.21.0 supports all required architectures +``` + +## What are some other uses for Skopeo? + +Copy an image from a registry to a local directory. This command is similar to `docker pull` and will copy the image from the remote registry to your local directory. + +```bash +skopeo copy docker://docker.io/armswdev/uname:latest dir:./uname +``` + +The output is: + +```output +Getting image source signatures +Copying blob cd741b12a7ea done | +Copying config d11135df72 done | +Writing manifest to image destination +``` + +Inspect an image in a remote registry: + +```bash +skopeo inspect docker://docker.io/armswdev/uname:latest +``` + +The output is: + +```output +{ + "Name": "docker.io/armswdev/uname", + "Digest": "sha256:4f1fe1e1e1ad179bb2cec6b3c8b458d6ead02bd7459798a357791353b867462d", + "RepoTags": [ + "latest" + ], + "Created": "2023-03-08T04:32:41.063980445Z", + "DockerVersion": "", + "Labels": { + "org.opencontainers.image.ref.name": "ubuntu", + "org.opencontainers.image.version": "22.04" + }, + "Architecture": "arm64", + "Os": "linux", + "Layers": [ + "sha256:cd741b12a7eaa64357041c2d3f4590c898313a7f8f65cd1577594e6ee03a8c38" + ], + "LayersData": [ + { + "MIMEType": "application/vnd.oci.image.layer.v1.tar+gzip", + "Digest": "sha256:cd741b12a7eaa64357041c2d3f4590c898313a7f8f65cd1577594e6ee03a8c38", + "Size": 27347481, + "Annotations": null + } + ], + "Env": [ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + ] +} +``` + +List tags in a remote registry for the Ubuntu image with many tags: + +```bash +skopeo list-tags docker://docker.io/library/ubuntu +``` + +The partial output is: + +```output +{ + "Repository": "docker.io/library/ubuntu", + "Tags": [ + "10.04", + "12.04", + "12.04.5", + "12.10", + "13.04", + "13.10", + "14.04", + "14.04.1", + "14.04.2", + "14.04.3", + "14.04.4", + "14.04.5", + "14.10", + "15.04", + "15.10", + "16.04", + "16.10", + "17.04", + "17.10", + "18.04", + "18.10", + "19.04", + "19.10", + "20.04", + "20.10", + "21.04", + "21.10", + "22.04", + "22.10", + "23.04", + "23.10", + "24.04", + "24.10", + "25.04", +< many more tag with Ubuntu release names omitted> +``` + +You are ready to use Skopeo for your projects.