Docker is gone, Podman is about to rise!

Introduction to Podman

What is Podman?

Podman is an open source container runtime project that can be used on most Linux platforms. Podman provides functions very similar to Docker. As mentioned earlier, it does not need to run any daemons on your system, and it can also run without root privileges.

Podman can manage and run any container and container image conforming to the OCI (Open Container Initiative) specification. Podman provides a Docker compatible command line front end to manage Docker images.

Podman official website address:

What are the main differences between Podman and Docker?
  • When dockers implements CRI, it needs a daemon, and then it needs to run as root, which also brings security risks.
  • podman does not need a daemon, nor does it need to be run by the root user. In terms of logical architecture, it is more reasonable than docker.
  • In the operating system of docker, multiple daemon s are required to call RunC, the implementation of OCI.
  • In the container managed link, the implementation of Docker Engine is dockerd
  • daemon, which needs to run as root in linux, dockerd calls containerd, containerd calls containerd shim, and then runC can be called. As the name suggests, shim functions as a "shim" to prevent the parent process from exiting and affecting the operation of the container
  • podman directly calls OCI,runtime (runC), and uses common as the management tool of the container process, but does not need a daemon running as root, such as dockerd.
  • In the podman system, there is a daemon called common. Its running path is usually / usr/libexec/podman/conmon. It is the parent process of each container process. Each container has one. The parent of common is usually process 1. Common in podman is actually equivalent to containerd shim in docker system.

What the figure shows is that podman does not need a daemon, while dorker needs a daemon. In the diagram, dorcker's containerd ship and podman's common are grouped in the Container layer.

What is the difference between Podman and docker?

The positioning of podman is also compatible with docker, so it should be used as close to docker as possible. In terms of use, it can be divided into two aspects: one is the perspective of the system builder, and the other is the perspective of the user.

In terms of system builder, the default software of podman is not different from docker, but in process model and process relationship. If you are used to the debugging method of several associated processes of docker, you need to adapt in podman. You can view the tree structure of the process through the pstree command. Overall, podman is simpler than docker. Since podman has one layer less daemon than docker, the restart mechanism is different.

In terms of users, podman is basically compatible with docker commands, Both include container runtime (run/start/kill/ps/inspect), local images (images/rmi/build), and image warehouse (login/pull/push) and other aspects. Therefore, podman's command line tools are similar to docker, such as building images, starting and stopping containers, etc. they can even be replaced by alias docker=podman. Therefore, even if podman is used, can still be used as the image warehouse, which is the most critical part of compatibility.

Podman common commands

podman run           Create and start the container
podman start       #Start container
podman ps          #View container
podman stop        #Terminate container
podman restart     #Restart container
podman attach      #Enter container
podman exec        #Enter container
podman export      #Export container
podman import      #Import container snapshot
podman rm          #Delete container
podman logs        #view log
podman search             #Retrieve image
docke pull                #Get image
podman images             #List mirrors
podman image Is           #List mirrors
podman rmi                #delete mirror
podman image rm           #delete mirror
podman save               #Export mirror
podman load               #Import mirror
podmanfile                #Custom image (three)
    podman build              #Build mirror
    podman run              #Run mirror
    podmanfile              #Common instructions (four)
        COPY                    #Copy file
        ADD                     #Advanced replication
        CMD                     #Container start command
        ENV                     #environment variable
        EXPOSE                  #Exposed port

Deploy Podman

//Install podman
[root@localhost ~]# yum -y install podman

//Warehouse configuration
[root@localhost ~]# vim /etc/containers/registries.conf
registries = ['', '', ''] //This is a search. Search from these three places. If only one is left, search in only one source
unqualified-search-registries = ["", "", "", ""] //It should also be changed to one here

registries = []   //Here are those http warehouses, such as harbor

//Configure accelerator
registries = ['','']

Using Podman

Using Podman is very simple. Most of the instructions of Podman and Docker are the same. Here are some common examples:

Run a container
[root@localhost ~]# podman run -d --name httpd
Trying to pull
Getting image source signatures
Copying blob e5ae68f74026 done  
Copying blob d3576f2b6317 done  
Copying blob bc36ee1127ec done  
Copying blob f1aa5f54b226 done  
Copying blob aa379c0cedc2 done  
Copying config ea28e1b82f done  
Writing manifest to image destination
Storing signatures

