Podman is a daemonless engine for developing, managing, and running Open Container Initiative (OCI)-compliant containers. This is the fifth and final article in a series about using Podman. The series provides content on basic container administration using Podman by manipulating different commands and parameters.
Before reading this article, make sure you've read the first four parts:
- Create fast, easy, and repeatable containers with Podman and shell scripts
- How to use Podman to get information about your containers
- How Podman can extract a container's external IP address
- How to update container images with Podman
This article demonstrates how to specify a chip architecture when pulling images. This is important when running containers in architectures other than x86_64, such as Arm, Arm64, mips64le, ppc64le, s390x, and others. To follow along with this article, pull the container images I specified in the Setting things up section of the first article in this series.
Inspecting images and manifests before pulling
Before proceeding with pulling images with different architectures, I'll review how to check the architecture of a given image and the architecture options its manifest provides. These are the current images I pulled to my host machine in the previous articles:
$ podman image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/httpd latest dabbfbe0c57b 2 months ago 148 MB
docker.io/library/wordpress latest 054741915cf1 3 months ago 629 MB
docker.io/library/mysql latest bbf6571db497 3 months ago 521 MB
<none> <none> ea28e1b82f31 3 months ago 148 MB
k8s.gcr.io/pause 3.5 ed210e3e4a5b 11 months ago 690 kB
By default, the podman pull command pulls an image with the architecture according to the target host machine. In my scenario, it pulled all my images with the Amd64 architecture:
$ podman image inspect docker.io/library/{httpd,wordpress,mysql} | jq -r '.[] | .Architecture'
amd64
amd64
amd64
But how many architecture options do these images give me if I want to pull a different architecture? Inspection in the image manifest helps me find out:
$ podman manifest inspect docker.io/library/httpd | grep architecture
"architecture": "amd64",
"architecture": "arm",
"architecture": "arm",
"architecture": "arm64",
"architecture": "386",
"architecture": "mips64le",
"architecture": "ppc64le",
"architecture": "s390x",
$ podman manifest inspect docker.io/library/wordpress | grep architecture
"architecture": "amd64",
"architecture": "arm",
"architecture": "arm",
"architecture": "arm64",
"architecture": "386",
"architecture": "mips64le",
"architecture": "ppc64le",
"architecture": "s390x",
$ podman manifest inspect docker.io/library/mysql | grep architecture
"architecture": "amd64",
As you can see, two of my three pulled images (httpd and wordpress) have eight different architecture options, but one of them (mysql) has only one architecture option. That doesn't mean this image doesn't have other architecture options, but for this specific manifest, it doesn't. However, you can find other repos for the same image in your target registry that give you other architecture options (for example, check the supported architectures for the official MySQL image in the Docker Hub page).
[ Learn about Podman 4.0's new network stack: What you need to know. ]
So, given this information, say I'm running two different systems, each one with a different CPU architecture: one with x86_64 and another one with AArch64. How can I pull an image of a specific architecture to each of these systems? Can I pull a different image architecture of the target host machine and run a container with it? Find out in the next section.
Specifying arch when pulling images in an x86_64 system
To demonstrate, I've created another host machine with an AArch64 architecture. This way, I can show how a container with a different image architecture behaves in each one. For this first demo, I'll use the host machine I created for the first article; it is running with x86_64 architecture:
$ uname -a
Linux fedora.example.local 5.16.11-200.fc35.x86_64 #1 SMP PREEMPT Wed Feb 23 17:08:49 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
To pull images, use the command that you've been running since the beginning of this series: podman pull. Check its options:
$ podman pull --help
Pull an image from a registry
Description:
Pulls an image from a registry and stores it locally.
An image can be pulled by tag or digest. If a tag is not specified, the image with the 'latest' tag is pulled.
Usage:
podman pull [options] IMAGE [IMAGE...]
Examples:
podman pull imageName
podman pull fedora:latest
Options:
--all-tags All tagged images in the repository will be pulled
--arch ARCH Use ARCH instead of the architecture of the machine for choosing images
--authfile string Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override
--cert-dir Pathname Pathname of a directory containing TLS certificates and keys
--creds Credentials Credentials (USERNAME:PASSWORD) to use for authenticating to a registry
--disable-content-trust This is a Docker specific option and is a NOOP
--os OS Use OS instead of the running OS for choosing images
--platform string Specify the platform for selecting the image. (Conflicts with arch and os)
-q, --quiet Suppress output information when pulling images
--tls-verify Require HTTPS and verify certificates when contacting registries (default true)
--variant string Use VARIANT instead of the running architecture variant for choosing images
Note there are three different yet very similar parameters: --arch ARCH, --platform string, and --variant string.
The main difference between them is that with the platform parameter, you can specify an operating system or architecture for the image that's different from the host machine (such as "windows" as the OS), while with arch, you're only specifying the architecture (that's what you want here), and with variant you're specifying the variant inside the given architecture (for example, arm/v5, arm/v7, etc.).
Now I'll demonstrate what happens when you try to pull an image with an architecture (using the --arch parameter) that is not specified in the image's manifest. This test uses the mysql image:
$ podman pull --arch=arm64 docker.io/library/mysql
Trying to pull docker.io/library/mysql:latest...
Error: choosing an image from manifest list docker://mysql:latest: no image found in manifest list for architecture arm64, variant "", OS linux
It won't work. But here's what happens if you try to do the same thing but using a valid arch from the provided image repo and manifest:
$ podman pull --arch=arm docker.io/library/httpd
Trying to pull docker.io/library/httpd:latest...
Getting image source signatures
Copying blob 43d17a883cdc done
Copying blob c2ff343d5fd2 done
Copying blob 6a6e631a1e74 done
Copying blob 071a8f3a328f done
Copying blob 59dbb2ac3829 done
Copying config 5c243f19b0 done
Writing manifest to image destination
Storing signatures
5c243f19b0c7a9b18d7d3bebf80054b594798361ddbab222fcafa6522cf2e87b
$ podman image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/httpd latest 5c243f19b0c7 6 days ago 116 MB
<none> <none> dabbfbe0c57b 2 months ago 148 MB
docker.io/library/wordpress latest 054741915cf1 3 months ago 629 MB
docker.io/library/mysql latest bbf6571db497 3 months ago 521 MB
<none> <none> ea28e1b82f31 3 months ago 148 MB
k8s.gcr.io/pause 3.5 ed210e3e4a5b 11 months ago 690 kB
It works! Pulling an image with an Arm arch, even when running an x86_64 host machine, is not a problem. You can check the other images (wordpress and mysql) and compare them to the httpd image to see that the current pulled image is now defaulting to the Arm arch:
$ podman image inspect docker.io/library/{httpd,wordpress,mysql} | jq -r '.[] | .Architecture'
arm
amd64
amd64
If you want to change the default pulled image for httpd, you can simply run the podman pull command again but specify the new arch that you want, for example, Arm64:
$ podman pull --arch=arm64 docker.io/library/httpd
Trying to pull docker.io/library/httpd:latest...
Getting image source signatures
Copying blob 5ba01719dd76 done
Copying blob 0e1e146c1fe7 done
Copying blob d2d2092da38e done
Copying blob 14e615a0c8e4 done
Copying blob 279a020076a7 done
Copying config c7469bac36 done
Writing manifest to image destination
Storing signatures
c7469bac360343c88158b2bf384f4521fa0590478c99e077ab4ec2f73b8c5316
$ podman image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/httpd latest c7469bac3603 5 days ago 141 MB
<none> <none> 5c243f19b0c7 6 days ago 116 MB
<none> <none> dabbfbe0c57b 2 months ago 148 MB
docker.io/library/wordpress latest 054741915cf1 3 months ago 629 MB
docker.io/library/mysql latest bbf6571db497 3 months ago 521 MB
<none> <none> ea28e1b82f31 3 months ago 148 MB
k8s.gcr.io/pause 3.5 ed210e3e4a5b 11 months ago 690 kB
$ podman image inspect docker.io/library/{httpd,wordpress,mysql} | jq -r '.[] | .Architecture'
arm64
amd64
amd64
The other httpd images are still there (check the IMAGE ID), with <none> for REPOSITORY and TAG. But the default is now the Arm64 arch for the httpd image.
[ Learn about Red Hat OpenShift Container Storage for database and analytics. ]
So you can pull an image with a different architecture than the host machine… but what about running a container from it? Check it out:
$ podman run --name=httpd-arm -p 8081:80 -d docker.io/library/httpd
64526b8be8ab570791fb80eaf710e95d60d5c9809ed1a42d9d86d43278367bbf
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ podman logs httpd-arm
{"msg":"exec container process `/usr/local/bin/httpd-foreground`: Exec format error","level":"error","time":"2022-03-07T21:54:40.000337957Z"}
By default, you aren't allowed to run a container from a different architecture than your host machine. However, there are some tricky ways to do it using emulation and other tweaks. Pulling different architectures like this could still be useful if you're building multi-architecture containers, but that's a topic for another article.
You can still use my old httpd image with the Amd64 arch to run a container in this x86_64 host machine. To demonstrate this, simply do:
$ podman image inspect dabbfbe0c57b | jq -r '.[] | .Architecture'
amd64
$ podman run --name=httpd -p 8081:80 -d dabbfbe0c57b
5a7752378dbee1e32cdd31deab1ea355f925023a38768319dad32a29d635766e
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a7752378dbe dabbfbe0c57b httpd-foreground 6 seconds ago Up 5 seconds ago 0.0.0.0:8081->80/tcp httpd
It's clear now how the pulling image process with different arch works in an x86_64 system, so see how it works in an AArch64 system.
Specifying arch when pulling images in an Arm64/AArch64 system
Just to show you that I'm running a real AArch64 system, check the following output:
$ uname -a
Linux fedoraarch 5.16.12-200.fc35.aarch64 #1 SMP Wed Mar 2 18:49:17 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
Since this is a freshly created machine, it still doesn't have any pulled images:
$ podman image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
To pull an image here, run the same command and go through the same processes as before:
$ podman pull docker.io/library/httpd
Trying to pull docker.io/library/httpd:latest...
Getting image source signatures
Copying blob 0e1e146c1fe7 done
Copying blob 5ba01719dd76 done
Copying blob 14e615a0c8e4 done
Copying blob 279a020076a7 done
Copying blob d2d2092da38e done
Copying config c7469bac36 done
Writing manifest to image destination
Storing signatures
c7469bac360343c88158b2bf384f4521fa0590478c99e077ab4ec2f73b8c5316
$ podman image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/httpd latest c7469bac3603 5 days ago 141 MB
$ podman inspect docker.io/library/httpd | jq -r '.[] | .Architecture'
arm64
The main difference now is that, as the podman inspect output shows, the pulled image is, by default, an Arm64 architecture. Why is that? It's because podman pull defaults the image architecture to the same arch as the base host machine. Since my base host machine is running an AArch64, Podman pulled an Arm64 arch image. Cool, isn't it?
Running a container from this pulled image should present no issues at all now:
$ podman run --name=httpd-arm -p 8081:80 -d docker.io/library/httpd
391bb0db8da04f6830336088b1d8cbece008e5d85e3fe00bec9d38e95126b082
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
391bb0db8da0 docker.io/library/httpd:latest httpd-foreground 20 seconds ago Up 12 seconds ago 0.0.0.0:8081->80/tcp httpd-arm
$ curl -s http://localhost:8081
<html><body><h1>Enable SysAdmin - Apache container on aarch64 system </h1></body></html>
It's running! And if you do the opposite now and try to run an Amd64 image on this AArch64 system, will it work? It doesn't hurt to try, right? First, get rid of the running container and pull a fresh httpd image specifying the Amd64 arch:
$ podman stop httpd-arm
httpd-arm
$ podman rm -a
391bb0db8da04f6830336088b1d8cbece008e5d85e3fe00bec9d38e95126b082
$ podman pull --arch=amd64 docker.io/library/httpd
Trying to pull docker.io/library/httpd:latest...
Getting image source signatures
Copying blob 4566427976c4 done
Copying blob f18d7c6e023b done
Copying blob f7a1c6dad281 done
Copying blob bf06bcf4b8a8 done
Copying blob 70a943c2d5bb done
Copying config faed93b288 done
Writing manifest to image destination
Storing signatures
faed93b2885914426b66f1a7d09d93dce9e532fa64f4ab269494f4f954a424ef
$ podman image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> c7469bac3603 5 days ago 141 MB
docker.io/library/httpd latest faed93b28859 6 days ago 148 MB
$ podman inspect docker.io/library/httpd | jq -r '.[] | .Architecture'
amd64
And now, as a final test, try to run a container from this image:
$ podman run --name=httpd-amd64 -p 8081:80 -d docker.io/library/httpd
3b1e54611b8aee0bea7937ffe23965213c9696f46471b73d0154e4ce03e49988
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ podman logs httpd-amd64
{"msg":"exec container process `/usr/local/bin/httpd-foreground`: Exec format error","level":"error","time":"2022-03-07T22:17:47.000637319Z"}
This is the same error that you saw in the other system. This proves the point of running containers of architectures that are compatible with the base system by default.
I hope these demos helped you better understand how to pull images and run containers on systems of different architectures using Podman.
Wrap up
Understanding how the architectures of container images work, how to pull them, and how to run containers from them on different systems is very advantageous for building multi-architecture solutions. It also allows you to explore the many benefits that each architecture may provide.
This is the final article of a five-part series that explored some basic Podman concepts and commands. Topics ranged from creating containers automatically through scripts, extracting information from running containers, getting network and IP information from rootful and rootless containers, and updating image versions. This final article covered pulling different image architectures.
I sincerely hope that this series built an initial foundation for your Podman knowledge. I also hope it sharpened your desire to step into the world of containers and explore its many options. Now that you know how to do it, put it to good use!
About the author
Alexon has been working as a Senior Technical Account Manager at Red Hat since 2018, working in the Customer Success organization focusing on Infrastructure and Management, Integration and Automation, Cloud Computing, and Storage Solutions. He is a part of the TAM Practices LATAM team based in São Paulo, Brazil, where his job is partnering with, advocating, trust-advising, and supporting customers in their success goals while making use of the complete portfolio. He also contributes to produce and enhance documentation, knowledge-base articles, blog posts, presentations, webinars, and workshops. He is a member of numerous communities in addition to the Sudoers, like Red Hat Academy and Red Hat Accelerators. When he’s not at work, he enjoys spending quality time with his family (wife, daughter, and cat) and participating in several volunteer jobs.
More like this
Red Hat and Sylva unify the future for telco cloud
Bridging the gap: Secure virtual and container workloads with Red Hat OpenShift and Palo Alto Networks
The Containers_Derby | Command Line Heroes
Can Kubernetes Help People Find Love? | Compiler
Browse by channel
Automation
The latest on IT automation for tech, teams, and environments
Artificial intelligence
Updates on the platforms that free customers to run AI workloads anywhere
Open hybrid cloud
Explore how we build a more flexible future with hybrid cloud
Security
The latest on how we reduce risks across environments and technologies
Edge computing
Updates on the platforms that simplify operations at the edge
Infrastructure
The latest on the world’s leading enterprise Linux platform
Applications
Inside our solutions to the toughest application challenges
Virtualization
The future of enterprise virtualization for your workloads on-premise or across clouds