В предыдущих двух статьях у нас уже есть кластерная среда K8s, которая «ждет загрузки», и у нас также есть базовое понимание связанных концепций и компонентов (вы можете получить представление о концепциях на ранней стадии, потому что только практики, может у вас есть глубокое понимание этого. Поймите, так называемое «на бумаге это мелко, и вы должны знать, что вы должны это сделать»), эта статья знакомит с практической точки зрения, как объединить наши обычно используемые Gitlab и Jenkins для автоматического развертывания проектов через K8s, примеры будут включать серверные проекты на основе SpringBoot и веб-проекты на основе Vue.js.
Инструменты и методы, описанные в этой статье, включают в себя:
- Gitlab — широко используемая система управления исходным кодом
- Jenkins, Jenkins Pipeline — широко используемый инструмент автоматизированной сборки и развертывания, Pipeline организует различные этапы построения и развертывания конвейерным способом.
- Docker, Dockerfile — контейнерный движок, все приложения в конечном итоге будут работать как контейнеры Docker, Dockerfile — это файл определения образа Docker.
- Kubernetes — система управления оркестрацией контейнеров с открытым исходным кодом от Google.
- Helm — инструмент управления пакетами Kubernetes, аналогичный Linux yum, apt или Node npm и другим инструментам управления пакетами, может организовывать и управлять приложениями и связанными зависимыми службами в Kubernetes в виде пакетов (диаграмма)
Экологический фон:
- Gitlab использовался для управления исходным кодом.Исходный код имеет разработанные (соответствующие среде разработки), предварительные версии (соответствующие тестовой среде) и основные (соответствующие производственной среде) ветки в соответствии с различными средами.
- Служба Jenkins была построена
- Существующая служба Docker Registry для хранения образов Docker (на основе Docker Registry или Harbour, созданных самостоятельно, или с использованием облачных служб, в этой статье используется служба образов облачных контейнеров Alibaba)
- Кластер K8s построен
ожидаемый результат:
- Развертывайте приложения в разных средах, разделяйте среду разработки, тестовую среду и производственную среду и развертывайте их в разных пространствах имен одного и того же кластера или в разных кластерах (например, разработка и тестирование развертываются в разных пространствах имен локального кластера, а производственная среда развернута в облачном кластере)
- Конфигурация является максимально общей, и автоматическую настройку развертывания нового проекта можно выполнить, только изменив небольшое количество свойств конфигурации в небольшом количестве файлов конфигурации.
- Среда разработки и тестирования автоматически запускает сборку и развертывание при отправке кода, а производственная среда добавляет тег версии в основную ветку и запускает автоматическое развертывание после тега push.
- Общий процесс взаимодействия выглядит следующим образом
файл конфигурации проекта
Во-первых, нам нужно добавить некоторые необходимые файлы конфигурации в корневой путь проекта, как показано на следующем рисунке.
включают:
- Dockerfile, файл, используемый для создания образа Docker (ссылкаПримечания к Docker (11): Подробное объяснение файла Docker и рекомендации)
- Файлы конфигурации, связанные с Helm. Helm — это инструмент управления пакетами для Kubernetes, который может упаковывать развертывание, сервис, вход и т. д., связанные с развертыванием приложения для выпуска и управления (конкретное введение Helm будет добавлено позже)
- Jenkinsfile, файл определения конвейера Jenkins, определяет задачи, которые должны выполняться на каждом этапе.
Dockerfile
Добавьте Dockerfile (имя файла называется Dockerfile) в корневой каталог проекта, чтобы определить, как создавать образ Docker.В качестве примера возьмем проект Spring Boot,
FROM frolvlad/alpine-java:jdk8-slim
#在build镜像时可以通过 --build-args profile=xxx 进行修改
ARG profile
ENV SPRING_PROFILES_ACTIVE=${profile}
#项目的端口
EXPOSE 8000
WORKDIR /mnt
#修改时区
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories \
&& apk add --no-cache tzdata \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& apk del tzdata \
&& rm -rf /var/cache/apk/* /tmp/* /var/tmp/* $HOME/.cache
COPY ./target/your-project-name-1.0-SNAPSHOT.jar ./app.jar
ENTRYPOINT ["java", "-jar", "/mnt/app.jar"]
Предоставьте SPRING_PROFILES_ACTIVE через профиль параметров, который можно динамически установить во время сборки с помощью --build-args profile=xxx, чтобы удовлетворить требования построения образа в различных средах.
SPRING_PROFILES_ACTIVE мог быть передан при запуске контейнера Docker.
docker run -e SPRING_PROFILES_ACTIVE=xxx
установить, поэтому развертывание с помощью Helm напрямую не проходитdocker run
запустить, поэтому укажите через ARG во время сборки образа
Конфигурационный файл шлема
Helm — это инструмент управления пакетами для Kubernetes, который упаковывает Deployment, Service и Ingress, связанные с развертыванием приложений для выпуска и управления (которые могут храниться в хранилище, подобно образу Docker). Как показано на рисунке выше, файл конфигурации Helm включает в себя:
helm - chart包的目录名
├── templates - k8s配置模版目录
│ ├── deployment.yaml - Deployment配置模板,定义如何部署Pod
│ ├── _helpers.tpl - 以下划线开头的文件,helm视为公共库定义文件,用于定义通用的子模版、函数、变量等
│ ├── ingress.yaml - Ingress配置模板,定义外部如何访问Pod提供的服务,类似于Nginx的域名路径配置
│ ├── NOTES.txt - chart包的帮助信息文件,执行helm install命令成功后会输出这个文件的内容
│ └── service.yaml - Service配置模板,配置访问Pod的服务抽象,有NodePort与ClusterIp等
|── values.yaml - chart包的参数配置文件,各模版文件可以引用这里的参数
├── Chart.yaml - chart定义,可以定义chart的名字,版本号等信息
├── charts - 依赖的子包目录,里面可以包含多个依赖的chart包,一般不存在依赖,我这里将其删除了
Мы можем определить имя диаграммы каждого проекта (аналогично имени установочного пакета) в Chart.yaml, например
apiVersion: v2
name: your-chart-name
description: A Helm chart for Kubernetes
type: application
version: 1.0.0
appVersion: 1.16.0
Определите переменные, которые необходимо использовать в файле шаблона в values.yaml, например
#部署Pod的副本数,即运行多少个容器
replicaCount: 1
#容器镜像配置
image:
repository: registry.cn-hangzhou.aliyuncs.com/demo/demo
pullPolicy: Always
# Overrides the image tag whose default is the chart version.
tag: "dev"
#镜像仓库访问凭证
imagePullSecrets:
- name: aliyun-registry-secret
#覆盖启动容器名称
nameOverride: ""
fullnameOverride: ""
#容器的端口暴露及环境变量配置
container:
port: 8000
env: []
#ServiceAccount,默认不创建
serviceAccount:
# Specifies whether a service account should be created
create: false
# Annotations to add to the service account
annotations: {}
name: ""
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
#使用NodePort的service,默认为ClusterIp
service:
type: NodePort
port: 8000
#外部访问Ingress配置,需要配置hosts部分
ingress:
enabled: true
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: demo.com
paths: ["/demo"]
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
#.... 省略了其它默认参数配置
Здесь контейнерная часть добавлена на основе дефолтной генерации, здесь можно указать номер порта контейнера без изменения файла шаблона (чтобы файл шаблона был общим в каждом проекте, и обычно его не нужно менять) , В то же время добавьте конфигурацию env, которую можно найти в При развертывании helm переменные среды передаются в контейнер. Тип службы изменен с ClusterIp по умолчанию на NodePort. При развертывании разных проектов одного и того же типа вам нужно всего лишь настроить несколько элементов конфигурации в файлах Chart.yaml и values.yaml в соответствии с ситуацией в проекте.Файлы шаблонов в каталоге templates можно напрямую использовать повторно.
При развертывании вам необходимо извлечь образ из репозитория образов Docker в среде K8s, поэтому вам необходимо создать учетные данные для доступа к репозиторию образов (imagePullSecrets) в K8s.
# 登录Docker Registry生成/root/.docker/config.json文件
sudo docker login --username=your-username registry.cn-shenzhen.aliyuncs.com
# 创建namespace develop(我这里是根据项目的环境分支名称建立namespace)
kubectl create namespace develop
# 在namespace develop中创建一个secret
kubectl create secret generic aliyun-registry-secret --from-file=.dockerconfigjson=/root/.docker/config.json --type=kubernetes.io/dockerconfigjson --namespace=develop
Jenkinsfile
Jenkinsfile — это файл конфигурации конвейера Jenkins, который следует синтаксису Groovy.Для создания и развертывания проектов Spring Boot напишите файл сценария Jenkinsfile следующим образом:
image_tag = "default" //定一个全局变量,存储Docker镜像的tag(版本)
pipeline {
agent any
environment {
GIT_REPO = "${env.gitlabSourceRepoName}" //从Jenkins Gitlab插件中获取Git项目的名称
GIT_BRANCH = "${env.gitlabTargetBranch}" //项目的分支
GIT_TAG = sh(returnStdout: true,script: 'git describe --tags --always').trim() //commit id或tag名称
DOCKER_REGISTER_CREDS = credentials('aliyun-docker-repo-creds') //docker registry凭证
KUBE_CONFIG_LOCAL = credentials('local-k8s-kube-config') //开发测试环境的kube凭证
KUBE_CONFIG_PROD = "" //credentials('prod-k8s-kube-config') //生产环境的kube凭证
DOCKER_REGISTRY = "registry.cn-hangzhou.aliyuncs.com" //Docker仓库地址
DOCKER_NAMESPACE = "your-namespace" //命名空间
DOCKER_IMAGE = "${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/${GIT_REPO}" //Docker镜像地址
INGRESS_HOST_DEV = "dev.your-site.com" //开发环境的域名
INGRESS_HOST_TEST = "test.your-site.com" //测试环境的域名
INGRESS_HOST_PROD = "prod.your-site.com" //生产环境的域名
}
parameters {
string(name: 'ingress_path', defaultValue: '/your-path', description: '服务上下文路径')
string(name: 'replica_count', defaultValue: '1', description: '容器副本数量')
}
stages {
stage('Code Analyze') {
agent any
steps {
echo "1. 代码静态检查"
}
}
stage('Maven Build') {
agent {
docker {
image 'maven:3-jdk-8-alpine'
args '-v $HOME/.m2:/root/.m2'
}
}
steps {
echo "2. 代码编译打包"
sh 'mvn clean package -Dfile.encoding=UTF-8 -DskipTests=true'
}
}
stage('Docker Build') {
agent any
steps {
echo "3. 构建Docker镜像"
echo "镜像地址: ${DOCKER_IMAGE}"
//登录Docker仓库
sh "sudo docker login -u ${DOCKER_REGISTER_CREDS_USR} -p ${DOCKER_REGISTER_CREDS_PSW} ${DOCKER_REGISTRY}"
script {
def profile = "dev"
if (env.gitlabTargetBranch == "develop") {
image_tag = "dev." + env.GIT_TAG
} else if (env.gitlabTargetBranch == "pre-release") {
image_tag = "test." + env.GIT_TAG
profile = "test"
} else if (env.gitlabTargetBranch == "master"){
// master分支则直接使用Tag
image_tag = env.GIT_TAG
profile = "prod"
}
//通过--build-arg将profile进行设置,以区分不同环境进行镜像构建
sh "docker build --build-arg profile=${profile} -t ${DOCKER_IMAGE}:${image_tag} ."
sh "sudo docker push ${DOCKER_IMAGE}:${image_tag}"
sh "docker rmi ${DOCKER_IMAGE}:${image_tag}"
}
}
}
stage('Helm Deploy') {
agent {
docker {
image 'lwolf/helm-kubectl-docker'
args '-u root:root'
}
}
steps {
echo "4. 部署到K8s"
sh "mkdir -p /root/.kube"
script {
def kube_config = env.KUBE_CONFIG_LOCAL
def ingress_host = env.INGRESS_HOST_DEV
if (env.gitlabTargetBranch == "pre-release") {
ingress_host = env.INGRESS_HOST_TEST
} else if (env.gitlabTargetBranch == "master"){
ingress_host = env.INGRESS_HOST_PROD
kube_config = env.KUBE_CONFIG_PROD
}
sh "echo ${kube_config} | base64 -d > /root/.kube/config"
//根据不同环境将服务部署到不同的namespace下,这里使用分支名称
sh "helm upgrade -i --namespace=${env.gitlabTargetBranch} --set replicaCount=${params.replica_count} --set image.repository=${DOCKER_IMAGE} --set image.tag=${image_tag} --set nameOverride=${GIT_REPO} --set ingress.hosts[0].host=${ingress_host} --set ingress.hosts[0].paths={${params.ingress_path}} ${GIT_REPO} ./helm/"
}
}
}
}
}
Jenkinsfile определяет весь автоматизированный процесс сборки и развертывания:
- Анализ кода, вы можете использовать инструменты статического анализа кода, такие как SonarQube, для завершения проверки кода, которая здесь игнорируется.
- Maven Build, запустите контейнер Maven Docker для завершения сборки и упаковки проекта maven, подключите каталог локального хранилища maven к хост-компьютеру и избегайте необходимости каждый раз повторно загружать пакет зависимостей.
- Docker Сборка, сборка образа Docker и отправка его в репозиторий образов Образы в разных средах различаются тегами Среда разработки использует форму dev.commitId, например dev.88f5822, тестовая среда использует test.commitId и производственная среда может установить событие веб-перехватчика для тега push-события, использовать имя тега напрямую
- Helm Развертывание, используйте helm для развертывания новых проектов или обновления существующих проектов.В разных средах используются разные конфигурации параметров, такие как имя домена доступа, учетные данные доступа к кластеру K8s kube_config и т. д.
Конфигурация Дженкинса
Конфигурация задачи Дженкинса
Создайте конвейерную задачу в Jenkins, как показано на рисунке
Настройте триггер сборки, установите целевую ветку на ветку разработки и сгенерируйте токен, как показано на рисунке.
Запишите здесь «URL-адрес веб-перехватчика GitLab» и значение токена и используйте его в конфигурации Gitlab.
Настройте конвейер, выберите «Сценарий конвейера из SCM», чтобы получить файл сценария конвейера из исходного кода проекта, настройте адрес Git проекта, получите сертификат исходного кода и т. д., как показано на рисунке.
Сохраните, чтобы завершить настройку Jenkins среды разработки проекта. В тестовой среде нужно только изменить соответствующую ветку на предварительную версию.
Конфигурация учетных данных Дженкинса
В Jenkinsfile мы используем два учетных данных для доступа — учетные данные Docker Registry и локальные учетные данные K8s kube,
DOCKER_REGISTER_CREDS = credentials('aliyun-docker-repo-creds') //docker registry凭证
KUBE_CONFIG_LOCAL = credentials('local-k8s-kube-config') //开发测试环境的kube凭证
Эти два учетных данных должны быть созданы в Jenkins.
Добавьте учетные данные для входа в реестр Docker, на странице учетных данных Jenkins добавьте имя пользователя и пароль для учетных данных, как показано на рисунке.
Добавьте учетные данные для доступа к кластеру K8s и закодируйте в base64 содержимое файла /root/.kube/config на главном узле.
base64 /root/.kube/config > kube-config-base64.txt
cat kube-config-base64.txt
Создайте секретный текстовый тип учетных данных в Jenkins, используя закодированное содержимое, как показано на рисунке.
Введите содержимое в кодировке base64 в текстовое поле «Секрет».
Конфигурация гитлаба
Настройте веб-перехватчик на странице «Настройки — Интеграция» проекта Gitlab, заполните «URL-адрес веб-перехватчика GitLab» и значение токена в предыдущем разделе триггера Jenkins в URL-адресе и секретном токене и выберите «События push» в качестве события триггера, как показано на рисунке
Если вы выберете «Отправлять события» для сред разработки и тестирования, когда разработчики отправляют код или объединяют код для разработки или предварительного выпуска ветвей, задача конвейера Jenkins в среде разработки или тестирования будет запущена для завершения автоматической сборки; для рабочей среды среде выберите «События отправки тегов» », чтобы запустить автоматическую сборку при отправке тега push в основную ветку. На рисунке показан вид конструкции трубопровода.
Суммировать
В этой статье рассказывается об использовании Gitlab+Jenkins Pipeline+Docker+Kubernetes+Helm для реализации автоматического развертывания проектов Spring Boot, которые можно применить к другим проектам на основе Spring Boot с небольшой модификацией (конкретная модификация объясняется в файле Readme). файл исходного кода).
Все конфигурационные файлы, задействованные в этой статье (включая серверные проекты на основе Spring Boot и веб-проекты на основе Vue.js), можно получить в проекте исходного кода (метод получения адреса исходного кода: обратите внимание на официальный аккаунт «Halfway Песня дождя», введите «k8sops» на главной странице (ок).
Оригинальный адрес:blog.J boost.cai/ke 8 — это 3-Chengdu.htm…
Автор: Юге, ветеран ИТ, который все еще учится.
Добро пожаловать, чтобы обратить внимание на официальный аккаунт автора: песня Halfway Rain, учитесь и растите вместе