容器引擎Podman常用命令浅析
Podman简介
Podman 是一个开源的无守护进程的容器引擎,用于在Linux系统上开发、管理和运行OCI容器。容器既可以以root身份运行,也可以在无root模式下运行。Podman 提供与 Docker 非常相似的功能,下一代容器引擎podman是docker的替代品。
Podman 可以管理和运行任何符合 OCI(Open Container Initiative)规范的容器和容器镜像。Podman 提供了一个与 Docker 兼容的命令行前端来管理 Docker 镜像。
Podman和Docker的区别
docker在实现CRI的时候,它需要一个守护进程,其次需要以root运行,因此这也带来了安全隐患。
podman不需要守护程序,也不需要root用户运行,从逻辑架构上,比docker更加合理。
在docker的运行体系中,需要多个daemon才能调用到OCI的实现RunC。
在容器管理的链路中,Docker Engine的实现就是dockerd
daemon,它在linux中需要以root运行,dockerd调用containerd,containerd调用containerd-shim,然后才能调用runC。顾名思义shim起的作用也就是“垫片”,避免父进程退出影响容器的运行
podman直接调用OCI,runtime(runC),通过common作为容器进程的管理工具,但不需要dockerd这种以root身份运行的守护进程。
在podman体系中,有个称之为common的守护进程,其运行路径通常是/usr/libexec/podman/common,它是各个容器进程的父进程,每个容器各有一个,common的父则通常是1号进程。podman中的common其实相当于docker体系中的containerd-shim。
图中所体现的事情是,podman不需要守护进程,而dorker需要守护进程。在这个图的示意中,dorcker的containerd-shim与podman的common被归在Container一层。
Podman的使用与docker使用的区别
podman的定位也是与docker兼容,因此在使用上面尽量靠近docker。在使用方面,可以分成两个方面来说,一是系统构建者的角度,二是使用者的角度。
在系统构建者方面,用podman的默认软件,与docker的区别不大,只是在进程模型、进程关系方面有所区别。如果习惯了docker几个关联进程的调试方法,在podman中则需要适应。可以通过pstree命令查看进程的树状结构。总体来看,podman比docker要简单。由于podman比docker少了一层daemon,因此重启的机制也就不同了。
在使用者方面,podman与docker的命令基本兼容,都包括容器运行时(run/start/kill/ps/inspect),本地镜像(images/rmi/build)、镜像仓库(login/pull/push)等几个方面。因此podman的命令行工具与docker类似,比如构建镜像、启停容器等。即便使用了podman,仍然可以使用http://docker.io作为镜像仓库,这也是兼容性最关键的部分。
Podman常用命令
容器
命令 | 用法 |
podman run | 创建并启动容器 |
podman start | 启动容器 |
podman ps | 查看容器 |
podman stop | 终止容器 |
podman restart | 重启容器 |
podman attach | 进入容器 |
podman exec | 进入容器 |
podman export | 导出容器 |
podman import | 导入容器快照 |
podman rm | 删除容器 |
podman logs | 查看日志 |
镜像
命令 | 用法 |
podman search | 检索镜像 |
podman pull | 获取镜像 |
podman images | 列出镜像 |
podman image Is | 列出镜像 |
podman rmi | 删除镜像 |
podman image rm | 删除镜像 |
podman save | 导出镜像 |
podman load | 导入镜像 |
podmanfile | 定制镜像(三个) |
podman build | 构建镜像 |
podman run | 运行镜像 |
podmanfile
podmanfile | 常用指令(四个) |
COPY | 复制文件 |
ADD | 高级复制 |
CMD | 容器启动命令 |
ENV | 环境变量 |
EXPOSE | 暴露端口 |
部署Podman配置镜像加速
//安装podman [root@localhost ~]# yum -y install podman //仓库配置 [root@localhost ~]# vim /etc/containers/registries.conf [registries.search] registries = ['registry.access.redhat.com', 'registry.redhat.io', 'docker.io'] //这个是查找,从这三个地方查找,如果只留一个,则只在一个源里查找 unqualified-search-registries = ["registry.fedoraproject.org", "registry.access.redhat.com", "registry.centos.org", "docker.io"] //这里也要改为一个 [registries.insecure] registries = [10.0.0.1] //这里写那些http的仓库,比如harbor //配置加速器 [registries.search] registries = ['https://l9h8fu9j.mirror.aliyuncs.com','docker.io']
描述:国内直接用拉取镜像会很慢所以需要配置阿里云容器镜像来加速访问。
配置说明: Podman 默认注册表配置文件在,把 location 对应的值修改为你的阿里云容器加速镜像地址然后重新启动服务即可;
# 参考1 unqualified-search-registries = ["docker.io"] [[registry]] prefix = "docker.io" insecure = true location = "xlx9erfu.mirror.aliyuncs.com" # 参考2 unqualified-search-registries = ['docker.io'] [[registry]] prefix = "docker.io" insecure = false location = "docker.io" [[registry.mirror]] location = "xlx9erfu.mirror.aliyuncs.com" insecure = true
注意事项:
版本1中registries.search, registries.insecure, and registries.block 格式已弃用
运行podman info命令可查看设置加速镜像
# 方式1 registries: docker.io: Blocked: false Insecure: false Location: docker.io MirrorByDigestOnly: false Mirrors: - Insecure: true Location: xlx9erfu.mirror.aliyuncs.com Prefix: docker.io search: - docker.io # 方式2 podman info -f "{{.Registries}}" map[docker.io:{docker.io {docker.io false} [{xlx9erfu.mirror.aliyuncs.com true}] false false} search:[docker.io]]
参考链接: https://github.com/containers/podman/issues/5764#issuecomment-611157552
使用Podman
podman 命令 - 容器管理常用命令
1.镜像容器信息流程
ps 子命令 - 列表容器
描述:打印出关于容器的信息
Examples:
# 1.显示所有容器信息并显示容器所属的pod id podman ps -ap # CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD ID PODNAME # 15e7d3797552 docker.io/mirrorgcrio/pause:3.2 25 hours ago Up 25 hours ago 73c5a062cb17-infra 73c5a062cb17 HelloWorld # 2fd059b66fb6 docker.io/library/hello-world:latest /hello 25 hours ago Exited (0) 25 hours ago friendly_neumann 73c5a062cb17 HelloWorld # 2.显示容器信息中指定的列 podman ps -ap --format "{{.ID}} {{.Image}} {{.Labels}} {{.Mounts}} {{.PodName}}" # 15e7d3797552 docker.io/mirrorgcrio/pause:3.2 map[] [] HelloWorld # 2fd059b66fb6 docker.io/library/hello-world:latest map[] [] HelloWorld # 3.显示文件的总大小并根据名称进行排序 podman ps --size --sort names # CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE # 15e7d3797552 docker.io/mirrorgcrio/pause:3.2 25 hours ago Up 25 hours ago 73c5a062cb17-infra 0B (virtual 683kB)
top 子命令 - 显示容器正在运行的进程
基础语法
podman top [options] container [format-descriptors] podman container top [options] container [format-descriptors] # 参数 --latest, -l # 显示通过Podman或以外的方式CRI-O运行容器 (The latest option is not supported on the remote client). # FORMAT DESCRIPTORS args, capbnd, capeff, capinh, capprm, comm, etime, group, hgroup, hpid, huser, label, nice, pcpu, pgid,pid, ppid, rgroup, ruser, seccomp, state, time, tty, user, vsz capbn:#Set of bounding capabilities. See capabilities (7) for more information. capeff:#Set of effective capabilities. See capabilities (7) for more information. capinh:#Set of inheritable capabilities. See capabilities (7) for more information. capprm:#Set of permitted capabilities. See capabilities (7) for more information. hgroup:#The corresponding effective group of a container process on the host. hpid:#The corresponding host PID of a container process. huser:#The corresponding effective user of a container process on the host. label:#Current security attributes of the process. seccomp:#Seccomp mode of the process (i.e., disabled, strict or filter). See seccomp (2) for more information. state:#Process state codes (e.g, R for running, S for sleeping). See proc(5) for more information. stime:#Process start time (e.g, "2019-12-09 10:50:36 +0100 CET).
Examples:
# 1.默认情况下,podman-top打印的数据类似ps -ef: $ sudo podman top 15e7d3797552 # USER PID PPID %CPU ELAPSED TTY TIME COMMAND # 0 1 0 0.000 46h15m55.488413816s ? 0s /pause # 2.可以通过在容器后面指定格式描述符作为参数来控制输出: $ podman top -l pid seccomp args %C # PID SECCOMP COMMAND %CPU # 1 filter sh 0.000 # 8 filter vi /etc/ 0.000 $ podman top -l pid seccomp state args %C # PID SECCOMP STATE COMMAND %CPU # 1 filter S nginx: master process nginx -g daemon off; 0.000 # 30 filter S nginx: worker process 0.000 # 31 filter S nginx: worker process 0.000 # 3.如果指定了未知的描述符,Podman将退回到在容器中执行ps(1)。 $ podman top -l -- aux USER PID PPID %CPU ELAPSED TTY TIME COMMAND root 1 0 0.000 1h2m12.497061672s ? 0s sleep 100000
status 子命令 - 查看运行中容器资源使用情况
Example:
$podman stats nginx ID NAME CPU % MEM USAGE / LIMIT MEM % NET IO BLOCK IO PIDS 19f105d5dc1e nginx -- 2.036MB / 1.893GB 0.11% 978B / 10.55kB -- / -- 2
log 子命令 - 查看容器运行的日志
Example:
podman logs nginx
inspect 子命令 - 镜像Image Layer信息
Example:
$ podman inspect nginx | grep -i "ipaddress" "SecondaryIPAddresses": null, "IPAddress": "10.88.0.110",
2.容器操作管理
pod 子命令 - 管理容器组的工具称为pods
描述:podman pod是一组管理pod或容器组的子命令。
# SYNOPSIS(n. 概要,大纲) podman pod subcommand # SUBCOMMANDS ┌────────┬───────────────────────┬─────────────────────────────┐ │Command │ Man Page │ Description │ ├────────┼───────────────────────┼─────────────────────────────┤ │create │ podman-pod-create(1) │ Create a new pod. │ ├────────┼───────────────────────┼─────────────────────────────┤ │exists │ podman-pod-exists(1) │ Check if a pod exists in local storage. │ ├────────┼───────────────────────┼─────────────────────────────┤ │inspect │ podman-pod-inspect(1) │ Displays information describing a pod. │ ├────────┼───────────────────────┼─────────────────────────────┤ │kill │ podman-pod-kill(1) │ Kill the main process of each container in one or more pods. │ ├────────┼───────────────────────┼─────────────────────────────┤ │pause │ podman-pod-pause(1) │ Pause one or more pods. │ ├────────┼───────────────────────┼─────────────────────────────┤ │prune │ podman-pod-prune(1) │ Remove all stopped pods and their containers. │ ├────────┼───────────────────────┼─────────────────────────────┤ │ps │ podman-pod-ps(1) │ Prints out information about pods. │ ├────────┼───────────────────────┼─────────────────────────────┤ │restart │ podman-pod-restart(1) │ Restart one or more pods. │ ├────────┼───────────────────────┼─────────────────────────────┤ │rm │ podman-pod-rm(1) │ Remove one or more stopped pods and containers. │ ├────────┼───────────────────────┼─────────────────────────────┤ │start │ podman-pod-start(1) │ Start one or more pods. │ ├────────┼───────────────────────┼─────────────────────────────┤ │stats │ podman-pod-stats(1) │ Display a live stream of resource usage stats for containers in one or more pods. │ ├────────┼───────────────────────┼─────────────────────────────┤ │stop │ podman-pod-stop(1) │ Stop one or more pods. │ ├────────┼───────────────────────┼─────────────────────────────┤ │top │ podman-pod-top(1) │ Display the running processes of containers in a pod. │ ├────────┼───────────────────────┼─────────────────────────────┤ │unpause │ podman-pod-unpause(1) │ Unpause one or more pods. │ └────────┴───────────────────────┴─────────────────────────────
example:
# 创建名称为 liuli 的 pod podman pod create --name liuli # 63cb481fd2fd6a02d97355d8f950e765e06654c3b3a25111bc4431320fae897e # 列出当前pod信息 podman pod ps podman pod list # POD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID # 63cb481fd2fd HugoBlog Running 40 minutes ago 2 6b317ba47f5b # 73c5a062cb17 HelloWorld Running 47 hours ago 2 15e7d3797552 # 列出指定pod中容器信息 podman pod top 73c5a062cb17 # USER PID PPID %CPU ELAPSED TTY TIME COMMAND # 0 1 0 0.000 47h27m58.166822731s ? 0s /pause podman pod top liuli # USER PID PPID %CPU ELAPSED TTY TIME COMMAND # 0 1 0 0.000 41m43.871974181s ? 0s /pause # root 1 0 0.000 41m43.872432777s ? 0s nginx: master process nginx -g daemon off; # nginx 30 1 0.000 41m43.872491657s ? 0s nginx: worker process # nginx 31 1 0.000 41m43.87252457s ? 0s nginx: worker process # 停止指定pod或者所有pod(其中的容器也随之停止) podman pod stop HelloWorld # 73c5a062cb17b5088072ec13c496c101b0b239f9aba1dcad93ba5d746cdfb12d podman pod stop $(podman pod ps -q) # 63cb481fd2fd6a02d97355d8f950e765e06654c3b3a25111bc4431320fae897e # 73c5a062cb17b5088072ec13c496c101b0b239f9aba1dcad93ba5d746cdfb12d # 删除指定Pod或者删除所有已经停止的pod podman pod rm -f liuli podman pod rm $(podman pod ps -q)
run 子命令 - 容器运行与构建
# 在指定pod中运行容器 podman run -d --pod liuli nginx:alpine Trying to pull docker.io/library/nginx:alpine... Getting image source signatures Copying blob f682f0660e7a done ... Copying config 6f715d38cf done Writing manifest to image destination Storing signatures e2a645aa73da2bf98c8e7598a4a1368f92959d18f60b8500c1af70132fb778ed
将 pod 导出为声明式部署清单:
podman generate kube liuli > HugoBlog.yaml
通过部署清单创建 pod:
podman play kube liuli.yaml cat liuli.yaml # Generation of Kubernetes YAML is still under development! # # Save the output of this file and use kubectl create -f to import # it into Kubernetes. # # Created with podman-2.0.6 apiVersion: v1 kind: Pod metadata: creationTimestamp: "2023-03-10T04:31:52Z" labels: app: liuli name: liuli spec: containers: - command: - nginx - -g - daemon off; env: - name: PATH value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - name: TERM value: xterm - name: NGINX_VERSION value: 1.19.2 - name: NJS_VERSION value: 0.4.3 - name: PKG_RELEASE value: "1" - name: container value: podman - name: HOSTNAME value: liuli image: docker.io/library/nginx:alpine name: inspiringkare resources: {} securityContext: allowPrivilegeEscalation: true capabilities: {} privileged: false readOnlyRootFilesystem: false seLinuxOptions: {} workingDir: / status: {} --- metadata: creationTimestamp: null spec: {} status: loadBalancer: {}
这是一个兼容 kubernetes 的 pod 定义,你可以直接通过 kubectl apply -f liuli.yaml 将其部署在 Kubernetes 集群中,也可以直接通过 podman 部署
container 子命令 - 容器相关操作以及备份导出
example:
Podman 支持将容器从一台机器迁移到另一台机器。 # 在源机器上对容器设置检查点并将容器打包到指定位置。 $ sudo podman container checkpoint <container_id> -e /tmp/checkpoint.tar.gz # 在目标机器上使用源机器上传输过来的打包文件对容器进行恢复。 $ sudo podman container restore -i /tmp/checkpoint.tar.gz