Red Hat Enterprise Linux 8 的新玩意 第1 篇之容器工具 podman

Red Hat Enterprise Linux 8 (RHEL8) 的新玩意 第1篇 之容器工具 podman

podman

podman 用于操作容器和镜像. 它轻量化,抛弃了后台的daemon, 配合其底层的runc应用; 实现了与docker相同的功能比如pull, push, build, run, commit, tag等等,可用来代替 docker daemon 以及docker 命令行; 同时又拥有其扩展以及不同点:

  • 通过参数-a 或者 --all 来实现对容器,容器镜像的快速清理. 比如, podman rm --all 或者 podman rmi --all

  • podman 支持登陆功能, 可以通过登陆 Red Hat 镜像资源来获取 Red Hat 官方容器镜像. (访问Red Hat 镜像资源, 需要通过有效的Red Hat账户来登陆.)

    • Red Hat 官方镜像资源 registry.redhat.io;

    • Red Hat 维护的第三方资源 registry.connect.redhat.com

      登入:

      1
      #podman login -u rhn-support-goodluck https://registry.redhat.io

      登出:

      1
      #podman logout https://registry.redhat.io
  • docker 容器的存储路径在 /var/lib/docker 而 podman 则使用 /var/lib/containers

说了这么多,我们还是来具体看看 podman 的一些常用的命令比如 pull, run, build , commit;同时也可以使用 podman -h 来了解更多的命令

1 podman pull 这个命令可以用来从HUB上将需要的镜像拷贝到本地.

  • 比如将 rhel8-beta 镜像从Red Hat 官方的 registry.redhat.io 拷贝到本地.(记得先login哦)
    1
    podman pull registry.redhat.io/rhel8-beta
    1
    2
    3
    4
    5
    6
    7
    8
    [root@goodluck~]#podman pull registry.redhat.io/rhel8-beta
    Trying to pull registry.redhat.io/rhel8-beta...Getting image source signatures
    Copying blob 619051b1good: 66.48 MiB / 66.48 MiB [=========================] 56s
    Copying blob 386105aegood: 1.33 KiB / 1.33 KiB [===========================] 56s
    Copying config a80dad1cgood: 6.33 KiB / 6.33 KiB [==========================] 0s
    Writing manifest to image destination
    Storing signatures
    a80dad1c19537b0961e485dfa0a43fbe3c0a71cec2cca32d3264e087e396good
  • 比如将 fedora:29 镜像从 docker.io 拷贝到本地.
    1
    podman pull docker.io/library/fedora:29
    1
    2
    3
    4
    5
    6
    7
    [root@goodluck~]#podman pull docker.io/library/fedora:29
    Trying to pull docker.io/library/fedora:29...Getting image source signatures
    Copying blob 01eb0781good: 85.81 MiB / 85.81 MiB [=========================] 17s
    Copying config d09302f7good: 1.97 KiB / 1.97 KiB [==========================] 0s
    Writing manifest to image destination
    Storing signatures
    d09302f77cfcc3e867829d80ff47f9e7738ffef69730d54ec44341a9fb1dgood

    2 podman run 等同于 docker run, 通过一个容器镜像来启动一个进程(容器), 它拥有独立的文件系统,独立网络和其维护的进程树等等

  • 比如以交互模式来执行一个 RHEL 8 beta 容器
    1
    podman run -it registry.redhat.io/rhel8-beta/rhel /bin/bash
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [root@goodluck~]#podman run -it registry.redhat.io/rhel8-beta/rhel /bin/bash
    bash-4.4# cat /etc/redhat-release
    Red Hat Enterprise Linux release 8.0 Beta (Ootpa)
    bash-4.4# uname -a
    Linux 2b225eeecc44 4.18.0-80.el8.x86_64 #1 SMP Wed Mar 13 12:02:46 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
    bash-4.4# echo "hello podman :-)"
    hello podman :-)
    bash-4.4# exit
    exit
    小Tips: 如果启动过程中看到类似的信息,可以将 selinux 设置为 permissive
    1
    /bin/bash: error while loading shared libraries: libc.so.6: cannot change memory protections

    3 podman build 生成容器镜像,有两种方法来生成容器镜像

  • 通过 Dockerfile 来生成一个新的容器镜像我们需要编写一个 Dockerfile ;例子, 我们以 rhel8-beta 为基础, 让容器启动时,执行我们的 hello_podman.sh
    1
    2
    3
    4
    5
    [root@goodluck~]# cat Dockerfile
    # This is a test dockerfile
    FROM registry.redhat.io/rhel8-beta:latest
    ENTRYPOINT ["/usr/bin/hello_podman.sh"]
    RUN echo $'#!/bin/sh \n echo " *** HELLO PODMAN *** "'>/usr/bin/hello_podman.sh && chmod +x /usr/bin/hello_podman.sh
    以 hello_podman 为镜像的 tag 生成一个新的容器镜像
    1
    2
    3
    4
    5
    6
    7
    8
    [root@goodluck~]# podman build -t rhel8-beta:hello_podman .
    STEP 1: FROM registry.redhat.io/rhel8-beta:latest
    STEP 2: ENTRYPOINT ["/usr/bin/hello_podman.sh"]
    --> Using cache e010d561555d180015d6c0d30a3f67fa602ea1ae54628d5666235db42f43good
    STEP 3: FROM e010d561555d180015d6c0d30a3f67fa602ea1ae54628d5666235db42f43good
    STEP 4: RUN echo $'#!/bin/sh \n echo " *** HELLO PODMAN *** "'>/usr/bin/hello_podman.sh && chmod +x /usr/bin/hello_podman.sh
    --> Using cache a292528dfb8c1477419904d19dce108e3d2c105c6efbf0fd677d1dd47fe7good
    STEP 5: COMMIT rhel8-beta:hello_podman
    执行验证我们的镜像
    1
    2
    [root@goodluck~]# podman run rhel8-beta:hello_podman
    *** HELLO PODMAN ***
  • 通过修改一个运行中的容器来生成一个新的容器镜像
    首先,我们执行一个容器并作相应的修改
    例子和logs
    1
    2
    3
    4
    [root@goodluck~]# podman run -it registry.redhat.io/rhel8-beta /bin/bash
    bash-4.4# echo $'#!/bin/sh \n echo " *** HELLO PODMAN AGAIN*** "'>/usr/bin/hello_podman_again.sh && chmod +x /usr/bin/hello_podman_again.sh
    bash-4.4# exit
    exit
    找出刚刚执行且修改过的容器ID
    1
    2
    3
    [root@goodluck~]# podman ps -l
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    8dfd64dfgood registry.redhat.io/rhel8-beta/rhel:latest /bin/bash About a minute ago Exited (0) About a minute ago frosty_bhabha
    通过 commit 基于刚刚的容器镜像,以 hello_podman_again 为 tag 生成一个新的容器镜像.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [root@goodluck~]# podman commit 8dfd64dfgood rhel8-beta:hello_podman_again
    Getting image source signatures
    Skipping blob fba35a2dgood (already present): 200.01 MiB / 200.01 MiB [=====] 0s
    Skipping blob 848ae511good (already present): 10.00 KiB / 10.00 KiB [=======] 0s
    Copying blob aed58d13good: 5.50 KiB / 5.50 KiB [============================] 0s
    Copying config 4036a262good: 3.12 KiB / 3.12 KiB [==========================] 0s
    Writing manifest to image destination
    Storing signatures
    4036a262d1c54477cc8f5014bcb57be323b408c31c78f35a7f6b198a4f6agood
    执行验证我们的镜像
    1
    2
    [root@goodluck~]# podman run rhel8-beta:hello_podman_again /usr/bin/hello_podman_again.sh
    *** HELLO PODMAN AGAIN***

    使用 docker commit 意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为 黑箱镜像,换句话说,就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像,别人根本无从得知。而且,即使是这个制作镜像的人,过一段时间后也无法记清具体的操作。这种黑箱镜像的维护工作是非常痛苦的

