Рубрики
Uncategorized

Оптимизация трубопровода CI / CD для проектов ржавчины (GitLab & Docker)

Что такое ржавчина? Rust представляет собой язык программирования (общего назначения) C-подобного, что означает … Теги с DevOps, Docker, Rust, Gitlab.

Что такое ржавчина?

Rust представляет собой язык программирования (общего назначения) C-подобного, что означает, что это скомпилированный язык, и он поставляется с новыми сильными функциями в управлении памятью и многое другое. Крутая вещь! У ржавчины не имеют сборщика мусора, и это потрясающе 😅.

Что такое devops?

Короче говоря, DEVOPS — это ключевая особенность, которая помогает команде Dev и команду OPS дружить без рабочих конфликтов, это искусство автоматизации. Это увеличивает скорость доставки лучшего программного обеспечения!

Определение проблемы

Мы можем сделать много вещей с Rust, как Web Apps, системные драйверы ANS гораздо больше, но есть одна проблема, которая является временем, когда ржавчину берет, чтобы сделать двоичный доступ, загрузка зависимостей и компилируйте их.

груз Команда помогает нам загружать пакеты (ящики в мире ржавчины), Rustc — наш компилятор. Теперь нам нужно сделать трубопровод, используя GitLab CI/CD и Docker, чтобы сделать развертывание быстрее.

Это наша проблема и цель этой статьи! 👊

Статическое связывание против динамического связывания

Rust по умолчанию использует метод динамического соединения для создания двоичного значения, так что такое динамическое связывание?

Динамическое соединение использует общие библиотеки, поэтому lib загружается в память, и только адрес интегрирован в двоичный. В этом случае Libc используется.

Статическое соединение использует статические библиотеки, которые физически интегрированы в двоичные адреса, никакие адреса не используются, а двоичный размер будет более больше. В этом случае Musl Libc используется.

Вы хотите узнать больше? Тогда проверьте это: Нажмите здесь Отказ

Оптимизация конвейера CI/CD

Трубопровод CI/CD — это установить шаги, которые позволяют нам сделать:

Построить → Тест → Развертывание

В этой статье я сосредоточусь на этапе сборки, потому что на мой взгляд, это очень чувствительная фаза, и это повлияет на « Время на рынок » подход!

Таким образом, первое, что нужно оптимизировать размер наших изображений докера, чтобы сделать развертывание быстрее. Прежде чем мы начнем, я буду использовать простой проект ржавчины для демонстрации демонстрации.

Давайте понять структуру проекта:

  • Src. : Этот режим содержит весь исходный код приложения (* .rs файлов).
  • Cargo.toml : Этот файл содержит пакет Meta-Data и зависимости, требуемые приложением и некоторыми другими функциями ….
  • Груз : CT содержит точную информацию о ваших зависимостях.
  • Rocket.toml : С помощью этого файла мы указываем состояние приложения (разработка, постановка или производство) и необходимую конфигурацию для каждого режима, например, конфигурацию порта для каждой среды.
  • Dockerfile : Это конфигурация Docker File для создания изображения с определенной средой, которая настраивается уже в Rocket.toml.

Вы готовы 👊 😈 !!! Давайте начнем шоу !! 🎉 🎉 🎉

Мы начнем с создания изображения приложения локально, поэтому давайте посмотрим, как выглядит документ Docker:

FROM rustdocker/rust:nightly as cargo-build 
RUN apt-get update 
RUN apt-get install musl-tools -y 
RUN /root/.cargo/bin/rustup target add x86_64-unknown-linux-musl 
RUN USER=root /root/.cargo/bin/cargo new --bin material 
WORKDIR /material 
COPY ./Cargo.toml ./Cargo.toml 
COPY ./Cargo.lock ./Cargo.lock 
RUN RUSTFLAGS=-Clinker=musl-gcc /root/.cargo/bin/cargo build --release --target=x86_64-unknown-linux-musl --features vendored 
RUN rm -f target/x86_64-unknown-linux-musl/release/deps/material* 
RUN rm src/*.rs 
COPY ./src ./src 
RUN RUSTFLAGS=-Clinker=musl-gcc /root/.cargo/bin/cargo build --release --target=x86_64-unknown-linux-musl --features vendored 
FROM alpine:latest 
COPY --from=cargo-build /auth/target/x86_64-unknown-linux-musl/release/material . 
CMD ["./material"]

Это DockerFile разделен на два раздела:

  • Раздел Builder (временный контейнер)
  • Окончательное изображение (уменьшено по размеру)

Раздел Builder: Чтобы использовать ржавчину, мы должны получить предварительно настроенные изображения, которые содержат компилятор RUSTC и Cargo Tool. Изображение имеет ночную сборку RUST ночной сборки, и это реальная задача, потому что она не стабильна 😠.

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

Давайте распадаем код:

  • Сначала мы импортируем базовое изображение.
  • Нам нужны Мускул Поддержка: Musl-Tool После обновления Source.List ваших пакетов APT-Get Update Musl — это простое в развертывание статических и минимальных динамически связанных программ.
  • Теперь мы должны указать цель, если вы не знаете! нет проблем ! Вы можете использовать X86_64-Unknown-Linux-Musl , бегите с рустанкой (установщик инструментов Rust Rust)
  • Чтобы определить структуру проекта на контейнере, мы используем грузовые новые --bin Материал (материал — это название проекта), это так же, как структура, которую мы видим ранее.
  • Делать каталог материала как по умолчанию, мы используем Workdir Команда DockerFile.
  • Cargo.toml и Cargo.lock требуется для депс. установка
  • Настройка RUST_FLAGS с GCC : Этот флаг рассказывает Cargo использовать Musl GCC для компиляции исходного кода, --release Аргумент используется для подготовки кода для выпуска (окончательная бинарная оптимизация).
  • --target Укажите целевую компиляцию 64 или 32 бит
  • --feature Подаваемая команда Thsi — это угол 😄! Это помогает решить любую проблему SSL, найдя ресурсы SSL автоматически без указания каталога SSL Lib и каталог SSL. Это экономит мне много времени, эта команда связана с некоторыми конфигурациями в Cargo.toml Файл под особенность раздел.

До сих пор мы создаем только зависимости в Cargo.toml, и мы делаем чистый (удаление ненужных файлов)

  • После загрузки и компиляции необходимых пакетов пришло время получить исходный код в контейнер и сделать окончательную сборку для получения окончательного двоичного двоичного ( автономный ).

Этап строителя завершен! Поздравляю 😙. 🎉 Ага !!. Теперь давайте будем использовать Alpine в качестве базового изображения, чтобы получить двоичную на стадии сборки, но! Подожди секунду ! Что такое альпийский ???

Alpine — это дистрибутив Linux, он отличается в мире Docker по его размеру! Это очень маленькое изображение (4 МБ), и он содержит только базовые команды (Busybox)

  • — из-за грузовой сборки …./материал Теперь мы скопируем окончательный двоичный к альпину, а промежуточный контейнер (Cargo-Build) будет уничтожен, и мы получаем в результате очень крошечное изображение (12-20 МБ), готовые к использованию 😃 😃 😃 😃

Вы знаете, как построить образец Docker прямо 😲? Ладно 😃

Трубопровод CI/CD

После проверки изображения локально, кажется хорошим 😃, мы разрешаем размер докера изображения, но в системе CI скорость очень важна, чем размер !! Итак, давайте возьмем эту проблему и уменьшите время компиляции этого проекта ржавчины !!

Давайте посмотрим на файл .gitlab-Ci.yml (наша конфигурация CI):

.caching_rust: &caching_rust
    cache:
      paths:
        - .cargo/
        - .cache/sccache
        - target/x86_64-unknown-linux-musl/release/material

stages:
    - build_binary
    - build_docker


prepare_deps_for_cargo:
   stage: build_binary
   image: hatembt/rust-ci:latest
   <<: *caching_rust
   before_script:
       - export CARGO_HOME="${PWD}/.cargo"
       - echo $CARGO_HOME
       - export SCCACHE_DIR="${PWD}/.cache/sccache"
       - echo $SCCACHE_DIR
       - export PATH="/builds/Astrolab-devops/material/.cargo/bin:$PATH"
       - export RUSTC_WRAPPER="$CARGO_HOME/bin/sccache"
       - echo $RUSTC_WRAPPER

   script:
       -  cargo build --release --target=x86_64-unknown-linux-musl --features vendored
   cache:
     paths:
       - .cargo/
       - .cache/sccache
   artifacts:
     paths:
       - target/x86_64-unknown-linux-musl/release/material


build_docker_image:
   stage: build_docker
   image: docker:latest
   << : *caching_rust
   services:
     - docker:dind
   script:
     - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
     - docker build -t registry.gitlab.com/astrolab-devops/material:0.2.1 .  
     - docker push registry.gitlab.com/astrolab-devops/material:0.2.1

В этом файле есть наконечник, я просто разбил документ Docker на два этапа в этом .gitlab-Ci.yml:

  • Стадия строителя (Rustdocker/Rust ..) → Создание зависимостей и двоичный
  • Последний этап (Alpine) → этап сборки

Для работы CI я подготовил готовый к использованию докера, который содержит все, что мне нужно сделать надежный и быстрый трубопровод для проекта ржавчины, это изображение размещено в моем $ Docker Hub Отказ

Hatembt/Rust-Ci: последний

Это изображение содержит следующие пакеты, установленные и настроенные:

  • Sccache Команда: эта команда кэширует скомпилированные зависимости! Поэтому, сделав это действие на нашу сборку, мы можем компилировать DEPS только один раз !! 😅, и мы набрали гораздо больше времени.
  • грузовик-аудитор : Это полезная команда, давайте сканировать безопасность зависимостей.

Давайте распадаем код и понять, что происходит !!

В первой работе: prepare_deps_for_cargo. Нам нужно наше базовое изображение Hatembt/Rust-Ci Отказ

В этой работе требуются некоторые настройки, чтобы сделать успешную сборку в до_script :

  • Определение груза домой в пути пути.
  • Определение каталога кэша, сгенерированного Sccache (Содержит кэш компиляции).
  • Добавление груза и рустика (они находятся под .cargo/bin ) на пути.
  • Указание RUSTC_WRAPPER переменная для использования Sccache Команда с Rustc или Мускул в нашем случае.

Теперь все что готовы! Итак, давайте сделаем сборку в Сценарий Раздел, вы уже сейчас то, что мы должны делать 😃, давайте пропустим это 👇.

Разделы кеша и артефактов очень важны! его сохраняет данные:

  • .cargo/
  • .cache/sccache.
  • Target/X86_64-Unknown-Linux-Musl/Release/Материал (это наш последний двоичный файл).

Чтобы узнать больше о кэшировании и артефактах эта ссылка Отказ

Все данные, созданные в первом запуске заданий CI, теперь будут сохранены и загружены в координатор GitLab. На следующую сборку (новые коды нажата), мы не запускаем сборку с нуля, мы просто строим новые пакеты, старые данные будут введены в ж <<: * Caching_rust после изображение ключевое слово.

Давайте перейдем на следующую работу: build_docker_image :

Я сделал новый Dockerfile для сцена сборки докеров, он основан на альпийском изображении, и он содержит только бинарный с предыдущего этапа.

Новый Dockerfile:

FROM alpine:latest
COPY target/x86_64-unknown-linux-musl/release/material .
CMD ["./material"]

Сначала нам нужен Docker в Docker Image (DIND) → Чтобы получить команду Docker и давайте сделаем шаги ниже:

  • Войдите в реестр GitLab
  • Создайте изображение с новым DockerFile
  • Нажмите на изображение в реестр GitLab

А теперь результаты! 😧

Размер изображения:

Время CI:

NB: Время предназначено для времени сборки отверстий, построение бинарных и этапов Docker_Build.

Это сила DevOps, искусство автоматизации с некоторыми Философия В конфигурациях и шагах для потока мы можем сделать еще лучше, чем эти результаты.

В бизнесе скорость, качество и необходимые особенности (на приложении) очень важны для приведения компании на высокие уровни успеха → Это успешный Цифровое преобразование Отказ

Наконец, я надеюсь, что эта история поможет вам перейти к следующим шагам в системах CI/CD, вы можете применить эти идеи на любой язык (в основном соответствующие языки, но все же одинаковые шаги). Если у вас есть какие-либо отзывы или критики, пожалуйста, не стесняйтесь делиться ими со мной.

Спасибо …| 😄.

Оригинал: «https://dev.to/hatembentayeb/optimizing-ci-cd-pipeline-for-rust-projects-gitlab-docker-hc9»