Docker将被取代?下一代容器管理工具Podman和Buildah

简介

谈到容器,就会想到Docker,这两个词是密切相关的。然而,Red Hat开发的Red Hat Enterprise Linux (RHEL)的最新版本8系不再包含Docker,并且不再提供支持。Docker的设计包括了Docker Daemon的所有功能,可以进行Docker镜像的推送和拉取,以及存储管理等,非常方便实用。然而,也存在一些问题。其中最大的问题有以下两点。

    • デーモンを起動する必要があり、プロセスが落ちると機能が停止する

 

    root権限でコンテナを起動しなければならず、脆弱性や設定不備がある場合権限奪取される恐れがある

为了解决这个问题,开发了一些新的容器工具。这些工具包括我们要介绍的Podman和Buildah。虽然关于它们的详细信息可以在Red Hat的官方参考资料中找到,但我希望能够亲自动手学习,并将学习结果写成一篇文章。

Podman 是什么

6be7d7353415417e558a1aa7f0ca966a.png

Podman与Docker在命令行方面具有互操作性,可以通过podman命令以类似docker命令的方式实现。然而,由于删除了部分docker选项,所以并非完全兼容。(参考文献第8章 关于容器命令行的资料)

Buidah是什么?

d08a2c27315e8830e4a200b19fb0f9f7.png

以下是 Buildah 的特点,尽管与 Podman 的功能存在重叠,但 Buildah 只具备构建容器镜像所需的最基本功能,并受到功能限制。

    • Daemonは使用されない

 

    • scratch(空)イメージからコンテナイメージをビルド可能

 

    イメージにビルドツールが含まれず、イメージサイズが小さい

由于可以构建scratch映像,因此可以获取比从官方仓库获取的映像更轻量的容器映像。
(例如:使用scratch映像安装RHEL包,并添加Apache等)
当然,也可以从Dockerfile构建映像。
我已经简单介绍了这两个工具,我希望能够安装在实际设备上并进行体验。

各种环境工具

    • OS:CentOS8.2

 

    • podman ver 1.6.4

 

    buildah ver 1.11.6

我认为RedHat的官方网页上提供的安装方法和各种工具的使用方法最为清晰易懂,所以我基本上会按照这个来进行各种验证。

各种安装和初始设置。

如果您想逐个安装,也可以这样做,但如果您是使用Red Hat系列的Linux发行版本的话,您可以使用以下命令来进行批量安装。

# yum(dnf) module install -y container-tools

下一步是根据之前提到的,在root以外的用户可以操作容器的前提下,进行无根容器的设置。

增加用户命名空间

