RedHat专属虚拟化工具-podman-第一季

1,767 阅读17分钟

前面一直在考证书,导致一直没有空闲更新帖子哈,各位老爷们,抱歉!

一、podman的自报家门

Podman是一种无守护进程、开源的 Linux 原生工具,旨在使用开放容器倡议 ( OCI ) 容器和 容器映像轻松查找、运行、构建、共享和部署应用程序。Podman 提供了任何使用过 Docker 容器引擎的人都熟悉的命令行界面 (CLI) 。大多数用户可以简单地将 Docker 别名为 Podman(别名 docker=podman),没有任何问题。与其他常见的 容器引擎(Docker、CRI-O、containerd)类似,Podman 依赖于符合 OCI 的 容器运行时(runc、crun、runv 等)与操作系统交互并创建正在运行的容器。这使得 Podman 创建的运行容器与任何其他常见容器引擎创建的容器几乎没有区别。
Podman 控制下的容器可以由 root 或非特权用户运行。Podman 使用 libpod库管理整个容器生态系统,包括 pod、容器、容器镜像和容器卷。Podman 专注于帮助您维护和修改 OCI 容器映像的所有命令和功能,例如拉取和标记。它允许您在生产环境中创建、运行和维护这些容器和容器映像。
有一个 RESTFul API 来管理容器。我们还有一个可以与 RESTFul 服务交互的远程 Podman 客户端。我们目前支持 Linux、Mac 和 Windows 上的客户端。RESTFul 服务仅在 Linux 上受支持。
如果您完全不熟悉容器,我们建议您查看 简介。对于高级用户或来自 Docker 的用户,请查看我们的 教程。对于高级用户和贡献者,您可以通过查看我们的 命令页面来获取有关 Podman CLI 的非常详细的信息。最后,对于寻求如何与 Podman API 交互的开发人员,请参阅我们的 API 文档 参考

二、podman工作机制

Podman 原来是 CRI-O 项目的一部分,后来被分离成一个单独的项目叫 libpod。Podman 的使用体验和 Docker类似,不同的是 Podman 没有 daemon。以前使用 Docker CLI 的时候,Docker CLI 会通过 gRPC API去跟 Docker Engine 说「我要启动一个容器」,然后 Docker Engine 才会通过 OCI Containerruntime(默认是 runc)来启动一个容器。这就意味着容器的进程不可能是 Docker CLI 的子进程,而是 DockerEngine 的子进程。
Podman 比较简单粗暴,它不使用 Daemon,而是直接通过 OCI runtime(默认也是 runc)来启动容器,所以容器的进程是podman 的子进程,这比较像 Linux 的 fork/exec 模型,而 Docker 采用的是 C/S(客户端/服务器)模型。
和C/S 模型相比,fork/exec 模型有很多优势,比如:

  1. 系统管理员可以知道某个容器进程到底是谁启动的。
  2. 如果利用 cgroup 对 podman 做一些限制,那么所有创建的容器都会被限制。
  3. SD_NOTIFY : 如果将 podman 命令放入 systemd 单元文件中,容器进程可以通过 podman 返回通知,表明服务已准备好接收任务。
  4. socket 激活 : 可以将连接的 socket 从 systemd 传递到 podman,并传递到容器进程以便使用它们。

三、docker和podman的区别

可能光看文字有那么点枯燥难以理解,下面上一张图帮助我们理解podman与docker的区别;

依照图中podman不需要守护进程,而dorker需要守护进程。在这个图的示意中,dorcker的containerd-shim与podman的common被归在Container一层。

ce8345714045c09912740e43fa530a3f.jpeg

