Многоветвевой конвейер Jenkins на GKE

1. Обзор

Jenkins — одно из самых популярных доступных решений непрерывной интеграции. Он используется для автоматизации основных частей процесса разработки программного обеспечения, не связанных с участием человека. Развернув Jenkins в Kubenetes в Google Cloud и используя плагин GKE, мы можем быстро и автоматически масштабировать исполнители сборки по мере необходимости. В сочетании с облачным хранилищем мы можем создать и протестировать приложение с минимальными усилиями.

Что ты будешь делать

  • Развертывание Jenkins в кластере Kubernetes
  • Разверните и настройте плагин Jenkins GKE, чтобы Jenkins мог создавать и уничтожать модули в качестве узлов-исполнителей.
  • Создайте и протестируйте пример приложения SpringBoot.
  • Создайте и опубликуйте контейнер в реестре контейнеров Google.
  • Разверните пример приложения в промежуточной и рабочей среде GKE.

Что вам понадобится

  • Проект Google Cloud с настроенной оплатой. Если у вас его нет, вам придется его создать .

2. Приступаем к настройке

Эта лаборатория кода может полностью работать на Google Cloud Platform без какой-либо локальной установки или настройки.

Облачная оболочка

В ходе этой лабораторной работы мы будем предоставлять различные облачные ресурсы и сервисы и управлять ими с помощью командной строки через Cloud Shell .

Включить API

Вот API, которые нам нужно включить в нашем проекте:

  • Compute Engine API — создает и запускает виртуальные машины.
  • Kubernetes Engine API — создает контейнерные приложения и управляет ими.
  • Cloud Build API — платформа непрерывной интеграции и непрерывной доставки Google Cloud.
  • API управления услугами – позволяет производителям услуг публиковать сервисы на Google Cloud Platform.
  • Cloud Resource Manager API — создает, считывает и обновляет метаданные для контейнеров ресурсов Google Cloud.

Включите необходимые API с помощью следующей команды gcloud:

gcloud services enable compute.googleapis.com \
container.googleapis.com \
cloudbuild.googleapis.com \
servicemanagement.googleapis.com \
cloudresourcemanager.googleapis.com \
--project ${GOOGLE_CLOUD_PROJECT}

Создайте сегмент GCS

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

gsutil mb gs://${GOOGLE_CLOUD_PROJECT}-jenkins-test-bucket/ 

3. Создание кластеров Kubernetes

Создайте кластер

Далее мы создадим кластер GKE, в котором будет размещаться наша система Jenkins, включая модули, которые будут отправляться как рабочие узлы. Дополнительная область, указанная флагом --scopes , позволит Дженкинсу получить доступ к облачным репозиториям исходного кода и реестру контейнеров. В облачной консоли выполните следующее:

gcloud container clusters create jenkins-cd \
--machine-type n1-standard-2 --num-nodes 1 \
--zone us-east1-d \
--scopes "https://www.googleapis.com/auth/source.read_write,cloud-platform" \
--cluster-version latest

Давайте также развернем 2 кластера для размещения промежуточных и производственных сборок нашего примера приложения:

gcloud container clusters create staging \
--machine-type n1-standard-2 --num-nodes 1 \
--zone us-east1-d \
--cluster-version latest
gcloud container clusters create prod \
--machine-type n1-standard-2 --num-nodes 2 \
--zone us-east1-d \
--cluster-version latest

28b45298e1e82748.png Проверять

После создания кластеров мы можем подтвердить, что они работают, используя gcloud container clusters list

В столбце STATUS должно быть указано RUNNING :

NAME        LOCATION    MASTER_VERSION  MASTER_IP     MACHINE_TYPE   NODE_VERSION  NUM_NODES  STATUS
jenkins-cd  us-east1-d  1.15.9-gke.9    34.74.77.124  n1-standard-2  1.15.9-gke.9  2          RUNNING
prod        us-east1-d  1.15.9-gke.9    35.229.98.12  n1-standard-2  1.15.9-gke.9  2          RUNNING
staging     us-east1-d  1.15.9-gke.9    34.73.92.228  n1-standard-2  1.15.9-gke.9  2          RUNNING

4. Развертывание Jenkins с помощью Helm

Установить Хелм

Мы будем использовать Helm, менеджер пакетов приложений для Kubernetes, для установки Jenkins в нашем кластере. Для начала загрузите проект, включающий манифесты Kubernetes, которые мы будем использовать для развертывания Jenkins:

git clone https://github.com/GoogleCloudPlatform/continuous-deployment-on-kubernetes.git ~/continuous-deployment-on-kubernetes

Измените текущий рабочий каталог на каталог проекта:

cd ~/continuous-deployment-on-kubernetes/

Создайте привязку роли кластера, чтобы предоставить себе разрешения роли администратора кластера:

kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)

Подключитесь к кластеру Jenkins, получив его учетные данные:

gcloud container clusters get-credentials jenkins-cd --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}

И загрузите двоичный файл Helm в свою облачную консоль:

wget https://storage.googleapis.com/kubernetes-helm/helm-v2.14.1-linux-amd64.tar.gz

Разархивируйте файл и скопируйте прилагаемый файл helm в текущий рабочий каталог:

tar zxfv helm-v2.14.1-linux-amd64.tar.gz && \
cp linux-amd64/helm .

Tiller — это серверная часть Helm, работающая в кластере Kubernetes. Давайте создадим сервисную учетную запись с именем tiller :

kubectl create serviceaccount tiller \
--namespace kube-system

И привяжите его к роли cluster-admin , чтобы он мог вносить изменения:

kubectl create clusterrolebinding tiller-admin-binding \
--clusterrole=cluster-admin \
--serviceaccount=kube-system:tiller

Теперь мы можем инициализировать Helm и обновить репозиторий:

./helm init --service-account=tiller && \
./helm repo update

28b45298e1e82748.png Проверять

Убедитесь, что Helm подходит для ./helm version — она должна вернуть номера версий клиента и сервера:

Client: &version.Version{SemVer:"v2.14.1", GitCommit:"5270352a09c7e8b6e8c9593002a73535276507c0", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.14.1", GitCommit:"5270352a09c7e8b6e8c9593002a73535276507c0", GitTreeState:"clean"}

Установить Дженкинс

Теперь, когда Helm установлен в нашем кластере, мы готовы к установке Jenkins:

./helm install stable/jenkins -n cd \
-f jenkins/values.yaml \
--version 1.2.2 --wait

28b45298e1e82748.png Проверять

Давайте проверим капсулы:

kubectl get pods

В выводе должен быть показан наш модуль Jenkins в состоянии «РАБОТАЕТ»:

NAME                          READY     STATUS    RESTARTS   AGE
cd-jenkins-7c786475dd-vbhg4   1/1       Running   0          1m

Убедитесь, что служба Jenkins создана правильно:

kubectl get svc

Вывод должен выглядеть примерно так:

NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)     AGE
cd-jenkins         ClusterIP   10.35.241.170   <none>        8080/TCP    2m27s
cd-jenkins-agent   ClusterIP   10.35.250.57    <none>        50000/TCP   2m27s
kubernetes         ClusterIP   10.35.240.1     <none>        443/TCP     75m

Установка Jenkins будет использовать плагин Kubernetes для создания агентов сборки. Они будут автоматически запускаться мастером Jenkins по мере необходимости. Когда их работа завершена, они автоматически завершают работу, а их ресурсы добавляются обратно в пул ресурсов кластера.

Подключиться к Дженкинсу

Jenkins работает в нашем кластере, но для доступа к пользовательскому интерфейсу давайте настроим переадресацию портов из Cloud Shell:

export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/component=jenkins-master" -l "app.kubernetes.io/instance=cd" -o jsonpath="{.items[0].metadata.name}") &&
kubectl port-forward $POD_NAME 8080:8080 >> /dev/null &

Во время установки был сгенерирован пароль администратора. Давайте восстановим его:

printf $(kubectl get secret cd-jenkins -o jsonpath="{.data.jenkins-admin-password}" | base64 --decode);echo

В верхней части Cloud Shell щелкните значок предварительного просмотра в Интернете. 7ddf5a65fd556dd6.png и выберите «Просмотр на порту 8080».

1d614c831a621cff.png

Мы должны увидеть экран входа в Jenkins, где мы можем ввести имя admin и пароль, полученные на предыдущем шаге:

9cba23e856cbc84f.png

Когда мы нажимаем «Войти», мы должны быть перенаправлены на главную страницу Дженкинса.

9261f3e914829137.png

5. Установите и настройте плагин GKE.

