Как использовать Скаффолд с объемами Кубернетес?

У меня есть приложение на Python, сборка которого занимает около 15-20 минут. Вот как выглядит мой Dockerfile более или менее

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

Теперь, если я использую skaffold, любое изменение кода вызывает перестроение, и оно будет переустанавливать все требования (начиная с шага COPY, все остальное будет перестраивать) независимо от того, были ли они уже установлены. В 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

будет ли эта дополнительная сборка требований решена с помощью скаффолда?

3 ответа

Я не могу говорить конкретно о скаффолде, но сборка образа контейнера может быть улучшена. Если доступно кэширование слоев, переустановите зависимости только тогда, когда requirements.txt изменения. Это задокументировано в разделе "ДОБАВИТЬ или КОПИРОВАТЬ".

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) с доступными слоями.

Если ваша цель - ускорить процесс разработки: вместо запуска совершенно нового процесса развертывания каждый раз, когда вы меняете строку кода, вы можете переключиться на процесс разработки на основе синхронизации, чтобы выполнить развертывание один раз, а затем обновить файлы в работающих контейнерах. при редактировании кода.

Skaffold поддерживает синхронизацию файлов для непосредственного обновления файлов внутри развернутых контейнеров, если вы измените их на локальном компьютере. Тем не менее, в документации указано "Синхронизация файлов - это альфа" ( https://skaffold.dev/docs/how-tos/filesync/), и я могу полностью согласиться с работой с ним некоторое время назад: механизм синхронизации является только однонаправленным (без синхронизации из контейнера обратно в локальный) и довольно глючный, то есть он часто падает при переключении веток git, установке зависимостей и т. д., что может быть довольно раздражающим.

Если вам нужна более стабильная альтернатива для разработки Kubernetes на основе синхронизации, с которой очень легко начать, взгляните на DevSpace: https://github.com/devspace-cloud/devspace

Я один из сопровождающих DevSpace и начал проект, потому что Skaffold был слишком медленным для нашей команды, и тогда у него не было синхронизации файлов.

@ Ответ Мэтта - отличная лучшая практика (+1) -skaffold сам по себе не решит проблемы недействительности кэша нижележащего уровня, что приводит к необходимости переустанавливать требования во время каждой сборки.

Для дополнительной производительности вы можете кэшировать все python пакеты в 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

Запуск 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: {}
Другие вопросы по тегам