Please enable Javascript to view the contents

老树开新花 - Cloud Native Buildpacks

 ·  ☕ 4 分钟

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 镜像的容器平台。工作原理如下:

  1. 探测。根据源码内容, 自动探测、匹配 buildpacks 。
  2. 分析。在历史构建中, 查找缓存。
  3. 构建。将应用的源码, 创建为可运行的包
  4. 导出 OCI 格式的容器镜像。

2. Cloud Native Buildpacks 适合哪些人

Cloud Native Buildpacks 非常适合需要频繁打包应用的场景, 而且应用的种类比较多。

  • aPaaS 平台

aPaaS 是提供运行时的平台, 经常需要部署各类应用。使用 Cloud Native Buildpacks 能规范打包流程, 快速将源码转换为镜像。

  • FaaS 平台

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 openshift jib ko
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/ --no-same-owner -xzv pack)

查看 pack 的版本

1
2
3
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

.
|-- manage.py
|-- project
|   |-- app1
|   |   |-- admin.py
|   |   |-- apps.py
|   |   |-- __init__.py
|   |   |-- migrations
|   |   |   `-- __init__.py
|   |   |-- models.py
|   |   |-- tests.py
|   |   `-- views.py
|   |-- __init__.py
|   |-- settings.py
|   |-- tests.py
|   |-- urls.py
|   `-- wsgi.py
`-- requirements.txt

3 directories, 14 files

这是一个非常普通的 Django 项目结构。

  • 查看推荐的 Builder

Builder 定义如何将源码转换为镜像的步骤, 如果有自己熟悉的 Builder 可以直接使用, 也可以使用 Pack 推荐的 Builder 。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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 --builder heroku/buildpacks:20

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
-----> Installing python-3.6.12
-----> Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2
-----> Installing SQLite3
-----> Installing requirements with pip
 !     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
-----> $ python manage.py collectstatic --noinput
       61 static files copied to '/workspace/static'.

-----> Discovering process types
       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
  • 查看镜像
1
2
3
docker images |grep python-sample

python-sample                     latest              39a646c853c2        41 years ago        756MB

41 years ago 应该是有 Bug, 镜像有点大。第二次构建时, 并没有看到明显提速, 看来得用自定义 Builder 才能展示上述表格中的优势。

  • 创建容器试试
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
docker run --rm -p 8000:8000 python-sample  python manage.py runserver 0.0.0.0:8000

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.
  • 在 8000 端口访问页面。

5. 总结

本文主要是体验了一下 Buildpacks 在云原生背景下的进化版本 Cloud Native Buildpacks 。

Buildpacks 与 S2I 一样, 支持开发者自定义 Builder, 也支持用户在源码仓库中自定义一些配置, 比如指定源码目录、指定解释器版本等。PaaS、FaaS 类的平台自己维护一套类似的工具, 不如直接采用并贡献这些开源项目。

6. 参考


微信公众号
作者
微信公众号