Создание и развертывание базового веб-приложения ASP.NET в качестве контейнера Docker с использованием Microsoft Azure, часть 2

Tags: ASP.NET, Microsoft, Azure, Docker

Введение

Это вторая статья в серии. Здесь мы собираемся настроить конвейер сборки Microsoft Azure DevOps для автоматизации задач, которые мы выполняли вручную в первой статье серии. Каждый раз, когда мы вносим изменения в основную ветку, сборка будет запускаться для построения нашего приложения, затем создавать образ Docker и отправлять его в Docker Hub.

Если вы следовали за вами, вы должны иметь:

  • Репозиторий GitHub
  • Работающее веб-приложение в ASP.NET Core (или что-то подобное)
  • Образ Docker для приложения
  • Работающий контейнер для локального размещения вашего приложения

Docker Registry

Во-первых, вам нужно настроить учетную запись в Docker Hub. После этого создайте репозиторий, в котором вы сможете хранить образы Docker для своего приложения.

У вас уже есть образ Docker, созданный в предыдущих шагах, который хорошо работает. Теперь вы можете пометить это изображение именем хранилища. Однако клиент Docker, работающий на вашем локальном компьютере, должен соединиться с учетной записью Docker Hub, прежде чем вы сможете отправить образ.

Следующие команды помечают локальный образ для хранилища Docker Hub, авторизуют клиент Docker и, наконец, помещают образ в Docker Hub.

$ docker tag <image-name> <namespace>/<repository>:<tag> 

// example
$ docker tag webapp quickdevnotes/webapp:v1

// login to your Docker Hub account
$ docker login 
username:
password:
// push the to Docker Hub
$ docker push quickdevnotes/webapp:v1

Обратите внимание, что мы используем публичный репозиторий в Docker Hub. Если вы используете частный репозиторий, то вам сначала нужно будет войти в систему с помощью команды входа в систему docker, а затем нажать на изображение. В противном случае отправка завершится ошибкой авторизации.

Azure DevOps: проект

Теперь начинается интересная часть. Чтобы начать использовать конвейеры DevOps Azure, сначала необходимо иметь учетную запись пользователя. Если у вас уже есть аккаунт - отлично: вы можете начинать или можете зарегистрироваться здесь.

После того, как вы окажетесь, он попросит вас создать организацию и место, где вы хотите разместить свой проект. Назовите его как угодно и выберите регион, который вам подходит:

Далее нам нужно создать проект под организацию. Выберите Create New Project в правом верхнем углу и предоставьте необходимую информацию.

Из раздела Advanced нам ничего не нужно для целей этой серии. Итак, мы оставляем выбор за вами.

Непрерывная интеграция (Build Pipeline)

Наконец-то пришло время автоматизировать ручные шаги. Из Pipelines> Builds выберите New Pipeline.

Где ваш код? 

Первое, что нужно конвейеру Azure, - это подключиться к вашему репозиторию кода приложения. Итак, на вкладке Connect выберите GitHub, соединение с вашим GitHub.

После этого вам будет предложено с помощью аутентификации OAuth авторизовать конвейеры Azure для доступа к репозиторию GitHub. Предоставьте разрешение и предоставьте учетные данные по мере необходимости.

 

Выберите репозиторий

После завершения авторизации вы можете увидеть список репозиториев из учетной записи GitHub. В списке репозиториев выберите репозиторий приложения, который затем предложит установить конвейеры Azure -  Install Azure Pipelines. Используйте опцию «only select repositories» и в раскрывающемся списке выберите свой репозиторий приложений.

Если вы хотите установить конвейеры Azure для всех текущих и будущих репозиториев, выберите «All repositories» и нажмите «Install».

 

azure-pipelines.yml

Конвейер Azure достаточно умен, чтобы проанализировать хранилище приложений и предоставить базовый файл azure-pipelines.yml. Этот файл yml находится в корне репозитория GitHub и используется конвейером сборки Azure для выполнения определенных задач, таких как создание приложения, выполнение тестов, сборка Docker Image и многие другие.

Вот файл azure-pipelines.yml для нашего конвейера сборки. Он может выглядить ошеломляющим; но все будет ясно после того, как мы поговорим о каждой задаче подробно.

trigger:
- master

pool:
  vmImage: 'Ubuntu-16.04'

variables:
  imageName: 'quickdevnotes/webapp:$(build.buildNumber)'

steps:
- script: dotnet test WebApp.Tests/WebApp.Tests.csproj --logger trx
  displayName: Run unit tests
- task: PublishTestResults@2
  condition: succeededOrFailed()
  inputs:
    testRunner: VSTest
    testResultsFiles: '**/*.trx'
- task: Docker@1
  displayName: Build an image
  inputs:
    command: Build an image
    containerregistrytype: Container Registry
    dockerRegistryEndpoint: DockerHub
    dockerFile: Dockerfile
    imageName: $(imageName)
    imageNamesPath: 
    restartPolicy: always
