Docker将被取代?下一代容器管理工具Podman和Buildah
简介
谈到容器,就会想到Docker,这两个词是密切相关的。然而,Red Hat开发的Red Hat Enterprise Linux (RHEL)的最新版本8系不再包含Docker,并且不再提供支持。Docker的设计包括了Docker Daemon的所有功能,可以进行Docker镜像的推送和拉取,以及存储管理等,非常方便实用。然而,也存在一些问题。其中最大的问题有以下两点。
-
- デーモンを起動する必要があり、プロセスが落ちると機能が停止する
- root権限でコンテナを起動しなければならず、脆弱性や設定不備がある場合権限奪取される恐れがある
为了解决这个问题,开发了一些新的容器工具。这些工具包括我们要介绍的Podman和Buildah。虽然关于它们的详细信息可以在Red Hat的官方参考资料中找到,但我希望能够亲自动手学习,并将学习结果写成一篇文章。
Podman 是什么
Podman与Docker在命令行方面具有互操作性,可以通过podman命令以类似docker命令的方式实现。然而,由于删除了部分docker选项,所以并非完全兼容。(参考文献第8章 关于容器命令行的资料)
Buidah是什么?
以下是 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的容器管理工具,所以我希望能更深入地理解并专注于使用它们。