Jenkins 语法
声明式流水线
pipeline{
# 在任何可用的代理上执行流水线或它的任何阶段,也就是执行流水线过程的位置,也可以指定到具体的节点
agent any
# 流水线具体的执行过程配置,包含多个stage
stages{
# 定义流水线的执行过程(相当于一个阶段),比如Build、Test、Deploy,这个名字可以根据实际情况进行定义
stage('Build'){
# 执行某节点具体的步骤
steps{
sh 'make'
}
}
stage('Test'){
# 执行某节点具体的步骤
steps{
sh 'make check'
junit 'report/**/*.xml'
}
}
stage('Deploy'){
# 执行某节点具体的步骤
steps{
sh 'make publish'
}
}
}
}
Jenkinsfile 详细解释
pipeline{
# 先不指定任何节点,使用Jenkins的master节点进行代码扫描
agent any
# options 关于流水线一些整体的基础配置
options {
# 设置流水线的超时时间,超过流水线时间,job 会自动终止
timeout(time: 10, unit: 'MINUTES')
# 为控制台输出时间戳
timestamps()
}
stages {
stage("扫描代码---拉取代码") {
steps { # steps 中定义的是真正执行的指令 获取用户选择的分支参数,必须双引号
checkout([$class: 'GitSCM', branches: [[name: "*/${params.BRANCH}"]], extensions: [], userRemoteConfigs: [[credentialsId: 'XXXXX', url: 'http://ip:port/XXXX/XXXX.git']]]) # 这里的credentialsId就是git账号在Jenkins生成的识别id
}
}
stage("扫描代码---sonarqube") {
steps { # steps 中定义的是真正执行的指令
script {
# 引入SonarQubeScanner工具
scannerHome = tool 'sonar-scanner'
}
# 引入SonarQube的服务器环境
withSonarQubeEnv('sonarqube6.7.4') {
sh "${scannerHome}/bin/sonar-scanner"
}
}
}
stage("Jenkins去拉取代码") {
# Jenkins 拉取代码是使用kubernetes内部的docker进行的,所以这里指定agent
agent {
kubernetes { # 这是使用 kubernetes 作为 slave 的示例
cloud 'kubernetes-yml' # 一般会有很多个kubernetes集群,这里指定使用 kubernetes-yml 集群
slaveConnectTimeout 1200 # slave 连接超时时间
workspaceVolume hostPathWorkspaceVolume(hostPath: "/opt/workspace", readOnly: false) # 指定工作路径
yaml ''' # kubernetes 中资源文件的yaml文件
apiVersion: v1
kind: Pod # 直接使用 pod 千万千万不要使用deployment!!!
spec:
containers: # 这里总共使用3个容器
- args: [\'$(JENKINS_SECRET)\', \'$(JENKINS_NAME)\']
image: 'harbor的地址/jnlp:alpine' # 为了节省资源,最小的镜像了。只保证基础功能
name: jnlp # jnlp 容器负责jenkins的slave节点和master节点通信的
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
readOnly: false
- command:
- "cat"
env:
- name: "LANGUAGE"
value: "en_US:en"
- name: "LC_ALL"
value: "en_US.UTF-8"
- name: "LANG"
value: "en_US.UTF-8"
image: "harbor的地址/kubectl:self-1.17" # 使用自己的镜像
imagePullPolicy: "IfNotPresent"
name: "kubectl" # kubectl 容器用来进行发版的,主要使用 kubectl set 命令
tty: true # 保持容器不要退出,要不然会进入容器创建/删除的死循环
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
readOnly: false
- command:
- "cat"
env:
- name: "LANGUAGE"
value: "en_US:en"
- name: "LC_ALL"
value: "en_US.UTF-8"
- name: "LANG"
value: "en_US.UTF-8"
image: "harbor的地址/docker:19.03.9-git"
imagePullPolicy: "IfNotPresent"
name: "docker" # docker 容器负责build程序的
tty: true # 保持容器不要退出,要不然会进入容器创建/删除的死循环
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
readOnly: false
- mountPath: "/var/run/docker.sock"
name: "dockersock"
readOnly: false
restartPolicy: "Never"
nodeSelector:
build: "true" # 选择 kubernetes 中节点有 build=true 标签的
securityContext: {}
volumes:
- hostPath: # 节点宿主机路径
path: "/var/run/docker.sock" # 将节点宿主机上的docker挂载进去使用
name: "dockersock"
- hostPath:
path: "/usr/share/zoneinfo/Asia/Shanghai"
name: "localtime"
'''
}
}
# Jenkins拉取的时候使用的环境变量,这里是局部变量
environment {
HARBOR_USER = credentials('HARRBOR_ACCOUNT') # credentials() 方法,可以用于在Jenkins环境中通过标识符获取预定义的凭证
MY_KUBECONFIG = credentials('K8S-KUBECONFIG') # credentials() 方法,可以用于在Jenkins环境中通过标识符获取预定义的凭证
}
steps { # steps 中定义的是真正执行的指令
echo "Jenkins 拉取代码" # 为了有的时候可以直接使用变量,简直直接使用双引号
checkout([$class: 'GitSCM', branches: [[name: "*/${params.BRANCH}"]], extensions: [], userRemoteConfigs: [[credentialsId: 'XXXXX', url: 'http://ip:port/XXXX/XXXX.git']]]) # 这里的credentialsId就是git账号在Jenkins生成的识别id
script {
COMMIT_ID = sh(returnStdout: true, script: "git log -n 1 --pretty=format:'%h'").trim()
TAG = BUILD_TAG + '-' + COMMIT_ID
println "Current branch is origin/master, Commit ID is ${COMMIT_ID}, Image TAG is ${TAG}"
}
echo "创建docker镜像"
# 使用container()指定上面kubernetes的pod中的docker容器
container(name: 'docker') {
sh """ # 指定在docker容器中是用shell命令
echo ${HARBOR_USER_USR} ${HARBOR_USER_PSW} ${TAG}
docker build -t ${HARBOR_ADDRESS}/${REGISTRY_DIR}/${IMAGE_NAME}:${TAG} .
docker login -u ${HARBOR_USER_USR} -p ${HARBOR_USER_PSW} ${HARBOR_ADDRESS}
docker push ${HARBOR_ADDRESS}/${REGISTRY_DIR}/${IMAGE_NAME}:${TAG}
"""
}
echo "部署到kubernetes"
# 使用container()指定上面kubernetes的pod中的kubectl容器
container(name: 'kubectl'){
sh """
/usr/local/bin/kubectl --kubeconfig $MY_KUBECONFIG set image deploy -l app=${IMAGE_NAME} ${IMAGE_NAME}=${HARBOR_ADDRESS}/${REGISTRY_DIR}/${IMAGE_NAME}:${TAG} -n $NAMESPACE
"""
}
}
}
}
# 全局的环境变量
environment {
COMMIT_ID = ""
HARBOR_ADDRESS = "harbor的地址"
REGISTRY_DIR = "harbor中的项目名称"
IMAGE_NAME = "自己的项目名称"
NAMESPACE = "Kubernetes中的名称空间-就是namespace"
TAG = ""
}
parameters {
gitParameter(branch: '', branchFilter: 'origin/(.*)', defaultValue: '', description: 'Branch for build and deploy', name: 'BRANCH', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'PT_BRANCH')
}
# 发送邮件通知
post { # post 一般用于流水线结束后的进一步处理,比如邮件通知等
success {
emailext (
subject: '项目自动构建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} - SUCCESS!',
body: '${FILE,path="/home/lighthouse/email.html"}',
to: 'XXXXX@XX.com' # 邮箱地址
)
}
failure {
emailext (
subject: '项目自动构建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} - FAILURE!',
body: '${FILE,path="/home/lighthouse/email.html"}',
to: 'XXXXX@XX.com' # 邮箱地址
)
}
}
}