总结:

  • dockers在实现CRI,它需要一个守护进程,其次需要以root运行,因此这也带来了安全隐患;

  • podman不需要守护程序,也不需要root用户运行,从逻辑架构上,比docker更加合理;

  • docker的运行体系中,需要多个daemon才能调用到OCI的实现RunC;

  • 容器管理的链路中,Docker Engine的实现就是dockerd;

  • demon,它在linux中需要以root运行,dockerd调用containerd,containerd调用containerd-shim,然后才能调用runC,顾名思义shim起的作用也就是“垫片”,避免父进程退出影响容器的运行;

  • podman直接调用OCI,runtime(runC),通过common作为容器进程的管理工具,但不需要dockerd这种以root身份运行的守护进程;

  • 在podman体系中,有个称之为common的守护进程,其运行路径通常是/usr/libexec/podman/conmon,它是各个容器进程的父进程,每个容器各有一个,common的父则通常是1号进程。podman中的common其实相当于docker体系中的containerd-shim;

四 实例演示

server: CentOS Linux 8 (Core)

Architecutre: x86-64

1. 安装部署podman (Centos 8)

[root@yb ~]# yum  module install -y container-tool

container-tools 模块包括安装多个工具的软件包,本次学习中使用的工具是podman和skopeo。

1-2 安装podman(Centos 7)

[root@localhost ~]# sudo subscription-manager repos --enable=rhel-7-server-extras-rpms  ##订阅并启用 Extras
[root@localhost ~]# sudo yum install -y podman        ##安装podman工具

2. 选择容器镜像和注册表

  1. 容器注册表是用于存储和检索容器镜像的存储库。开发人员将容器镜像上传或推送到容器注册表中,从注册表中将这些容器镜像下载或提取到本地系统,可用于运行容器。

  2. 可使用包含第三方镜像的公共注册表,也可以使用自己私有的注册表。容器镜像来源很重要,和任何其他软件包一样,您必须知道是否可以信任容器镜像中的代码。不同的注册表对于是否及如何提供评估和测试提交给它们的容器镜像有不同的策略。

  3. 官方通过两个主容器注册表分发认证容器镜像,而使用红帽登录凭据可访问这两个注册表。

    -- registry.redhat.io:适用于基于官方红帽产品的容器

    -- registry.connect.redhat.com: 适用于基于第三方产品的容器

3.相关配置文件

[root@yb ~]# cd    /etc/containers/      ##进入容器镜像配置目录

image.png

  1. registries.conf 是重要的镜像选择的配置文件,在这里我们可以使用自定义的镜像来加速镜像拉取

image.png 2. 这里我们做出重要修改来加速容器提取

[root@yb containers]# cp registries.conf  registries.bak     ##备份源文件
[root@yb containers]# vim registries.conf                    ## 编辑配置

unqualified-search-registries = [ "docker.io"]
[[registry]]
location = "f0pqsi2y.mirror.aliyuncs.com"      ## 配置本地阿里源容器地址
insecure = false                               ## 如果为真,未加密的 HTTP 以及与不受信任的 TLS 连接
blocked = false                                ## 如果为 true,则禁止拉取具有匹配名称的映像
  1. 查看配置是否生效
[root@yb ~]# podman  info  | grep f0pqsi2y.mirror.aliyuncs.com
  f0pqsi2y.mirror.aliyuncs.com:
    Location: f0pqsi2y.mirror.aliyuncs.com
    Prefix: f0pqsi2y.mirror.aliyuncs.com
  1. 容器命名约定 registry_name/user_name/image_name:tag
  • registry_name是存储镜像的注册表的名称。它通常是注册表的完全限定域名;
  • User_name表示镜像所属的用户或组织;
  • image_name: 在命名空间中必须唯一;
  • tag标识镜像版本。如果镜像名称不包含镜像标签,则假定为latest

五、podman常用操作