名稱空間(namespace)是一種功能,存在於系統中關於多種不同類型資源的所屬過程,並且在視覺上為所屬過程展示獨立資源。由於我仍在學習階段,無法提供詳細解釋,但使用者名稱空間將展示獨立的使用者ID和組ID。詳細內容請參考2020年Software Design七月號的「試著理解Linux架構角落」(https://gihyo.jp/magazine/SD/archive/2020/202007)。
接下來,我將使用以下命令來增加該名稱空間。

# echo "user.max_user_namespaces=28633" > /etc/sysctl.d/userns.conf
# sysctl -p /etc/sysctl.d/userns.conf

我将在将用户更改为非root用户的情况下,尝试使用podman获取镜像来确认这种状态。

$ podman pull registry.access.redhat.com/ubi8/ubi
$ podman run registry.access.redhat.com/ubi8/ubi cat /etc/os-release
NAME="Red Hat Enterprise Linux"
VERSION="8.2 (Ootpa)"
ID="rhel"
ID_LIKE="fedora"
VERSION_ID="8.2"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Red Hat Enterprise Linux 8.2 (Ootpa)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:8.2:GA"
HOME_URL="https://www.redhat.com/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 8"
REDHAT_BUGZILLA_PRODUCT_VERSION=8.2
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="8.2"

我正在使用由Red Hat提供的Universal Base Images (UBI)获取映像,并启动容器。
我使用cat /etc/os-release命令在启动的容器上查看容器的操作系统版本信息。
我确认能够以非root用户身份运行podman并对容器进行操作。接下来,我将说明各种操作。

图像搜索和提取

在中国我们可以通过使用 “podman search <镜像名称>” 来搜索镜像。

$ podman search node
INDEX        NAME                                                                                  DESCRIPTION                                       STARS   OFFICIAL   AUTOMATED
redhat.com   registry.access.redhat.com/openshift3/node                                            Provides a containerized OpenShift Node with...   0    
redhat.com   registry.access.redhat.com/openshift3/prometheus-node-exporter                        Prometheus exporter for hardware and OS metr...   0    
redhat.com   registry.access.redhat.com/codeready-workspaces/stacks-node                           Red Hat CodeReady Workspaces - Node Stack co...   0    
redhat.com   registry.access.redhat.com/rhel7/kubernetes-scheduler                                 The Kubernetes scheduler watches for new un-...   0    
redhat.com   registry.access.redhat.com/openshift3/metrics-hawkular-openshift-agent                Hawkular OpenShift Agent is a Hawkular feed ...   0    
redhat.com   registry.access.redhat.com/openshift3/ose-node-problem-detector                       Node Problem Detector monitors OpenShift nod...   0    
redhat.com   registry.access.redhat.com/openshift3/ose-metrics-heapster                            Retrieves container and node metrics from an...   0    
redhat.com   registry.access.redhat.com/openshift3/metrics-heapster                                Retrieves container and node metrics from an...   0    
redhat.com   registry.access.redhat.com/openshift3/ose-keepalived-ipfailover                       Optional Pod providing keepalived support fo...   0    
redhat.com   registry.access.redhat.com/openshift3/ose-metrics-hawkular-openshift-agent            Hawkular OpenShift Agent is a Hawkular feed ...   0    
redhat.com   registry.access.redhat.com/openshift3/ose-node                                        Provides a containerized OpenShift Node with...   0    
redhat.com   registry.access.redhat.com/amqstreams-1/amqstreams10-kafkaconnect-openshift           AMQ Streams image for running an Apache Kafk...   0    
redhat.io    registry.redhat.io/openshift3/node                                                    Provides a containerized OpenShift Node with...   0    
redhat.io    registry.redhat.io/openshift4/ose-prometheus-node-exporter                            Prometheus exporter for hardware and OS metr...   0    
redhat.io    registry.redhat.io/openshift4/ose-cluster-node-tuning-operator                        'OpenShift Node Tuning Operator'                  0    
redhat.io    registry.redhat.io/openshift4/ose-node                                                'OpenShift Container Platform Node'               0    
redhat.io    registry.redhat.io/openshift3/prometheus-node-exporter                                Prometheus exporter for hardware and OS metr...   0    
redhat.io    registry.redhat.io/openshift4/ose-csi-node-driver-registrar                           CSI Node Driver Registar                          0    
redhat.io    registry.redhat.io/openshift4/ose-node-feature-discovery                              Node Feature Discovery Container Image            0    
redhat.io    registry.redhat.io/openshift4/ose-cluster-nfd-operator                                Node Feature Discovery (NFD) Operator             0    
redhat.io    registry.redhat.io/codeready-workspaces/stacks-node                                   Red Hat CodeReady Workspaces - Node Stack co...   0    
redhat.io    registry.redhat.io/codeready-workspaces/stacks-node-rhel8                             Red Hat CodeReady Workspaces - Node 10 Stack      0    
redhat.io    registry.redhat.io/codeready-workspaces/plugin-java8-rhel8                            Red Hat CodeReady Workspaces - Java 8 plugin...   0    
redhat.io    registry.redhat.io/rhel7/kubernetes-scheduler                                         The Kubernetes scheduler watches for new un-...   0    
redhat.io    registry.redhat.io/openshift3/metrics-hawkular-openshift-agent                        Hawkular OpenShift Agent is a Hawkular feed ...   0    
redhat.io    registry.redhat.io/openshift3/ose-node-problem-detector                               Node Problem Detector monitors OpenShift nod...   0    
redhat.io    registry.redhat.io/openshift3/ose-metrics-heapster                                    Retrieves container and node metrics from an...   0    
redhat.io    registry.redhat.io/openshift3/metrics-heapster                                        Retrieves container and node metrics from an...   0    
redhat.io    registry.redhat.io/openshift3/ose-metrics-hawkular-openshift-agent                    Hawkular OpenShift Agent is a Hawkular feed ...   0    
redhat.io    registry.redhat.io/openshift3/ose-keepalived-ipfailover                               Optional Pod providing keepalived support fo...   0    
redhat.io    registry.redhat.io/container-native-virtualization/node-maintenance-operator          Red Hat Container Native Virtualization imag...   0    
redhat.io    registry.redhat.io/openshift3/ose-node                                                Provides a containerized OpenShift Node with...   0    
redhat.io    registry.redhat.io/amqstreams-1/amqstreams10-kafkaconnect-openshift                   AMQ Streams image for running an Apache Kafk...   0    
redhat.io    registry.redhat.io/openshift4/ose-cluster-machine-approver                            'Validates and approves CSRs for nodes attem...   0    
redhat.io    registry.redhat.io/container-native-virtiualization/node-maintenance-rhel8-operator   Red Hat Container Native Virtualization imag...   0    
redhat.io    registry.redhat.io/openshift4/ose-ptp                                                 Linuxptp daemonset to apply ptp configuratio...   0    
redhat.io    registry.redhat.io/container-native-virtualization/kubevirt-cpu-node-labeller         Red Hat Container Native Virtualization imag...   0    
docker.io    docker.io/library/node                                                                Node.js is a JavaScript-based platform for s...   9152    [OK]
docker.io    docker.io/nodered/node-red-docker                                                     Deprecated - older Node-RED Docker images.        351                [OK]
docker.io    docker.io/bitnami/node                                                                Bitnami Node.js Docker Image                      45                 [OK]
docker.io    docker.io/appsvc/node                                                                 Azure App Service Node.js dockerfiles             14                 [OK]
docker.io    docker.io/circleci/node                                                               Node.js is a JavaScript-based platform for s...   110  
docker.io    docker.io/prom/node-exporter                                                                                                            193                [OK]
docker.io    docker.io/calico/node                                                                 Calico's per-host DaemonSet container image....   19                 [OK]
docker.io    docker.io/library/mongo-express                                                       Web-based MongoDB admin interface, written w...   754     [OK]
docker.io    docker.io/iron/node                                                                   Tiny Node image                                   29   
docker.io    docker.io/bitnami/node-exporter                                                       Bitnami Node Exporter Docker Image                2                  [OK]
docker.io    docker.io/kkarczmarczyk/node-yarn                                                     Node docker image with yarn package manager ...   48                 [OK]
docker.io    docker.io/nodered/node-red                                                            Low-code programming for event-driven applic...   175  
docker.io    docker.io/nodecg/nodecg                                                               Create broadcast graphics using Node.js and ...   1                  [OK]
docker.io    docker.io/selenium/node-chrome                                                                                                          213                [OK]
docker.io    docker.io/appsvctest/node                                                             node build                                        0                  [OK]
docker.io    docker.io/library/iojs                                                                io.js is an npm compatible platform original...   135     [OK]
docker.io    docker.io/camptocamp/node-collectd                                                    rancher node monitoring agent                     0                  [OK]
docker.io    docker.io/ppc64le/node                                                                Node.js is a JavaScript-based platform for s...   2    
docker.io    docker.io/testim/node-chrome                                                          Selenium Chrome Node + Testim Extension           0                  [OK]
docker.io    docker.io/digitallyseamless/nodejs-bower-grunt                                         Node.js w/ Bower & Grunt Dockerfile for tru...   48                 [OK]
docker.io    docker.io/cusspvz/node                                                                ? Super small Node.js container (~15MB) b...      8                  [OK]
docker.io    docker.io/ogazitt/node-env                                                            node app that shows environment variables         2    
docker.io    docker.io/basi/node-exporter                                                          Node exporter image that allows to expose th...   8                  [OK]
docker.io    docker.io/selenium/node-firefox                                                                                                         136                [OK]
docker.io    docker.io/tarampampam/node                                                            Docker image, based on node, with some addit...   2                  [OK]

您可以使用–filter=is-official来过滤只包含官方镜像的分发源。

$ podman search node --filter=is-official
INDEX       NAME                              DESCRIPTION                                       STARS   OFFICIAL   AUTOMATED
docker.io   docker.io/library/node            Node.js is a JavaScript-based platform for s...   9152    [OK]
docker.io   docker.io/library/mongo-express   Web-based MongoDB admin interface, written w...   757     [OK]
docker.io   docker.io/library/iojs            io.js is an npm compatible platform original...   135     [OK]

然后,就像Docker一样,可以使用podman pull <镜像名称>将镜像拉取到本地。

$ podman pull docker.io/library/node
Trying to pull docker.io/library/node...
Getting image source signatures
Copying blob de30e8b35015 done
Copying blob 419e7ae5bb1e done
Copying blob 7ec8a0667334 done
Copying blob 848839e0cd3b done
~~~~~中略~~~~~~~
$ podman images
REPOSITORY                            TAG      IMAGE ID       CREATED       SIZE
docker.io/library/node                latest   784e696f5060   2 weeks ago   972 MB

Podman的容器镜像存储在Red Hat官方网站上。(https://catalog.redhat.com/software/containers/explore)

启动容器

Podman与Docker一样,可以使用podman run命令来启动容器。

$ podman run -it --rm node bash
root@cc0bf2c6cc65:/# cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
VERSION_CODENAME=stretch
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

构建形象

在buildah命令中,可以构建镜像,也可以使用”buildah bud”命令构建Dockerfile。(请参考官方教程)
另外,通过”buildah images”命令,您还可以显示使用podman拉取的镜像列表。

$ podman images
REPOSITORY                                    TAG      IMAGE ID       CREATED          SIZE
localhost/johndoe/webserver                   latest   6d36abc8f72f   24 minutes ago   245 MB
registry.access.redhat.com/ubi8/ubi           latest   a1f8c9699786   5 weeks ago      211 MB
registry.access.redhat.com/ubi8/ubi-minimal   latest   86c870596572   5 weeks ago      146 MB

$ buildah images
REPOSITORY                                    TAG      IMAGE ID       CREATED          SIZE
localhost/johndoe/webserver                   latest   6d36abc8f72f   24 minutes ago   245 MB
registry.access.redhat.com/ubi8/ubi           latest   a1f8c9699786   5 weeks ago      211 MB
registry.access.redhat.com/ubi8/ubi-minimal   latest   86c870596572   5 weeks ago      146 MB

我们将使用buildah命令对以下格式的Dockerfile进行构建。

# ls
Dockerfile  myecho
# cat Dockerfile
FROM registry.access.redhat.com/ubi8/ubi:latest
ADD myecho /usr/local/bin
ENTRYPOINT "/usr/local/bin/myecho"
# cat myecho
echo "This container works!"
# chmod 755 myecho
# ./myecho
This container works!

创建Dockerfile后,运行buildah bud -t fedora-httpd .命令来构建镜像。
根据文件中的指令,镜像将被构建。
完成构建后,尝试运行容器。

$ buildah  images
REPOSITORY                            TAG      IMAGE ID       CREATED          SIZE
localhost/myecho-container            latest   5098f73df28e   50 seconds ago   211 MB
$ podman run localhost/myecho-container
This container works!

顺便说一下,关于buildah的教程中提到可以使用buildah run来启动容器,但是我尝试失败了。

$ buildah run localhost/myecho-container
command must be specified
ERRO exit status 1                 

删除容器、映像

与Docker相同,可以使用rm选项来删除容器和镜像。

$ podman ps -a
CONTAINER ID  IMAGE                                       COMMAND        CREATED        STATUS                         PORTS                 NAMES
06a79ab009f3  registry.access.redhat.com/ubi8/ubi:latest  /bin/bash      3 minutes ago  Exited (1) About a minute ago                        mystifying_jepsen
e8a1c6fbc91f  localhost/johndoe/webserver:latest          -D FOREGROUND  29 hours ago   Exited (135) 28 hours ago      0.0.0.0:8080->80/tcp  agitated_morse
$ podman rm e8a1c6fbc91f
e8a1c6fbc91f9252f13a34e6a2275078cdadef196e135bb32330784b8d012ad3
$ podman ps -a
CONTAINER ID  IMAGE                                       COMMAND        CREATED        STATUS                    PORTS                 NAMES
06a79ab009f3  registry.access.redhat.com/ubi8/ubi:latest  /bin/bash      4 minutes ago  Exited (1) 3 minutes ago                        mystifying_jepsen

同样,你也可以使用RMI选项来删除图像。

$ podman images
REPOSITORY                                    TAG      IMAGE ID       CREATED        SIZE
localhost/johndoe/webserver                   latest   6d36abc8f72f   29 hours ago   245 MB
registry.access.redhat.com/ubi8/ubi           latest   a1f8c9699786   5 weeks ago    211 MB
registry.access.redhat.com/ubi8/ubi-minimal   latest   86c870596572   5 weeks ago    146 MB
docker.io/library/fedora                      latest   a368cbcfa678   7 weeks ago    189 MB

$ podman rmi docker.io/library/fedora
Untagged: docker.io/library/fedora:latest
Deleted: a368cbcfa6789bc347345f6d19132afe138b62ff5373d2aa5f37120277c90b54
$ podman rmi 86c870596572
Untagged: registry.access.redhat.com/ubi8/ubi-minimal:latest
Deleted: 86c870596572a5b4fe016f4fb7ae9d181e88df6ac91d2cb15250c5e053cfad15

$ podman images
REPOSITORY                            TAG      IMAGE ID       CREATED        SIZE
localhost/johndoe/webserver           latest   6d36abc8f72f   29 hours ago   245 MB
registry.access.redhat.com/ubi8/ubi   latest   a1f8c9699786   5 weeks ago    211 MB

创建Kubernetes Pod Yaml文件

Podman的另一个特点是,可以使用podman generate命令创建Kubernetes的Pods文件。
运行mariadb容器进程,并通过`podman generate`命令输出Kubernetes YAML,然后将其保存至文件中。

$ podman run -d -e MYSQL_USER=user -e MYSQL_PASSWORD=pass \
>      -e MYSQL_DATABASE=db -p 3306:3306 --name mymariadb rhscl/mariadb-102-rhel7
Trying to pull registry.access.redhat.com/rhscl/mariadb-102-rhel7...
Getting image source signatures
Copying blob 9e7a6dc796f0 done
Copying blob e7021e0589e9 done
Copying blob fc5b206e9329 [======================================] 72.7MiB / 72.7MiB
Copying blob 98b39311ee6a done
Copying config 5ca39d258f done
Writing manifest to image destination
Storing signatures
8e994c65e7a24febfa57c6cc79c44c7fce37c8593a087d9efb5c45b994169b48

$ podman ps -a
CONTAINER ID  IMAGE                                                      COMMAND     CREATED         STATUS             PORTS                   NAMES
8e994c65e7a2  registry.access.redhat.com/rhscl/mariadb-102-rhel7:latest  run-mysqld  41 seconds ago  Up 40 seconds ago  0.0.0.0:3306->3306/tcp  mymariadb

$ podman generate kube mymariadb > mymariadbkube.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-1.9.3
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2020-08-29T05:37:11Z"
  labels:
    app: mymariadb
  name: mymariadb
spec:
  containers:
  - command:
    - run-mysqld
    env:
    - name: PATH
      value: /opt/app-root/src/bin:/opt/app-root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    - name: TERM
      value: xterm
    - name: HOSTNAME
    - name: container
      value: oci
    - name: STI_SCRIPTS_URL
      value: image:///usr/libexec/s2i
    - name: MYSQL_PASSWORD
      value: pass
    - name: ENABLED_COLLECTIONS
      value: rh-mariadb102
    - name: PROMPT_COMMAND
      value: . /usr/share/container-scripts/mysql/scl_enable
    - name: HOME
      value: /var/lib/mysql
    - name: ENV
      value: /usr/share/container-scripts/mysql/scl_enable
    - name: PLATFORM
      value: el7
    - name: STI_SCRIPTS_PATH
      value: /usr/libexec/s2i
    - name: MYSQL_USER
      value: user
    - name: MYSQL_DATABASE
      value: db
    - name: DESCRIPTION
      value: MariaDB is a multi-user, multi-threaded SQL database server. The container
        image provides a containerized packaging of the MariaDB mysqld daemon and
        client application. The mysqld server daemon accepts connections from clients
        and provides access to content from MariaDB databases on behalf of the clients.
    - name: SUMMARY
      value: MariaDB 10.2 SQL database server
    - name: APP_ROOT
      value: /opt/app-root
    - name: MYSQL_PREFIX
      value: /opt/rh/rh-mariadb102/root/usr
    - name: APP_DATA
      value: /opt/app-root/src
    - name: BASH_ENV
      value: /usr/share/container-scripts/mysql/scl_enable
    - name: CONTAINER_SCRIPTS_PATH
      value: /usr/share/container-scripts/mysql
    - name: MYSQL_VERSION
      value: "10.2"
    image: registry.access.redhat.com/rhscl/mariadb-102-rhel7:latest
    name: mymariadb
    ports:
    - containerPort: 3306
      hostPort: 3306
      protocol: TCP
    resources: {}
    securityContext:
      allowPrivilegeEscalation: true
      capabilities: {}
      privileged: false
      readOnlyRootFilesystem: false
      runAsGroup: 27
      runAsUser: 27
      seLinuxOptions: {}
    workingDir: /opt/app-root/src
status: {}

然后,您可以使用kubectl命令基于这个yaml文件创建Pods。
kubectl create -f mymariadbkube.yaml

总结

我向大家解释了各种工具的操作方法。
这两个命令是在下一篇文章中介绍的Ansible-bender内部所使用的工具,可以使用Ansible来创建容器映像。
虽然我很少听说人们使用Podman和Buildah,但我认为它们将成为未来替代Docker的容器管理工具,所以我希望能更深入地理解并专注于使用它们。

广告
将在 10 秒后关闭
bannerAds