docker push很慢怎么办_如何加速 Docker Build 构建过程

Dockerfile

docker 已经成为现代开发的基础技术,

而在 docker 开发流中,

Dockerfile 是最基础的文件。

一个包括了系统配置、依赖安装、业务代码的 Dockerfile 可能长这样子:

FROM python:3.8-buster

WORKDIR /app

COPY Pipfile Pipfile.lock ./

COPY code /app/code

RUN pip install pipenv

RUN pipenv sync

RUN echo "Asia/Shanghai" > /etc/timezone

RUN dpkg-reconfigure -f noninteractive tzdata

RUN apt-get update

RUN apt-get -y dist-upgrade

RUN apt-get -y install vim tmux git

RUN curl -sL https://sentry.io/get-cli/ | bash

然后很自然地,

开发者小周发现:

每次改完代码以后重新 docker build 都非常慢。

他需要加速构建过程

改写文件

最简单的加速是改写 Dockerfile,

因为 Dockerfile 中的一些命令 (ADD/COPY/RUN) 会产生新的 layer,

而 Docker 会自动跳过已经构建好的 layer。

所以一般优化的原则基于以下几点:变动越小的命令,越靠前,增加 cache 使用率。

合并目的相同的命令,减少 layer 层数。

使用国内源,或者内网服务加速构建。

少装些东西,不是代码依赖的就尽量别装了…

记得加上合适的注释,以便日后的维护。

改写以后的 Dockerfile 可能长这样:

FROM python:3.8-buster

WORKDIR /app

# 默认使用上海时区 + 阿里源

RUN echo "Asia/Shanghai" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata && \

echo "deb http://mirrors.aliyun.com/debian/ buster main non-free contrib" > /etc/apt/sources.list

# 预装必须的包,sentry-cli 是预先存入内网的

RUN apt-get update && apt-get -y dist-upgrade && apt-get -y install git && \

wget http://internal-nginx-service.domain.com/sentry.sh /usr/bin/sentry-cli && \

pip install pipenv

# 装依赖,顺便祝 pipenv 早日发布新版本

COPY Pipfile Pipfile.lock ./

RUN pipenv sync

# 代码频繁变更,放在文件底部,下面就别加更多命令了

COPY code /app/code

改过以后的版本,

开发者小周发现,

每次本地改完代码 build 调试都飞快,

他很满意。

但是用公司的分布式 gitlab runner 构建以后,

他发现:

有时镜像没用到 cache,又跑了一遍漫长的构建过程。

分布式构建

在 codebase 足够大的情况下,

CI/CD 一般都是分布式多台机器的,

默认的 docker build 只会从本地寻找 cache layer,

无法应对如此复杂的场面。

简单的办法是使用 docker build --cache-from 指定镜像,

我们会在 ci 脚本中这么写:

docker pull LKI/code:latest || true

docker build . -t LKI/code:latest --cache-from LKI/code:latest

docker push LKI/code:latest

但是这样手写的弊端是逻辑比较臃肿,

比如要完美适配多分支构建 (dev/master/hotfix/release) 的话,

往往就要自己实现一套判断究竟 cache from 哪个版本的逻辑。

更通用的办法是使用类似 GoogleContainerTools/kaniko 这样的工具来构建。

最适合 kaniko 的场景是 kaniko + kubernetes,

但这个我们留到最后一章再讲,

我们顺着我们的工作流往下看。

使用 kaniko + docker 的构建,

我们可以把上面的 pull/build/push 三连改写为以下这样:

# 这个命令包括了 cache/build/push

docker run \

-v "$CODE"/LKI/code:/workspace \

gcr.io/kaniko-project/executor:latest \

--cache=true \

--context dir:///workspace/ \

--destination LKI/code:latest

and Kubernetes?

上面提到,kaniko 可以直接丢到 kubernetes 集群中构建:

apiVersion: v1

kind: Pod

metadata:

name: kaniko

spec:

containers:

- name: kaniko

image: gcr.io/kaniko-project/executor:latest

args: ["--dockerfile=Dockerfile",

# 没错,可以直接从 s3 里捞代码构建

"--context=s3:///bucket/code/",

"--destination=LKI/code:latest"]

volumeMounts:

- name: kaniko-secret

mountPath: /secret

restartPolicy: Never

volumes:

- name: kaniko-secret

secret:

secretName: kaniko-secret

随着研究的进一步深入,

很容易想到,

其实 docker 开发流跟 kubernetes 的开发流理应有更好的集成。

这就是 GoogleContainerTools/skaffold 在做的事情了。

skaffold 不仅支持前面讲到的 kaniko 构建,

还囊括了 port-forwarding/test/helm-deploy 等一系列常用工作流。

有兴趣的同学可以自行了解,

关于 skaffold 的故事我们以后有机会,

再慢慢讲 :)

(完)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值