【问题标题】:How to use Skaffold with kubernetes volumes?如何将 Skaffold 与 kubernetes 卷一起使用?
【发布时间】:2020-01-02 01:52:41
【问题描述】:

我有一个 python 应用程序,它的 docker build 大约需要 15-20 分钟。 以下是我的 Dockerfile 或多或少的样子

FROM ubuntu:18.04
...
COPY . /usr/local/app
RUN pip install -r /usr/local/app/requirements.txt
...
CMD ...

现在,如果我使用 skaffold,任何代码更改都会触发重建,并且它将重新安装所有要求(从 COPY 步骤开始,其他所有要求都将被重建),无论它们是否已经安装。 iIn docker-compose 这个问题将使用卷来解决。在 Kubernetes 中,如果我们按以下方式使用卷:

apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- image: test:test
name: test-container
volumeMounts:
- mountPath: /usr/local/venv # this is the directory of the 
# virtualenv of python
    name: test-volume
volumes:
- name: test-volume
  awsElasticBlockStore:
    volumeID: <volume-id>
    fsType: ext4

这个额外的需求构建会用 skaffold 解决吗?

【问题讨论】:

    标签: kubernetes docker-compose docker-volume volumes skaffold


    【解决方案1】:

    我不能专门为 skaffold 说话,但可以改进容器映像构建。如果有可用的层缓存,则仅在 requirements.txt 更改时重新安装依赖项。这记录在“添加或复制”Best Practices。

    FROM ubuntu:18.04
    ...
    COPY requirements.txt /usr/local/app/
    RUN pip install -r /usr/local/app/requirements.txt
    COPY . /usr/local/app
    ...
    CMD ...
    

    如果模块版本定义松散并说您想要新的补丁版本,您可能需要触发更新。我发现要求应该是具体的,这样版本就不会在你不知情/没有测试的情况下滑到你的应用程序下面。

    Kaniko 集群内构建

    对于 kaniko 构建以使用默认情况下没有持久存储的集群中的缓存,kaniko 需要安装持久卷 (--cache-dir) 或具有可用层的容器映像存储库 (--cache-repo) .

    【讨论】:

      【解决方案2】:

      如果您的目标是加快开发流程:您可以切换到基于同步的开发流程部署一次,然后更新其中的文件,而不是每次更改代码行时都触发全新的部署流程编辑代码时正在运行的容器。

      Skaffold 支持文件同步以直接更新已部署容器内的文件,如果您在本地计算机上更改它们。但是,文档声明“文件同步是 alpha”(https://skaffold.dev/docs/how-tos/filesync/),我完全同意不久前使用它:同步机制只是单向的(没有从容器同步回本地)并且非常错误,即它在切换 git 分支、安装依赖项等时经常崩溃,这可能很烦人。

      如果您想要一个更稳定的基于同步的 Kubernetes 开发替代方案,并且非常容易上手,请查看 DevSpace:https://github.com/devspace-cloud/devspace

      我是 DevSpace 的维护者之一并开始了这个项目,因为 Skaffold 对我们的团队来说太慢了,而且当时它没有文件同步。

      【讨论】:

      • 是的,tilt 是我遇到的另一个工具,它可以做同样的事情。我目前正在运行一些测试和 POC 来尝试一下docs.tilt.dev/live_update_tutorial.html
      • 是的,倾斜度也不错。特别是如果您想在本地集群中使用 minikube 等。
      【解决方案3】:

      @Matt 的 answer 是一个很好的最佳实践 (+1) - skaffold 本身并不能解决底层缓存失效问题,这导致必须在每次构建期间重新安装需求。

      为了提高性能,您可以将所有 python 包缓存在安装在您的 pod 中的 volume 中,例如:

      apiVersion: v1
      kind: Pod
      metadata:
      name: test
      spec:
      containers:
      - image: test:test
        name: test-container
      volumeMounts:
      - mountPath: /usr/local/venv
          name: test-volume
      - mountPath: /root/.cache/pip
          name: pip-cache
      volumes:
      - name: test-volume
        awsElasticBlockStore:
          volumeID: <volume-id>
          fsType: ext4
      - name: pip-cache
        awsElasticBlockStore:
          volumeID: <volume-id>
          fsType: ext4
      

      这样,如果构建缓存失效并且您必须重新安装requirements.txt,您可以通过从缓存中获取它们来节省一些时间。

      如果您使用kaniko 构建,您还可以使用kaniko-warmer 将基础映像缓存到永久磁盘,例如:

      ...
      volumeMounts:
      ...
      - mountPath: /cache
          name: kaniko-warmer
      volumes:
      ...
      - name: kaniko-warmer
        awsElasticBlockStore:
          volumeID: <volume-id>
          fsType: ext4
      

      在 pod 内运行 kaniko-warmer:docker run --rm -it -v /cache:/cache --entrypoint /kaniko/warmer gcr.io/kaniko-project/warmer --cache-dir=/cache --image=python:3.7-slim --image=nginx:1.17.3。您的 skaffold.yaml 可能类似于:

      apiVersion: skaffold/v1beta13
      kind: Config
      build:
        artifacts:
        - image: test:test
          kaniko:
            buildContext:
              localDir: {}
            cache:
              hostPath: /cache
        cluster:
          namespace: jx
          dockerConfig:
            secretName: jenkins-docker-cfg
        tagPolicy:
          envTemplate:
            template: '{{.DOCKER_REGISTRY}}/{{.IMAGE_NAME}}'
      deploy:
        kubectl: {}
      

      【讨论】:

      • 如果您正在进行集群内 docker 构建,假设为 kaniko,同样可以使用 --cache 和 --cache-dir 选项完成
      • 可以将--cache-dir 用于python 包吗?不知道这一点,我使用kaniko-warmer 将基本图像缓存在--cache-dir(也由永久磁盘支持)中,必须对其进行测试。谢谢。
      • 抱歉,我的评论措辞不当。您不使用cache-dir 专门用于python 包,而是使用相同的mountPath 设置来设置kaniko 缓存目录,kaniko 可以缓存容器映像层。一旦你从 my answer 设置了 Dockerfile,初始的 requirements.txt 和 pip install 层可以从本地磁盘缓存中提取,而内容没有改变。
      • 实际上,通过多阶段构建,您可以拥有一个带有 pip 缓存的缓存图像。然后最终图像可以保持干净,只需复制您想要的文件路径。
      • 啊,是的,我使用 kaniko / kaniko-warmer(jenkins x 和 tekton 管道)进行构建 - 更新了我的答案。没有考虑多阶段构建,但这是一个好点,例如按照最佳实践构建仅包含依赖项的映像,缓存映像以使用kaniko-warmer 扩展它们,如果需要重建它们,则缓存依赖项(即 pip-cache)。似乎合法。
      猜你喜欢
      • 2023-02-04
      • 2021-11-18
      • 2019-07-26
      • 2016-05-18
      • 1970-01-01
      • 2019-06-28
      • 1970-01-01
      • 2016-11-17
      • 1970-01-01
      相关资源
      最近更新 更多