使用 docker 构建 Rust 项目在 google 云上极其缓慢

Building a rust project with docker is extremely slow on google cloud

我对 Rust 比较陌生,但我一直在 Docker 容器中开展项目。下面是我的 dockerfile,效果很好。我的构建使用中间容器在主项目之前构建所有货物容器。除非我更新依赖项,否则项目会在本地快速构建。即使依赖项得到重建,在我的旧 macbook pro 上最多也不会超过 10 分钟。

FROM ekidd/rust-musl-builder as builder

WORKDIR /home/rust/

# Avoid having to install/build all dependencies by copying
# the Cargo files and making a dummy src/main.rs
COPY Cargo.toml .
COPY Cargo.lock .
RUN echo "fn main() {}" > src/main.rs
RUN cargo test
RUN cargo build --release

# We need to touch our real main.rs file or else docker will use
# the cached one.
COPY . .
RUN sudo touch src/main.rs

RUN cargo test
RUN cargo build --release

# Size optimization
RUN strip target/x86_64-unknown-linux-musl/release/project-name

# Start building the final image
FROM scratch
WORKDIR /home/rust/
COPY --from=builder /home/rust/target/x86_64-unknown-linux-musl/release/project-name .
ENTRYPOINT ["./project-name"]

但是,当我将我的项目设置为通过 google 云构建从 github 存储库自动构建时,我震惊地发现构建花费了将近 45 分钟!我想如果我为中间容器正确设置了缓存,至少可以节省一些时间。即使构建器成功地提取了缓存的图像,它似乎也没有使用它并且总是从头开始构建中间容器。这是我的 cloudbuild.yaml:

steps:
  - name: gcr.io/cloud-builders/docker
    args:
      - "-c"
      - >-
        docker pull $_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:latest
        || exit 0
    id: Pull
    entrypoint: bash
  - name: gcr.io/cloud-builders/docker
    args:
      - build
      - "-t"
      - "$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:latest"
      - "--cache-from"
      - "$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:latest"
      - .
      - "-f"
      - Dockerfile
    id: Build
  - name: gcr.io/cloud-builders/docker
    args:
      - push
      - "$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:latest"
    id: Push
  - name: gcr.io/google.com/cloudsdktool/cloud-sdk
    args:
      - run
      - services
      - update
      - $_SERVICE_NAME
      - "--platform=managed"
      - "--image=$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:latest"
      - >-
        --labels=managed-by=gcp-cloud-build-deploy-cloud-run,commit-sha=$COMMIT_SHA,gcb-build-id=$BUILD_ID,gcb-trigger-id=$_TRIGGER_ID,$_LABELS
      - "--region=$_DEPLOY_REGION"
      - "--quiet"
    id: Deploy
    entrypoint: gcloud
timeout: 3600s
images:
  - "$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:latest"
options:
  substitutionOption: ALLOW_LOOSE

我正在寻找关于我在我的 cloudbuild.yaml 中做错了什么的任何信息,以及关于如何加速我的云构建的提示,考虑到它在本地是如此之快。理想情况下,我想坚持使用 google 云,但如果有另一个 CI 服务可以更好地处理 rust/docker 这样的构建,我愿意切换。

在速度方面有两点需要考虑:

  • 在你的(甚至是旧的)macbook pro 上,

    • 你有多核超线程CPU
    • CPU 在 Turbo 模式下最高可达 3.5Ghz
  • 云端构建

    • 每个构建只有一个 vCPU(默认)
    • vCPU是“服务器设计CPU”:没有高端性能,但稳定一致的性能,大约2.1Ghz(在turbo模式下略多)

所以,性能的差异是显而易见的。为了加快构建速度,我建议使用 the machine type option:

...
...
options:
  substitutionOption: ALLOW_LOOSE
  machineType: 'E2_HIGHCPU_8'

应该会更好!

这就是我在 Google Cloud Build 上改进 Rust 项目构建时间所做的工作。不是一个完美的解决方案,但总比没有好:

  • 在 Docker 文件中对您的文件进行类似更改,以便为部门和我自己的来源创建不同的缓存层。

  • 使用 kaniko 来利用缓存(这似乎是您的特定问题)

  steps:
 - name: 'gcr.io/kaniko-project/executor:latest'
    args:
    - --destination=eu.gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA
    - --cache=true
    - --cache-ttl=96h
    timeout: 2400s

文档:https://cloud.google.com/build/docs/kaniko-cache

  • 将机器类型更改为更高选项,在我的例子中:
options:
  machineType: 'E2_HIGHCPU_8'

不过要小心,更改机器类型会影响您的预算,因此您应该考虑这对您的特定项目是否值得。

如果您经常推送您的更改,效果会更好,但老实说仍然不够好。