Вступление
По моему опыту, понимание того, как организовать конвейер от разработки к эксплуатации, оказалось весьма успешным. В этой статье мы расскажем вам о необходимых инструментах, необходимых для развертывания вашего кода в виде контейнеров Docker, выполнив шаги, связанные с созданием простого приложения «Hello World» (хотя ранее существующие проекты также легко применимы для этого подхода).
Если вы продвинулись достаточно далеко, чтобы рассмотреть конвейер для вашего проекта, я ожидаю, что вы знакомы с некоторыми более простыми инструментами (например, Git, Java, Maven), задействованными в этом процессе, и не будете охватывать их всесторонне.
Вам также может понравиться: Создание конвейеров CI / CD для Java с использованием DevOps Azure (ранее VSTS)
Чтобы приступить к созданию конвейера для нашего приложения «Hello World», кратко будут рассмотрены следующие темы:
Чтобы прояснить ситуацию: наша цель состоит в том, чтобы бегать docker run <dockerid>/<image>:<tag>
, а до этого бегать только git push
на мастере. Это попытка создать основу для будущих реализаций CI / CD, что в конечном итоге приведет к созданию среды DevOps.
Azure DevOps
Одним из предварительных условий этого пошагового руководства является использование платформы DevOps Azure. Я могу настоятельно рекомендовать полный пакет, но модули Repos и Pipelines являются единственными необходимыми. Итак, если вы еще этого не сделали, вам нужно зарегистрироваться и создать проект. После этого мы можем перейти к модулю Repos.
Лазурный Репо
Этот модуль предоставляет несколько простых инструментов для поддержки хранилища для вашего кода. Хотя хранилище может легко управляться чем-то вроде Github , этот модуль поддерживает надежную синергию между хранилищами и конвейерами.
После того, как вы щелкнете по модулю, вы встретитесь с обычным предисловием Git для настройки репозитория. Я настоятельно рекомендую использовать методы SSH для долгосрочного использования (если это вам неизвестно, см. Подключение к вашим репозиториям Git по SSH ). Теперь, после его настройки, вы сможете клонировать репозиторий на свой компьютер.
Продолжая, мы создадим проект Maven в папке репозитория, используя IntelliJ IDEA (можно использовать другие IDE, но я расскажу только о IntelliJ) , что в конечном итоге напечатает знаменитое предложение «Hello World!» (для настройки проекта с Maven см. Создание нового проекта Maven — IntelliJ ). Это должно оставить вас с деревом проекта следующим образом:
Завершаем создание основного класса в src / main / java:
Джава
1
public class Main {
2
public static void main(String[] args) {
3
System.out.println("Hello World!");
4
}
5
}
Но прежде чем приступить к освоению этих изменений, необходимо решить несколько вопросов.
специалист
Maven предоставляет разработчикам мощный инструмент управления программным обеспечением, настраиваемый из одного места, файл pom.xml. Глядя на сгенерированный файл pom в нашем проекте, мы увидим следующее:
XML
xxxxxxxxxx
1
2
<project xmlns="http://maven.apache.org/POM/4.0.0"
3
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5
<modelVersion>4.0.0</modelVersion>
6
<groupId>surgo.testing</groupId>
8
<artifactId>testing-helloworld</artifactId>
9
<version>1.0</version>
10
</project>
В нашем случае единственной действительно интересной частью файла pom является тег версии. Причина в том, что после передачи нашего исходного кода мастеру, Maven будет каждый раз требовать новую версию, следуя надлежащей практике.
В качестве расширения нам нужно заставить Maven создать исполняемый файл .jar с манифестом о том, где должен находиться главный класс. К счастью, мы можем просто использовать их собственный плагин Maven:
XML
xxxxxxxxxx
1
2
<project xmlns="http://maven.apache.org/POM/4.0.0"
3
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5
<modelVersion>4.0.0</modelVersion>
6
<groupId>surgo.testing</groupId>
8
<artifactId>testing-helloworld</artifactId>
9
<version>1.0</version>
10
<properties>
12
<main.class>Main</main.class>
13
</properties>
14
<build>
16
<plugins>
17
<plugin>
18
<groupId>org.apache.maven.plugins</groupId>
19
<artifactId>maven-jar-plugin</artifactId>
20
<version>3.1.2</version>
21
<configuration>
22
<archive>
23
<manifest>
24
<addClasspath>true</addClasspath>
25
<classpathPrefix>lib/</classpathPrefix>
26
<mainClass>${main.class}</mainClass>
27
</manifest>
28
</archive>
29
</configuration>
30
</plugin>
31
</plugins>
32
</build>
33
</project>
Единственное, что вы можете изменить, - это имя основного класса (строка 12). Запомните имя пакета, если оно не находится непосредственно в src / main / java (я предпочитаю использовать свойства, но вы можете вставить имя непосредственно в строку 26, если хотите).
Наконец, перед тем как добавить наши дополнения в master, нам нужно создать целевую папку, в которую входит наш файл .jar. Это можно сделать напрямую через IntelliJ или через терминал (если у вас установлен Maven). Просто нажмите «пакет» жизненного цикла в пользовательском интерфейсе или запустите mvn package
в терминале. После завершения файл .jar появится в целевой папке:
На этом мы завершаем начальную настройку, необходимую для нашего конвейера, и теперь мы можем наконец передать наши изменения в master.
Гит
Большинство из вас, вероятно, хорошо знакомы с Git, но я все равно расскажу о том, что нужно сделать.
Инструмент Git предоставляет нам распределенную систему контроля версий, доступную из любой точки мира. Теперь, если мы правильно настроили наш репозиторий в репозитории Azure, клонировали его на наш локальный компьютер и инициализировали проект IntelliJ в этой папке, все должно быть просто.
Поскольку все наши добавленные файлы еще не подготовлены, запустите git add
. Это установит каждый измененный или добавленный файл. Затем запустите, git commit -m "initial commit"
чтобы зафиксировать поставленные файлы. Наконец, запустите, git push
чтобы подтолкнуть зафиксированные файлы к мастеру.
Вы могли бы теперь задаваться вопросом, "H как все волшебство случилось?" И ответом будет нет. На самом деле, мало что произошло. Мы создали репозиторий и наполнили его проектом Maven, который печатает «Hello World» при вызове, что, честно говоря, не является большим достижением. Но, что более важно, мы создали основу для нашего трубопровода.
Лазурные Трубопроводы
Pipelines , звезда шоу, предоставляет нам автоматизацию сборки и развертывания. Это позволяет нам настроить то, что должно происходить всякий раз, когда сборка запускается (в нашем случае, нажав на master).
Позвольте мне провести процесс настройки простого конвейера.
- Сначала перейдите в модуль Azure DevOps Pipeline. Это представит вам одну кнопку «Создать конвейер», нажмите ее.
- Теперь нам будет предложено указать местонахождение нашего кода, и, поскольку мы использовали репозитории Azure, нажмите «Git репозитория Azure».
- Теперь он будет просматривать ваши репозитории. Нажмите на тот, на кого вы поместили проект Maven.
- Поскольку это проект Maven, выберите «Maven».
- Теперь вам должен быть представлен следующий файл azure.pipelines.yml:
HXML
xxxxxxxxxx
1
# Maven
2
# Build your Java project and run tests with Apache Maven.
3
# Add steps that analyze code, save build artifacts, deploy, and more:
4
# https://docs.microsoft.com/azure/devops/pipelines/languages/java
5
trigger:
7
- master
8
pool:
10
vmImage: 'ubuntu-latest'
11
steps:
13
- task: Maven@3
14
inputs:
15
mavenPomFile: 'pom.xml'
16
mavenOptions: '-Xmx3072m'
17
javaHomeOption: 'JDKVersion'
18
jdkVersionOption: '1.8'
19
jdkArchitectureOption: 'x64'
20
publishJUnitResults: true
21
testResultsFiles: '**/surefire-reports/TEST-*.xml'
22
goals: 'package'
Не думайте слишком много о семантике файла. Теперь важно знать, что триггер настроен на мастер, а шаги включают задачу для Maven. Для получения дополнительной информации о входных данных Maven см. Задачу Maven .
Если все выглядит по порядку, нажмите «сохранить и запустить» в правом верхнем углу, чтобы добавить файл azure.pipelines.yml в репозиторий. Затем конвейер активируется и запускает свою первую работу.
докер
Docker, последняя часть головоломки, предоставляет нам виртуализацию на уровне операционной системы в форме контейнеров с множеством возможностей и возможностей. Нам нужен этот инструмент для развертывания наших сборок на машинах, и, к счастью, он сильно интегрирован в платформу DevOps Azure. Чтобы полностью использовать его многочисленные возможности, вам необходимо зарегистрироваться на DockerHub .
- После регистрации создайте репозиторий с названием вашего приложения. Затем выберите, делать ли это общедоступным (у вас может быть только один частный репозиторий с бесплатным планом).
- Затем нам нужно авторизовать DockerHub в нашем проекте Azure DevOps. Для этого вернитесь в DevOps Azure и нажмите «Настройки проекта» в левом нижнем углу.
- Выберите «Трубопроводы / Сервисные соединения *».
- Теперь нажмите на верхнюю правую кнопку «Подключение к новой услуге» и найдите реестр Docker, отметьте его и нажмите «Далее».
- Выберите «Docker Hub» в качестве типа реестра.
- Заполните оставшиеся поля (имя подключения службы зависит от вас). Теперь вы должны увидеть свою запись под заголовком «Сервисные подключения».
Соединение станет актуальным позже, но сейчас нам нужно вернуться к проекту и добавить несколько вещей. Поскольку мы добавили файл azure.pipelines.yml в хранилище, git pull
необходимо вызвать новейшие изменения. Кроме того, нам нужно определить наш образ Docker, используя Dockerfile. Создайте новый файл в корне проекта и назовите его «Dockerfile». Дерево вашего проекта теперь должно выглядеть примерно так:
Dockerfile следует рассматривать как шаблон для контейнеров, так же как классы для объектов. Что нужно определить в этом шаблоне:
- Нам нужно установить основу для виртуальной среды (ОТ openjdk: 8).
- Нам нужно скопировать наш файл .jar в виртуальную среду (COPY /target/testing-helloworld-?.?*.jar.).
- Нам нужно запустить файл .jar после инициализации (CMD java -jar testing-helloworld -? -? *. Jar).
Теперь у вас должен быть файл, похожий на этот:
Dockerfile
1
FROM openjdk:8
2
COPY /target/testing-helloworld-?.?*.jar .
3
CMD java -jar testing-helloworld-?.?*.jar
Регулярное выражение просто учитывает развертываемые версии, но фактическое имя должно соответствовать файлу .jar из целевой папки.
Подводя итог нашему текущему прогрессу, мы сделали проект Maven, связали его с конвейером и создали шаблон для виртуальной среды. Единственное, чего не хватает, это подключить все через файл azure.pipelines.yml.
Во-первых, нам нужно добавить некоторые переменные для соединения DockerHub, а также постоянно изменяющийся номер версии в файл azure.pipelines.yml (вставьте свой репозиторий Service Connection и Docker):
HXML
xxxxxxxxxx
1
...
2
variables:
3
containerRegistryServiceConnection: saban17-testing
4
imageRepository: saban17/testing-helloworld
5
tag: 1.0.0
6
...
Эти переменные не являются строго необходимыми, но никогда не помешает следовать принципу СУХОЙ. Во-вторых, нам нужно добавить больше задач к нашим шагам конвейера. Что должно произойти: войдите в Docker, создайте ранее определенный Dockerfile и отправьте образ в наш репозиторий DockerHub.
По одному за раз мы добавляем требуемое поведение, начиная с входа в Docker:
HXML
xxxxxxxxxx
1
- task: Docker@2
2
displayName: dockerLogin
3
inputs:
4
command: login
5
containerRegistry: $(containerRegistryServiceConnection)
Затем сборка Docker:
HXML
xxxxxxxxxx
1
- task: Docker@2
2
displayName: dockerBuild
3
inputs:
4
repository: $(imageRepository)
5
command: build
6
Dockerfile: Dockerfile
7
tags: |
8
$(tag)
И, наконец, толчок Docker:
HXML
xxxxxxxxxx
1
- task: Docker@2
2
displayName: dockerPush
3
inputs:
4
command: push
5
containerRegistry: $(containerRegistryServiceConnection)
6
repository: $(imageRepository)
7
tags: |
8
$(tag)
Теперь у вас должен быть файл azure.pipelines.yml, похожий на этот (с добавлением mavenAuthenticateFeed:true
входных данных в Maven @ 3):
HXML
xxxxxxxxxx
1
trigger:
2
- master
3
pool:
5
vmImage: 'ubuntu-latest'
6
variables:
8
containerRegistryServiceConnection: saban17-testing
9
imageRepository: saban17/testing-helloworld
10
tag: 1.0.0
11
steps:
13
- task: Maven@3
14
inputs:
15
mavenPomFile: 'pom.xml'
16
mavenOptions: '-Xmx3072m'
17
javaHomeOption: 'JDKVersion'
18
jdkVersionOption: '1.8'
19
jdkArchitectureOption: 'x64'
20
publishJUnitResults: true
21
mavenAuthenticateFeed: true
22
testResultsFiles: '**/surefire-reports/TEST-*.xml'
23
goals: 'package'
24
- task: Docker@2
26
displayName: dockerLogin
27
inputs:
28
command: login
29
containerRegistry: $(containerRegistryServiceConnection)
30
- task: Docker@2
32
displayName: dockerBuild
33
inputs:
34
repository: $(imageRepository)
35
command: build
36
Dockerfile: Dockerfile
37
tags: |
38
$(tag)
39
- task: Docker@2
41
displayName: dockerPush
42
inputs:
43
command: push
44
containerRegistry: $(containerRegistryServiceConnection)
45
repository: $(imageRepository)
46
tags: |
47
$(tag)
48
Понятно, что это может быть немного подавляющим, но не бойтесь, это выглядит сложнее, чем на самом деле. Для получения дополнительной информации об этих входах см. Задачу Docker .
В заключение. Теперь мы видим, как происходит волшебство. Однако, прежде чем сделать это, я должен рассказать вам о рутинной процедуре, которая заключается в передаче в конвейер:
- Перейдите в файл pom.xml и azure.pipelines.yml и увеличьте номер версии.
- Запустите жизненный цикл Maven,
clean
чтобы удалить более ранние файлы .jar из целевой папки. - Запустите жизненный цикл Maven,
package
чтобы собрать и упаковать свой код (создав новый файл .jar). - При условии, что вы находитесь в основной ветке, выполните команды git:
-
git add .
-
git commit -m "commit message"
-
git push
-
- Проверьте, проходит ли задание в конвейере.
Если все прошло как надо, вы загрузили изображение с файлом .jar в связанный репозиторий DockerHub. Для запуска этого образа теперь требуется, чтобы на хосте был установлен Docker. Давайте попробуем это!
Ввод (а) инициирует контейнер из запрошенного хранилища. Затем изображение было извлечено, создано и обработано с конечным результатом (b), отображающим «Hello World!»
На этом завершается руководство по настройке вашего конвейера Java с помощью Azure DevOps и Docker.
Заключение
К настоящему времени должно быть ясно, почему этот подход имеет свои преимущества. Это позволяет разработчику формировать среду выполнения (Dockerfile) и загружать ее в работу просто и без усилий ( git push
). Хотя этот подход не был рассмотрен, этот подход также создает артефакты в DevOps Azure, что очень полезно при использовании чего-то вроде Maven, поскольку делает удивительно простым управление зависимостями.
Так как этот подход только недавно вошел в нашу команду, он все еще находится в стадии разработки, и многие дополнения еще предстоит сделать. Я настоятельно рекомендую вам расширять свой трубопровод, чтобы он соответствовал вашим потребностям.
Я надеюсь, что это руководство оказалось полезным и практичным, и если у вас есть какие-либо дополнительные вопросы, не стесняйтесь комментировать ниже.
Спасибо за чтение.
Дальнейшее чтение
Настройка конвейеров Azure CI / CD с помощью Visual Studio