4. 使用inspect 查看容器详细信息

1
# podman inspect 8dfd64dfgood

5. 使用logs 查看信息

1
# podman logs -f 8dfd64dfgood

6. 停止一个容器

1
# podman stop 8dfd64dfgood

7. 查看一个容器的文件系统的改动

1
# podman diff 8dfd64dfgood

8 查看镜像,容器,卷 占用的空间大小

1
2
3
4
5
# podman system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 57 4 57.3GB 57.3GB (99%)
Containers 5 0 1.36GB 1.36GB (100%)
Local Volumes 2 1 9.31MB 9.31MB (100%)

9 启动一个容器 -d 已 deamon的形式执行, -p host的端口:容器的端口

(格式为 EXPOSE <端口1> [<端口2>…]
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker/podman run -P 时,会自动随机映射 EXPOSE 的端口。
要将 EXPOSE 和在运行时使用 -p <宿主端口>:<容器端口> 区分开来。-p,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。) 注: 容器是否会长久运行,是和 docker run 指定的命令有关,和 -d 参数无关。

1
2
3
4
5
6
[root@sam Python-3.4.10]# podman run --rm --name webserver -d -p 8888:80 nginx
5d8a68f639dcdfea6e0a74a4916973b44b2babb0b3998bc0ec1c71f55c99b648
[root@sam Python-3.4.10]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5d8a68f639dc docker.io/library/nginx:latest nginx -g daemon o... 11 seconds ago Up 11 seconds ago 0.0.0.0:8888->80/tcp webserver
[root@sam Python-3.4.10]#

10 进入刚刚的容器 (也可以使用attach, 但是注意的,如果exit之后,容器也会终止, 使用exec则不会终止)

1
# podman exec -it webserver bash

11 使用diff看里面文件的修改

1
# podman diff webserver

12 查看修改的历史(–no-trunc 现实完整命令)

