{"id":4725,"date":"2023-05-23T14:24:44","date_gmt":"2023-05-23T12:24:44","guid":{"rendered":"http:\/\/miro.borodziuk.eu\/?p=4725"},"modified":"2023-09-22T09:20:06","modified_gmt":"2023-09-22T07:20:06","slug":"container-life-cycle-management-with-podman","status":"publish","type":"post","link":"http:\/\/miro.borodziuk.eu\/index.php\/2023\/05\/23\/container-life-cycle-management-with-podman\/","title":{"rendered":"Managing Container Images with Podman"},"content":{"rendered":"<p>Image registries are services offering container images to download. They allow image creators and maintainers to store and distribute container images to public or private audiences. Podman searches for and downloads container images from public and private registries. Red Hat Container Catalog is the public image registry managed by Red Hat. It hosts a large set of container images, including those provided by major open source projects, such as Apache, MySQL, and Jenkins.<\/p>\n<p><!--more--><\/p>\n<p>Quay.io is another public image repository sponsored by Red Hat. Quay.io introduces several exciting features, such as server-side image building, fine-grained access controls, and automatic scanning of images for known vulnerabilities. While Red Hat Container Catalog images are trusted and verified, Quay.io offers live images regularly updated by creators. Quay.io users can create their namespaces, with fine-grained access control, and publish the images they create to that namespace. Container Catalog users rarely or<br \/>\nnever push new images, but consume trusted images generated by the Red\u00a0Hat team.<\/p>\n<p><span style=\"color: #3366ff;\"> <b>Configuring Registries in Podman<\/b><\/span><br \/>\nTo configure registries for the podman command, you need to update the \/etc\/containers\/registries.conf file. Edit the registries entry in the [registries.search] section, adding an entry to the values list.<\/p>\n<pre class=\"lang:default decode:true\">[registries.search]\r\nregistries = [\"registry.access.redhat.com\", \"quay.io\", 'docker.io']<\/pre>\n<p>Use an FQDN and port number to identify a registry. A registry that does not include a port number has a default port number of 5000. If the registry uses a different port, it must be specified. Indicate port numbers by appending a colon (:) and the port number after the FQDN.<\/p>\n<p>Secure connections to a registry require a trusted certificate. To support insecure connections, add the registry name to the registries entry in [registries.insecure] section of \/etc\/containers\/registries.conf file:<\/p>\n<pre class=\"lang:default decode:true \">[registries.insecure]\r\nregistries = ['localhost:5000']<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\"> <b>Searching for Images in Registries<\/b><\/span><br \/>\nThe podman search command finds images by image name, user name, or description from all the registries listed in the <code>\/etc\/containers\/registries.conf<\/code> configuration file. The syntax for the podman search command is shown below:<\/p>\n<p><code>$ sudo podman search [OPTIONS] &lt;term&gt;<\/code><\/p>\n<p>The following table shows some useful options available for the search subcommand:<\/p>\n<table style=\"border-collapse: collapse; width: 100%; height: 397px;\">\n<tbody>\n<tr style=\"height: 26px;\">\n<td style=\"width: 50%; height: 26px;\"><strong> Option<\/strong><\/td>\n<td style=\"width: 50%; height: 26px;\"><strong> Description<\/strong><\/td>\n<\/tr>\n<tr style=\"height: 53px;\">\n<td style=\"width: 50%; height: 53px;\"><code> --limit &lt;number&gt;<\/code><\/td>\n<td style=\"width: 50%; height: 53px;\">Limits the number of listed images per<br \/>\nregistry.<\/td>\n<\/tr>\n<tr style=\"height: 265px;\">\n<td style=\"width: 50%; height: 265px;\"><code> --filter &lt;filter=value&gt;<\/code><\/td>\n<td style=\"width: 50%; height: 265px;\">Filter output based on conditions provided. Supported filters are:<br \/>\n\u2022<code> stars=&lt;number&gt;<\/code>: Show only images with at least this number of stars.<br \/>\n\u2022<code> is-automated=&lt;true|false&gt;<\/code>: Show<br \/>\nonly images automatically built.<br \/>\n\u2022<code> is-official=&lt;true|false&gt;<\/code>: Show only images flagged as official.<\/td>\n<\/tr>\n<tr style=\"height: 53px;\">\n<td style=\"width: 50%; height: 53px;\"><code> --tls-verify &lt;true|false&gt;<\/code><\/td>\n<td style=\"width: 50%; height: 53px;\">Enables or disables HTTPS certificate<br \/>\nvalidation for all used registries. <code>true<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Some container image registries require access authorization. The podman login command allows username and password authentication to a registry:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman login -u username -p password registry.access.redhat.com\r\nLogin Succeeded!<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\"> <b>Pulling Images<\/b><\/span><br \/>\nTo pull container images from a registry, use the<code> podman pull<\/code> command:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman pull [OPTIONS] [REGISTRY[:PORT]\/]NAME[:TAG]<\/pre>\n<p>The podman pull command uses the image name obtained from the search subcommand to pull an image from a registry. The pull subcommand allows adding the registry name to the image. This variant supports having the same image in multiple registries. For example, to pull an NGINX container from the quay.io registry, use the following command:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman pull quay.io\/bitnami\/nginx<\/pre>\n<p>If the image name does not include a registry name, Podman searches for a<br \/>\nmatching container image using the registries listed in the<code> \/etc\/containers\/<\/code><br \/>\n<code>registries.conf<\/code> configuration file. Podman search for images in registries in the same order they appear in the configuration file.<\/p>\n<p><span style=\"color: #3366ff;\"><b>Listing Local Copies of Images<\/b><\/span><\/p>\n<p>Any container image downloaded from a registry is stored locally on the same host where the podman command is executed.\u00a0 Podman also stores any custom container images you build in the same local storage. By default, Podman stores container images in the <code>\/var\/lib\/containers\/<\/code><code>storage\/overlay-images<\/code> directory. Podman provides an images subcommand to list all the container images stored locally.<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman images\r\nREPOSITORY TAG IMAGE ID CREATED SIZE\r\nregistry.redhat.io\/rhscl\/mysql-57-rhel7 latest c07bf25398f4 13 days ago 444MB<\/pre>\n<p><span style=\"color: #3366ff;\"><b>Image Tags<\/b><\/span><br \/>\nAn image tag is a mechanism to support multiple releases of the same image. This feature is useful when multiple versions of the same software are provided, such as a production-ready container or the latest updates of the same software developed for community evaluation. Any Podman subcommand that requires a container image name accepts a tag parameter to differentiate<br \/>\nbetween multiple tags. If an image name does not contain a tag, then the tag value defaults to latest. For example, to pull an image with the tag 5.7 from rhscl\/mysql-57-rhel7, use the following command:<\/p>\n<pre class=\"lang:default decode:true\">$ sudo podman pull rhscl\/mysql-57-rhel7:5.7\r\n88 DO180-OCP4.2-en-1-20191105<\/pre>\n<p>To start a new container based on the rhscl\/mysql-57-rhel7:5.7 image, use the following command:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman run rhscl\/mysql-57-rhel7:5.7<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\"><b>Saving and Loading Images<\/b><\/span><br \/>\nExisting images from the Podman local storage can be saved to a<code> .tar<\/code> file using the podman save command. The generated file is not a regular TAR archive; it contains image metadata and preserves the original image layers. Using this file, Podman can recreate the original image exactly as it was.<\/p>\n<p>The general syntax of the save subcommand is as follows:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman save [-o FILE_NAME] IMAGE_NAME[:TAG]<\/pre>\n<p>Podman sends the generated image to the standard output as binary data. To avoid that, use the <code>-o<\/code> option. The following example saves the previously downloaded MySQL container image from the Red Hat Container Catalog to the mysql.tar file:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman save -o mysql.tar registry.access.redhat.com\/rhscl\/mysql-57-rhel7:5.7<\/pre>\n<p>Use the .tar files generated by the save subcommand for backup purposes. To restore the container image, use the podman load command. The general syntax of the command is as follows:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman load [-i FILE_NAME]\r\n<\/pre>\n<p>For example, this command would load an image saved in a file named mysql.tar.<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman load -i mysql.tar<\/pre>\n<p>If the .tar file given as an argument is not a container image with metadata, the podman load command fails. To save disk space, compress the file generated by the <code>save<\/code> subcommand with Gzip using the <code>--compress<\/code> parameter. The load subcommand uses the <code>gunzip<\/code> command before importing the file to the local storage.<\/p>\n<p><span style=\"color: #3366ff;\"><b>Deleting Images<\/b><\/span><br \/>\nPodman keeps any image downloaded in its local storage, even the ones currently unused by any container. However, images can become outdated, and should be subsequently replaced. Any updates to images in a registry are not automatically updated. The image must be removed and then pulled again to guarantee that the local storage has the latest version of an image.<\/p>\n<p>To delete an image from the local storage, run the<code> podman rmi<\/code> command.<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman rmi [OPTIONS] IMAGE [IMAGE...]<\/pre>\n<p>An image can be referenced using its name or its ID for removal purposes. Podman cannot delete images while containers are using that image. You must stop and remove all containers using that image before deleting it. To avoid this, the rmi subcommand has the <code>--force<\/code> option. This option forces the removal of<br \/>\nan image even if that the image is used by several containers or these containers are running.\u00a0 Podman stops and removes all containers using the forcefully removed image before removing it.<br \/>\n<b><\/b><\/p>\n<p>To delete all images that are not used by any container, use the following command:<\/p>\n<pre class=\"lang:default decode:true\">$ sudo podman rmi -a\r\n<\/pre>\n<p>The command returns all the image IDs available in the local storage and passes them as parameters to the podman rmi command for removal. Images that are in use are not deleted. However, this does not prevent any unused images from being removed.<\/p>\n<p><span style=\"color: #3366ff;\"> <b>Modifying Images<\/b><\/span><br \/>\nIdeally, all container images should be built using a Dockerfile, in order to create a clean, lightweight set of image layers without log files, temporary files, or other artifacts created by the container customization. However, some users may provide container images as they are, without a Dockerfile. As an alternative approach to creating new images, change a running container in place and save its layers to create a new container image. The podman commit command<br \/>\nprovides this feature.<\/p>\n<p>Even though the podman commit command is the most straightforward approach to creating new images, it is not recommended because of the image size (commit keeps logs and process ID files in the captured layers), and the lack of change traceability. A Dockerfile provides a robust mechanism to customize and implement changes to a container using a human-readable set of commands, without the set of files that are generated by the operating system.<\/p>\n<p>The syntax for the podman commit command is as follows:<\/p>\n<pre class=\"lang:default decode:true\">$ sudo podman commit [OPTIONS] CONTAINER [REPOSITORY[:PORT]\/]IMAGE_NAME[:TAG]<\/pre>\n<p>The following table shows the most important options available for the podman commit command:<\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 36.0345%;\"><strong> Option<\/strong><\/td>\n<td style=\"width: 63.9655%;\"><strong> Description<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 36.0345%;\"><code> --author \"\"<\/code><\/td>\n<td style=\"width: 63.9655%;\">Identifies who created the container image.<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 36.0345%;\"><code> --message \"\"<\/code><\/td>\n<td style=\"width: 63.9655%;\">Includes a commit message to the registry.<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 36.0345%;\"><code> --format<\/code><\/td>\n<td style=\"width: 63.9655%;\">Selects the format of the image. Valid options<br \/>\nare oci and docker.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The <code>--message<\/code> option is not available in the default OCI container format.<\/p>\n<pre class=\"lang:default decode:true \">To find the ID of a running container in Podman, run the podman ps command:\r\n$ sudo podman ps\r\nCONTAINER ID IMAGE ... NAMES\r\n87bdfcc7c656 mysql ...output omitted... mysql-basic<\/pre>\n<p>Eventually, administrators might customize the image and set the container to the desired state. To identify which files were changed, created, or deleted since the container was started, use the <code>diff<\/code> subcommand. This subcommand only requires the container name or container ID:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman diff mysql-basic\r\nC \/run\r\nC \/run\/mysqld\r\nA \/run\/mysqld\/mysqld.pid\r\nA \/run\/mysqld\/mysqld.sock\r\nA \/run\/mysqld\/mysqld.sock.lock\r\nA \/run\/secrets<\/pre>\n<p>The diff subcommand tags any <em>added<\/em> file with an <code>A<\/code>, any <em>changed<\/em> ones with a <code>C<\/code>, and any <em>deleted<\/em> file with a<code> D<\/code>. The diff command only reports added, changed, or deleted files to the container file system. Files that are mounted to a running container are not considered part of the container file system.<\/p>\n<p>To retrieve the list of mounted files and directories for a running container, use the podman inspect command:<\/p>\n<pre class=\"lang:default decode:true\">$ sudo podman inspect \\\r\n-f \"{{range .Mounts}}{{println .Destination}}{{end}}\" CONTAINER_NAME\/ID<\/pre>\n<p>Any file in this list, or file under a directory in this list, is not shown in the output of the podman diff command.<br \/>\nTo commit the changes to another image, run the following command:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman commit mysql-basic mysql-custom<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\"> <b>Tagging Images<\/b><\/span><br \/>\nA project with multiple images based on the same software could be distributed, creating individual projects for each image, but this approach requires more maintenance for managing and deploying the images to the correct locations. Container image registries support tags to distinguish multiple releases of the same project. For example, a customer might use a container image to run with a MySQL or PostgreSQL database, using a tag as a way to differentiate which database is to be used by a container image. Usually, the tags are used by container developers to distinguish between multiple versions of the same software. Multiple tags are provided to identify a release easily.<\/p>\n<p>To tag an image, use the podman tag command:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman tag [OPTIONS] IMAGE[:TAG] \\\r\n [REGISTRYHOST\/][USERNAME\/]NAME[:TAG]<\/pre>\n<p>The IMAGE argument is the image name with an optional tag, which is managed by Podman. The following argument refers to the new alternative name for the image. Podman assumes the latest version, as indicated by the latest tag, if the tag value is absent. For example, to tag an image, use the following command:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman tag mysql-custom devops\/mysql\r\n<\/pre>\n<p>The mysql-custom option corresponds to the image name in the container registry. To use a different tag name, use the following command instead:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman tag mysql-custom devops\/mysql:snapshot\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\"><b>Removing Tags from Images<\/b><\/span><br \/>\nA single image can have multiple tags assigned using the podman tag command. To remove them, use the podman rmi command, as mentioned earlier:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman rmi devops\/mysql:snapshot<\/pre>\n<p>Because multiple tags can point to the same image, to remove an image referred to by multiple tags, first remove each tag individually.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\"><b>Best Practices for Tagging Images<\/b><\/span><br \/>\nPodman automatically adds the latest tag if you do not specify any tag, because Podman considers the image to be the latest build. However, this may not be true depending on how each project uses tags. For example, many open source projects consider the latest tag to match the most recent release, but not the latest build. Moreover, multiple tags are provided to minimize the need to remember the latest release of a particular version of a project. Thus, if there is a project version release, for example, 2.1.10, another tag called 2.1 can be created pointing to the same image from the 2.1.10 release. This simplifies pulling images from the registry.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\"><b>Publishing Images to a Registry<\/b><\/span><br \/>\nTo publish an image to a registry, it must reside in the Podman&#8217;s local storage and be tagged for identification purposes. To push the image to the registry the syntax of the push subcommand is:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman push [OPTIONS] IMAGE [DESTINATION]<\/pre>\n<p>For example, to push the bitnami\/nginx image to its repository, use the following command:<\/p>\n<pre class=\"lang:default decode:true \">$ sudo podman push quay.io\/bitnami\/nginx<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Image registries are services offering container images to download. They allow image creators and maintainers to store and distribute container images to public or private audiences. Podman searches for and downloads container images from public and private registries. Red Hat Container Catalog is the public image registry managed by Red Hat. It hosts a large &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/miro.borodziuk.eu\/index.php\/2023\/05\/23\/container-life-cycle-management-with-podman\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Managing Container Images with Podman&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":4726,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[91],"tags":[],"_links":{"self":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/4725"}],"collection":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/comments?post=4725"}],"version-history":[{"count":16,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/4725\/revisions"}],"predecessor-version":[{"id":4763,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/4725\/revisions\/4763"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/media\/4726"}],"wp:attachment":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/media?parent=4725"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/categories?post=4725"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/tags?post=4725"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}