目录
一、实验
1.环境
2. GitLab 共享库新建HELM CI流水线
3.Jenkins新建HELM CI流水线
5.Jenkins构建前端项目
6.GitLab 共享库新建HELM CD流水线
7.Jenkins新建HELM CD流水线
8.HELM完成前端项目应用发布与回滚
9.Jenkins再次构建前端项目
10.HELM再次完成前端项目应用发布与回滚
二、问题
1. HELM CD流水线报错
(1)主机
表1 主机
主机 | 架构 | 版本 | IP | 备注 |
master1 | K8S master节点 | 1.20.6 | 192.168.204.180 | jenkins slave (从节点) |
helm | 3.6.0 | |||
git | 1.8.3.1 | |||
node1 | K8S node节点 | 1.20.6 | 192.168.204.181 | |
node2 | K8S node节点 | 1.20.6 | 192.168.204.182 | |
jenkins | jenkins主节点 |
2.414.2 | 192.168.204.15:8080 | gitlab runner (从节点) |
harbor私有仓库 | 1.2.2 | 192.168.204.15 | ||
gitlab | gitlab 主节点 | 12.10.14 | 192.168.204.8:82 | jenkins slave (从节点) |
sonarqube | 9.6 | 192.168.204.8:9000 |
(1)共享库新建CI流水线
(2)修改k8scihelm.jenkinsfile
@Library("mylib@master") _
import org.devops.*
def checkout = new Checkout()
def build = new Build()
def unittest = new UnitTest()
def sonar = new Sonar()
def gitlabutil = new Gitlab()
pipeline {
agent { label "build"}
options {
skipDefaultCheckout true
}
stages{
stage("Checkout"){
steps{
script {
println("GetCode")
checkout.GetCode("${env.srcUrl}","${env.branchName}")
}
}
}
stage("build"){
steps{
script{
println("Build")
build.CodeBuild("${env.buildTool}")
}
}
}
stage("UnitTest"){
steps{
script{
println("Test")
unittest.CodeTest("${env.buildTool}")
}
}
}
stage("SonarScan"){
steps {
script {
groupName = "${JOB_NAME}".split("/")[0]
projectName ="${JOB_NAME}".split("/")[-1].split("_")[0]
sonar.CodeSonar("${env.buildTool}",projectName,groupName)
}
}
}
stage("PushImage"){
steps {
script {
repoName = "${JOB_NAME}".split("/")[0]
projectName ="${JOB_NAME}".split("/")[-1].split("_")[0]
env.registry = "192.168.204.15"
env.imageName = "${env.registry}/${repoName}/${projectName}:${env.branchName}"
withCredentials([usernamePassword(credentialsId: '8c662308-4991-4576-9826-74a5417de685', passwordVariable: 'DOCKER_PASSWD', usernameVariable: 'DOCKER_USER')]) {
sh """
#重写HTML首页
echo "${env.imageName}" > dist/index.html
#构建镜像
docker build -t ${env.imageName} .
#登录镜像仓库
docker login -u ${DOCKER_USER} -p ${DOCKER_PASSWD} ${env.registry}
#上传镜像
docker push ${env.imageName}
#删除镜像
sleep 2
docker rmi ${env.imageName}
"""
}
}
}
}
stage("ReleaseFile"){
steps{
script{
env.namespace = "${JOB_NAME}".split("/")[0]
env.appName ="${JOB_NAME}".split("/")[-1].split("_")[0]
// 获取values.yaml文件
fileData = gitlabutil.GetRepoFile(23,"${env.appName}%2fvalues.yaml", "master")
yamlData = readYaml text: fileData
// 替换模板文件内容
yamlData.image.tag = "${env.imageName}".split(":")[-1]
yamlData.image.repository = "${env.registry}/${env.namespace}/${env.appName}"
//保存yaml文件
sh "rm -fr values.yaml"
writeYaml charset: 'UTF-8', file: 'values.yaml', data: yamlData
// 上传替换后的版本文件(新建文件或者更新文件)
newYaml = sh returnStdout: true, script: 'cat values.yaml'
println(newYaml)
//更新gitlab文件内容
base64Content = newYaml.bytes.encodeBase64().toString()
// 会有并行问题,同时更新报错
try {
gitlabutil.UpdateRepoFile(23,"${env.appName}%2fvalues.yaml",base64Content, "master")
} catch(e){
gitlabutil.CreateRepoFile(23,"${env.appName}%2fvalues.yaml",base64Content, "master")
}
}
}
}
}
}
(1)新建CI流水线
(2)修改脚本路径
(3)新建视图
(5)查看视图
(1)Jenkins构建前端项目 CI流水线,指定版本为RELEASE-1.1.6
(2)完成
(3)GitLab HELM项目显示更新了文件values.yaml
更新前:
更新后:
(1)共享库新建CD流水线
(2)修改k8scdhelm.jenkinsfile
@Library("mylib@master") _
import org.devops.*
def checkout = new Checkout()
def gitlabbutil = new Gitlab()
env.groupName = "${JOB_NAME}".split("/")[0]
env.projectName ="${JOB_NAME}".split("/")[-1].split("_")[0]
pipeline {
agent { label "k8s"}
options {
skipDefaultCheckout true
}
stages{
stage("GetChartRepo"){
steps{
script {
println("GetCode")
checkout.GetCode("${env.srcUrl}","${env.branchName}")
}
}
}
stage("DeployAPP"){
steps{
script{
env.namespace = "${env.groupName}"
env.appName = "${env.projectName}"
// HELM 发布
sh """
helm package "${env.appName}/"
helm upgrade --install --create-namespace "${env.appName}" ./"${env.appName}"-*.tgz -n ${env.namespace}
helm history "${env.appName}" -n ${env.namespace}
"""
//获取release的历史版本
env.revision = sh returnStdout: true, script: """helm history ${env.appName} -n ${env.namespace} | grep -v 'REVISION' | awk '{print \$1}' """
println("${env.revision}")
println("${env.revision.split('\n').toString()}")
env.REVISION = "${env.revision.split('\n').toString()}"
println("${env.REVISION}")
// 获取应用状态
5.times{
sh "sleep 2; kubectl -n ${env.namespace} get pod | grep ${env.appName}"
}
}
}
}
stage("RollOut"){
steps{
script{
//获取release的历史版本
env.revision = sh returnStdout: true, script: """helm history ${env.appName} -n ${env.namespace} | grep -v 'REVISION' | awk '{print \$1}' """
//println("${env.revision}")
//println("${env.revision.split('\n').toString()}")
env.REVISION = "${env.revision.split('\n').toString()}"
println("${env.REVISION}")
def result = input message: 'RollBack?',
ok: 'submit',
parameters: [choice(choices: "${env.REVISION}", description: '', name: 'revision')]
env.result = result - "\n"
echo "Actions is ${env.result}, doing......."
if ( "${env.result}" != ""){
sh """ helm rollback ${env.appName} ${env.result} -n ${env.namespace} """
} else {
println("Skip rollback .....")
}
}
}
}
}
}
(3)查看共享库目录
(1)新建CD流水线
(2)修改脚本路径
(3)复制Clone项目地址
(4)添加字符参数
(5)新建并查看视图
(1)K8S master节点另开一个终端用watch命令观察pod变化
# watch -n 1 "kubectl get pod -n devops03"
(2)外部测试访问(当前版本为1.1.6)
# curl http://devops03-devops-ui.devops.com:31291
(3)Jenkins构建前端项目CD 流水线,指定分支为master
(4)选择回滚 1 版本
相当于选择1 版本
# helm rollback devops03-devops-ui 1 -n devops03
(5)完成
(6)观察pod变化
(1)Jenkins构建前端项目 CI流水线,指定版本为RELEASE-1.1.7
(2)完成
(3)GitLab HELM项目显示更新了文件values.yaml
更新前:
更新后:
(1)Jenkins构建前端项目CD 流水线,指定分支为master
(3)外部测试访问(当前版本为1.1.7)
# curl http://devops03-devops-ui.devops.com:31291
(4)选择回滚 6 版本
相当于选择6 版本
# helm rollback devops03-devops-ui 1 -n devops03
(5)完成
(6)观察pod变化
(7)外部测试访问(当前版本为1.1.6)
# curl http://devops03-devops-ui.devops.com:31291
(8)查看历史版本
# helm history devops03-devops-ui -n devops03
(1) 报错
(2)原因分析
GitLab HELM项目只有master分支
(3)解决方法
分支名输入master.
修改:
成功: