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: https://podman.io/
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, docker.io can still be used as the image warehouse, which is the most critical part of compatibility.
Podman common commands
container
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
image
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.search] registries = ['registry.access.redhat.com', 'registry.redhat.io', 'docker.io'] //This is a search. Search from these three places. If only one is left, search in only one source unqualified-search-registries = ["registry.fedoraproject.org", "registry.access.redhat.com", "registry.centos.org", "docker.io"] //It should also be changed to one here [registries.insecure] registries = [10.0.0.1] //Here are those http warehouses, such as harbor //Configure accelerator [registries.search] registries = ['https://l9h8fu9j.mirror.aliyuncs.com','docker.io']
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 docker.io/library/httpd Trying to pull docker.io/library/httpd... 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 0492e405b9ecb05e6e6be1fec0ac1a8b6ba3ff949df259b45146037b5f355035 //View mirror [root@localhost ~]# podman images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/httpd 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 docker.io/library/httpd:latest 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": "10.88.0.5", [root@localhost ~]# curl 10.88.0.5 <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
option --latest #current [root@localhost ~]# podman logs --latest AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.5. Set the 'ServerName' directive globally to suppress this message AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.5. 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' 10.88.0.1 - - [13/Dec/2021:15:19:48 +0000] "GET / HTTP/1.1" 200 45 10.88.0.1 - - [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
Syntax:
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 2f3edf712621d3a41e03fa8c7f6a5cdba56fbbad43a7a59ede26cc88f31006c4 [root@localhost ~]# podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Delete a container
[root@localhost ~]# podman rm --latest 2f3edf712621d3a41e03fa8c7f6a5cdba56fbbad43a7a59ede26cc88f31006c4 [root@localhost ~]# podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
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 FROM docker.io/library/centos 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 docker.io/library/nginx:latest docker.io/1314444/test:latest // Log in and upload the image [root@localhost ~]# podman login docker.io / / you need to tell them to log in to the docker warehouse [root@localhost ~]# podman login docker.io Username: 1314444 #account Password: ******** #password Login Succeeded! [root@localhost nginx]# podman push docker.io/1314444/test:latest / / 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 //Output: [ { "Id": "7f3589c0b8849a9e1ff52ceb0fcea2390e2731db9d1a7358c2f5fad216a48263", "Digest": "sha256:7822b5ba4c2eaabdd0ff3812277cfafa8a25527d1e234be028ed381a43ad5498", "RepoTags": [ "docker.io/1314444/test:nginx", ......
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 docker.io/library/nginx c8664d2e43c872e1e5219f82d41f63048ed3a5ed4fb6259c225a14d6c243677f [root@localhost ~]# podman inspect web | grep crun "OCIRuntime": "crun", "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 zz:100000:65536 [root@localhost ~]# cat /etc/subgid zz:100000:65536 // 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 /etc/subuid:hh:200000:1001 /etc/subgid:hh:200000:1001
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
1./etc/containers/storage.conf 2.$HOME/.config/containers/storage.conf
In ordinary users, / etc / containers / storage Some fields of conf will be ignored
[root@localhost ~]# vi /etc/containers/storage.conf [storage] # 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
graphroot="$HOME/.local/share/containers/storage" runroot="$XDG_RUNTIME_DIR/containers"
- 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.
1./etc/containers/registries.conf 2./etc/containers/registries.d/* 3.HOME/.config/containers/registries.conf
Authorization document
The password of docker account is written in this file and displayed in encrypted form
[root@localhost ~]# podman login Username: 1314444 Password: Login Succeeded! [root@localhost ~]# cat /run/user/0/containers/auth.json { "auths": { "registry.fedoraproject.org": { "auth": "MTMxNDQ0NDpIMjAxNy0xOA==" } } }
Ordinary users cannot see the image of the root user
//root user [root@localhost ~]# podman images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/httpd latest ea28e1b82f31 11 days ago 146 MB //Ordinary users [root@localhost ~]# su - zz [zz@localhost ~]$ podman images REPOSITORY TAG IMAGE ID CREATED SIZE
volume
- 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 /home/zz [zz@localhost ~]$ mkdir /home/zz/data [zz@localhost ~]$ podman run -it -v "$(pwd)"/data:/data docker.io/library/busybox /bin/sh Trying to pull docker.io/library/busybox:latest... 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 docker.io/library/busybox /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 0.0.0.0:80: bind: permission denied
Ordinary users can map ports with > = 1024
[zz@localhost ~]$ podman run -d -p 1024:80 httpd 58613a6bdc70d4d4f9f624583f795a62a610596d166f0873bdff8fb26aa15092 [zz@localhost ~]$ ss -anlt State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 128 0.0.0.0:22 0.0.0.0:* 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 1215455a0c300d78e7bf6afaefc9873f818c6b0f26affeee4e2bc17954e72d8e [zz@localhost ~]$ ss -anlt State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 *:1024 *:* LISTEN 0 128 *:80 *:* LISTEN 0 128 [::]:22 [::]:*