//View mirror
[root@localhost ~]# podman images
REPOSITORY                  TAG      IMAGE ID       CREATED       SIZE     latest   ea28e1b82f31   11 days ago   148 MB
Lists the containers that are running
[root@localhost ~]# podman ps
CONTAINER ID  IMAGE                             COMMAND           CREATED             STATUS                 PORTS  NAMES
0492e405b9ec    httpd-foreground  About a minute ago  Up About a minute ago         httpd

Note: if you add - a to the ps command, Podman will display all containers.

Check running containers

You can "check" the metadata of a running container and details about itself. We can even use the inspect subcommand to view the IP address assigned to the container. Because the container is running in rootless mode, no IP address is assigned and the value will be listed as "None" in the output of the check.

[root@localhost ~]# podman inspect -l | grep IPAddress\": 
            "SecondaryIPAddresses": null, 
            "IPAddress": "",

[root@localhost ~]# curl
<html><body><h1>It works!</h1></body></html>

Note: - l is a convenient parameter for the latest container. You can also use the ID of the container instead of - l.

View the log of a running container
    --latest        #current
[root@localhost ~]# podman logs --latest
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using Set the 'ServerName' directive globally to suppress this message
[Mon Dec 13 15:17:53.690844 2021] [mpm_event:notice] [pid 1:tid 140665160166720] AH00489: Apache/2.4.51 (Unix) configured -- resuming normal operations
[Mon Dec 13 15:17:53.690946 2021] [core:notice] [pid 1:tid 140665160166720] AH00094: Command line: 'httpd -D FOREGROUND' - - [13/Dec/2021:15:19:48 +0000] "GET / HTTP/1.1" 200 45 - - [13/Dec/2021:15:20:47 +0000] "GET / HTTP/1.1" 200 45
View the process resource usage in a running container

You can use top to observe the nginx pid in the container


    podman top <container_id>  
[root@localhost ~]# podman top httpd
USER       PID   PPID   %CPU    ELAPSED            TTY   TIME   COMMAND
root       1     0      0.000   15m38.599711321s   ?     0s     httpd -DFOREGROUND 
www-data   7     1      0.000   15m38.599783256s   ?     0s     httpd -DFOREGROUND 
www-data   8     1      0.000   15m38.599845342s   ?     0s     httpd -DFOREGROUND 
www-data   9     1      0.000   15m38.599880444s   ?     0s     httpd -DFOREGROUND 
Stop a running container
[root@localhost ~]# podman stop --latest
[root@localhost ~]# podman ps
Delete a container
[root@localhost ~]# podman rm --latest
[root@localhost ~]# podman ps -a

These features are basically the same as Docker. Besides being compatible with these features, Podman also supports some new features.

Upload image

For example, if we want to be in docker It's easy to share our new Nginx container image on Io. Log in to the dock first:

[root@localhost nginx]# tree 
├── Dockerfile
└── files
    └── nginx-1.20.1.tar.gz

[root@localhost nginx]# cat Dockerfile 

ENV PATH /usr/local/nginx/sbin:$PATH
ADD files/nginx-1.20.1.tar.gz /usr/src
RUN useradd -r -M -s /sbin/nologin nginx && \
    yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ make && \
    mkdir -p /var/log/nginx && \
    cd /usr/src/nginx-1.20.1 && \
    ./configure \
    --prefix=/usr/local/nginx \
    --user=nginx \
    --group=nginx \
    --with-debug \
    --with-http_ssl_module \
    --with-http_realip_module \
    --with-http_image_filter_module \
    --with-http_gunzip_module \
    --with-http_gzip_static_module \
    --with-http_stub_status_module \
    --http-log-path=/var/log/nginx/access.log \
    --error-log-path=/var/log/nginx/error.log && \
  make && make install

CMD ["nginx","-g","daemon off"]
[root@localhost nginx]# podman build -t nginx .
// Modify image name
 [root@localhost ~]# podman tag

// Log in and upload the image
[root@localhost ~]# podman login / / you need to tell them to log in to the docker warehouse
[root@localhost ~]# podman login
Username: 1314444        #account
Password: ********        #password
Login Succeeded!

