1. Buildpack 老树开新花
Buildpacks 项目最早是由 Heroku 在 2011 年发起, 被以 Cloud Foundry 为代表的 PaaS 平台广泛采用。在之前的文档 《PaaS 部署之 buildpack》 中, 我演示了如何将一个 Django 应用部署到 Heroku 上。Buildpacks 不足的是产出包是 Droplet 格式, 不能直接适配容器平台。在 2018 年 1 月, Pivotal 和 Heroku 发起了一个项目 Cloud Native Buildpacks(简称, CNB) , 并在同年十月份加入 CNCF 。这个项目的目标就是实现一个统一的应用打包生态系统。简单点就是, 之前打包出来是 Droplet, 现在是 OCI 容器镜像, 可以部署在任意兼容 OCI 镜像的容器平台。工作原理如下:
探测。根据源码内容, 自动探测、匹配 buildpacks 。
分析。在历史构建中, 查找缓存。
构建。将应用的源码, 创建为可运行的包
导出 OCI 格式的容器镜像。
2. Cloud Native Buildpacks 适合哪些人
Cloud Native Buildpacks 非常适合需要频繁打包应用的场景, 而且应用的种类比较多。
aPaaS 是提供运行时的平台, 经常需要部署各类应用。使用 Cloud Native Buildpacks 能规范打包流程, 快速将源码转换为镜像。
FaaS 平台提供函数的运行环境。在以容器为核心的基础设施上, FaaS 将用户代码打包为镜像, 再创建容器运行。而 Cloud Native Buildpacks 既能探测用户代码的编程语言、框架, 还能快速编译成 OCI 镜像, 正是 FaaS 之所需。Google Cloud Platform 的 FaaS 采用的就是 Buildpacks。
并不是每个开发者都适合使用 Cloud Native Buildpacks, 学习和维护也需要成本。如果你有很多应用需要维护和发布, 那么 Cloud Native Buildpacks 将拯救你, 起码可以少写很多 Dockerfile。
3. 与同类应用打包工具的比较
关于 S2I, 我之前写过一篇文档, 使用 S2I 构建云原生应用。我负责研发的一款产品中, 采用的就是 S2I 对源码进行打包成镜像。而 Buildpacks 是我上一份工作中接触到的技术。当时我开发 SaaS , 需要借助 Buildpacks 打包应用。这是来自 Buildpacks 社区的同类工具对比:
Logo




