Приветствую Хабр!

Меня зовут Рустем и я занимаю должность 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.

С теорией, думаю, можно закончить, давайте перейдем к практике.


Сперва подготовим наш кластер, много нам тут делать не нужно, нужно будет только:

  1. Создать Namespace (пространстов имен) для изоляции нашего проекта.

  2. Создать DockerSecrets, чтобы Openshift мог пулить (скачивать) образы для создания контейнера для нашего реестра (без него под просто не сможет функционировать)

  3. Создать namespace можно в левом меню UI перейдя в Adminstration -> namespaces

Либо также можно использовать CLI: oc create namespace avs.

Теперь создадим DockerSecrets для нашего пространства имен.

Нужно перейти в левом меню в Workloads -> Secrets -> Create -> Image pull Secret.

И вводим следующие значения:

  1. Secret Name — универсальное имя нашего секрета.

  2. Authentication type — способ аутентификации. Есть два способа аутентификации: Credentials (связка логин — пароль) и Upload Configuration File (нужно загрузить .dockercfg, либо .docker/config.json). Я использую первый.

  3. Registry server address — адрес нашего реестра.

  4. Username — имя пользователя, который имеет разрешение на скачивание образов из нашего реестра.

  5. 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 — тут мы уже конфигурируем наш пайплайн.

Написание пайплайна:

Наши пайплайны будут состоять из следующих шагов:

  1. Checkout — проверяем нашу ветку git;

  2. Build and unit test — сборка и тестирование;

  3. Push to IBM cloud registry — загружаем собранный образ в наш реестр;

  4. 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 и взаимодействуют друг с другом. Регистрация доступна по ссылке для всех желающих.

Комментарии (0)