
Приветствую Хабр!
Меня зовут Рустем и я занимаю должность Senior DevOps Engineer в компании IBM, город Краков. Сегодня я хотел бы Вам показать и рассказать, как можно подружить Openshift и Jenkins и использовать их связку в CI-процессе.
Давайте начнем с пререквизитов, что же нам понадобится? А это:
-
Github с кодом нашего приложения.
-
Jenkins — для сборки и доставки.
-
Openshift — наш оркестратор и куда мы будем все это деплоить.
Что такое github, я уверен, все тут знают, поэтому предлагаю начать нашу вводную с Jenkins’а и закончить её Openshift.
Jenkins
Jenkins — это сервер непрерывной интеграции, написанный на Java. Конфигурируется же пайплайн в декларативном стиле на языке Groovy, а сам файл конфигурации (Jenkinsfile) располагается в системе контроля версий.
В рамках этой статьи нам понадобится знать всего две сущности Jenkins — это пайплайн (конвейер) и секреты. Пайплайны или же конвееры сборки и доставки бывают двух видов: Декларативный и императивный (он же скриптовый). В чем же разница?
Декларативный — это когда мы описываем конечное состояние системы, к которому машина должна прийти сама.
Императивный (Скриптовый) — это когда мы описываем именно шаги, которые должна произвести машина, в точности как мы ей это указали.
Секреты — это конфиденциальные данные, которые мы будем использовать для аутентификации. Нам нужно будет сконфигурировать следующие секреты:
-
GITHUB_CREDENTIALS— для доступа к нашему репозиторию; -
IBM_CLOUD_API_KEY— для загрузки нашего образа в реестр; -
OS_QA_API_KEY— для аутентификации в наш Openshift cluster; -
SLACK_TOKEN— для отправки сообщение о деплое в слак в канал нашей команды.
Конфигурируются они Credentials -> System -> Global credentials -> Add Credentials:
Openshift
Openshift — это оркестратор, разработанный компанией RedHat и который распространяется как PaaS, т.е. Platform as a Service. Под капотом у него находится все тот же Kubernetes, понимает он все те же команды, только вместо kubectl для ввода команд мы используем oc. Например: если в K8s мы будем использовать kubectl get po, то в OpenShift мы будем использовать oc get po.
Я использовал термин “Оркестратор”, когда давал определение Openshift, но давайте теперь разберем понятие оркестратора.
Оркестратор — это инструмент, который управляет жизненным циклом нашего кластера, то есть он занимается автоматизацией и управлением наших контейнеров, микросервисов и услуг, и решает он эту проблему за счет автоматизации планирования, развертывания, масштабируемости, балансировки нагрузки, доступности и организации сетей контейнеров
Openshift имеет в себе все те же сущности, что K8s: pod, deployment, ReplicaSet, Volumes, Secrets, Services и т.д. С Openshift можно взаимодействовать как через WebUI, так и через CLI.
С теорией, думаю, можно закончить, давайте перейдем к практике.
Сперва подготовим наш кластер, много нам тут делать не нужно, нужно будет только:
-
Создать Namespace (пространстов имен) для изоляции нашего проекта.
-
Создать DockerSecrets, чтобы Openshift мог пулить (скачивать) образы для создания контейнера для нашего реестра (без него под просто не сможет функционировать)
-
Создать namespace можно в левом меню UI перейдя в Adminstration -> namespaces

Либо также можно использовать CLI: oc create namespace avs.
Теперь создадим DockerSecrets для нашего пространства имен.
Нужно перейти в левом меню в Workloads -> Secrets -> Create -> Image pull Secret.


И вводим следующие значения:
-
Secret Name — универсальное имя нашего секрета.
-
Authentication type — способ аутентификации. Есть два способа аутентификации: Credentials (связка логин — пароль) и Upload Configuration File (нужно загрузить
.dockercfg, либо.docker/config.json). Я использую первый. -
Registry server address — адрес нашего реестра.
-
Username — имя пользователя, который имеет разрешение на скачивание образов из нашего реестра.
-
Password — пароль.

Наш Openshift готов к деплою, давайте сконфигурируем Jenkins и напишем наш деплой.
Сперва подготовим наши Секреты, для этого переходим в Credentials -> System -> Global credentials -> Add Credentials и создаем наши Секреты.
Небольшое уточнение: так как Кластер находится в IBM Cloud, то ключ API для аутентификации в кластер получаем из следующей документации.

Отлично, секреты созданы, теперь напишем наш пайплайн.
Для этого заходим в Dashboard -> New Item.

Даем имя нашему пайплайну и выбираем pipeline.

Далее мы увидим 4 секции, в General можно будет дать описание нашему пайплану, чтобы тот, кто будет работать с ним после нас, мог понять “Что это, зачем, как и куда?”
Также можно увидеть секцию BuildTriggers — тут можно будет настроить действия, которые будут автоматически запускать наш конвеер (например, пуш в репозиторий на нашу ветку, чтобы у нас уже был полный Continuous Development процесс).
Advanced Project Options — тут можно задать необязательное отображаемое имя отображается для проекта в графическом веб-интерфейсе Jenkins. Поскольку оно предназначено только для отображения, отображаемое имя не обязательно должно быть уникальным среди проектов. Если отображаемое имя не задано, веб-интерфейс Jenkins по умолчанию будет отображать имя проекта. Вот, собственно, и все.
Pipeline — тут мы уже конфигурируем наш пайплайн.

