内容简介:最近在调整公司项目的 CI,目前主要使用 GitLab CI,在尝试多阶段构建中踩了点坑,然后发现了一些有意思的玩意本文参考:公司目前主要使用 GitLab CI 作为主力 CI 构建工具,而且由于机器有限,我们对一些包管理器的本地 cache 直接持久化到了本机;比如 maven 的
最近在调整公司项目的 CI,目前主要使用 GitLab CI,在尝试多阶段构建中踩了点坑,然后发现了一些有意思的玩意
本文参考:
一、起因
公司目前主要使用 GitLab CI 作为主力 CI 构建工具,而且由于机器有限,我们对一些包管理器的本地 cache 直接持久化到了本机;比如 maven 的 .m2
目录,nodejs 的 .npm
目录等;虽然我们创建了对应的私服,但是在 build 时毕竟会下载,所以当时索性调整 GitLab Runner 在每个由 GitLab Runner 启动的容器中挂载这些缓存目录(GitLab CI 在 build 时会新启动容器运行 build 任务);今天调整 nodejs 项目浪了一下,直接采用 Dockerfile 的 multi-stage build 功能进行 “Build => Package(docker image)” 的实现,基本 Dockerfile 如下
FROM gozap/build as builder
COPY . /xxxx
WORKDIR /xxxx
RUN source ~/.bashrc \
&& cnpm install \
&& cnpm run build
FROM gozap/nginx-react:v1.0.0
LABEL maintainer="mritd <mritd@linux.com>"
COPY --from=builder /xxxx/public /usr/share/nginx/html
EXPOSE 80
STOPSIGNAL SIGTERM
CMD ["nginx", "-g", "daemon off;"]
本来这个 cnpm
命令是带有 cache 的( 见这里
),不过运行完 build 以后发现很慢,检查宿主机 cache 目录发现根本没有 cache…然后突然感觉
仔细想想,情况应该是这样事儿的…
+------------+ +-------------+ +----------------+
| | | | | |
| | | build | | Multi-stage |
| Runner +--------------->+ conatiner +----------->+ Build |
| | | | | |
| | | | | |
+------------+ +------+------+ +----------------+
^
|
|
|
|
+------+------+
| |
| Cache |
| |
+-------------+
后来经过查阅文档,发现 Dockerfile 是有扩展语法的(当然最终我还是没用),具体请见
IF ELSE
语法、直接挂载宿主机目录等功能
二、开启 Dockerfile 扩展语法
2.1、开启实验性功能
目前这个扩展语法还处于实验性功能,所以需要配置 dockerd 守护进程,修改如下
ExecStart=/usr/bin/dockerd -H unix:// \
--init \
--live-restore \
--data-root=/data/docker \
--experimental \
--log-driver json-file \
--log-opt max-size=30m \
--log-opt max-file=3
主要是 --experimental
参数,参考 官方文档
;
同时在 build 前声明 export DOCKER_BUILDKIT=1
变量
2.2、修改 Dockerfile
开启实验性功能后,只需要在 Dockerfile 头部增加 # syntax=docker/dockerfile:experimental
既可;为了保证稳定性,你也可以指定具体的版本号,类似这样
# syntax=docker/dockerfile:1.1.1-experimental FROM tomcat
2.3、可用的扩展语法
-
RUN --mount=type=bind
这个是默认的挂载模式,这个允许将上下文或者镜像以可都可写/只读模式挂载到 build 容器中,可选参数如下(不翻译了)
| Option | Description |
|---|---|
target
(required) |
Mount path. |
source
|
Source path in the from
. Defaults to the root of the from
. |
from
|
Build stage or image name for the root of the source. Defaults to the build context. |
rw
, readwrite
|
Allow writes on the mount. Written data will be discarded. |
-
RUN --mount=type=cache
专用于作为 cache 的挂载位置,一般用于 cache 包管理器的下载等
| Option | Description |
|---|---|
id
|
Optional ID to identify separate/different caches |
target
(required) |
Mount path. |
ro
, readonly
|
Read-only if set. |
sharing
|
One of shared
, private
, or locked
. Defaults to shared
. A shared
cache mount can be used concurrently by multiple writers. private
creates a new mount if there are multiple writers. locked
pauses the second writer until the first one releases the mount. |
from
|
Build stage to use as a base of the cache mount. Defaults to empty directory. |
source
|
Subpath in the from
to mount. Defaults to the root of the from
. |
Example: cache Go packages
# syntax = docker/dockerfile:experimental FROM golang ... RUN --mount=type=cache,target=/root/.cache/go-build go build ...
Example: cache apt packages
# syntax = docker/dockerfile:experimental FROM ubuntu RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/var/lib/apt \ apt update && apt install -y gcc
-
RUN --mount=type=tmpfs
专用于挂载 tmpfs 的选项
| Option | Description |
|---|---|
target
(required) |
Mount path. |
-
RUN --mount=type=secret
这个类似 k8s 的 secret,用来挂载一些不想打入镜像,但是构建时想使用的密钥等,例如 docker 的 config.json
,S3 的 credentials
| Option | Description |
|---|---|
id
|
ID of the secret. Defaults to basename of the target path. |
target
|
Mount path. Defaults to /run/secrets/
+ id
. |
required
|
If set to true
, the instruction errors out when the secret is unavailable. Defaults to false
. |
mode
|
File mode for secret file in octal. Default 0400. |
uid
|
User ID for secret file. Default 0. |
gid
|
Group ID for secret file. Default 0. |
Example: access to S3
# syntax = docker/dockerfile:experimental FROM python:3 RUN pip install awscli RUN --mount=type=secret,id=aws,target=/root/.aws/credentials aws s3 cp s3://... ...
注意: buildctl
是 BuildKit 的命令,你要测试的话自己换成 docker build
相关参数
$ buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. \ --secret id=aws,src=$HOME/.aws/credentials
-
RUN --mount=type=ssh
允许 build 容器通过 SSH agent 访问 SSH key,并且支持 passphrases
| Option | Description |
|---|---|
id
|
ID of SSH agent socket or key. Defaults to “default”. |
target
|
SSH agent socket path. Defaults to /run/buildkit/ssh_agent.${N}
. |
required
|
If set to true
, the instruction errors out when the key is unavailable. Defaults to false
. |
mode
|
File mode for socket in octal. Default 0600. |
uid
|
User ID for socket. Default 0. |
gid
|
Group ID for socket. Default 0. |
Example: access to Gitlab
# syntax = docker/dockerfile:experimental FROM alpine RUN apk add --no-cache openssh-client RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan gitlab.com >> ~/.ssh/known_hosts RUN --mount=type=ssh ssh -q -T git@gitlab.com 2>&1 | tee /hello # "Welcome to GitLab, @GITLAB_USERNAME_ASSOCIATED_WITH_SSHKEY" should be printed here # with the type of build progress is defined as `plain`.
$ eval $(ssh-agent) $ ssh-add ~/.ssh/id_rsa (Input your passphrase here) $ buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. \ --ssh default=$SSH_AUTH_SOCK
你也可以直接使用宿主机目录的 pem 文件,但是带有密码的 pem 目前不支持
目前根据文档测试,当前的挂载类型比如 cache
类型,仅用于 multi-stage 内的挂载,比如你有 2+ 个构建步骤, cache
挂载类型能帮你在各个阶段内共享文件;但是它目前无法解决直接将宿主机目录挂载到 multi-stage 的问题(可以采取些曲线救国方案,但是很不优雅);但是未来还是很有展望的,可以关注一下
转载请注明出处,本文采用 CC4.0 协议授权
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 批量下载 BCompare 的语法高亮扩展包
- SG :一个简单的PHP语法糖扩展
- 在ES6中使用扩展语法有什么好处?它与rest语法有什么不同?
- iBoxDB.NET Linq 查询语法扩展库 0.5 发布
- 嵌入式C语言自我修养(01):Linux 内核中的 C 语言语法扩展
- Swift语法快速入门(一)之 Swift基础语法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
About Face 3
Alan Cooper、Robert Reimann、David Cronin / John Wiley & Sons / 2007-5-15 / GBP 28.99
* The return of the authoritative bestseller includes all new content relevant to the popularization of how About Face maintains its relevance to new Web technologies such as AJAX and mobile platforms......一起来看看 《About Face 3》 这本书的介绍吧!