Плагин Google Kubernetes Engine позволяет нам публиковать развертывания, созданные в Jenkins, в наших кластерах Kubernetes, работающих в GKE. В вашем проекте необходимо выполнить некоторую настройку с разрешениями IAM. Мы развернем эту конфигурацию с помощью Terraform.

Сначала загрузите проект плагина GKE:

git clone https://github.com/jenkinsci/google-kubernetes-engine-plugin.git ~/google-kubernetes-engine-plugin

Автоматизированная настройка разрешений IAM

Измените текущий рабочий каталог на каталог rbac проекта GKE, который мы клонировали ранее:

cd ~/google-kubernetes-engine-plugin/docs/rbac/

gcp-sa-setup.tf — это файл конфигурации Terraform, который создает пользовательскую роль GCP IAM с ограниченными разрешениями вместе с учетной записью службы GCP, которой можно предоставить эту роль. Для файла требуются значения переменных имени проекта, региона и учетной записи службы. Мы предоставляем эти значения, сначала объявляя следующие переменные среды:

export TF_VAR_project=${GOOGLE_CLOUD_PROJECT}
export TF_VAR_region=us-east1-d
export TF_VAR_sa_name=kaniko-role

Инициализируйте Terraform, создайте план и примените его:

terraform init
terraform plan -out /tmp/tf.plan
terraform apply /tmp/tf.plan && rm /tmp/tf.plan

Сервисному аккаунту потребуются права администратора хранилища для сохранения в нашем сегменте Cloud Storage:

gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member serviceAccount:kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com \
--role 'roles/storage.admin'

Ему также потребуются разрешения контейнера на этапах развертывания нашего конвейера:

gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member \
serviceAccount:kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com --role 'roles/container.developer'

Теперь мы можем использовать Helm для настройки разрешений кластера для плагина GKE с помощью программы развертывания роботов gke. Измените свой рабочий каталог на каталог helm проекта GKE:

cd ~/google-kubernetes-engine-plugin/docs/helm/

И установите, используя предоставленную схему Helm:

export TARGET_NAMESPACE=kube-system && \
envsubst < gke-robot-deployer/values.yaml | helm install ./gke-robot-deployer --name gke-robot-deployer -f -

6. Настройте Дженкинс

Ключи сервисной учетной записи

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

gcloud iam service-accounts keys create /tmp/kaniko-secret.json --iam-account kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com

Мы создадим секретный ключ в секретном хранилище Kubernetes с помощью этого файла:

kubectl create secret generic jenkins-int-samples-kaniko-secret --from-file=/tmp/kaniko-secret.json 

Загрузите файл JSON на локальный диск, открыв пункт «Загрузить файл» в трехточечном меню Cloud Shell:

c40378e72013b843.png

Введите путь к файлу /tmp/kaniko-secret.json и нажмите «Загрузить».

Вернувшись на страницу Jenkins, на левой боковой панели нажмите «Учетные данные», затем «Система».

6c140f7e6bb82f8.png

3b874912cdc8019b.png

В разделе страницы « Система» нажмите «Глобальные учетные данные», а затем «Добавить учетные данные» слева:

4350c0e68561119b.png

3d3526551cdae8b.png

В раскрывающемся списке «Тип» выберите «Аккаунт службы Google из закрытого ключа» . Введите «kaniko-role» в качестве имени, затем загрузите ключ JSON, созданный на предыдущих шагах, и нажмите «ОК».

b0502213408e730e.png

Переменные среды

Есть некоторые переменные среды, которые нам нужно будет определить в Jenkins, прежде чем мы создадим многоветвевой конвейер. Они есть:

  • JENK_INT_IT_ZONE — зона кластера Kubernetes. В нашем случае us-east1-d
  • JENK_INT_IT_PROJECT_ID — относится к идентификатору проекта GCP, в котором размещен этот экземпляр Jenkins.
  • JENK_INT_IT_STAGING — имя нашего «промежуточного» кластера, в демонстрационных целях оно staging .
  • JENK_INT_IT_PROD — имя нашего кластера «prod». Для демонстрационных целей это prod
  • JENK_INT_IT_BUCKET — сегмент Google Cloud Storage, созданный на предыдущем этапе.
  • JENK_INT_IT_CRED_ID — относится к учетным данным, созданным с использованием json на предыдущем шаге. Значение должно соответствовать имени, которое мы ему дали, kaniko-role