1、podman --help

    [root@103 ~]# podman --help
    Manage pods, containers and images
    管理豆荚,容器和图像
    Usage:
    用法:
    podman [options] [command]
    podman[选项](命令)
    Available Commands:
     可用命令:
    attach Attach to a running container
    附加到运行容器
    auto-update Auto update containers according to their auto-update policy
    Auto -update根据容器的自动更新策略自动更新容器
    build Build an image using instructions from Containerfiles
    使用容器文件中的指令构建映像
    commit Create new image based on the changed container
    commit根据更改的容器创建新的映像
    container Manage containers
    容器管理的容器
    cp Copy files/folders between a container and the local filesystem
    cp在容器和本地文件系统之间复制文件/文件夹
    create Create but do not start a container
    create创建但不启动容器
    diff Display the changes to the object's file system
    diff显示对对象文件系统的更改
    events Show podman events
    events显示podman事件
    exec Run a process in a running container
    在运行的容器中运行进程
    export Export container's filesystem contents as a tar archive
    export将容器的文件系统内容导出为tar存档文件
    generate Generate structured data based on containers, pods or volumes.
    生成基于容器、荚或卷的结构化数据。
    healthcheck Manage health checks on containers
    healthcheck管理容器的运行状况检查
    help Help about any command
    help表示对任何命令的帮助
    history Show history of a specified image
    history显示指定图像的历史记录
    image Manage images
    图像处理图像
    images List images in local storage
    images列出本地存储中的图像
    import Import a tarball to create a filesystem image
    import通过导入tarball来创建文件系统映像
    info Display podman system information
    info显示podman系统信息
    init Initialize one or more containers
    初始化化一个或多个容器
    inspect Display the configuration of object denoted by ID
    inspect显示ID表示的对象配置信息
    kill Kill one or more running containers with a specific signal
    kill使用特定信号杀死一个或多个正在运行的容器
    load Load image(s) from a tar archive
    load从tar存档文件中加载图像
    login Login to a container registry
    login登录到容器注册表
    logout Logout of a container registry
    logout容器注册表的注销
    logs Fetch the logs of one or more containers
    logs获取一个或多个容器的日志
    machine Manage a virtual machine
    machine管理虚拟机
    manifest Manipulate manifest lists and image indexes
    操作清单列表和图像索引
    mount Mount a working container's root filesystem
    挂载一个工作容器的根文件系统
    network Manage networks
    网络管理网络
    pause Pause all the processes in one or more containers
    暂停一个或多个容器中的所有进程
    play Play containers, pods or volumes from a structured file.
    从一个结构化文件中播放容器、豆荚或卷。
    pod Manage pods
    豆荚管理豆荚
    port List port mappings or a specific mapping for the container
    port列出容器的端口映射或特定映射
    ps List containers
    ps 列表容器
    pull Pull an image from a registry
    pull从注册表中提取一个图像
    push Push an image to a specified destination
    push将映像推送到指定的目的地
    rename Rename an existing container
    rename重命名现有容器
    restart Restart one or more containers
    restart重启一个或多个容器
    rm Remove one or more containers
    删除一个或多个容器
    rmi Removes one or more images from local storage
    rmi从本地存储中删除一个或多个映像
    run Run a command in a new container
    在新容器中运行命令
    save Save image(s) to an archive
    save将图像保存到存档中
    search Search registry for image
    search搜索图像注册表
    secret Manage secrets
    保密管理的秘密
    start Start one or more containers
    start启动一个或多个容器
    stats Display a live stream of container resource usage statistics
    stats显示实时的容器资源使用统计信息流
    stop Stop one or more containers
    stop停止一个或多个容器
    system Manage podman
    系统管理podman
    tag Add an additional name to a local image
    tag为本地图像添加额外的名称
    top Display the running processes of a container
    top显示容器的运行进程
    unmount Unmounts working container's root filesystem
    卸载工作容器的根文件系统
    unpause Unpause the processes in one or more containers
    unpause取消一个或多个容器中的进程
    unshare Run a command in a modified user namespace
    unshare在修改后的用户命名空间中执行命令
    untag Remove a name from a local image
    untag从本地映像中删除一个名称
    version Display the Podman Version Information
    version显示Podman版本信息
    volume Manage volumes
    卷管理卷
    wait Block on one or more containers
    wait一个或多个容器的Bloc

2、查看podman版本号