[root@localhost nginx]# podman push / / upload image
Getting image source signatures
Copying blob 38c40d6c2c85 done
Copying blob fee76a531659 done
Copying blob c2adabaecedb done
Copying config 7f3589c0b8 done
Writing manifest to image destination
Copying config 7f3589c0b8 done
Writing manifest to image destination
Storing signatures

//Please note that we have pushed four layers to our registry, which can now be shared by others. Quick browse:
[root@localhost ~]# podman inspect 1314444/test:nginx
        "Id": "7f3589c0b8849a9e1ff52ceb0fcea2390e2731db9d1a7358c2f5fad216a48263",
        "Digest": "sha256:7822b5ba4c2eaabdd0ff3812277cfafa8a25527d1e234be028ed381a43ad5498",
        "RepoTags": [

In summary, Podman makes it easy to find, run, build, and share containers.

Configure alias

If you are used to using the Docker command, you can directly configure an alias for Podman to achieve seamless transfer. You just need to be here Add the following line under bashrc:

[root@localhost ~]# echo "alias docker=podman" >> .bashrc
source .bashrc
[root@localhost ~]# alias
alias cp='cp -i'
alias docker='podman'
User operation

Before allowing users without root privileges to run Podman, the administrator must install or build Podman and complete the following configuration.

The cgroup V2Linux kernel function allows users to limit the resources available to ordinary user containers. If the Linux distribution running Podman is enabled using cgroupV2, the default OCI runtime may need to be changed. Some older versions of runc are not applicable to cgroupV2 and must be switched to the standby OCI runtime crun.

[root@localhost ~]# Yum - y install crun / / centos8 comes with the system

[root@localhost ~]# vi /usr/share/containers/containers.conf 
    446 # Default OCI runtime
    447 # 
    448 runtime = "crun"      //Uncomment and change runc to crun

[root@localhost ~]# podman run -d --name web -p 80:80

[root@localhost ~]# podman inspect web | grep crun
        "OCIRuntime": "crun",
Install slirp4netns and fuse overlay FS

When using Podman in an ordinary user environment, it is recommended to use fuse overlay FS instead of VFS file system, which requires at least version 0.7 6. Now the new version is by default.

[root@localhost ~]# yum -y install slirp4netns

[root@localhost ~]# yum -y install fuse-overlayfs
[root@localhost ~]# vi /etc/containers/storage.conf
77 mount_program = "/usr/bin/fuse-overlayfs"     //note off
/Configuration of / etc/subuid and / etc/subgid

Podman requires the user running it to list a series of UIDs in the / etc/subuid and / etc/subgid files, which are provided by the shadow utils or newuid package

[root@localhost ~]# yum -y install shadow-utils

It can be viewed in / etc/subuid and / etc/subgid. The value of each user must be unique without any overlap.

[root@localhost ~]# useradd zz
[root@localhost ~]# cat /etc/subuid
[root@localhost ~]# cat /etc/subgid

// Start non privileged ping 
[root@localhost ~]# sysctl -w "net.ipv4.ping_group_range=0 200000" / > 100000 indicates that tom can operate podman
net.ipv4.ping_group_range = 0 200000

The format of this file is USERNAME:UID:RANGE

  • getpwent is the user name listed in / etc/passwd or output.
  • The initial UID assigned to the user.
  • The size of the UID range assigned to the user.

The usermod program can be used to assign UID s and GID S to users instead of directly updating files.

[root@localhost ~]# usermod --add-subuids 200000-201000 --add-subgids 200000-201000 hh
grep hh /etc/subuid /etc/subgid
User profile

The three main configuration files are container conf,storage.conf and registers conf. Users can modify these files as needed.

  • container.conf

    // User profile
    [root@localhost ~]# cat /usr/share/containers/containers.conf
    [root@localhost ~]# cat /etc/containers/containers.conf
    [root@localhost ~]# cat ~/.config/containers/containers.conf / / highest priority

    If they exist in this order. Each file can overwrite the previous file for a specific field.

  • Configure storage Conf file


    In ordinary users, / etc / containers / storage Some fields of conf will be ignored

    [root@localhost ~]#  vi /etc/containers/storage.conf
    # Default Storage Driver, Must be set for proper operation.
    driver = "overlay"        #Change here to overlay
    mount_program = "/usr/bin/fuse-overlayfs"        #note off
    [root@localhost ~]# sysctl user.max_user_namespaces=15000  #If the version is below 8, you need to do the following:

    In ordinary users, these fields default

  • registries.conf

The configuration is read in this order. These files are not created by default. You can copy the file / etc/containers from / usr/share/containers or modify it.

Authorization document

The password of docker account is written in this file and displayed in encrypted form

[root@localhost ~]# podman login
Username: 1314444
Login Succeeded!
[root@localhost ~]# cat /run/user/0/containers/auth.json 
        "auths": {
                "": {
                        "auth": "MTMxNDQ0NDpIMjAxNy0xOA=="

Ordinary users cannot see the image of the root user

//root user
[root@localhost ~]# podman images
REPOSITORY                  TAG      IMAGE ID       CREATED       SIZE     latest   ea28e1b82f31   11 days ago   146 MB

//Ordinary users
[root@localhost ~]# su - zz
[zz@localhost ~]$ podman images


  • If the container runs with the root user, the user in the root container is actually the user on the host.
  • UID GID is the first UID GID specified in the user mapping in / etc/subuid and / etc/subgid.
  • If an ordinary user is mounted from the host directory to the container and creates a file in the directory as root user, you will see that it is actually owned by your user on the host.
Use volume
[root@localhost ~]# su - zz
[zz@localhost ~]$ pwd
[zz@localhost ~]$ mkdir /home/zz/data

[zz@localhost ~]$ podman run -it -v "$(pwd)"/data:/data /bin/sh
Trying to pull
Getting image source signatures
Copying blob 3cb635b06aa2 done  
Copying config ffe9d497c3 done  
Writing manifest to image destination
Storing signatures
/ # ls
bin   data  dev   etc   home  proc  root  run   sys   tmp   usr   var
/ # cd data/
/data # ls
/data # touch 123
/data # ls -l
total 0
-rw-r--r--    1 root     root             0 Dec 13 00:17 123
View on host
[zz@localhost ~]$ ll data/
Total consumption 0
-rw-r--r-- 1 zz zz 0 12 June 13 00:17 123

//write file
[zz@localhost ~]$ echo "hell world" >> 123
[zz@localhost ~]$ cat 123
hell world
View in container
/data # cat 123
hell world

//We can find that the owner and group of files in the container belong to root, so how can we make them belong to tom user? Here's the answer
/data # ls -l
total 4
-rw-rw-r--    1 root     root            12 Dec 13 00:20 123

//Just add a -- userns = keep ID when running the container.
[zz@localhost ~]$ podman run -it --name test -v "$(pwd)"/data:/data --userns=keep-id /bin/sh
~ $ cd data/
/data $ ls -l
total 4
-rw-r--r--    1 zz       zz              11 Dec 13 00:21 123

"permission denied" error will be reported when using ordinary users to map container ports

[zz@localhost ~]$ podman run  -d -p 80:80 httpd
Error: rootlessport cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or choose a larger port number (>= 1024): listen tcp bind: permission denied

Ordinary users can map ports with > = 1024

[zz@localhost ~]$ podman run  -d -p 1024:80 httpd
[zz@localhost ~]$ ss -anlt
State       Recv-Q      Send-Q           Local Address:Port           Peer Address:Port      Process      
LISTEN      0           128                  *                      
LISTEN      0           128                          *:1024                      *:*                      
LISTEN      0           128                       [::]:22                     [::]:* 

Configure echo 'net ipv4. ip_ unprivileged_ port_ start=80’ >> /etc/sysctl. After conf, ports greater than or equal to 80 can be mapped

[root@localhost ~]# echo  'net.ipv4.ip_unprivileged_port_start=80'  >> /etc/sysctl.conf
[root@localhost ~]# sysctl -p
net.ipv4.ip_unprivileged_port_start = 80

[zz@localhost ~]$ podman run -d -p 80:80 httpd
[zz@localhost ~]$ ss -anlt
State       Recv-Q      Send-Q           Local Address:Port           Peer Address:Port      Process      
LISTEN      0           128                  *                      
LISTEN      0           128                          *:1024                      *:*                      
LISTEN      0           128                          *:80                        *:*                      
LISTEN      0           128                       [::]:22                     [::]:*  


Keywords: Java Linux Docker Programmer Container

Added by bombytza on Mon, 27 Dec 2021 16:16:13 +0200