![](https://habrastorage.org/getpro/habr/upload_files/b68/0e5/eb1/b680e5eb14b5ef1bade9ef6f4bb18f59.png)
![](https://habrastorage.org/getpro/habr/upload_files/a6d/2ee/642/a6d2ee6420445760e000d8bbf2d0470d.jpg)
Автор статьи: Рустем Галиев
Senior DevOps Engineer & Integration Architect at IBM
Привет Хабр! На связи Рустем.
Недавно я был на одном интересном воркшопе от компании iTechArt и хотел бы сегодня поделится тем, что мы там делали, а точнее писали CD Pipeline с интеграцией Docker, Kubernetes и Jenkins в Google Cloud (GCE/GKE).
![](https://habrastorage.org/getpro/habr/upload_files/890/f69/fe4/890f69fe43e828ec632c354f562e39ea.png)
В этой статье мы узнаем, как развернуть динамическое веб-приложение на GKE (Google Kubernetes Engine) с использованием Jenkins.
Тема достаточно интересная, так что давайте начнем.
Наши реквизиты: Jenkins, Kubernetes(GKE), репозиторий Github и реестр образов Dockerhub.
Прежде чем двигаться дальше, давайте получим общее представление о терминологии, используемой в этом проекте:
GCP: Google Cloud Platform — поставщик общедоступного облака, который предлагает своим пользователям вычислительные услуги через Интернет.
Docker: Docker — это программа с открытым исходным кодом, которая позволяет нам создавать, развертывать и управлять виртуализированными приложениями. Это позволяет нам отделить наше приложение от нашей инфраструктуры, поскольку мы можем создавать и запускать наше приложение в контейнерной среде.
Jenkins: это сервер автоматизации с открытым исходным кодом, который позволяет разработчикам надежно создавать, тестировать и развертывать свое программное обеспечение. Он организует цепочку действий (сборка, тестирование, развертывание) для достижения процесса непрерывной интеграции и непрерывной доставки автоматизированным способом.
-
Kubernetes: Kubernetes или K8s — это портативная, расширяемая платформа или программное обеспечение с открытым исходным кодом, которое обеспечивает возможности настройки, автоматизации и управления контейнерами, т.е. Решает вопросы оркестрации
Давайте начнем с подготовки инфраструктуры.
Шаг 1: Создадим и настроим машины
1. Создайте машину разработчика:
Откройте консоль Google Cloud Platform > Compute Engine > Create New Instance
![](https://habrastorage.org/getpro/habr/upload_files/0a4/876/ba2/0a4876ba2d7eaeed2da58b1818aa6597.png)
![](https://habrastorage.org/getpro/habr/upload_files/e86/a48/567/e86a48567cc153623b93089306ff1174.png)
2. Создадим новый экземпляр для сервера Jenkins и Docker Engine:
Установим Docker:
sudo apt-get update
sudo apt install docker.io
Установим Jenkins:
1) Сперва установим JDK:
sudo apt-get update
sudo apt install openjdk-11-jre-headless
2) Добавим ключ
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
3) Apt repo
sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
4) Обновим пакеты и установим Jenkins
sudo apt-get update
sudo apt-get install jenkins
Также не забудьте дать Jenkins’у привелегии администратора
Откроем файл /etc/sudoers
и добавим следующую строчку:
jenkins ALL=(ALL) NOPASSWD: ALL
3. Создадим кластер Kubernetes в GKE
Open GCP console > GKE (Kubernetes engine) > Create
Шаг 2. Настроим Jenkins
1. Откройте дэшборд Jenkins через public IP вашего инстанса по порту 8080
http://<server_publicIP>:8080
![](https://habrastorage.org/getpro/habr/upload_files/e76/c59/dfb/e76c59dfb6a731ee44464327de796665.png)
По указанному пути найдем пароль администратора, скопируем и вставим
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Теперь выберем Install suggested plugins
![](https://habrastorage.org/getpro/habr/upload_files/e52/15a/95b/e5215a95bed8501113995881ed2e7bcf.png)
После установки Jenkins попросит создать аккаунт для администратора, что мы и сделаем
![](https://habrastorage.org/getpro/habr/upload_files/3f8/e38/de3/3f8e38de359b5d1fcd1187e09b24ff16.png)
2. Установим следующие плагины: Git, github, Docker pipeline, Google Kubernetes Engine
Jenkins Dashboard -> Plugin Manager -> Available -> Search bar
![](https://habrastorage.org/getpro/habr/upload_files/ccd/eb6/070/ccdeb6070dcc578f8033600010b5d47c.png)
3. Добавим реквизиты для аутентификации в GKE и Dockerhub
Загрузите ключ сервисного аккаунта Google:
Open GCP console > IAM and Admin > service account > open default one or create new one > add key > create new key (json format) and save it
![](https://habrastorage.org/getpro/habr/upload_files/fe0/9f5/707/fe09f57073b8bf7f6980452e17dacc4b.png)
![](https://habrastorage.org/getpro/habr/upload_files/8d0/366/8e9/8d03668e949c92ee7461b09b72220060.png)
![](https://habrastorage.org/getpro/habr/upload_files/a91/2ac/c38/a912acc38440402055cbfa10c9eee0d5.png)
Загрузим ключ в Jenkins
Jenkins Dashboard > manage Jenkins > manage credentials > Jenkins > global credentials > add credentials
![](https://habrastorage.org/getpro/habr/upload_files/151/f51/101/151f5110142dc4bfe70d3dccac1263ed.png)
![](https://habrastorage.org/getpro/habr/upload_files/fab/049/b0c/fab049b0cee4ef662f94ab2f593d47d0.png)
Для Docker тоже добавим (где Secret - это пароль нашего аккаунта)
![](https://habrastorage.org/getpro/habr/upload_files/1dd/f02/6b3/1ddf026b3b14ba3b9032490319f46550.png)
3. Создадим Pipeline в Jenkins:
Dashboard -> New item
![](https://habrastorage.org/getpro/habr/upload_files/835/de5/80c/835de580c17e2fb22dc7800e2dbc3b54.png)
Дадим любое имя, выбираем pipeline
![](https://habrastorage.org/getpro/habr/upload_files/d86/099/77b/d8609977be03ccb2f0b7a4963a8bb742.png)
Definition = Pipeline script from SCM
SCM = git
Repository Url: url вашего репозитория
Script Path: Jenkinsfile
![](https://habrastorage.org/getpro/habr/upload_files/770/2d2/2be/7702d22bece6d3f6fbc646a79cea9797.png)
![](https://habrastorage.org/getpro/habr/upload_files/da0/996/e92/da0996e927cbc07afa18408ea297f61e.png)
Шаг 3. Настроим наш проект для сборки
Для примера давайте соберем это приложение и форкнем или склоним его: https://github.com/komarserjio/notejam
1. Напишем Dockerfile:
FROM python:2.7
RUN mkdir app
COPY django/notejam app/
COPY django/requirements.txt ./
RUN pip install -r requirements.txt
RUN pip install psycopg2
WORKDIR app/
EXPOSE 5000
2. Напишем deployment.yaml для Kubernetes
В моем случае он содержит манифест развертывания веб-приложения и его манифест его службы, а также манифест для persistent volume claim, secret, configMap, database deployment и service.
#data-db-persistentvolumeclaim.yam
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
service: data-db
name: data-db
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
---
#db-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
labels:
service: db
name: db-config
data:
db-name: "nj"
#db-secret
apiVersion: v1
kind: Secret
metadata:
name: notejam-credentials
type: Opaque
data:
user: YWRtaW4=
password: YWRtaW5AMTIz
#db-deployment
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
service: db
name: db
spec:
replicas: 1
selector:
matchLabels:
service: db
template:
metadata:
labels:
service: db
tier: backend
spec:
containers:
- image: postgres
name: database
env:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: notejam-credentials
key: user
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: notejam-credentials
key: password
- name: POSTGRES_DB
valueFrom:
configMapKeyRef:
name: db-config
key: db-name
ports:
- containerPort: 5432
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
volumeMounts:
- mountPath: /var/lib/mysql/data
name: data-db
restartPolicy: Always
volumes:
- name: data-db
persistentVolumeClaim:
claimName: data-db
#db-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
service: db
name: db
spec:
ports:
- name: "5432"
protocol: TCP
port: 5432
targetPort: 5432
selector:
service: db
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
service: web
name: web
spec:
replicas: 1
selector:
matchLabels:
service: web
template:
metadata:
labels:
service: web
spec:
containers:
- args:
- bash
- -c
- python manage.py syncdb --noinput && python manage.py migrate && python manage.py runserver 0.0.0.0:5000
image: arshad1914/pipeline:latest
name: notejam
ports:
- containerPort: 5000
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 250Mi
restartPolicy: Always
apiVersion: v1
kind: Service
metadata:
labels:
service: web
name: web
spec:
type: LoadBalancer
ports:
- name: "5000"
port: 5000
targetPort: 5000
selector:
service: web
3. Создадим Jenkinsfile, где опишем процесс сборки и доставки
pipeline {
agent any
environment {
PROJECT_ID = 'docker'
CLUSTER_NAME = 'jenkins'
LOCATION = 'us-central-1a'
CREDENTIALS_ID = 'kubernetes'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build image') {
steps {
script {
app = docker.build("zetzo/pipeline:{env.BUILD_ID}")
}
}
}
stage('Deploy to K8s') {
steps{
echo "Deployment started ..."
sh 'ls -ltr'
sh 'pwd'
sh "sed -i 's/pipeline:latest/pipeline:class: 'KubernetesEngineBuilder',
projectId: env.PROJECT_ID,
clusterName: env.CLUSTER_NAME,
location: env.LOCATION,
manifestPattern: 'deployment.yaml',
credentialsId: env.CREDENTIALS_ID,
verifyDeployments: true])
}
}
}
}
Шаг 4. Протестируем наш пайплайн (спойлер: успешно)
![](https://habrastorage.org/getpro/habr/upload_files/96c/e1f/41b/96ce1f41b343f638b3b6fcc08837897e.png)
Задеплоили, Вы восхитительны!
P.s.
Если хотите чтобы деплой был полностью автоматизированным (т.е. Перейти от Continuous Delivery к Continuous Deployment), то рекомендую настроить вебхук в вашем репозитории
settings > webhooks > add webhooks > url Вашего Jenkins instance
В Вашем Jenkins pipeline, заходим в конфигурацию и ставим галочку в поле здесь
![](https://habrastorage.org/getpro/habr/upload_files/323/64a/da2/32364ada2d759b47bb5c319372ad6c7e.png)
На этом все. Также хочу порекомендовать всем бесплатный урок от OTUS на котором вы сможете изучить предпосылки к возникновению контейнеризации и познакомиться с устройством самого популярного "контейнеризатора" - docker.