jenkins+pipeline+harbork8s实现自动化部署
1、安装jenkins
1.登陆linux,在linux上执行docker命令,拉去jenkinsci/blueocean镜像并运行镜像。
命令如下:
docker run \
-d \
-u root \
-p 8080:8080 \
-v jenkins_home:/var/jenins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkinsci/blueocean
2.访问 http://localhost:8080 地址,会出现解锁界面
3.使用docker logs 命令从日志信息中 复制自动生成的密码(在两组星号之间)。
4.在 解锁Jenkins 页面, 粘贴密码并继续。
5.解锁jenkins后,在界面中选择“安装建议的插件”。
6.最后,jenkins要求创建管理员用户。创建新用户或使用admin用户,按照步骤完成后即可登录使用jenkis了。


2、准备spring boot工程
1.创建spring boot基础工程,添加一个示例Controller类。
2. 修改application配置文件,设置端口
3.编译运行,访问 http://localhost:8082 地址可以看到示例运行结果。


3、添加Dockerfile
在工程根目录创建Dockerfile,用来构建docker镜像。
from: 指定基础镜像
workdir: 工作目录,指定之后下面的命令都在这个目录下执行
copy: 复制jar文件到指定目录
entrypoint :和CMD类似都是配置容器启动后执行的命令,并且不可被docker run提供的参数覆盖。

4、添加k8s的Deployment配置
在工程根目录创建k8s-deployment.tpl文件,此文件用来作为k8s的yaml文件模板。在jenkens pipeline执行时,会先将tpl文件中{}括起来的自定义参数用sed命令替换为实际的内容。

5、添加Jenkinsfile
在工程根目录创建Jenkinsfile,用来执行jenkins pipeline任务。
parameters中变量说明:
HARBOR_HOST:harbor镜像仓库地址。
DOCKER_IMAGE:docker镜像名,包含harbor项目名称。
APP_NAME:k8s中的标签名称,对应k8s的yaml模板中的{APP_NAME}。
K8S_NAMESPACE:k8s中的namespace名称,执行kubectl命令会部署至此命名空间。
stages说明:
Git Tag :获取gitlab最新版本的tag标签
Maven Build:执行maven命令
Docker Build:通过sh依次执行docker命令登录harbor、构建镜像、上传镜像、移除本地镜像。
运行kubectl:执行kubectl命令。在执行前先将K8S_CONFIG中的内容进行base64解密并存为~/.kube/config配置文件,然后执行sed命令将k8s-deployment.tpl文件中“{参数名}”形式参数替换为实际的参数值,最后执行kubectl命令部署至k8s。
以下部分定义slave Pod 的执行环境,和设置挂载master的目录
注意:在使用maven镜像的时候,因为我们项目使用的是私有仓库,所以需要定制镜像。否则,在下载依赖的时候会报错。定制镜像的步骤请自行查找资料