Написание пайплайна:
Наши пайплайны будут состоять из следующих шагов:
-
Checkout — проверяем нашу ветку git;
-
Build and unit test — сборка и тестирование;
-
Push to IBM cloud registry — загружаем собранный образ в наш реестр;
-
Recreate pods on openshift QA — Обновляем поды на нашем Openshift.
Переходим в секцию pipeline.
У нас есть выбор: либо написать наш пайплайн прямо в jenkins, либо запускать его из Jenkinsfile (нужно будет только создать Jenkinsfile в нашем репозитории и прописать уже путь до него).


Давайте уже писать:
Зададим переменные среды:
node { try { withEnv([ "TAG=1.0.build-qa-${BUILD_NUMBER}", "REGISTRY=de.icr.io/s2p-platform" ])
Далее создадим Stage Checkout, где мы проверим нашу ветку.
Тут мы прописываем адрес нашего репозитория (repoUrl), ветку (branches) и секреты для аутентификации в наш репозиторий (UserRemoteConfigs:credentialsId).
stage ("Checkout") { //checkout scm checkout([$class: 'GitSCM', branches: [[name: '*/angular-QA']], browser: [$class: 'GithubWeb', repoUrl: 'https://github.ibm.com/airlines-vendor-service.git'], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'GITHUB_CREDENTIALS', url: 'https://github.ibm.com/airlines-vendor-service.git']]]) }
Далее соберем наше приложение, также хорошей практикой является дополнительное краткое описание, того, что сейчас происходит через echo
stage ("Build and unit test") { echo "Start building Airlines-Vendor-Service QA version ${TAG}" sh "docker-compose -f docker-compose-openshift.yaml build" }
Дальше загрузим наш образ в реестр, нам необходимо прописать наш ключ в withCredentials
stage ("Push to IBM cloud registry") { echo "Push Airlines-Vendor-Service QA version ${TAG} to cloud registry" withCredentials([ string(credentialsId: 'IBM_CLOUD_API_KEY', variable: 'IBM_CLOUD_API_KEY'), ]) { sh "ibmcloud login --apikey ${IBM_CLOUD_API_KEY} -g 'CPS S2P' -r eu-de" echo "Try to login de.icr.io cloud registry" sh "ibmcloud cr login" sh "docker-compose -f docker-compose-openshift.yaml push" echo "push successed!" } }
Далее, прежде, чем мы создадим шаг обновления контейнеров (а также других сущностей, если они были изменены, например Secrets, VirtualServices и т.д.), нам нужно создать два скрипта — один сгенерирует обновленные yaml-файлы для наших сущностей, а другой уже загрузит их в наш кластер.
generate-yamls.sh

Update-yamls.sh

Теперь можно написать наш последний шаг “Recreate pods”
Прописываем наши секреты в withCredentials
Делаем наши скрипты исполняемыми:
"chmod +x './openshift/generate-yamls.sh”
Запускаем их:
sh "'./openshift/generate-yamls.sh'"
Логинимся в наш кластер
sh "oc login -u apikey -p ${OS_QA_API_KEY} --server=https://c101-e.eu-de.containers.cloud.ibm.com:30478"
Переключаем пространство имен на пространство имен нашего проекта:
sh "oc project avs"
Очищаем все старое:
sh "oc delete jobs --all"
Обновляем наши сущности:
sh "'./openshift/update-image.sh'"
Отправляем сообщение об успешном деплое в наш канал:
“def slack_message = """Airlines-Vendor-Service container version ${TAG} pushed to ibm cloud registry and deployed on QA instance :clean:""" slackSend(message: slack_message, channel: "#DevOps-deployments")”
В итоге наш шаг будет выглядеть вот так:
stage ("Recreate pods on openshift QA") { withCredentials([ string(credentialsId: 'OS_QA_API_KEY', variable: 'OS_QA_API_KEY'), ]) { withEnv(["REGISTRY=de.icr.io\/s2p-platform"]) {
echo "generate yaml's files version ${TAG}" sh "chmod +x './openshift/generate-yamls.sh'" sh "chmod +x './openshift/update-image.sh'" sh "'./openshift/generate-yamls.sh'" echo 'Login to openshift cluster' sh "oc login -u apikey -p ${OS_QA_API_KEY} --server=https://c101-e.eu-de.containers.cloud.ibm.com:30478" echo "set default project to avs" sh "oc project avs" echo "clear old jobs" sh "oc delete jobs --all" echo "apply deployment ${TAG}" sh "'./openshift/update-image.sh'" echo 'Deployed! You are breathtaking!' def slack_message = """`Airlines-Vendor-Service container version ${TAG}` pushed to ibm cloud registry and deployed on QA instance :clean:""" slackSend(message: slack_message, channel: "#DevOps-deployments") }
Сохраняем и запускаем наш пайплайн.



Вот таким образом мы сконфигурировали и написали паплайн в связке Jenkins+Openshift и успешно задеплоили наше приложение.
Скоро в Otus состоится открытое занятие «Основные компоненты Kubernetes и их взаимодействие». На нем мы познакомимся с основными компонентами и концепциями системы Kubernetes, а также узнаем, как работают компоненты Kubernetes и взаимодействуют друг с другом. Регистрация доступна по ссылке для всех желающих.
ссылка на оригинал статьи https://habr.com/ru/articles/664704/
Добавить комментарий