Покращення швидкості GitHub Actions за допомогою ефективного кешування залежностей

pic

Як інженери DevOps, ми працюємо в світі "автоматизації". Від написання скриптів, чи то в BASH, чи Python, до створення CI/CD пайплайнів для автоматизації всього процесу розробки програмного забезпечення до його розгортання. CI/CD (неперервна інтеграція та неперервний розвиток) є важливими частинами процесу розробки програмного забезпечення, і GitHub Actions став найпопулярнішим інструментом для автоматизації цих процесів.

У цьому блозі ми розглянемо GitHub Actions, де ми побачимо ефективну стратегію кешування, яку слід застосовувати в кількох додатках, оскільки кешування відіграє дуже важливу роль у прискоренні виконання нашого пайплайну, що покращує процеси доставки програмного забезпечення. Перед тим, як продовжити, ознайомтесь з моїми попередніми блогами:

Створення безсерверного веб-застосунку з AWS Lambda, API Gateway, DynamoDB, S3

End-to-End DevOps для Golang веб-додатку: Docker, EKS, AWS CI/CD

Розгортання вашого вебсайту на AWS S3 за допомогою Terraform

Навчання розгортанню масштабованих 3-тиричних додатків з AWS ECS

Вступ до GitHub Actions та кешування залежностей

Сьогодні більшість компаній переходять до GitHub Actions з Jenkins через проблеми безпеки, а Jenkins зазвичай самостійно хоститься для більшості компаній, тому необхідно підтримувати сервери у нашому дата-центрі. GitHub Actions — це ще одна платформа CI/CD, на якій розробники можуть автоматизувати свої робочі процеси безпосередньо у репозиторіях GitHub.

У GitHub Actions багато функцій покращують безпеку та усувають деякі вузькі місця в пайплайні, але коли мова йде про кешування залежностей, багато користувачів стикаються з проблемами продуктивності, особливо під час встановлення залежностей або повторення завдань в кількох робочих процесах. Кешування залежностей — це техніка, яку слід застосовувати для зменшення часу збірки пайплайну, що також зменшує споживання ресурсів. Шляхом кешування артефактів і бібліотек ми можемо використовувати їх як артефакти в інших збірках.

У GitHub Actions є вбудований механізм через actions/cache, де користувачі можуть кешувати залежності, використовуючи цю дію в пайплайні.

Кращі практики для реалізації кешування залежностей

  1. Використовуйте ефективні ключі кешу: Хешуйте файли ключів, такі як package.json або requirements.txt, щоб підтримувати актуальність кешу.
  2. Уникайте конфліктів кешу: Використовуйте унікальні ключі для різних середовищ або гілок, щоб уникнути змішування.
  3. Реалізуйте інвалідність кешу: Змінюйте ключі кешу, коли оновлюються залежності.
  4. Керуйте розміром кешу: Великі кеші можуть уповільнювати процес, тому зберігайте лише необхідні файли.

Як працює кешування в GitHub Actions

Тепер ми реалізуємо дію кешування в додатку NodeJs, де кешуватимемо шари Docker-образу за допомогою кешу gha, тобто кешу GitHub Actions, що є за замовчуванням. Однак кеш GitHub Actions надає лише 10 ГБ сховища для кешу, тому більшість корпоративних середовищ використовують віддалене спільне сховище для зберігання артефактів на Nexus або AWS CodeArtifacts, а для Docker Builds можна використовувати Harbor або DockerHub.

Якщо мені потрібно зберігати, наприклад, node_modules для NodeJs або requirements.txt (venv) для Python, ми можемо використовувати кеш GitHub Actions або сховище, сумісне з S3 (Minio).
Зараз давайте реалізуємо кешування шарів Docker у кеші GitHub Actions і перевіримо швидкість збірки.

GitHub Code: github.com/amitmaurya07/DevSecOps-GHA

.github/workflows/pipeline.yml:

name : NodeJs Application and Caching  
on:  
 workflow_dispatch:  
 push:  
 branches:  
 - master  
jobs:  
 docker-build:  
 runs-on: ubuntu-latest  
 steps:  
 - name: Checkout Code  
 uses: actions/checkout@v3  

 - name: Cache Docker layers  
 uses: actions/cache@v3  
 with:  
 path: /tmp/.buildx-cache  
 key: ${{ runner.os }}-buildx-${{ hashFiles('**/Dockerfile') }}  
 restore-keys: |  
 ${{ runner.os }}-buildx-  

 - name: Login to docker-hub  
 uses: docker/login-action@v1  
 with:  
 username: ${{ vars.DOCKER_USERNAME }}  
 password: ${{ secrets.docker_pat }}  

 - name: Set up Docker Buildx  
 uses: docker/setup-buildx-action@v3  

 - name: Build and Push Image  
 uses: docker/build-push-action@v6  
 with:  
 context: .  
 push: true  
 tags: "amaurya07/devsecops_app:${{ github.ref_name }}"  
 cache-from: type=local,src=/tmp/.buildx-cache  
 cache-to: type=local,dest=/tmp/.buildx-cache,new=true

