如何使用Buildah构建OCI和Docker容器镜像
在我们开始使用Buildah构建图像之前,我认为有必要进行一些清理工作,因为在大多数文章的开头几段中,容器化领域可能会成为术语的迷宫。
首先,让我们了解OCI,Buildah和Docker的全部含义。
开放式容器倡议(OCI)
嗯,由OCI官方站点引用,由Docker,CoreOS和其他合作伙伴于2014年6月22日发起的开放容器计划(OCI)是一个轻量级项目,其明确目的是围绕容器格式和运行时创建开放行业标准。
OCI当前包含两个规范:运行时规范(runtime-spec)和镜像规范(image-spec)。
运行时规范概述了如何运行在磁盘上解压缩的"文件系统包"。
"文件系统包"是一组以某种方式组织的文件,并包含所有符合条件的运行时(例如Docker和CRI-O)必需的所有数据和元数据,以对其执行所有标准操作。
在较高级别上,OCI实施将下载OCI镜像,然后将该镜像解压缩到OCI运行时文件系统捆绑包中。
此时,OCI运行时捆绑包将由OCI运行时(例如Docker和CRI-O)运行。
现在移至Buildah。
Buildah
Buildah是一个命令行工具,可用于构建符合打开容器计划(OCI)的图像。
它可以与Docker,Podman,Kubernetes或者任何我们喜欢的容器工具一起使用.Buildah的命令与我们可以在dockerfile中找到的所有命令类似。
Buildah的目标也是提供一个较低级Coreutils界面来构建容器图像,允许人们在不需要Dockerfile的情况下构建容器。
最强大的使用方法是编写Bash脚本,以创建图像 - 以类似的方式,我们将在不需要守护程序的情况下编写Dockerfile。
我们可以通过Buildah命令实现以下几点,更重要
从DockerFile(使用Buildah Bud)构建一个容器图像.Build从另一个基础图像(来自墓地)或者从划痕(使用刮擦)检查容器或者图像(使用Buildah检查)安装容器:安装a容器的根文件系统添加或者更改内容(Buildah Mount)。
创建一个新的容器层(使用buildah提交).unmount一个容器:卸载挂载的容器(buildah umount).delete容器(使用buildah rm)或者图像(在普通的英语中使用Buildah RMI),OCI列出了构建图像的规则以及如何消耗IT Whild Buildah将其设置并用于构建容器图像的规则。
现在码头是什么?
Docker.
很难保持简要介绍,但阅读概念肯定会帮助码头1.11 of Docker,实现是一款单片守护进程。
Monolith Dit As作为一个包,例如下载容器图像,启动容器进程,开启远程API,并充当日志收集守护程序,所有内容都在作为root(源核心)运行的集中进程中。
这种集中式架构在部署时具有一些好处,但却无法解决其他基本问题。
一个例子是它不遵循UNIX进程和特权分离的最佳实践。
此外,整体实施使Docker难以与Linux Init系统进行适当集成,例如Upstart和Systemd https://coreos.com/rkt/docs/latest/rkt-vs-ot-projects.html#rkt-vs-docker。
这导致Docker分成了不同的部件,可以在推出Docker 1.11之后在下面的开头段落中所示。
"我们很高兴推出Docker引擎1.11,我们的第一个在RunC™和ContainTD™内置的版本。
通过此版本,Docker是第一个根据OCI技术运行运行时的运行时,展示团队自2014年6月在Linux基金会下捐赠行业标准的集装箱格式和运行时的进展。
源码码头".According对他们来说(Docker),将Docker拆卸到聚焦的独立工具意味着更具专注的维护者,最终更好的质量软件.Since然后Containtn现在处理以前由Docker守护程序本身完成的容器的执行。
这是精确的流量,用户从Docker-CLI运行命令。
Docker-CLI与Docker守护程序交谈。
Docker守护程序(Dockerd)侦听请求,并通过IT与其接触的Contains管理容器的生命周期。
ContainerD获取请求并通过RUNC启动容器,并在主机内完成所有容器寿命。
RONC简单的是根据OCI规范的用于产卵和运行容器的CLI工具。
安装buildah.
在CentOS 8盒上运行下面的命令以安装Buildah。
我们将在它旁边安装Podman,以便我们可以使用它来从头开始运行我们的图像。
sudo dnf update sudo dnf -y install buildah podman
检查它是否已成功安装
$rpm -q buildah buildah-1.11.6-4.module_el8.1.0+272+3e64ee36.x86_64
使用Buildah从头开始创建OCI镜像
其中我们将构建一个仅包含少量容器元数据的镜像,然后添加运行简单的Apache Web服务器所需的所有内容。
这样做可以使我们逐块构建容器镜像。
正如前面所解释的,我们使用buildah scratch命令来实现此目的。
为了避免出现问题,我们将使用" root"用户帐户从此处开始。
brandnewcontainer=$(buildah from scratch)
$buildah containers CONTAINER ID BUILDER IMAGE ID IMAGE NAME CONTAINER NAME e6c2f7b0b567 * scratch working-container -- You can also use podamn $ podman images
上面的命令创建一个空容器(无图像)。
如下安装空容器:
scratchmnt=$(buildah mount $brandnewcontainer) echo $scratchmnt /var/lib/containers/storage/overlay/40e7215211b47e8de47991d0dc7be07e0b1b4f48eda25ebaf6ff8ff46c466be5/merged
通过Buildah mount命令,我们可以挂载容器的根文件系统,从而可以从主机对其进行访问。
接下来,将软件包安装到暂存镜像中。
yum -y group install "Minimal Install" --releasever=8 --installroot=$scratchmnt
安装软件包之后。
现在,我们可以卸载镜像并将其作为独立的容器运行,因为它具有需要独立的所有内容。
$buildah umount $brandnewcontainer e6c2f7b0b5679133ad6e0ad6bd74164dac7f357f0076cf6cc819f9ed664236d5
要将图像作为连续图像运行,请在下面提供以下命令,我们应该能够直接进入从头创建的新容器的怀抱中。
我们可以其中安装其他应用程序。
$buildah run $brandnewcontainer bash [Hyman@theitroad /]# ls bin dev home lib64 mnt proc run srv tmp var boot etc lib media opt root sbin sys usr
从上面可以看到,所有目录在标准容器中都可以使用。
我们可以安装Apache来测试一切是否正常。
[Hyman@theitroad /]# yum install httpd -y
在默认的Apache文档根目录中添加一个简单的html页面,然后从容器中退出
[Hyman@theitroad /]# echo "Testing Apache." > /var/www/html/index.html [Hyman@theitroad /]# exit
回到我们的主机系统,而不是将httpd作为初始化服务运行,而是设置一些buildah config选项来直接从容器中运行httpd守护程序:
$buildah config --cmd "/usr/sbin/httpd -DFOREGROUND" working-container $buildah config --port 80/tcp working-container $buildah commit working-container localhost/firstapache:latest Getting image source signatures Copying blob b34ab2705c68 done Copying config a0c546bc39 done Writing manifest to image destination Storing signatures a0c546bc39271565946d11a843979e017aae73e2b792cc5d9ca589661f427543
在buildah提交完镜像之后,现在让我们挥舞Podman来按以下方式运行它:首先,检查系统中所有可用的镜像并获取我们感兴趣的镜像的ID。
$podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/firstapache latest a0c546bc3927 8 minutes ago 1.68 GB
现在运行图像
$podman run -p 8080:80 -d --name apache-server a0c546bc3927 b1d29603542c8f91a289127cee4fa9157962f8fcdda9baa82b335e08a94c0992
为了确保我们的Apache网络服务器正在提供我们之前添加的页面,我们必须做一些事情。
我们猜对了,我们可以卷曲甚至可以使用浏览器查看结果。
请记住,容器中的端口80已绑定到系统上的端口8080。
我们可以使用curl进行如下所示的测试。
curl -ik "localhost:8080" HTTP/1.1 200 OK Date: Thu, 23 Apr 2017 22:21:54 GMT Server: Apache/2.4.37 (centos) Last-Modified: Thu, 23 Apr 2017 22:02:43 GMT ETag: "f-5a3fc6872e6c0" Accept-Ranges: bytes Content-Length: 15 Content-Type: text/html; charset=UTF-8 Testing Apache.
我们可以清楚地看到,Web服务器正在侦听并返回了我们期望的响应。
它正在运行。
Buildah附带了许多可供我们使用的工具。
我们可以删除图像和容器,还可以检查图像和容器。
以检查为例,使用" buildah images"命令列出所有图像以获取其ID,然后获取要检查的图像的ID,然后运行:
$buildah inspect a0c546bc3927 { "Type": "buildah 0.0.1", "FromImage": "localhost/firstapache:latest", "FromImageID": "a0c546bc39271565946d11a843979e017aae73e2b792cc5d9ca589661f427543", "FromImageDigest": "sha256:2060eb441d905934f0aa1749b0d9ed065fd464b30483a963e5719b27836c844d", "Config": "{\"created\":\"2017-04-23T22:09:50.515019063Z\",\"architecture\":\"amd64\",\"os\":\"linux\",\"config\":{\"ExposedPorts\":{\"80/tcp\":{}},\"Cmd\":[\"/usr/sbin/httpd\",\"-DFOREGROUND\"],\"Labels\":{\"io.buildah.version\":\"1.11.6\"}},\"rootfs\":{\"type\":\"layers\",\"diff_ids\":[\"sha256:b34ab2705c68989b396dfc33dd5174f34b14890242aae93397d628787d2a6a94\"]},\"history\":[{\"created\":\"2017-04-23T22:09:50.515019063Z\",\"created_by\":\"/bin/sh\"}]}", "Manifest": "{\"schemaVersion\":2,\"config\":{\"mediaType\":\"application/vnd.oci.image.config.v1+json\",\"digest\":\"sha256:a0c546bc39271565946d11a843979e017aae73e2b792cc5d9ca589661f427543\",\"size\":396},\"layers\":[{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar\",\"digest\":\"sha256:b34ab2705c68989b396dfc33dd5174f34b14890242aae93397d628787d2a6a94\",\"size\":1684295168}]}", "Container": "", "ContainerID": "", "MountPoint": "", "ProcessLabel": "", "MountLabel": "", "ImageAnnotations": null, "ImageCreatedBy": "", "OCIv1": { "created": "2017-04-23T22:09:50.515019063Z", "architecture": "amd64", "os": "linux", "config": { "ExposedPorts": { "80/tcp": {} }, "Cmd": [ "/usr/sbin/httpd", "-DFOREGROUND" ], "Labels": { "io.buildah.version": "1.11.6" } }, "rootfs": { "type": "layers", "diff_ids": [ "sha256:b34ab2705c68989b396dfc33dd5174f34b14890242aae93397d628787d2a6a94" ] }, "history": [ { "created": "2017-04-23T22:09:50.515019063Z", "created_by": "/bin/sh" } ] }, "Docker": { "created": "2017-04-23T22:09:50.515019063Z", "container_config": { "Hostname": "", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "ExposedPorts": { "80/tcp": {} },