1
# podman history registry.redhat.io/rhel7:7.8-crash-v2

13 导出本地镜像

1
# docker export 7691a814370e > ubuntu.tar

14 一次清除所有在推出状态的容器

1
# podman container prune

15 仓库服务器

1
2
[Registry 注册服务器地址]		[仓库名]			[镜像名字]
registry.access.redhat.com/rhosp13/openstack-nova-compute

16 查找镜像可以使用search

1
# podman search centos

17 通过使用docker-registry建立本地镜像仓库(这将使用官方的 registry 镜像来启动私有仓库。默认情况下,仓库会被创建在容器的 /var/lib/registry 目录下。你可以通过 -v 参数来将镜像文件存放在本地的指定路径。例如下面的例子将上传的镜像放到本地的 /opt/data/registry 目录。)

17.1 创建好私有仓库之后,就可以使用 podman tag 来标记一个镜像,然后推送它到仓库。例如私有仓库地址为 127.0.0.1:5000

1
2
# podman run -d -p 5000:5000 --restart=always --name registry registry
# podman run -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry registry

17.2 使用podman tag来对tag的设置

使用 podman tag 将 ubuntu:latest 这个镜像标记为 127.0.0.1:5000/ubuntu:latest。
格式为 podman tag IMAGE[:TAG] [REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]

1
# podman tag ubuntu:latest 127.0.0.1:5000/ubuntu:latest

18 创建一个数据卷

1
# podman volume create sam-volume

19 查看一个数据卷

1
# podman volume ls

20 查看一个数据卷的详细信息

1
# podman volume inspect sam-volume

21 如果需要在删除容器的时候,也删除数据卷

1
# podman rm -v

22 清理无主的数据卷

1
# podman volume prune

23 挂载一个主机目录作为数据卷 (使用 –mount 标记可以指定挂载一个本地主机的目录到容器中去). 上面的命令加载主机的 /src/webapp 目录到容器的 /opt/webapp目录。这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。本地目录的路径必须是绝对路径,(以前使用 -v 参数时如果本地目录不存在 podman 会自动为你创建一个文件夹,现在使用 –mount 参数时如果本地目录不存在,podman 会报错。)

1
# podman run --name sampinta --mount type=bind,source=/root/Pictures,target=/opt/ localhost/pinta_filezilla:v3

24 挂载一个本地主机文件作为数据卷

1
# podman run --name sampinta --mount type=bind,source=/tmp/history,target=/root/.bash_history localhost/pinta_filezilla:v3

25 映射指定端口以及针对IP的端口(-p 标记可以多次使用来绑定多个端口)

25.1 主机的6000端口与容器的5000端口映射

1
podman run -d -p 6000:5000 registry.redhat.io/rhel7

25.2 主机的IP上的6000端口与容器的5000端口映射

1
podman run -d -p 127.0.0.1:6000:5000 registry.redhat.io/rhel7

25.3 主机的任意端口与容器的5000端口映射

1
podman run -d -p 127.0.0.1::5000 registry.redhat.io/rhel7

25.4 主机的IP的6000端口与容器的5000端口通过UDP映射

1
podman run -d -p 127.0.0.1:6000:5000/udp reg-p 标记可以多次使用来绑定多个端口istry.redhat.io/rhel7

25.5 查看端口映射配置

1
podman port nostalgic_morse 6000

26 容器互联,我们也可以通过“podman network” 类命令实现 (可以通过使用–dns=DNS_IP指定 容器需要的DNS地址)

26.1 创建一个新的网络 (-d指定网络的类型,有overlay,bridge。 其中 overlay 网络类似与 “swarm mode”)

1
podman network create -d bridge test-net

26.2 运行一个容器并且连接到test-net

1
podman run -it --rm --name ubi2-test-net --network test-net registry.redhat.io/rhel7:7.8-crash-v2 sh

27 如果容器需要访问外部网络,需要使用

1
net.ipv4.ip_forward = 1

28 podman ps 显示全的命令

1
2
docker ps -a --no-trunc
podman ps -a --no-trunc

27 (TO BE VERIFIED)多个容器互联,推荐docker compose

21 (TO BE VERIFIED) 启动一个挂在数据卷的容器(在用 podman run 命令的时候,使用 –mount 标记来将 数据卷 挂载到容器里。在一次 podman run 中可以挂载多个 数据卷。下面创建一个名为 web 的容器,并加载一个 数据卷 到容器的 /webapp 目录)

1
$ podman run -d -P --name web --mount source=sam-volume,target=/webapp bash

-p 标记可以多次使用来绑定多个端口

好, Red Hat Enterprise Linux 8 (RHEL8) 的新玩意 第1篇 之容器工具 podman 就介绍完毕了. 想要了解更多? 可以参考 man podman 和 podman -h
想要亲手玩一下新玩具? 请随时去 https://www.redhat.com 下载最新的 REHL 8 咯

也可以关注 AddOS 微信公众号获取更多的,有意思的新玩具 :-)