podman的使用

Posted 寒江雪linux

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了podman的使用相关的知识,希望对你有一定的参考价值。

podman的使用

设置别名

[root@hzy ~]# alias
alias cp='cp -i'
alias docker='podman'

拉取镜像

[root@hzy ~]# docker pull nginx
Resolving "nginx" using unqualified-search registries (/etc/containers/registries.conf)
Trying to pull docker.io/library/nginx:latest...
Getting image source signatures
Copying blob 33847f680f63 skipped: already exists  
Copying blob c90b090c213b done  
Copying blob 1f41b2f2bf94 done  
Copying blob dbb907d5159d done  
Copying blob b10cf527a02d done  
Copying blob 8a268f30c42a done  
Copying config 08b152afcf done  
Writing manifest to image destination
Storing signatures
08b152afcfae220e9709f00767054b824361c742ea03a9fe936271ba520a0a4b

运行容器

[root@hzy ~]# docker run -d --name nginx -p 80:80 nginx 
bcb891fcc9e7ab89413ca418fd0cace16ba5d858110577ac3ee4a802250df28c
[root@hzy ~]# docker ps
CONTAINER ID  IMAGE                           COMMAND               CREATED         STATUS             PORTS               NAMES
bcb891fcc9e7  docker.io/library/nginx:latest  nginx -g daemon o...  16 seconds ago  Up 16 seconds ago  0.0.0.0:80->80/tcp  nginx
[root@hzy ~]# curl 192.168.207.137
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body 
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

查看容器的详细信息

[root@hzy ~]# docker inspect -l //-l表示最后创建的容器

