4

Jenkins-Kubernetes-Docker-Helm CI/CD实践

 2 years ago
source link: https://chinalhr.github.io/post/jenkins-kubernetes-helm-ci-cd/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Jenkins-Kubernetes-Docker-Helm CI/CD实践

 Jan 12, 2021      DevOps 

基于Kubernetes、Docker、Helm、Jenkins的CI/CD实践,对于前文Jenkins-pipeline-Docker 实现CI/CD 的补充扩展

Helm是Kubernetes生态系统中的一个包管理工具;Helm使用的包格式称为 charts,chart就是一个描述Kubernetes相关资源的文件集合。

Kubernetes应用部署面临的一些问题

kubernetes提供了基于容器的应用集群管理,容器编排,路由网关、水平扩展、监控、备份、灾难恢复等运维功能。用户通过使用kubernetes API对象来描述应用程序规格,如Pod,Service,Volume,Namespace,ReplicaSet,Deployment,Job…;而对这些对象的操作都需要写入到yaml文件通过kubectl进行部署;这时就会遇到如下的几个问题:

  • 如何对kubernetes应用配置文件进行管理
  • 如何把一套的相关配置文件作为一个应用进行管理
  • 如何分发和重用kubernetes的应用配置

这时候就可以引进Helm之类的包管理工具解决如上问题

Helm提供了什么功能

对于开发者而言,可以通过Helm打包应用,管理应用依赖关系,管理应用版本并发布应用到软件仓库;Helm提供了kubernetes上的软件部署,删除,升级,回滚应用的功能。

Helm相关组件

  • Helm: Kubernetes应用打包工具。
  • Tiller: Helm服务端,部署于Kubernetes集群中,用于接收处理Helm的相关命令。
  • Chart: Helm的打包格式,描述Kubernetes相关资源的文件集合。
  • Repoistory: Helm的软件仓库。

图片

相关内容可以参考helm官方文档:https://helm.sh/zh/docs

Kubernetes Helm Jenkins CI/CD流程

  • 一个安装了Tiller的kubernetes集群
  • 部署服务器,安装配置了Helm、Docker、Kubectl、Jenkins、Git
  • 代码托管服务,如Gitlab、Github
  • Docker Registry

图片

  1. 开发人员提交代码到Git仓库
  2. 运维人员触发Jenkins deploy任务,拉取代码进行Docker镜像打包,推送到远程仓库
  3. Jenkins使用 Helm 更新 Release到Kubernetes集群中

本次实践的项目是一个简单的Spring Boot 后端服务

仓库地址为:https://github.com/ChinaLHR/shovel-kubernetes-helm-devops

项目目录如下:

├── Jenkinsfile (Jenkins Pipeline Script)
├── Makefile (打包构建相关markfile)
├── README.md
├── chart (chart文件夹)
│   ├── Chart.yaml
│   ├── templates
│   │   ├── NOTES.txt
│   │   ├── _helpers.tpl
│   │   ├── configmap.yaml
│   │   ├── deployment.yaml
│   │   ├── service.yaml
│   │   ├── serviceaccount.yaml
│   │   └── tests
│   └── values.yaml
├── package.Dockerfile
├── pom.xml
├── release.Dockerfile
├── script (运行脚本)
│   └── bin
│       └── deploy.sh
└── src	(项目源码)
    ├── main
    │   ├── java
    │   └── resources
    └── test
        └── java

Jenkins Pipeline

  • Jenkins流水线项目配置

新增一个流水线项目,配置Pipeline from SCM,配置对应的参数BRANCH imageimage

这里使用Jenkins Checkout插件进行Git代码拉取

stage('Clone target repo') {
             checkout([$class: 'GitSCM', branches: [[name: branch]],
             doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [],
             userRemoteConfigs: [[credentialsId: 'deploy', url: 'https://gitee.com/***.git']]])
        }
  • 代码编译打包-Docker镜像构建

这里使用Docker多阶段构建,第一阶段使用maven:3-jdk-8基础镜像对项目进行打包,第二阶段将第一阶段生成的jar与项目的script部署脚本添加到镜像中进行镜像打包。

最后编写makefile,使用make命令进行构建打包镜像、项目打包操作、构建项目镜像、推送项目镜像到远程Docker仓库的操作。

具体可以参考项目对应package.Dockerfilerelease.DockerfileMakefiledeploy.sh文件;相关pipeline script如下:

stage('Build package') {
            sh "make build-package-image package-image=${packageImage}"
            sh "make package package-image=${packageImage}"
}

stage('Build release') {
            sh "make build-release-image release-image=${releaseImage}"
}

stage('Push release image to registry') {
						withDockerRegistry(credentialsId: 'docker-user', url: 'https://registry.cn-hangzhou.aliyuncs.com') {
                sh "docker push ${releaseImage}"
            }
}
  • Helm Chart更新 Release到Kubernetes集群中

初始化Helm Chart:

helm create shovel
mv shovel chart
# 删除非必要文件
cd chart-copy/templates && rm hpa.yaml && rm ingress.yaml

修改Chart配置文件:

# values.yaml文件
# 修改镜像image相关配置,去除ingress相关配置,增加自定义配置如下:
env:
  app:
    port: 8088
    name: shovel-server-app

# templates/deployment.yaml
# 修改containers下的configMap、ports、livenessProbe标签配置
containers:
        - name: {{ .Chart.Name }}
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          envFrom:
            - configMapRef:
                name: {{ include "shovel.fullname" . }}
          ports:
            - name: http
              containerPort: 8088
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /ping
              port: http
          readinessProbe:
            httpGet:
              path: /ping
              port: http
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
            
# 添加templates/configmap.yaml设置应用的环境变量
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "shovel.fullname" . }}
  labels:
  {{- include "shovel.labels" . | nindent 4 }}

data:
  SERVER_PORT: "{{ .Values.env.app.port}}"
  APPLICATION_NAME: {{ .Values.env.app.name }}
  • 使用Helm发布/更新服务

切换当前context到dev(这里的env可以通过jenkins parameters 进行传递),使用Helm发布/更新服务

stage('Deploy') {
            sh """
               kubectl config use-context dev
               helm -n ${namespace} upgrade ${project} chart \
                    -f chart/values.yaml \
                    --set-string image.tag=${imageTag} \
                    --wait --install
                """
        }

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK