基于Jenkins+k8sv1.23+Git+DockerHub等技术链构建企业级DevOps容器云平台
测试jenkins的CI/CD
资源 | 版本 |
---|---|
Jenkins | jenkins2.421 |
k8s | V 1.23 |
在Jenkins中安装kubernetes插件
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/
系统管理------>插件管理------>可选插件------>搜索kubernetes------>出现如下
清华大学jekins源
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/
安装blueocean插件
添加自己的dockerhub凭据,当前国内无法登录
首页------>系统管理Manage Credentials(管理凭据)------>点击Stores scoped to Jenkins下的第一行jenkins后的全局,显示如下
点击添加凭据,出现如下
username:alvinyuan5157
password:1989*****
ID:dockerhub
描述:随意写一段描述即可
上面改好之后选择确定即可
配置jenkins连接到我们存在的k8s集群
访问http://192.168.40.110:30002/configureClouds/
新增一个云,在下拉菜单中选择kubernets并添加
填写云kubernetes配置内容
名称: kubernetes
Kubernetes地址: https://192.168.40.110:6443
Kubernetes名称空间:jenkins-k8s
测试jenkins和k8s是否可以通信
点击连接测试,如果显示Connected to Kubernetes v1.23.1,说明测试成功,Jenkins可以和k8s进行通信
Jenkins地址:
http://jenkins-service.jenkins-k8s.svc.cluster.local:8080
配置pod-template
配置pod template
点击Pod Template details
名称:随意写 jenkins-pod
Kubernetes名称空间: jenkins-k8s
标签(与pipeline脚本有关):testyuan
点击容器列表下的添加容器
名称:jnlp
Docker镜像:jenkins-slave-latest:v1
给上面的pod template添加卷
/var/run/docker.sock
/var/run/docker.sock
/root/.kube
/home/jenkins/.kube
在k8smaster1 执行
scp -r /root/.kube/ k8snode1:/root/
在Service Account处输入jenkins-k8s-sa,这个sa就是我们最开始安装jenkins时的sa
jenkins-k8s-sa
上面配置好之后,Apply(应用)------>Save(保存)
测试Jenkins slave动态构建
新建任务:test
开始创建一个新任务------>
修改pipeline标签为上面pod模板标签testyuan
pipeline {
agent {
label 'testyuan'
}
stages {
stage('test') {
steps {
script {
println "test"
}
}
}
}
}
立即构建
最后可得构建成功
测试通过Jenkins部署应用发布到k8s开发环境、测试环境、生产环境
在k8s的控制节点创建名称空间
kubectl create ns devlopment
kubectl create ns production
kubectl create ns qatest
新建任务jenkins-variable-test-deploy
输入一个任务名称:jenkins-variable-test-deploy
流水线
确定------>
访问github fork到自己的项目当中
访问https://github.com/luckylucky421/jenkins-sample 点击fork 到自己的github,之后可以编辑如下三个文件
- k8s-dev.yaml
- k8s-prod.yaml
- k8s-qa.yaml
修改镜像为自己的dockerhub登录名和项目名
alvinyuan5157/jenkins-demo
image: alvinyuan5157/jenkins-demo:<BUILD_TAG>
修改Pipeline script 配置
1:在Pipeline script处输入如下内容
node('testyuan') {
stage('Clone') {
echo "1.Clone Stage"
git url: "https://github.com/alvinyuan5157/jenkins-sample.git"
script {
build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
}
}
stage('Test') {
echo "2.Test Stage"
}
stage('Build') {
echo "3.Build Docker Image Stage"
sh "docker build -t alvinyuan5157/jenkins-demo:${build_tag} ."
}
stage('Push') {
echo "4.Push Docker Image Stage"
withCredentials([usernamePassword(credentialsId: 'dockerhub', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]) {
sh "docker login -u ${dockerHubUser} -p ${dockerHubPassword}"
sh "docker push alvinyuan5157/jenkins-demo:${build_tag}"
}
}
stage('Deploy to dev') {
echo "5. Deploy DEV"
sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-dev.yaml"
sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-dev.yaml"
// sh "bash running-devlopment.sh"
sh "kubectl apply -f k8s-dev.yaml --validate=false"
}
stage('Promote to qa') {
def userInput = input(
id: 'userInput',
message: 'Promote to qa?',
parameters: [
[
$class: 'ChoiceParameterDefinition',
choices: "YES\nNO",
name: 'Env'
]
]
)
echo "This is a deploy step to ${userInput}"
if (userInput == "YES") {
sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-qa.yaml"
sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-qa.yaml"
// sh "bash running-qa.sh"
sh "kubectl apply -f k8s-qa.yaml --validate=false"
sh "sleep 6"
sh "kubectl get pods -n qatest"
} else {
//exit
}
}
stage('Promote to pro') {
def userInput = input(
id: 'userInput',
message: 'Promote to pro?',
parameters: [
[
$class: 'ChoiceParameterDefinition',
choices: "YES\nNO",
name: 'Env'
]
]
)
echo "This is a deploy step to ${userInput}"
if (userInput == "YES") {
sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-prod.yaml"
sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-prod.yaml"
// sh "bash running-production.sh"
sh "cat k8s-prod.yaml"
sh "kubectl apply -f k8s-prod.yaml --record --validate=false"
}
}
}
注意需要修改的配置
#修改Pipeline script 中的git为自己fork的地址
git url: "https://github.com/alvinyuan5157/jenkins-sample.git"
#credentialsId: 'dockerhub' 为上面配置dockerhub凭据中的ID:dockerhub
withCredentials([usernamePassword(credentialsId: 'dockerhub', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')])
#注意alvinyuan5157 替换为自己的dockerhub登录名
sh "docker build -t alvinyuan5157/jenkins-demo:${build_tag} ."
#推送镜像至dockerhub
sh "docker push alvinyuan5157/jenkins-demo:${build_tag}"
立即构建
应用------>保存------>立即构建,在#1的Console Output可看到构建过程:
在Console Output如果看到如下:
点击Input requested
点击继续
上面可以看到已经把应用部署到dev环境了
点击Input requested
通过上面可以看到把应用部署到了pro环境了
验证是否在devlopment和production名称空间下有应用
kubectl get pods -n production
kubectl get pods -n devlopment
kubectl get pods -n qatest
通过上面可以看到jenkins对接k8s,可以把应用发布到k8s集群的开发、测试、生产环境了。
基于Jenkins+k8s+Git+harbor构建DevOps容器云平台
流程
开发提交代码到代码仓库gitlab–>jenkins检测到代码更新–>调用k8s api在k8s中创建jenkins slave pod:
Jenkins slave pod拉取代码—>通过maven把拉取的代码进行构建成war包或者jar包—>上传代码到Sonarqube,进行静态代码扫描- -->基于war包构建docker image–>把镜像上传到harbor镜像仓库–>基于镜像部署应用到开发环境–>部署应用到测试环境—>部署应用到生产环境。
添加凭据
需要有一台harbor服务,我的harbor安装在了139.155.70.174机器上
相关配置可参考:学习笔记九:docker私有镜像仓库harbor
https://blog.youkuaiyun.com/weixin_43258559/article/details/129621761?fromshare=blogdetail&sharetype=blogdetail&sharerId=129621761&sharerefer=PC&sharesource=weixin_43258559&sharefrom=from_link
添加凭据
首页------>系统管理管理凭据------>点击Stores scoped to Jenkins下的第一行jenkins,显示如下
username:admin
password:Harbor12345
ID:tencentharbor
新建docker harbor项目
因为镜像要上传到harbor私有镜像仓库,所以需要在harbor上创建一个项目,项目名称是jenkins-demo,如下所示:
上面项目创建成功之后,执行如下步骤:
新建任务:jenkins-pipeline-harbor
新建一个任务------>输入一个任务名称处输入 jenkins-pipeline-harbor------>流水线------>确定------>在Pipeline script处输入如下内容
node('testyuan') {
stage('Clone') {
echo "1.Clone Stage"
git url: "https://github.com/alvinyuan5157/jenkins-sample.git"
script {
build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
}
}
stage('Test') {
echo "2.Test Stage"
}
stage('Build') {
echo "3.Build Docker Image Stage"
sh "docker build -t 139.155.70.174/jenkins-demo/jenkins-demo:${build_tag} ."
}
stage('Push') {
echo "4.Push Docker Image Stage"
withCredentials([usernamePassword(credentialsId: 'tencentharbor', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]) {
sh "docker login 139.155.70.174 -u ${dockerHubUser} -p ${dockerHubPassword}"
sh "docker push 139.155.70.174/jenkins-demo/jenkins-demo:${build_tag}"
}
}
stage('Deploy to dev') {
echo "5. Deploy DEV"
sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-dev-harbor.yaml"
sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-dev-harbor.yaml"
// sh "bash running-devlopment.sh"
sh "kubectl apply -f k8s-dev-harbor.yaml --validate=false"
}
stage('Promote to qa') {
def userInput = input(
id: 'userInput',
message: 'Promote to qa?',
parameters: [
[
$class: 'ChoiceParameterDefinition',
choices: "YES\nNO",
name: 'Env'
]
]
)
echo "This is a deploy step to ${userInput}"
if (userInput == "YES") {
sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-qa-harbor.yaml"
sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-qa-harbor.yaml"
// sh "bash running-qa.sh"
sh "kubectl apply -f k8s-qa-harbor.yaml --validate=false"
sh "sleep 6"
sh "kubectl get pods -n qatest"
} else {
//exit
}
}
stage('Promote to pro') {
def userInput = input(
id: 'userInput',
message: 'Promote to pro?',
parameters: [
[
$class: 'ChoiceParameterDefinition',
choices: "YES\nNO",
name: 'Env'
]
]
)
echo "This is a deploy step to ${userInput}"
if (userInput == "YES") {
sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-prod-harbor.yaml"
sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-prod-harbor.yaml"
// sh "bash running-production.sh"
sh "cat k8s-prod-harbor.yaml"
sh "kubectl apply -f k8s-prod-harbor.yaml --record --validate=false"
}
}
}
注意需要修改的配置
#调整为你自己的
git url: "https://github.com/alvinyuan5157/jenkins-sample.git"
#调整为你自己的dockerharbor
sh "docker build -t 139.155.70.174/jenkins-demo/jenkins-demo:${build_tag} ."
#调整为你自己的tencentharbor 凭据
withCredentials([usernamePassword(credentialsId: 'tencentharbor', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')])
sh "docker login 139.155.70.174 -u ${dockerHubUser} -p ${dockerHubPassword}"
sh "docker push 139.155.70.174/jenkins-demo/jenkins-demo:${build_tag}"
应用------>保存------>立即构建即可,打开blue ocean会看到如下流程,可以手动点击确认
Jenkins实现k8s应用按照指定版本回滚
回到首页:
新建任务:jenkins-variable-test-deploy-rollout
新建一个任务------>输入一个任务名称处输入jenkins-variable-test-deploy-rollout------>流水线------>确定------>在Pipeline script处输入如下内容
node('testyuan') {
stage('git clone') {
git url: "https://github.com/alvinyuan5157/jenkins-rollout.git"
sh "ls -al"
sh "pwd"
}
stage('select env') {
def envInput = input(
id: 'envInput',
message: 'Choose a deploy environment',
parameters: [
[
$class: 'ChoiceParameterDefinition',
choices: "devlopment\nqatest\nproduction",
name: 'Env'
]
]
)
echo "This is a deploy step to ${envInput}"
sh "sed -i 's/<namespace>/${envInput}/' getVersion.sh"
sh "sed -i 's/<namespace>/${envInput}/' rollout.sh"
sh "bash getVersion.sh"
// env.WORKSPACE = pwd()
// def version = readFile "${env.WORKSPACE}/version.csv"
// println version
}
stage('select version') {
env.WORKSPACE = pwd()
def version = readFile "${env.WORKSPACE}/version.csv"
println version
def userInput = input(id: 'userInput',
message: '选择回滚版本',
parameters: [
[
$class: 'ChoiceParameterDefinition',
choices: "$version\n",
name: 'Version'
]
]
)
sh "sed -i 's/<version>/${userInput}/' rollout.sh"
}
stage('rollout deploy') {
sh "bash rollout.sh"
}
}
点击应用->保存-立即构建
Jenkins+k8s+nexus+gitlab+harbor+sonarqube+springloud构建DevOps
Jenkins接入Sonarqube
介绍
- Sonar是一个用于代码质量管理的开源平台,用于管理Java 源代码的质量。通过插件机制,Sonar 可以集成不同的测试工具,代码分析工具,以及持续集成工具,比如pmd-cpd、checkstyle、findbugs、Jenkins。
- 通过不同的插 件对这些结果进行再加工处理,通过量化的方式度量代码质量的变化,从而可以方便地对不同规模和种类的工程进行代码质量管理。
- 同时 Sonar 还对大量的持续集成工具提供了接口支持,可以很方便地在持续集成中使用 Sonar。
在dockerharbor上安装sonarqube:
我在harbor服务器 139.155.70.174 新建sonarqube
生产环境要与开发同步,确认sonarqube 版本
docker run -d --name postgres10 -p 5432:5432 -e POSTGRES_USER=sonar -e POSTGRES_PASSWORD=123456 postgres
docker run -d --name sonarqube7.9 -p 9000:9000 --link postgres10 -e SONARQUBE_JDBC_URL=jdbc:postgresql://postgres10:5432/sonar -e SONARQUBE_JDBC_USERNAME=sonar -e SONARQUBE_JDBC_PASSWORD=123456 -v sonarqube_conf:/opt/sonarqube/conf -v sonarqube_extensions:/opt/sonarqube/extensions -v sonarqube_logs:/opt/sonarqube/logs -v sonarqube_data:/opt/sonarqube/data sonarqube
浏览器访问http://139.155.70.174:9000/
默认账密都是 admin
我更改为 Redhat@123456
在jenkins中安装sonarqube插件:
系统管理->插件管理->可选插件:搜索sonar,找到Sonarqube Scanner
选择Sonarqube Scanner直接安装,安装之后重启jenkins即可
在sonarqube的web界面创建一个token:
选择Generate出现如下:
把copy后面的一串token记录下来:
squ_b6d07c92627b01850c351712a6edb63e9519128b
回到k8s的master1节点:
上传microservic-test.zip 至k8smaster1
通过网盘分享的文件:microservic-test.zip
链接: https://pan.baidu.com/s/1EgfUOqreszCA7fomIu_EsQ?pwd=pka4 提取码: pka4
unzip microservic-test.zip
cd /root/microservic-test
mvn sonar:sonar -Dsonar.host.url=http://139.155.70.174/:9000 -Dsonar.login=squ_b6d07c92627b01850c351712a6edb63e9519128b
Jenkins界面添加harbor凭据
安装nexus
概念:
- Nexus服务器是一个代码包管理的服务器,可以理解 Nexus 服务器是一个巨大的 Library 仓库。Nexus 可以支持管理的工具包括 Maven , npm 等,对于 JAVA 开发来说,只要用到 Maven 管理就可以了。
- Nexus服务器作用:因为传统的中央仓库在国外,其地理位置比较远,下载速度比较缓慢。因此,当公司开发人员数量越来越多时,如果不架设一台自己的Nexus服务器,会产生大量的流量阻塞带宽,并且在出现一些不可抗原因(光缆被挖断)导致无法连接到中央仓库时,开发就会因为无法下载相关依赖包而进度停滞。
- 因此在本地环境部署一台私有的Nexus服务器来缓存所有依赖包,并且将公司内部开发的私有包也部署上去,方便其他开发人员下载,是非常有必要的。因为 Nexus 有权限控制,因此外部人员是无法得到公司内部开发的项目包的。
下面将介绍如何将自己的maven构件发布到nexus私服 上呢?
在139.155.70.174上安装:nexus
docker run -d -p 8081:8081 -p 8082:8082 -p 8083:8083 -v /etc/localtime:/etc/localtime --name nexus3 sonatype/nexus3
在日志中,会看到一条消息: Started Sonatype Nexus OSS 3.20.1-01 这意味着Nexus Repository Manager可以使用了。现在转到浏览器并打开
http://139.155.70.174:8081
以下XML文件为开发操作,可不管
第一步:在 pom.xml 文件中声明发布的宿主仓库和 release 版本发布的仓库。
<!-- 发布构件到Nexus -->
<distributionManagement>
<repository>
<id>releases</id>
<name>nexus-releases</name>
<url>http://139.155.70.174:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>nexus-snapshots</name>
<url>http://139.155.70.174:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
第二步:在 settings.xml 文件中配置
由于用 Maven 分发构件到远程仓库需要认证,须要在~/.m2/settings.xml或者中加入验证信息:
<servers>
<server>
<id>public</id>
<username>admin</username>
<password>123456</password>
</server>
<server>
<id>releases</id>
<username>admin</username>
<password>123456</password>
</server>
<server>
<id>snapshots</id>
<username>admin</username>
<password>123456</password>
</server>
</servers>
注意: settings.xml 中 server 元素下 id 的值必须与 POM 中 repository 或 snapshotRepository 下 id 的值完全一致 。
安装gitlab (消耗内存过大,无法实验,2C4G带不动)
在139.155.70.174上安装
因harbor占用443和80端口,调整端口为8080 和8090
需要等待一段时间
docker run -d -p 8080:443 -p 8090:80 -p 222:22 --name gitlab --restart always -v /home/gitlab/config:/etc/gitlab -v /home/gitlab/logs:/var/log/gitlab -v /home/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce
原配置
docker run -d -p 443:443 -p 80:80 -p 222:22 --name gitlab --restart always -v /home/gitlab/config:/etc/gitlab -v /home/gitlab/logs:/var/log/gitlab -v /home/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce
改配置:在末尾增加如下三行:
cat /home/gitlab/config/gitlab.rb
external_url 'http://139.155.70.174'
gitlab_rails['gitlab_ssh_host'] = '139.155.70.174'
gitlab_rails['gitlab_shell_ssh_port'] = 222
重启docker:
docker restart gitlab
查看密码:
docker exec -it gitlab cat /etc/gitlab/initial_root_password
#初始用户名root
#密码:
登录139.155.70.174即可登录:
第一次登录注册账号密码之后,报错如下:
Your account is pending approval from your GitLab administrator and hence bl
docker exec -it gitlab bash
#进入控制台
gitlab-rails console -e production
# 查询id为1的用户,id为1的用户是超级管理员
u=User.where(id:1).first
# 修改密码
u.password='12345678'
u.password_confirmation='12345678'
# 保存
u.save!
再次登录139.155.70.174
用户名是root
密码是12345678
在Jenkins安装git插件
系统管理-插件管理-可选插件-搜索git安装即可
Jenkins-凭据-全局凭据
在gitlab上新建项目:
创建密钥对:
ssh-keygen -t rsa
#一路回车
上传密钥:
cat ~/.ssh/id_rsa.pub #查看公钥
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8KZUe+PJykjZzJherolD+vXsw8/aL3OMyX/x1HF6Rz73dNZFCERQxA6t/9ahRrya8iY7IIloLjzi5iX666mzYI3fAEq1Ga3Dz2MWqEeWZGdbNKvL9lf0qTy0aLBIRe2fnQwrkrP2YakiqzDRpyjQgr05VkrnF5bVLX2HCHuC2GXwnHUAuJEkjb1f9vmII7YP0BmYDMOMpricQ1LeFnQ9cc2ZvPw6212yiXOrbhrbiMtjCYTPoRA8EIfmRAPcNcVl4GT3fZxAVocDk70rA/tEWCgu+zzFFH+aWhaIXMdkC70FEWLD28AxLWwwKj22KA9ezqp0eoxofzU3tSCIymVU9 root@localhost.localdomain
提交本地代码到gitlab:
yum install git -y
unzip microservic-test.zip
cd microservic-test
git init #建仓
git add * #把当前文件夹所有代码提交
git commit -m "add microservic-test" #代码提交到缓冲区
git remote add origin http://192.168.40.135/root/microservic-test.git #代码提交到远程仓库
git push -u origin master #最后一步push推送过去,push的时候,会让你输入账号和密码,这里的用户名和密码就是gitlab上注册的用户了
回到gitlab首页,可以看到,已经有项目了
Jenkins+k8s+nexus+sonarqube+harbor+gitlab构建DevOps
jenkins-jnlp-v2.tar.gz这个压缩包封装的镜像带有mvn命令
上传至k8snode1
docker load -i jenkins-jnlp-v2.tar.gz
在http://192.168.40.180:30002/configureClouds/,把Container Template镜像改成jenkins-jnlp-v2.tar.gz压缩包解压之后的镜像xianchao/jenkins-jnlp:v2
修改gitlab上portal.yaml文件:
把image镜像变成:192.168.40.132/microservice/jenkins-demo:v1
注意:microservice需要在harbor里提前创建这个仓库
打开Jenkins,新建流水线,流水线名字是mvn-gitlab-harbor-springcloud
在Pipeline Script处输入如下内容:
node('testhan') {
stage('Clone') {
echo "1.Clone Stage"
git credentialsId: 'gitlab', url: 'http://192.168.40.135/root/microservic-test.git '
script {
build_tag = sh(returnStdout: true, script: 'git rev-parse --shortHEAD').trim()
}
}
stage('Test') {
echo "2.Test Stage"
}
stage('mvn') {
sh "mvn clean package -D maven.test.skip=true"
}
stage('Build') {
echo "3.Build Docker Image Stage"
sh "cd /home/jenkins/agent/workspace/mvn-gitlab-harbor-springcloud/portal-service"
sh "docker build --tag 192.168.40.132/microservice/jenkins-demo:v1 /home/jenkins/agent/workspace/mvn-gitlab-harbor-springcloud/portal-service/"
}
stage('Push') {
echo "4.Push Docker Image Stage"
withCredentials([usernamePassword(credentialsId: 'dockerharbor',passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]) {
sh "docker login 192.168.40.132 -u ${dockerHubUser} -p ${dockerHubPassword}"
sh "docker push 192.168.40.132/microservice/jenkins-demo:v1"
}
}
stage('Promoteto pro') {
sh "kubectl apply -f /home/jenkins/agent/workspace/mvn-gitlab-harbor-springcloud/k8s/portal.yaml"
}
}
立即构建即可
注意事项:url: http://192.168.40.135/root/microservic-test.git