[
    
        "Id": "bcb891fcc9e7ab89413ca418fd0cace16ba5d858110577ac3ee4a802250df28c",
        "Created": "2021-08-13T09:45:41.302784855+08:00",
        "Path": "/docker-entrypoint.sh",
        "Args": [
            "nginx",
            "-g",
            "daemon off;"
        ],
        "State": 
            "OciVersion": "1.0.2-dev",
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 19936,
……

查看容器日志

[root@hzy ~]# docker logs -f -l
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/08/13 01:45:41 [notice] 1#1: using the "epoll" event method
2021/08/13 01:45:41 [notice] 1#1: nginx/1.21.1
2021/08/13 01:45:41 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6) 
2021/08/13 01:45:41 [notice] 1#1: OS: Linux 4.18.0-257.el8.x86_64
2021/08/13 01:45:41 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/08/13 01:45:41 [notice] 1#1: start worker processes
2021/08/13 01:45:41 [notice] 1#1: start worker process 31
2021/08/13 01:45:41 [notice] 1#1: start worker process 32
2021/08/13 01:45:41 [notice] 1#1: start worker process 33
2021/08/13 01:45:41 [notice] 1#1: start worker process 34
192.168.207.131 - - [13/Aug/2021:01:46:04 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.67" "-"
2021/08/13 01:46:04 [error] 31#31: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.207.131, server: hzy, request: "GET /favicon.ico HTTP/1.1", host: "192.168.207.137", referrer: "http://192.168.207.137/"
192.168.207.131 - - [13/Aug/2021:01:46:04 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://192.168.207.137/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.67" "-"
192.168.207.137 - - [13/Aug/2021:01:46:15 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.61.1" "-"

查看容器pid

USER    PID   PPID   %CPU    ELAPSED           TTY   TIME   COMMAND
root    1     0      0.000   8m36.799916878s   ?     0s     nginx: master process nginx -g daemon off; 
nginx   31    1      0.000   8m35.800072169s   ?     0s     nginx: worker process 
nginx   32    1      0.000   8m35.800114617s   ?     0s     nginx: worker process 
nginx   33    1      0.000   8m35.800158776s   ?     0s     nginx: worker process 
nginx   34    1      0.000   8m35.800190938s   ?     0s     nginx: worker process 

上传镜像

[root@hzy ~]# docker login
Username: 18463751776
Password: 
Login Succeeded!
[root@hzy ~]# docker tag  docker.io/library/1228322088/test:nginx 1228322088/test:nginx
[root@hzy ~]# docker push 18463751776/test:nginx
Getting image source signatures
Copying blob ca4de55a7918 skipped: already exists  
Copying blob 0d97d41c4cc9 skipped: already exists  
Copying blob 17a18be5dbcf skipped: already exists  
Copying blob 79409a31937f skipped: already exists  
Copying blob 814bff734324 [--------------------------------------] 0.0b / 0.0b
Copying config bde40dcb22 done  
Writing manifest to image destination
Storing signatures

授权文件

podman login 登录,默认授权文件位于中$XDG_RUNTIME_DIR/containers/auth.json

[root@hzy ~]# docker login
Authenticating with existing credentials...
Existing credentials are valid. Already logged in to docker.io
[root@hzy ~]# cat /run/user/0/containers/auth.json 

    "auths": 
        "docker.io": 
            "auth": "**************"
        
    

使用卷

容器与root用户一起运行,则root容器中的用户实际上就是主机上的用户。UID/GID1是在/etc/subuid和/etc/subgid等用户映射中指定的第一个UID/GID。如果普通用户的身份从主机目录挂载到容器中,并在该目录中以root用户身份创建文件,则会看到它实际上是你的用户在主机上拥有的

[root@hzy ~]$ docker run -it  -v /tmp/root:/root httpd /bin/sh
# cd /root
# touch 111
# ls -l
total 0
-rw-r--r--. 1 root root 0 Aug 13 03:19 111
[root@hzy ~]# ll /tmp/root/
total 0
-rw-r--r--. 1 root root 0 Aug 13 11:19 111

--userns=keep-id参数,以确保用户被映射到容器内自己的UID和GID

[root@hzy ~]$ docker run -it --rm -v /tmp/root:/root --userns=keep-id httpd /bin/sh
$ whoami
root
$ touch 2222
$ ls -l
total 0
-rw-r--r--. 1 root root 0 Aug 13 03:23 111
-rw-r--r--. 1 root root 0 Aug 13 03:23 2222
[root@hzy ~]# ll /tmp/root/
total 0
-rw-r--r--. 1 root root 0 Aug 13 11:23 111
-rw-r--r--. 1 root root 0 Aug 13 11:23 2222

使用普通用户映射容器端口时会报“ permission denied”的错误

[root@hzy ~]$ docker 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

普通用户可以映射>= 1024的端口

[root@hzy ~]$ docker run  -d -p 1024:80 httpd
0643591b2ca22c826f0945a58807a30a83cd0dedfe9daccd5dbc0efdab1c2c9f
[root@hzy ~]$ 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               [::]:*        

配置echo ‘net.ipv4.ip_unprivileged_port_start=80’ >> /etc/sysctl.conf后可以映射大于等于80的端口

[root@hzy user]# echo  'net.ipv4.ip_unprivileged_port_start=80'  >> /etc/sysctl.conf
[root@hzy user]# sysctl -p
net.ipv4.ip_unprivileged_port_start = 80
[root@hzy ~]$ docker run -d -p 80:80 httpd
409221aa479316a50f43a074b7234daa46625beaea32e0eccc819d033b0b33aa
[root@hzy ~]$ 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                    *:81                  *:*               
LISTEN   0        128                 [::]:22               [::]:*   

普通用户使用的配置

在允许没有root特权的用户运行podman之前,管理员必须需要安装或构件podman并完成以下配置

在允许没有特殊权限的用户运行podman之前,管理员必须需要安装或构件podman并完成以下配置

cgroup V2Linux内核功能允许用户限制普通用户容器可以使用的资源,如果使用cgroup V2启用了运行Podman的Linux发行版,则可能需要更改默认的OCI运行时。某些较旧的版本runc不适用于cgroup V2,必须切换到备用OCI运行时crun。

[root@hzy ~]# rpm -aq| grep crun
crun-0.18-2.module_el8.4.0+830+8027e1c4.x86_64

可以使用--runtime选项在命令行中打开对cgroup V2的替代OCI运行时支持

podman --runtime crun

或者修改containers.conf文件

[root@hzy ~]# vim /usr/share/containers/containers.conf 
……
runtime = "crun"
……
[root@hzy ~]# docker inspect nginx | grep crun
        "OCIRuntime": "crun",
            "crun",

安装slirp4netns

slirp4nets包为普通用户提供一种网络模式

[root@hzy ~]# rpm -qa | grep slirp4netns
slirp4netns-1.1.8-1.module_el8.4.0+641+6116a774.x86_64

安装fuse-overlayfs

在普通用户环境中使用Podman时,建议使用fuse-overlayfs而不是VFS文件系统,至少需要版本0.7.6

[root@hzy ~]# rpm -qa | grep fuse-overlayfs
fuse-overlayfs-1.4.0-3.module_el8.4.0+830+8027e1c4.x86_64

配置storage.conf文件

[root@hzy ~]# vim /etc/containers/storage.conf 
……
driver = "overlay"
……
mount_program = "/usr/bin/fuse-overlayfs"
……

/etc/subuid和/etc/subgid配置

podman要求运行它的用户在/etc/subuid和/etc/subgid文件中列出一系列UID,shadow-utils或newuid包需要提供这些文件

[root@hzy ~]# rpm -qa| grep shadow-util
shadow-utils-4.6-12.el8.x86_64

可以在/etc/subuid和/etc/subgid查看,每个用户的值必须唯一且没有任何重叠

[root@hzy ~]# useradd ha
[root@hzy ~]# cat /etc/subuid 
ha:100000:65536

该文件的格式为USERNAME:UID:RANGE

  • 在/etc/passwd或个体pwent中列出用户名
  • 为用户分配的初始UID
  • 为用户分配的UID范围的大小

用户的配置文件

container.conf

podman读取顺序

  • /usr/share/containers/containers.conf
  • /etc/containers/containers.conf
  • ~/.configg/containers/containers.conf

storage.conf

podman读取顺序

  • /etc/containers/storage.conf
  • ~/.configg/containers/storage.conf

在普通用户中这些字段默认

runroot = "/run/containers/storage"

# Primary Read/Write location of container storage
graphroot = "/var/lib/containers/storage"

# Storage path for rootless users
#
# rootless_storage_path = "$HOME/.local/share/containers/storage"

registries.conf

podman的读取顺序

  • /etc/containers/registries.conf
  • /etc/containers/registries.d/*
  • ~/.config/containers/registries.conf

容器网络配置

创建新网络

[root@hzy ~]# docker network create mynetwork
[root@hzy ~]# docker network ls
NAME       VERSION  PLUGINS
podman     0.4.0    bridge,portmap,firewall,tuning
mynetwork  0.4.0    bridge,portmap,firewall,tuning

修改新生成的网络配置文件的子网和网关或者创建时使用–subnet 指定网段和子网掩码,–gateway指定网关

[root@hzy ~]# vim /etc/cni/net.d/mynetwork.conflist 

   "cniVersion": "0.4.0",
   "name": "mynetwork",
   "plugins": [
      
         "type": "bridge",
         "bridge": "cni-podman1",
         "isGateway": true,
         "ipMasq": true,
         "hairpinMode": true,
         "ipam": 
            "type": "host-local",
            "routes": [
               
                  "dst": "0.0.0.0/0"
               
            ],
            "ranges": [
               [
                  
                     "subnet": "192.168.207.0/24",
                     "gateway": "192.168.207.1"
……

修改/usr/share/containers/containers.conf文件设置默认网络为新创建的网络

[root@hzy ~]# vim /usr/share/containers/containers.conf 
……
[network]

# Path to directory where CNI plugin binaries are located.
#
# cni_plugin_dirs = ["/usr/libexec/cni"]

# Path to the directory where CNI configuration files are located.
#
default_network = "mynetwork"
……

创建容器查看网络

[root@hzy ~]# docker run -it --rm  bash
bash-5.1# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
3: eth0@if19: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP 
    link/ether 2a:12:9f:df:91:eb brd ff:ff:ff:ff:ff:ff
    inet 192.168.207.136/24 brd 192.168.207.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::2812:9fff:fedf:91eb/64 scope link tentative 
       valid_lft forever preferred_lft forever

容器的导入和导出

首先修改runtime为runc

[root@hzy ~]# vim /usr/share/containers/containers.conf 
……
runtime = "runc"
……

运行一个容器并导出

[root@hzy ~]# docker run -dt --name httpd -p 8080:80/tcp httpd
8e85e9a56944f988337653b8a6e8d715f32b279c56de2d2ee16d276649e755e2
[root@localhost ~]# docker inspect httpd | grep -i runtime
        "OCIRuntime": "runc",
            "--runtime",
            "Runtime": "oci",
            "CpuRealtimeRuntime": 0,
[root@hzy ~]# docker container checkpoint httpd -e /tmp/http.tar.gz
8e85e9a56944f988337653b8a6e8d715f32b279c56de2d2ee16d276649e755e2
[root@hzy ~]# ls /tmp
containers-user-1001  http.tar.gz         run-1001
ha                    ks-script-0ljylxmv  vmware-root_921-3980298495
hzy                 podman-run-1001

删除容器再导入

[root@hzy ~]# docker ps -a
CONTAINER ID  IMAGE                           COMMAND           CREATED        STATUS                         PORTS                 NAMES
8e85e9a56944  docker.io/library/httpd:latest  httpd-foreground  2 minutes ago  Exited (0) About a minute ago  0.0.0.0:8080->80/tcp  httpd
[root@hzy ~]# docker rm 8e85e9a56944
8e85e9a56944f988337653b8a6e8d715f32b279c56de2d2ee16d276649e755e2
[root@hzy ~]# docker container restore -i /tmp/http.tar.gz
8e85e9a56944f988337653b8a6e8d715f32b279c56de2d2ee16d276649e755e2
[root@hzy ~]# docker ps
CONTAINER ID  IMAGE                           COMMAND           CREATED         STATUS             PORTS                 NAMES
8e85e9a56944  docker.io/library/httpd:latest  httpd-foreground  14 seconds ago  Up 15 seconds ago  0.0.0.0:8080->80/tcp  httpd

以上是关于podman的使用的主要内容,如果未能解决你的问题,请参考以下文章

使用 Podman

podman用啥语言开发的

新手带你手把手搭建podman

podman的使用

podman的使用

podman的使用