6、Jenkinsfile文件内容如下
因为上面图片太模糊,所以内容贴在下面:
podTemplate( containers: [
containerTemplate(name: 'maven', image: 'harbor.k8s-dev.com/test/maven:3.5.2-jdk-8-1', command: 'cat', ttyEnabled: true),
containerTemplate(name: 'docker', image: 'docker', command: 'cat', ttyEnabled: true),
containerTemplate(name: 'kubectl', image: 'cnych/kubectl', command: 'cat', ttyEnabled: true),
containerTemplate(name: 'helm', image: 'cnych/helm', command: 'cat', ttyEnabled: true)
], volumes: [
hostPathVolume(mountPath: '/root/.m2', hostPath: '/var/run/m2'),
hostPathVolume(mountPath: '/home/jenkins/.kube', hostPath: '/root/.kube'),
hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock')
])
{
properties([parameters(
[ string(name: 'HARBOR_HOST', defaultValue: 'harbor.k8s-dev.com', description: 'harbor仓库地址'),
string(name: 'DOCKER_IMAGE', defaultValue: 'library/sptingboot-test', description: 'docker镜像名'),
string(name: 'APP_NAME', defaultValue: 'sptingboot-test', description: 'k8s中标签名'),
string(name: 'K8S_NAMESPACE', defaultValue: 'default', description: 'k8s的namespace名称')
])])
node(POD_LABEL) {
def myRepo = checkout scm
def gitCommit = myRepo.GIT_COMMIT
def gitBranch = myRepo.GIT_BRANCH
def GIT_TAG = ""
stage('Git Tag') {
GIT_TAG = sh(returnStdout: true,script: 'git describe --tags --always').trim()
echo "${GIT_TAG}"
if("${GIT_TAG}"==""){
echo "ERROR: git tag not null!"
}
}
stage('Test') {
}
stage('Maven Build') {
container('maven') {
if("${GIT_TAG}"!=""){
sh "mvn clean compile"
sh "mvn clean package"
}
}
}
stage('Docker Build') {
container('docker') {
if("${GIT_TAG}"!=""){
sh "docker login -u " + getCredentials("jenkins-harbor-creds","username") + " -p " + getCredentials("jenkins-harbor-creds","password") + " ${params.HARBOR_HOST}"
sh "docker build -t ${params.DOCKER_IMAGE}:${GIT_TAG} ."
sh "docker tag ${params.DOCKER_IMAGE}:${GIT_TAG} ${params.HARBOR_HOST}/${params.DOCKER_IMAGE}:${GIT_TAG}"
sh "docker push ${params.HARBOR_HOST}/${params.DOCKER_IMAGE}:${GIT_TAG}"
sh "docker rmi ${params.DOCKER_IMAGE}:${GIT_TAG}"
}
}
}
stage('运行 Kubectl') {
container('kubectl') {
if("${GIT_TAG}"!=""){
sh "mkdir -p ~/.kube"
sh "echo " + getCredentials("jenkins-k8s-config","") + " | base64 -d > ~/.kube/config"
sh "sed -e 's#{IMAGE_URL}#${params.HARBOR_HOST}/${params.DOCKER_IMAGE}#g;s#{IMAGE_TAG}#${GIT_TAG}#g;s#{APP_NAME}#${params.APP_NAME}#g' k8s-deployment.tpl > k8s-deployment.yml"
sh "kubectl apply -f k8s-deployment.yml --namespace=${params.K8S_NAMESPACE}"
}
}
}
stage('运行 Helm') {
container('helm') {
if("${GIT_TAG}"!=""){ }
}
}
}
}
@NonCPS
def getCredentials(id,type)
{
def res = ""
def credentials_store = jenkins.model.Jenkins.instance.getExtensionList( 'com.cloudbees.plugins.credentials.SystemCredentialsProvider')
credentials_store[0].credentials.each {
if(id == "${it.id}"){
if(it instanceof com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl){
if(type=="username"){
res = "${it.username}"
}
if(type == "password"){
res ="${it.password}"
}
}
if(it instanceof org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl){
res = "${it.secret}"
}
}
}
return res
}
7、新建pipeline任务
点击“新建任务”,输入名称并选择“流水线”(pipeline),然后点击确定。

8、配置 pipeline任务
进入任务的配置界面,在流水线(pipeline)设置部分,选择“Pipeline script from SCM”。SCM选项选为“Git”,配置好工程的git地址以及获取代码的凭证信息。然后在“Additional Behaviours”中添加“Clean before checkout”。

9、配置harbor账号与密码
选择“凭据”,然后在下图所示位置点击“添加凭据”。在新凭据设置界面,类型选择为“Username with password”,ID设置为“jenkins-harbor-creds”(此处的ID必须与Jenkinsfile中的保持一致)。Username与Password分别设置为harbor镜像私库的用户名和密码。


10、配置k8s的kube.config配置信息
1.k8s中使用kubectl命令时需要yaml格式的服务器及授权信息配置文件。这里将kubectl的yaml配置文件的内容以base64编码后保存在jenkins的凭据中。pipeline任务执行时,先从jenkins凭据中获取内容,进行base64解码后将配置保存为~/.kube/config文件。kubectl的配置文件的样式如下:
注:文件只做为样式参考。读者请自行向k8s管理员获取config文件
2.可以在linux中采用下面命令将kubectl的yaml配置文件进行base64编码
3.然后类似上一步,在jenkins凭据中增加配置文件内容。在凭据设置界面,类型选择为“Secret text”,ID设置为“jenkins-k8s-config”(此处的ID必须与Jenkinsfile中的保持一致),Secret设置为上面经过base64编码后的配置文件内容。



11、配置cloud
Jenkins 地址和Jenkins 通道一定要配置正确,否则Slave Template会创建失败。


12、测试pipeline任务
1.在创建的pipeline任务中,点击“立即构建”即可立即执行pipeline任务。
2.执行成功后,查看harbor镜像仓库,docker镜像成功上传至harbor。
3.执行成功后,查看k8s中pod运行日志,服务启动成功。



13、设置gitlab自动触发jenkins
这一步比较简单,此篇不再赘述。请参考网上其他教程