Чтобы добавить их, перейдите в «Управление Jenkins» :

d54f279190a07878.png

Затем настройте систему:

ce79d218b2799640.png

Там будет раздел с названием «Глобальные свойства» , и когда мы установим флажок « Переменные среды», мы получим кнопку «Добавить» , которую мы нажмем, чтобы добавить переменные, указанные выше, в виде пар ключ-значение:

81aa222a2b17b2cc.png

Нажмите кнопку «Сохранить» внизу страницы, чтобы применить изменения.

7. Настройте конвейер

В Дженкинсе нажмите «Новый элемент»:

8d1270ce4d7b6a8a.png

Введите «jenkins-integration-sample» в качестве имени, выберите «Multibranch Pipeline» в качестве типа проекта и нажмите «ОК»:

eb071ecfbb4d775b.png

Мы будем перенаправлены на страницу конфигурации конвейера. В разделе «Источники ветвей» введите https://github.com/GoogleCloudPlatform/jenkins-integration-samples.git в качестве репозитория проекта. В разделе «Конфигурация сборки» введите «gke/Jenkinsfile» в качестве пути к сценарию.

5135bd6b0374508c.png

Нажмите «Сохранить» , чтобы применить эти настройки. После сохранения Дженкинс запустит сканирование репозитория и последующую сборку для каждой ветки. По ходу процесса вы увидите, как модули создаются, запускаются и уничтожаются по мере выполнения сборки на странице «Рабочие нагрузки Kubernetes».

Когда сборки будут завершены, на странице «Рабочие нагрузки Kubernetes» вы найдете два элемента с именем jenkins-integration-samples-gke, каждый из которых соответствует либо кластеру продукта, либо кластеру тестирования. Статус будет ОК:

bdec6b1753d1ba07.png

Используя следующую команду gcloud, мы увидим, что мы загрузили образ контейнера в реестр контейнеров Google, соответствующий нашему конвейеру:

gcloud container images list

Чтобы увидеть рабочую нагрузку в браузере, получите учетные данные для кластера prod:

gcloud container clusters get-credentials prod --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}

И выполните следующую команду, чтобы настроить перенаправление порта с порта 8081 вашей оболочки на порт 8080 вашей рабочей нагрузки:

export POD_NAME=$(kubectl get pods -o jsonpath="{.items[0].metadata.name}") &&
kubectl port-forward $POD_NAME 8081:8080 >> /dev/null &

В верхней части Cloud Shell щелкните значок веб-просмотра и выберите «Просмотр на порту 8081».

1b19b5b56f1bae7.png

e80e995e71763bb2.png

8. Очистка

Мы рассмотрели, как развернуть Jenkins и пример многоветвевого конвейера в Kubernetes. Теперь пришло время очистить наш проект от всех созданных нами ресурсов.

Удалить проект

При желании вы можете удалить весь проект. В консоли GCP перейдите на страницу диспетчера облачных ресурсов :

В списке проектов выберите проект, над которым мы работали, и нажмите «Удалить» . Вам будет предложено ввести идентификатор проекта. Введите его и нажмите «Выключить».

Альтернативно вы можете удалить весь проект непосредственно из Cloud Shell с помощью gcloud:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

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

Кластер Кубернетес

Удалите весь кластер Kubernetes с помощью gcloud:

gcloud container clusters delete jenkins-cd --zone=us-east1-d

Ведра для хранения

Удалите все загруженные файлы и удалите нашу корзину с помощью gsutil:

gsutil rm -r gs://${GOOGLE_CLOUD_PROJECT}-jenkins-test-bucket

Образы реестра контейнеров Google

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

gcloud container images list-tags gcr.io/${GOOGLE_CLOUD_PROJECT}/jenkins-integration-samples-gke --format="value(digest)"

Затем для каждого возвращаемого дайджеста:

gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/jenkins-integration-samples-gke@sha256:<DIGEST>

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

Ууууу! Вы сделали это. Вы узнали, как развертывать Jenkins в GKE и отправлять задания в кластеры Kubernetes.

Что мы рассмотрели

  • Мы развернули кластер Kubernetes и использовали Helm для установки Jenkins.
  • Мы установили и настроили плагин GKE, позволяющий Jenkins развертывать артефакты сборки в кластерах Kubernetes.
  • Мы настроили Jenkins для настройки многоветвевого конвейера, который распределяет работу по кластерам GKE.