Product Name |
Cloud Native Buildpacks |
source-to-image (s2i) |
Jib |
ko |
Advanced Caching |
Yes |
Yes |
No |
No |
Bill-of-Materials |
Yes |
No |
No |
No |
Modular / Pluggable |
Yes |
No |
N/A † |
N/A † |
Multi-language |
Yes |
Yes |
No |
No |
Multi-process |
Yes |
No |
No |
No |
Minimal app image |
Yes |
Yes ‡ |
Yes |
Yes |
Rebasing |
Yes |
No |
No |
No |
Reproducibility |
Yes |
No |
Yes |
Yes |
Reusability |
Yes |
Yes |
N/A † |
N/A † |
Integrations |
* Azure* CircleCI* GitLab* Google* Heroku* Spring Boot* Tekton* … |
* OpenShift |
* Gradle* Maven |
|
Governance |
CNCF |
Red Hat |
Google |
Google |
从生态和功能上看, Buildpacks 比 S2I 更好。
4. 在 Docker 环境下打包应用
需要提前安装 Git 环境, 在 Docker 环境下操作。
4.1 安装 Pack 命令工具
Pack 是 Cloud Native Buildpacks 提供用于使用 buildpacks 的工具。这里以 Linux 系统为例进行安装:
1
|
(curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.17.0/pack-v0.17.0-linux.tgz" | sudo tar -C /usr/local/bin/
|
查看 pack 的版本
|
| pack version | | | | 0.17.0+git-d9cb4e7.build-2045 |
|
4.2 打包一个应用
1
|
git clone https://github.com/shaowenchen/devops-python-sample
|
1
|
cd devops-python-sample/src
|
| 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | | 9 | | 10 | | 11 | | 12 | | 13 | | 14 | | 15 | | 16 | | 17 | | 18 | | 19 | | 20 | | 21 | | 22 |
|
| tree | | | | . | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ` | | | | | | | | | | | | | | ` | | | | | | | | | | | | | | | | | | | ` | | ` | | | | 3 directories, 14 files |
|
这是一个非常普通的 Django 项目结构。
Builder 定义如何将源码转换为镜像的步骤, 如果有自己熟悉的 Builder 可以直接使用, 也可以使用 Pack 推荐的 Builder 。
|
| pack builder suggest | | | | Suggested builders: | | Google: gcr.io/buildpacks/builder:v1 Ubuntu 18 base image with buildpacks for .NET, Go, Java, Node.js, and Python | | Heroku: heroku/buildpacks:18 heroku-18 base image with buildpacks for Ruby, Java, Node.js, Python, Golang, & PHP | | Heroku: heroku/buildpacks:20 heroku-20 base image with buildpacks for Ruby, Java, Node.js, Python, Golang, & PHP | | Paketo Buildpacks: paketobuildpacks/builder:base Ubuntu bionic base image with buildpacks for Java, .NET Core, NodeJS, Go, Ruby, NGINX and Procfile | | Paketo Buildpacks: paketobuildpacks/builder:full Ubuntu bionic base image with buildpacks for Java, .NET Core, NodeJS, Go, PHP, Ruby, Apache HTTPD, NGINX and Procfile | | Paketo Buildpacks: paketobuildpacks/builder:tiny Tiny base image (bionic build image, distroless-like run image) with buildpacks for Java Native Image and Go | | | | Tip: Learn more about a specific builder with: | | pack inspect-builder <builder-image> |
|
- 进行构建, 这里采用 heroku/buildpacks:20 进行构建
| 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | | 9 | | 10 | | 11 | | 12 | | 13 | | 14 | | 15 | | 16 | | 17 | | 18 | | 19 | | 20 | | 21 | | 22 | | 23 | | 24 | | 25 | | 26 | | 27 | | 28 | | 29 | | 30 | | 31 | | 32 | | 33 | | 34 | | 35 | | 36 | | 37 | | 38 | | 39 | | 40 | | 41 | | 42 | | 43 | | 44 | | 45 | | 46 | | 47 | | 48 | | 49 | | 50 | | 51 |
|
| pack build python-sample | | | | 20: Pulling from heroku/buildpacks | | Digest: sha256:128508a60a25ecac8ed16b4507747cceaf627e2617b2e898d98ac303411a010f | | Status: Image is up to date for heroku/buildpacks:20 | | 20: Pulling from heroku/pack | | Digest: sha256:6f7301c933d3d0d777c3f5b99b5cc9d8e5ee7304e69b5f05989e19e5c4206a95 | | Status: Image is up to date for heroku/pack:20 | | ===> DETECTING | | ======== Output: heroku/[email protected] ======== | | no | | err: heroku/[email protected] (1) | | heroku/python 0.3 | | heroku/procfile 0.6 | | ===> ANALYZING | | Previous image with name "python-sample" not found | | ===> RESTORING | | ===> BUILDING | | | | | | | | | | ! Your Django version is nearing the end of its community support. | | ! Upgrade to continue to receive security updates and for the best experience with Django. | | ! For more information, check out https://www.djangoproject.com/download/#supported-versions | | Collecting Django==1.11.29 | | Downloading Django-1.11.29-py2.py3-none-any.whl (6.9 MB) | | Collecting coverage==4.5.4 | | Downloading coverage-4.5.4-cp36-cp36m-manylinux1_x86_64.whl (205 kB) | | Collecting pytz | | Downloading pytz-2021.1-py2.py3-none-any.whl (510 kB) | | Installing collected packages: pytz, Django, coverage | | Successfully installed Django-1.11.29 coverage-4.5.4 pytz-2021.1 | | | | 61 static files copied to '/workspace/static'. | | | | | | Procfile declares types -> (none) | | ===> EXPORTING | | Adding layer 'heroku/python:profile' | | Adding 1/1 app layer(s) | | Adding layer 'launcher' | | Adding layer 'config' | | Adding label 'io.buildpacks.lifecycle.metadata' | | Adding label 'io.buildpacks.build.metadata' | | Adding label 'io.buildpacks.project.metadata' | | Warning: default process type 'web' not present in list [] | | *** Images (1de89df98f60): | | python-sample | | Adding cache layer 'heroku/python:shim' | | Successfully built image python-sample |
|
|
| docker images |grep python-sample | | | | python-sample latest 39a646c853c2 41 years ago 756MB |
|
41 years ago
应该是有 Bug, 镜像有点大。第二次构建时, 并没有看到明显提速, 看来得用自定义 Builder 才能展示上述表格中的优势。
|
| docker run | | | | Performing system checks... | | | | System check identified no issues (0 silenced). | | | | You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. | | Run 'python manage.py migrate' to apply them. | | February 04, 2021 - 08:33:02 | | Django version 1.11.29, using settings 'project.settings' | | Starting development server at http://0.0.0.0:8000/ | | Quit the server with CONTROL-C. |
|

5. 总结
本文主要是体验了一下 Buildpacks 在云原生背景下的进化版本 Cloud Native Buildpacks 。Buildpacks 与 S2I 一样, 支持开发者自定义 Builder, 也支持用户在源码仓库中自定义一些配置, 比如指定源码目录、指定解释器版本等。PaaS、FaaS 类的平台自己维护一套类似的工具, 不如直接采用并贡献这些开源项目。
6. 参考
- https://buildpacks.io/
- https://github.com/GoogleCloudPlatform/buildpacks