[root@yb ~]# podman --version 
podman version 3.3.1

这里有个比较重要的点,我提一下(centos的podman版本1.6.4 不支持--new参数),如果是这个版本或者以下,可能导致无根容器开机自启动失败!

3、podman info显示整个系统的信息

[root@yb ~]# podman  info 
host:
  arch: amd64
  buildahVersion: 1.22.3
  cgroupControllers:
  - cpuset
  - cpu
  - cpuacct
  - blkio
  - memory
  - devices
  - freezer
  - net_cls
  - perf_event
  - net_prio
  - hugetlb
  - pids
  - rdma
  cgroupManager: systemd
  cgroupVersion: v1
  conmon:
    package: conmon-2.0.29-1.module_el8.5.0+890+6b136101.x86_64
    path: /usr/bin/conmon
    version: 'conmon version 2.0.29, commit: 84384406047fae626269133e1951c4b92eed7603'
  cpus: 1
  distribution:
    distribution: '"centos"'
    version: "8"
  eventLogger: file
  hostname: yb
  idMappings:
    gidmap: null
    uidmap: null
  kernel: 4.18.0-193.28.1.el8_2.x86_64
  linkmode: dynamic
  memFree: 128077824
  memTotal: 890982400
  ociRuntime:
    name: runc
    package: runc-1.0.2-1.module_el8.5.0+911+f19012f9.x86_64
    path: /usr/bin/runc
    version: |-
      runc version 1.0.2
      spec: 1.0.2-dev
      go: go1.16.7
      libseccomp: 2.4.1
  os: linux
  remoteSocket:
    path: /run/podman/podman.sock
  security:
    apparmorEnabled: false
    capabilities: CAP_NET_RAW,CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SE
TUID,CAP_SYS_CHROOT    rootless: false
    seccompEnabled: true
    seccompProfilePath: /usr/share/containers/seccomp.json
    selinuxEnabled: false
  serviceIsRemote: false
  slirp4netns:
    executable: /usr/bin/slirp4netns
    package: slirp4netns-1.1.8-1.module_el8.5.0+890+6b136101.x86_64
    version: |-
      slirp4netns version 1.1.8
      commit: d361001f495417b880f20329121e3aa431a8f90f
      libslirp: 4.4.0
      SLIRP_CONFIG_VERSION_MAX: 3
      libseccomp: 2.4.1
  swapFree: 0
  swapTotal: 0
  uptime: 100h 51m 2.99s (Approximately 4.17 days)
registries:
  f0pqsi2y.mirror.aliyuncs.com:
    Blocked: false
    Insecure: false
    Location: f0pqsi2y.mirror.aliyuncs.com
    MirrorByDigestOnly: false
    Mirrors: null
    Prefix: f0pqsi2y.mirror.aliyuncs.com
  search:
  - docker.io
store:
  configFile: /etc/containers/storage.conf
  containerStore:
    number: 0
    paused: 0
    running: 0
    stopped: 0
  graphDriverName: overlay
  graphOptions:
    overlay.mountopt: nodev,metacopy=on
  graphRoot: /var/lib/containers/storage
  graphStatus:
    Backing Filesystem: xfs
    Native Overlay Diff: "false"
    Supports d_type: "true"
    Using metacopy: "true"
  imageStore:
    number: 0
  runRoot: /run/containers/storage
  volumePath: /var/lib/containers/storage/volumes
version:
  APIVersion: 3.3.1
  Built: 1636493036
  BuiltTime: Wed Nov 10 05:23:56 2021
  GitCommit: ""
  GoVersion: go1.16.7
  OsArch: linux/amd64
  Version: 3.3.1

4、查找镜像(举例apache镜像)

4-1:模糊查询 image.png

4-2:精准查询 image.png

5、拉取镜像:

[root@yb ~]# podman   pull  docker.io/library/httpd

image.png

6、运行一个容器

1、查看下载好的镜像