- task: Docker@1
  displayName: Push an image
  inputs:
    command: Push an image
    containerregistrytype: Container Registry
    dockerRegistryEndpoint: DockerHub
    dockerFile: Dockerfile
    imageName: $(imageName)
    imageNamesPath: 
    restartPolicy: always

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

Задачи CI - пристальный взгляд

Давайте подробнее рассмотрим задачи, определенные в приведенном выше файле сборки. Однако мы останемся на уровне выше, чтобы все было просто для этой серии.

trigger:
- master

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

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

pool:
vmImage: 'Ubuntu-16.04'

Вышеуказанные строки указывают, какой пул агентов использовать для задания / задачи конвейера.

variables:
imageName: 'quickdevnotes/webapp:$(build.buildNumber)'

Мы используем раздел переменных, чтобы объявить любые переменные, которые мы хотим использовать в нашем конвейере. Например, здесь мы создаем переменную imageName, которой будет присвоено имя образа Docker, который мы хотим создать.

В рекомендациях по непрерывной интеграции рекомендуется использовать $(build.buildNumber) для маркировки изображений Docker. Потому что это позволяет легко обновлять или откатывать любые изменения.

- script: dotnet test WebApp.Tests/WebApp.Tests.csproj --logger trx
  displayName: Run unit tests
- task: PublishTestResults@2
  condition: succeededOrFailed()
  inputs:
    testRunner: VSTest
    testResultsFiles: '**/*.trx'

Я также добавил несколько базовых модульных тестов в свое приложение. С помощью приведенного выше сценария эти тесты будут выполняться при каждом запуске сборки. Мы также можем получить отчеты об испытаниях из этих тестов.

- task: Docker@1
  displayName: Build an image
  inputs:
    command: Build an image
    containerregistrytype: Container Registry
    dockerRegistryEndpoint: DockerHub
    dockerFile: Dockerfile
    imageName: $(imageName)
    imageNamesPath: 
    restartPolicy: always
- task: Docker@1
  displayName: Push an image
  inputs:
    command: Push an image
    containerregistrytype: Container Registry
    dockerRegistryEndpoint: DockerHub
    dockerFile: Dockerfile
    imageName: $(imageName)
    imageNamesPath: 
    restartPolicy: always

Первая из указанных выше двух задач - создание образа Docker с использованием файла Docker, доступного в корне хранилища. После создания образа вторая задача отправляет этот образ в наш репозиторий на Docker Hub.

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

Чтобы отправить образ в ваш репозиторий Docker Hub, клиент Docker, работающий на агенте сборки, должен сначала авторизоваться. Аналогично тому, что вы сделали, нажимая на изображение вручную.

- task: Docker@1
...
    dockerRegistryEndpoint: DockerHub
...

Для точки dockerRegistryEndpoint установлено соединение со службой реестра Docker, которое содержит учетные данные для учетной записи Docker Hub и используется для авторизации. Давайте настроим это дальше.

Подключение службы регистрации Docker


В левом нижнем углу панели навигации выберите Project Settings. Затем в разделе Pipelines выберите Service connections, и вы должны увидеть здесь свое GitHub-соединение.

Чтобы подключиться к реестру Docker, нажмите New service connection и в списке выберите Docker Registry.

В следующем диалоговом окне выберите Docker Hub в качестве типа реестра и установите DockerHub (должен совпадать с dockerRegistryEndpoint в задаче построения) в качестве имени соединения.

Затем укажите идентификатор Docker и пароль своей учетной записи Docker Hub. Электронная почта не является обязательной. Убедитесь, что установлен флажок «Allow all pipelines to use this connection».

Вы можете проверить соединение, используя ссылку Verify this connection. Нажмите «ОК», и мы готовы.

Тестирование сборки конвейера

К настоящему времени у вас должно быть достаточно информации для настройки конвейера непрерывной интеграции. Хорошо, пришло время проверить работоспособность этого.

Перейдите в Pipelines > Builds и выберите Queue, чтобы поставить в очередь сборку. Если вы не получили никаких ошибок, вы должны увидеть процесс сборки. Вот вывод из нашего конвейера сборки после успешной сборки:

Последняя задача в конвейере успешно передала недавно созданный образ Docker в Docker Hub. Обратите внимание на тег image, который равен номеру сборки на изображении выше:

 

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

 

Обратите внимание, как описание сборки говорит вам о триггере сборки, и это доказывает, что это не ручной триггер.

Поздравляем!

Заключение

В этой статье мы успешно настроили рабочий конвейер непрерывной интеграции с Microsoft Azure DevOps. Начиная от создания веб-приложения .NET Core и заканчивая настройкой конвейера CI, мы на полпути.

Далее мы настроим конвейер выпуска для развертывания нашего приложения в качестве контейнера Docker в службе веб-приложений Azure. Это должно быть увлекательно.

No Comments

Add a Comment