У першій частині ми задали назву пайплайну "NodeJs Application and Caching", потім налаштували тригер для виконання, визначивши, коли пайплайн буде запускатися. Тут пайплайн запускається при пуші на гілку master, а workflow_dispatch означає, що ми можемо вручну запустити пайплайн, коли хочемо. Це означає, що коли щось буде закинуто в гілку master, пайплайн виконується автоматично.

jobs:  
 docker-build:  
 runs-on: ubuntu-latest  
 steps:  
 - name: Checkout Code  
 uses: actions/checkout@v3  

 - name: Cache Docker layers  
 uses: actions/cache@v3  
 with:  
 path: /tmp/.buildx-cache  
 key: ${{ runner.os }}-buildx-${{ hashFiles('**/Dockerfile') }}  
 restore-keys: |  
 ${{ runner.os }}-buildx-  

 - name: Login to docker-hub  
 uses: docker/login-action@v1  
 with:  
 username: ${{ vars.DOCKER_USERNAME }}  
 password: ${{ secrets.docker_pat }}  

 - name: Set up Docker Buildx  
 uses: docker/setup-buildx-action@v3  

 - name: Build and Push Image  
 uses: docker/build-push-action@v6  
 with:  
 context: .  
 push: true  
 tags: "amaurya07/devsecops_app:${{ github.ref_name }}"  
 cache-from: type=local,src=/tmp/.buildx-cache  
 cache-to: type=local,dest=/tmp/.buildx-cache,new=true

У другій частині ми визначили завдання після тригера, тобто docker-build, потім задали параметр runs-on, що визначає, де виконуються кроки в завданні. Ми вказали ubuntu-latest, який надається GitHub Actions. У вкладці "Actions" репозиторію перейдіть до розділу "Runners" і перевірте ім'я виконуваного агента в Standard GitHub-hosted runners.

pic

Тепер перейдемо до кроків, які визначені в завданні. В завданні є 4 кроки (Checkout Code, Login to DockerHub, Docker Buildx, потім Docker Build і Push):

  1. Checkout Code: Дія actions/checkout@v3, яка виконує checkout вихідного коду з репозиторію.
  2. Cache Docker Layers: Дія actions/cache@v3, яка кешує шари Docker локально в директорії /tmp, де ключ кешу — ${{ runner.os }}-buildx-${{ hashFiles('**/Dockerfile') }}, що означає обчислення хешів вмісту Dockerfile, і коли Dockerfile змінюється, буде використовуватися новий кеш.
  3. Login to DockerHub: Дія docker/login-action@v1, де використовуються змінні та секрети, які є в репозиторії, для входу в DockerHub, щоб завантажити образ.
  4. Docker Buildx: Дія docker/setup-buildx-action@v3, де налаштовується Docker Buildx, оскільки ми використовуємо дію build і push на наступному кроці. Це також використовується для кешування шарів Docker-образів і дозволяє будувати кілька етапів або архітектур паралельно, що зменшує час збірки для складних Dockerfile.
    5.
    Docker Build and Push: У цьому кроці встановлюємо контекст на поточний робочий каталог, де знаходиться Dockerfile, потім встановлюємо push на true з тегами. Далі, у cache-from тип кешу встановлюється як local, де src вказує на директорію /tmp, в якій кеш було збережено на попередньому кроці, а в cache-to також встановлюється тип local, де new=true означає примусове створення нового кешу замість оновлення існуючого.

pic

pic

pic

Як ми бачимо, у наступній збірці відбувається імпорт кешу з gha, і всі шари кешуються в наступній збірці.

Приклади кешування залежностей для популярних мов і інструментів

Node.js

- uses: actions/cache@v3  
 with:  
 path: node_modules  
 key: node-${{ hashFiles('package-lock.json') }}

Python

- uses: actions/cache@v3  
 with:  
 path: ~/.cache/pip  
 key: pip-${{ hashFiles('requirements.txt') }}

Java (Maven)

- uses: actions/cache@v3  
 with:  
 path: ~/.m2/repository  
 key: maven-${{ hashFiles('pom.xml') }}

Висновок: Майбутнє швидких CI/CD з GitHub Actions

Кешування залежностей — чудовий спосіб прискорити ваші CI/CD пайплайни з GitHub Actions. Використовуючи правильні стратегії кешування, ви можете зменшити час зборки, отримати швидший зворотний зв'язок і заощадити ресурси. Спробуйте кешування сьогодні, щоб створювати більш ефективні та масштабовані робочі процеси.

GitHub Code: https://github.com/amitmaurya07/DevSecOps-GHA

Twitter : x.com/amitmau07

LinkedIn: linkedin.com/in/amit-maurya07

Якщо у вас є питання, ви можете залишити повідомлення на LinkedIn або Twitter.

Підтримайте мою роботу ☕️
Якщо ви знайшли цей блог корисним і хочете підтримати мою роботу, подумайте про покупку мені кави! Ваша підтримка допомагає мені створювати більше такого контенту.

Дякую за вашу підтримку!

Перекладено з: Boost GitHub Actions Speed with Effective Dependency Caching

Leave a Reply

Your email address will not be published. Required fields are marked *