[root@yb ~]# podman  images 
REPOSITORY               TAG         IMAGE ID      CREATED     SIZE
docker.io/library/httpd  latest      28505717e3ae  5 days ago  150 MB

2、运行容器

[root@yb ~]# podman  run  -tid  --name  myweb -p  80:80  28505717e3ae
[root@yb ~]# podman  ps 
CONTAINER ID  IMAGE                           COMMAND           CREATED        STATUS            PORTS      
         NAMES0b762f3d7238  docker.io/library/httpd:latest  httpd-foreground  5 seconds ago  Up 5 seconds ago  0.0.0.0:80-
>80/tcp  myweb

3、测试一下

image.png

4、进入容器修改内容

[root@yb ~]# podman  exec -it  myweb  /bin/bash
# root@0b762f3d7238:/usr/local/apache2# ls
    bin  build  cgi-bin  conf  error  htdocs  icons  include  logs	modules
# root@0b762f3d7238:/usr/local/apache2# cd htdocs/
# root@0b762f3d7238:/usr/local/apache2/htdocs# ls
    index.html
# root@0b762f3d7238:/usr/local/apache2/htdocs# echo "hello world"  > index.html
# root@0b762f3d7238:/usr/local/apache2/htdocs# cat index.html 
    hello world
[root@yb ~]# curl 10.60.98.125
hello world

5、podman inspectl 查看容器详细信息

[root@yb ~]# podman  inspect  -l 

部分省略.......... image.png

6、查看容器日志

[root@yb ~]# podman  logs  -l

image.png

7、查看容器状态(这个经常使用到,建议记住)

[root@yb ~]# podman  top -l 

image.png

7、将容器保存为文件(比较重要)

  1. docker export 【容器名称】 [options] 【文件名称】 OPTIONS说明:
    -o表示输出的文件,这里指定了输出的路径,如果没有指定路径,则默认生成到当前文件夹。
[root@yb ~]# podman  export  -o myweb.tar.gz  myweb 
[root@yb ~]# ls
myweb.tar.gz
或者
[root@yb ~]# podman export myweb  > myweb.tar.gz
提示:此刻的容器正在运行中
  1. 从tar包导入内容为podman镜像
    docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
    OPTIONS说明:
    -c :应用docker 指令创建镜像;
    -m :提交时的说明文字
[root@yb ~]# podman  images 
REPOSITORY               TAG         IMAGE ID      CREATED     SIZE
docker.io/library/httpd  latest      28505717e3ae  5 days ago  150 MB
[root@yb ~]# ls
myweb.tar.gz
[root@yb ~]# podman import  myweb.tar.gz  apache-yb:v1 -m "this is web"
Getting image source signatures
Copying blob 776919d514f7 done  
Copying config 992fa5f7de done  
Writing manifest to image destination
Storing signatures
sha256:992fa5f7de42339d98beb23a004575d46f334226642544d010b2443d333990f5
[root@yb ~]# podman  images 
REPOSITORY               TAG         IMAGE ID      CREATED        SIZE
localhost/apache-yb      v1          992fa5f7de42  9 minutes ago  147 MB
docker.io/library/httpd  latest      28505717e3ae  5 days ago     150 MB

8. 将容器打包成镜像

可以使用podman commit命令来完成,podman commit可以从容器创建一个新的镜像

语法格式 docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

[root@yb ~]# podman  commit  -a "xbjuejin" 0b762f3d7238  apache.io/centos:v2
说明:此处命令和git和svn的命令有些类似  
commit 是提交的意思,类似告诉svn服务器我要生成一个新的版本。  
-m 添加注释  
-a 作者。  
108a85b1ed99 容器环境id:就是你每次输入命令行@后面的字符,例如:root@108a85b1ed99:/#  
daocloud.io/ubuntu:v2 镜像名称:hub的名称/镜像名称:tag  
-p,–pause=true 提交时暂停容器运行

image.png

9、将镜像打包成文件

