Evgeny Rudinsky
Evgeny Rudinsky Cloud Architect @ Nordcloud

Использование Azure Container Registry в Azure DevOps

Использование Azure Container Registry в Azure DevOps

В данной статье я хочу поделиться опытом использования Azure Container Registry на проектах с Azure DevOps. Реестр контейнеров используется для хранения образов Docker, Helm чартов и других артефактов OCI. Из дополнительных преимуществ ACR я бы выделил возможность сборки образов “на лету” (с помощью ACR task), возможность подключения сканера для поиска уязвимостей в образе и его зависимостях, а также георепликацию артефактов по выбранным ЦОДам (на момент написания статьи Azure предалагает 54 региона ).

CI для Docker с использованием Azure DevOps и ACR

CI для Docker с использованием Azure DevOps и ACR

Небольшое пояснения:

  • Разработчик использует git, который развернут в Azure DevOps (Repos)
  • Приложение будет упаковано в Docker образ со следующими условиями:
    • Сборка будет производиться на агенте Azure DevOps (используется Pipeline);
    • Образ, после сборки и сканирования на уязвимости, отправляется в Azure Container Regisry;
  • Процесс повторяется автоматически (например, при обновлении файлов приложения или Dockerfile) или запускается в ручком режиме при необходимости.

Я буду использовать бесплатную версию Azure DevOps (на момент написания статьи 1800 минут работы агента в месяц, неограниченный git, 2 Гб для хранения артифактов и Azure Boards на 5 пользователей можно использовать бесплатно ).

Начнём с git

Для начала нужна организация в Azure DevOps и проект. Если ещё нет, то можно достаточно просто сделать это здесь.

Azure DevOps - начало

Шаблон проекта не важен (я использую Agile). Если все проделано правильно, то на выходе должен получиться один дефолтный git репозиторий, используя git-клиент склонируем на локальную машину.

Azure DevOps - Repos git

Сделаем ACR и дадим доступ к нему из Azure DevOps

Создать Azure Container Registry можно несколькими способами. Для данной статьи я использовал west europe в качестве региона, сам ресурс создавал в базовой конфигурации (basic tier) для нашей цели этого достаточно.

Azure Container Registy - Overview

  1. Сервер нашего хранилища (можно использовать в командах docker);
  2. SKU (aka tier) - базовый. Также доступны стандартный и премиум конфигурации;
  3. Можно сменить tier при необходимости.

У нас есть ресурс в Azure, теперь можно добавить его в Azure DevOps для использования во время сборки. Для этого находим Service Connections в Azure DevOps > Project Settings > Pipelines > Service Connections. Добавим новый с типом Docker Registry:

Azure DevOps - Docker service connection

Я использовал Service Principal для подключения к моему ресурсу из AzDo Pipelines. После сохранения настроек в Azure AD в приложениях появится новое приложение. Исследуем его настройки, для этого через az cli попробуем посмотреть список всех service connections:

PS C:\dev\azurefort> az devops service-endpoint list

Azure DevOps - aad sp

Выделен сверху тот самый SPN, который имеет AcrPush роль для нашего Azure Container Registry.

AcrPush - позволяет отправить и получить образ (push & pull), чего вполне достаточно для нашей задачи.

Azure Container Registry - Roles assignments

Всё, service connection готов.

Dockerfile и контент

Будем использовать nginx образ в качестве базового и добавим немного своего контента (html + картинка).

Вот тут git.

Немного пояснений:

FROM nginx
COPY src /usr/share/nginx/html

В src лежит контент сайт (рядом с Dockerfile), который копируется в контейнер во время его сборки в путь /usr/share/nginx/html. Сервер nginx с настройками по умолчанию загружает эту директорию и слушает порт 80.

Сборка приложения

Для сборки мы будем использовать Pipelines (синяя ракета! ). В Azure DevOps можно использовать классический визард (всё происходит через UI), YAML и расширенный YAML (Mutlistage). В данном примере я будут использовать последний, но сделаю короткий обзор первых двух.

Классический редактор

Azure DevOps - classic editor

С ним достаточно просто начать, необходимо пройти небольшой визард, ответить на вопросы: где хранится код (например, можно использовать Bitbucket или свой собственный git) и далее в графическом интерфейсе выбрать какие конкретно таски (task) будут запускаться (на каком агенте) в пачке каких конкретно задач (job).

Отличный вариант конфигурации пайплайна, но хранить как код не получится, всё будет лежать где-то в БД Microsoft.. всё-таки yaml хочется, чтоб прям Инфраструктура-как-Код (IaC).

YAML и multistage

Эти два варианта очень похожи друг на друга (в multistage добавляется подолнительные indent’ы и появляется понятие stage). Начинка задач (скоуп job) одинаковый. Ещё в multistage добавляется дополнительный тип задач (в дополнение к традиционным), который называется deployment.

Вернёмся к нашей поставленной задаче. Посмотрим на наш yaml:

trigger: none

stages:
- stage: build 
  pool:
    vmImage: 'ubuntu-latest'
  jobs:
    - job: build
      steps:
      - task: Docker@2
        inputs:
          containerRegistry: 'azurefort'
          repository: 'my-nginx'
          command: 'buildAndPush'
          Dockerfile: '**/Dockerfile'

У нас всего один stage с одной job и одной task.

Лучше всего работать с этим файлов через редактор Pipelines, меньше будет опечаток и синтаксических ошибок. Рекомендую также использовать ассистент для задач.

Azure DevOps - Pipeline editor

Сохраним и запустим.

В результате сборки в реестре образов появился новый образ my-nginx с нашим приложением и тэгом $(build.buildid). Рекомендую ознакомиться со встроенными переменными, они позволяет оптимизировать работу пайплайна, иметь меньше хардкода.

Несколько полезных команд для работы с ACR / Docker

  1. Подключиться к ACR:

#  подключиться к реестру образов

az acr login -n <name> 
Login Succeeded

# получить список доступных образов в реестре

az acr repository list -n <name> // список образов

# скачать образ my-nginx:2 

docker pull <name>.azurecr.io/my-nginx:2

# запустить образ, слушать на ноде 8080, в контейнере - 80 
# (tip: curl -v localhost:8080)

docker run -d -p 8080:80 <name>.azurecr.io/my-nginx:2 

Список пополнятся!

Что дальше?

  • Дальше можно автоматизировать сборку добавив trigger: <branch>. Допустим вы хотите собирать новый образ каждый раз когда вы делаете push или merge с main веткой;
  • Добавить Azure Key Vault для секретов, сертификатов итд;
  • С помощью дополнительных stages можно деплоить приложение. Вот здесь расписывал как работать с docker-compose.

Удачи

comments powered by Disqus