1. Jenkins Pipeline
1.1 2种脚本模式
Pipeline主要有2种脚本模式:
- 声明式
- 脚本式
1.2 基本概念
Stage阶段
,一个Pipeline可以划分为若干个Stage,每个Stage代表一组操作。注意,Stage是一个逻辑分组的概念,可以跨多个Node。
Node节点
,一个Node就是一个Jenkins节点,或者是Master,或者是Agent,是执行Step的具体运行期环境。
Step步骤
,Step是基本的操作单元,小到创建一个目录,大到构建一个Docker镜像,由各类Jenkins Plugin提供。
yaml
node {
def mvnHome
stage('pull code'){
echo "pull code"
}
stage('build project'){
echo "build project"
}
stage('push code'){
echo "pull code"
}
}
node {
def mvnHome
stage('pull code'){
echo "pull code"
}
stage('build project'){
echo "build project"
}
stage('push code'){
echo "pull code"
}
}
主要流程:
1、定义变量;
2、参数化构建;
3、创建pod模版;
4、stage阶段(多阶段);
1.3 脚本式优点
- 更少的代码段落和弱规范要求。
- 更强大的程序代码能力。
- 更像编写代码程序。
- 传统的流水线即代码模型,用户熟悉并向后兼容性。
- 更灵活的自定义代码操作。
- 能够构建更复杂的工作流和流水线。
2. Java完整pipeline-slave
采用了扩展
Extended Choice Parameter
采用了扩展
Extended Choice Parameter
pipline脚本
yaml
def git_address = "http://house.freehan.ink/root/springdemo.git"
def git_auth = "02d72dd6-0eab-4261-b0c0-12824e083421"
//构建版本的名称
def tag = "latest"
//Harbor私服地址
def harbor_url = "registry.cn-zhangjiakou.aliyuncs.com"
//Harbor的项目名称
def harbor_project_name = "spring"
//Harbor的凭证
def harbor_auth = "1e7ee468-9da7-469b-a43a-xxx"
//启动时间
def start = new Date().format('yyyy-MM-dd HH:mm:ss')
//创建一个Pod的模板,label为jenkins-slave-java
podTemplate(label: 'jenkins-slave-java', cloud: 'kubernetes', containers: [
containerTemplate(
name: 'jnlp',
image: "registry.cn-zhangjiakou.aliyuncs.com/hsuing/jenkins-slave-maven:v1",
ttyEnabled: true
),
containerTemplate(
name: 'docker',
image: "registry.cn-zhangjiakou.aliyuncs.com/hsuing/docker:stable",
ttyEnabled: true,
command: 'cat'
)
],
volumes: [
hostPathVolume(mountPath: '/var/run/docker.sock', hostPath:'/var/run/docker.sock'),
],
)
{
//引用jenkins-slave-java的pod模块来构建Jenkins-slave-java的pod
node("jenkins-slave-java"){
stage('拉取代码'){
checkout([$class: 'GitSCM', branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]])
}
stage('编译描述') {
// 自定义设置构建历史显示的名称和描述信息
// 不同的部署方式设置构建历史显示的名称和描述信息方式不一样,根据自己的部署方式自行百度找到设置方法
script {
//设置buildName
wrap([$class: 'BuildUser']) {
//修改Description
buildDescription "${BUILD_USER} > ${project_name} > ${branch}"
}
}
}
stage('代码编译'){
//把选择的项目信息转为数组
def selectedProjects = "${project_name}".split(',')
for(int i=0;i<selectedProjects.size();i++){
//取出每个项目的名称
def currentProjectName = selectedProjects[i];
//定义镜像名称
def imageName = "${currentProjectName}:${tag}"
//定义newTag
def newTag = sh(returnStdout: true,script: 'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()
//编译,构建本地镜像
sh "mvn clean package -Dmaven.test.skip=true"
}
}
stage('构建镜像'){
//把选择的项目信息转为数组
def selectedProjects = "${project_name}".split(',')
for(int i=0;i<selectedProjects.size();i++){
//取出每个项目的名称
def currentProjectName = selectedProjects[i];
//定义镜像名称
def imageName = "${currentProjectName}:${tag}"
//定义newTag
def newTag = sh(returnStdout: true,script: 'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()
//镜像编译
//sh "sed -i 's#ACTIVEPROFILE#${springProfilesActive}#g' Dockerfile"
container('docker') {
sh "docker build -t ${imageName} ."
//给镜像打标签
sh "docker tag ${imageName} ${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
//登录Harbor,并上传镜像
withCredentials([usernamePassword(credentialsId:"${harbor_auth}", passwordVariable: 'password', usernameVariable:'username')])
{
//登录
sh "docker login -u ${username} -p ${password} ${harbor_url}"
//上传镜像
sh "docker push ${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
}
//删除本地镜像
sh "docker rmi -f ${imageName}"
sh "docker rmi -f ${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
}
}
}
stage('部署到k8s平台'){
def selectedProjects = "${project_name}".split(',')
for(int i=0;i<selectedProjects.size();i++){
//取出每个项目的名称
def currentProjectName = selectedProjects[i];
//定义newTag
def newTag = sh(returnStdout: true,script: 'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()
def deploy_image_name ="${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
//基于控制器的方式部署到K8S
sh """
sed -i 's#\$IMAGE_NAME#${deploy_image_name}#' deployment.yaml
sed -i 's#\$APP_NAME#${currentProjectName}#' deployment.yaml
sed -i 's#\$APP_REPLICAS#${replicas}#' deployment.yaml
sed -i 's#\$NAMESPACE#${namespaces}#' deployment.yaml
sed -i 's#\$SPRINGENV#${springProfilesActive}#' deployment.yaml
sed -i 's#\$PODMEMORY#${podsMem}#' deployment.yaml
sed -i 's#\$PODCPU#${podsCpu}#' deployment.yaml
cat deployment.yaml
"""
}
//部署到K8S
kubernetesDeploy(kubeconfigId: "55a88b59-fd12-4bf0-ba57-8a664fed2f71", configs: "deployment.yaml")
}
}
}
def git_address = "http://house.freehan.ink/root/springdemo.git"
def git_auth = "02d72dd6-0eab-4261-b0c0-12824e083421"
//构建版本的名称
def tag = "latest"
//Harbor私服地址
def harbor_url = "registry.cn-zhangjiakou.aliyuncs.com"
//Harbor的项目名称
def harbor_project_name = "spring"
//Harbor的凭证
def harbor_auth = "1e7ee468-9da7-469b-a43a-xxx"
//启动时间
def start = new Date().format('yyyy-MM-dd HH:mm:ss')
//创建一个Pod的模板,label为jenkins-slave-java
podTemplate(label: 'jenkins-slave-java', cloud: 'kubernetes', containers: [
containerTemplate(
name: 'jnlp',
image: "registry.cn-zhangjiakou.aliyuncs.com/hsuing/jenkins-slave-maven:v1",
ttyEnabled: true
),
containerTemplate(
name: 'docker',
image: "registry.cn-zhangjiakou.aliyuncs.com/hsuing/docker:stable",
ttyEnabled: true,
command: 'cat'
)
],
volumes: [
hostPathVolume(mountPath: '/var/run/docker.sock', hostPath:'/var/run/docker.sock'),
],
)
{
//引用jenkins-slave-java的pod模块来构建Jenkins-slave-java的pod
node("jenkins-slave-java"){
stage('拉取代码'){
checkout([$class: 'GitSCM', branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]])
}
stage('编译描述') {
// 自定义设置构建历史显示的名称和描述信息
// 不同的部署方式设置构建历史显示的名称和描述信息方式不一样,根据自己的部署方式自行百度找到设置方法
script {
//设置buildName
wrap([$class: 'BuildUser']) {
//修改Description
buildDescription "${BUILD_USER} > ${project_name} > ${branch}"
}
}
}
stage('代码编译'){
//把选择的项目信息转为数组
def selectedProjects = "${project_name}".split(',')
for(int i=0;i<selectedProjects.size();i++){
//取出每个项目的名称
def currentProjectName = selectedProjects[i];
//定义镜像名称
def imageName = "${currentProjectName}:${tag}"
//定义newTag
def newTag = sh(returnStdout: true,script: 'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()
//编译,构建本地镜像
sh "mvn clean package -Dmaven.test.skip=true"
}
}
stage('构建镜像'){
//把选择的项目信息转为数组
def selectedProjects = "${project_name}".split(',')
for(int i=0;i<selectedProjects.size();i++){
//取出每个项目的名称
def currentProjectName = selectedProjects[i];
//定义镜像名称
def imageName = "${currentProjectName}:${tag}"
//定义newTag
def newTag = sh(returnStdout: true,script: 'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()
//镜像编译
//sh "sed -i 's#ACTIVEPROFILE#${springProfilesActive}#g' Dockerfile"
container('docker') {
sh "docker build -t ${imageName} ."
//给镜像打标签
sh "docker tag ${imageName} ${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
//登录Harbor,并上传镜像
withCredentials([usernamePassword(credentialsId:"${harbor_auth}", passwordVariable: 'password', usernameVariable:'username')])
{
//登录
sh "docker login -u ${username} -p ${password} ${harbor_url}"
//上传镜像
sh "docker push ${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
}
//删除本地镜像
sh "docker rmi -f ${imageName}"
sh "docker rmi -f ${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
}
}
}
stage('部署到k8s平台'){
def selectedProjects = "${project_name}".split(',')
for(int i=0;i<selectedProjects.size();i++){
//取出每个项目的名称
def currentProjectName = selectedProjects[i];
//定义newTag
def newTag = sh(returnStdout: true,script: 'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()
def deploy_image_name ="${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
//基于控制器的方式部署到K8S
sh """
sed -i 's#\$IMAGE_NAME#${deploy_image_name}#' deployment.yaml
sed -i 's#\$APP_NAME#${currentProjectName}#' deployment.yaml
sed -i 's#\$APP_REPLICAS#${replicas}#' deployment.yaml
sed -i 's#\$NAMESPACE#${namespaces}#' deployment.yaml
sed -i 's#\$SPRINGENV#${springProfilesActive}#' deployment.yaml
sed -i 's#\$PODMEMORY#${podsMem}#' deployment.yaml
sed -i 's#\$PODCPU#${podsCpu}#' deployment.yaml
cat deployment.yaml
"""
}
//部署到K8S
kubernetesDeploy(kubeconfigId: "55a88b59-fd12-4bf0-ba57-8a664fed2f71", configs: "deployment.yaml")
}
}
}
- 效果