docker save -o <保存路径> <镜像名称:标签>
[root@yb ~]# podman images 
REPOSITORY               TAG         IMAGE ID      CREATED         SIZE
apache.io/centos         v2          d42716ed65a3  8 minutes ago   150 MB
localhost/apache-yb      v1          992fa5f7de42  55 minutes ago  147 MB
docker.io/library/httpd  latest      28505717e3ae  5 days ago      150 MB
[root@yb ~]# podman  save -o ./images.tar.gz    docker.io/library/httpd
Getting image source signatures
Copying blob 8553b91047da done  
Copying blob 1f1fd2176485 done  
Copying blob ce0966b9747d done  
Copying blob dd2c46072168 done  
Copying blob bcd6790c3ff4 done  
Copying config 28505717e3 done  
Writing manifest to image destination
Storing signatures
[root@yb ~]# ls
images.tar.gz  myweb.tar.gz

10、将文件导入

命令解释:

方式一:podman load --input uu.tar(也可以使用podman load -i uu.tar或者 podman load < uu.tar);

方式二:docker load < uu.tar

[root@yb ~]# ls
images.tar.gz  myweb.tar.gz
[root@yb ~]# clan 
.bash_history  .bash_profile  .cshrc         myweb.tar.gz   .ssh/          .viminfo       
.bash_logout   .bashrc        images.tar.gz  .pip/          .tcshrc        
[root@yb ~]# podman  load  --input  images.tar.gz  
Getting image source signatures
Copying blob 8553b91047da skipped: already exists  
Copying blob 1f1fd2176485 skipped: already exists  
Copying blob ce0966b9747d skipped: already exists  
Copying blob dd2c46072168 skipped: already exists  
Copying blob bcd6790c3ff4 [--------------------------------------] 0.0b / 0.0b
Copying config 28505717e3 done  
Writing manifest to image destination
Storing signatures
Loaded image(s): docker.io/library/httpd:latest

11、看到容器、镜像导入,导出,文件什么的,可能有些同学已经开始口吐芬芳了,这里小饼给大家总结一下

容器导入导出与镜像导入导出区别 export/import 操作对象:容器 导出对象:tar文件 导入对象:镜像 镜像层数:一层 save/load 操作对象:镜像 导出对象:tar文件 导入对象:镜像 镜像层数:多层 说明: 你需要把 A 机器上的 甲 容器迁移到 B 机器, 且 甲 容器中有重要的数据需要随之一起迁移的, 就可以使用 export 和 import 参数来导入和导出

【导入的镜像层数】 最大的区别就在这里, 通过export 和 import导出的容器形成镜像时, 该镜像只有一层。通过save 和 load 导出的镜像保留了原镜像所有的层次结构, 导出时原镜像有几层, 导入的时候就还是有几层 想导出容器, 但是还想保留层次结构怎么办?

导出容器, 很快就想到唯一一个可以导出容器的工具 export,但是又想保留底层镜像的层次结构, 那么 export 就不符合需求了。想想导出带层次结构的工具就只有镜像导出工具 save 了, 但是容器在镜像层之上还有一层新的数据怎么一起导出去呢?

这个时候就需要引入一个新的参数 commit, 用来保存容器现有的状态为一个新的镜像。 比如在 A 机器上运行的甲容器是基于甲方乙方这个镜像跑起来的, 那么我就可以通过 commit 参数, 将 甲 容器的所有内容保存为一个新的镜像, 名字叫 私人订制 (内含一梗哦) 最后我再通过镜像导出工具 save 就可以完整的将 私人订制镜像(也就是 甲容器 )导出为一个 tar 包了 而且包含了 X+1 层镜像, X 层是原镜像 甲方乙方的所有镜像层数, 是容器甲多的那一层可写层的镜像

这里是小饼,本来打算一下子写完,篇幅限制实在是太长了,我打算第二篇接着来,下面是内容大纲

1-容器持久化存储

2-容器网络

3-root用户容器开机自动启动

4-无根容器开机自启动

总结!