Jenkins 搭建
- Jenkins 搭建
- 更换源提升下载速度
- 更新Docker jenkins 最新版本
- 更改成中文
- 使用阿里云镜像仓库
- Gitee项目(示例)
- ~~生成公钥~~
- 目录权限调整
- Jenkinsfile
- input node 运行时输入需要指定的参数
- pipeline
- 入门
- 进阶
- Node 写法(推荐)
- 登录镜像仓库
- 大佬二
Jenkins 搭建
原贴参考地址
docker pull jenkinsci/blueocean:1.24.6
docker run \
--name jenkins \
-d \
-u root \
-p 8066:8080 \
-e TZ="Asia/Shanghai" -v /etc/localtime:/etc/localtime:ro \
--env JAVA_OPTS="-Xms256m -Xmx512m -XX:MaxNewSize=256m" \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$HOME":/home \
-v /mydata/jenkins:/var/jenkins_home \
jenkinsci/blueocean:1.24.6
# 进入容器
docker exec -it jenkins bash
# 查看docker 命令情况
docker info
# 更换jenkins 最新源
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
# 容器目录copy
# docker container cp jenkins:/var/jenkins_home /mydata/jenkins/
加速初始化可以配置镜像加速
1、切换目录,
cd /root/jenkins
2、修改hudson.model.UpdateCenter.xml文件
vim hudson.model.UpdateCenter.xml
3、将文件中的链接修改为(清华大学镜像源)https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
更换源提升下载速度
更新Docker jenkins 最新版本
更改成中文
echo $LANG
vi /etc/sysconfig/i18n
英文:
LANG="en_US.UTF-8"
中文:
LANG="zh_CN.UTF-8"
source /etc/sysconfig/i18n
echo $LANG
# zh_CN.UTF-8
wktJDC.jasper
# 腾讯云修改字体
vi /etc/locale.conf
source /etc/locale.conf
# 重启服务器
使用阿里云镜像仓库
# 阿里云镜像仓库库 需要使用 【jenkins】账号登录
sudo docker login --username=zsdf**c registry.cn-hangzhou.aliyuncs.com
# 是否启动成功
docker ps | grep jenkins;
# 进入容器 使用【alpine】 存在区别 amewin bash
docker exec -it amewin /bin/sh
# jenkins 默认工作目录
cd /var/jenkins_home/workspace/
# 阿里云镜像仓库库 需要使用 【jenkins】账号登录
sudo docker login --username=zsdf**c registry.cn-hangzhou.aliyuncs.com
Gitee项目(示例)
用于没有gitlab的朋友作为原
前提是仓库类型为public
,并且在jenkins 配置好 token
,不懂自行百度
# 我项目 gitee
https://gitee.com/amewin/amwin-boot.git
docker container cp jenkins:/var/jenkins_home /mydata/jenkins/
docker container cp jenkins:/var/jenkins_home/workspace/amewin/target/demo-0.0.1-SNAPSHOT.jar /mydata/myboot
amewin/target/
docker container cp jenkins:/var/jenkins_home/workspace/amewin/target/demo-0.0.1-SNAPSHOT.jar /mydata/myboot
生成公钥
docker exec -it jenkins bash
# 生成公钥
ssh-keygen
ssh-keygen -C xxxx@xxx.com
ssh-keygen -t rsa -C "your_email@example.com"
-t 指定密钥类型,默认是 rsa ,可以省略。
-C 设置注释文字,比如邮箱。
-f 指定密钥文件存储文件名。
# 查看公钥
cat /var/jenkins_home/.ssh/id_rsa.pub
目录权限调整
# 容器
docker run --name jenkins -d -p 8066:8080 -p 50000:50000 -u root jenkinsci/blueocean
http://192.168.56.10:8066/login?from=%2F
--安装推荐插件
# 慢慢等待完成
# 进入容器
docker exec -it jenkins bash
# 查看密码
cat /var/jenkins_home/secrets/initialAdminPassword
# 将容器器的文件拷贝出来
docker container cp jenkins:/var/jenkins_home /mydata/jenkins/
# 删除容器
docker rm -f jenkins-blueocean
# 添加目录权限
sudo chown -R 1000:1000 /mydata/jenkins
# 将容器
docker run --name jenkins -d -p 8066:8080 -p 50000:50000 -v /mydata/jenkins:/var/jenkins_home jenkinsci/blueocean
# 进入容器
docker exec -it jenkins bash
# 或者
cat /mydata/jenkins/secrets/initialAdminPassword
docker run --name jenkins -d -p 8066:8080 -p 50000:50000 jenkinsci/blueocean
Jenkinsfile
官方文档
https://www.jenkins.io/doc/book/pipeline/syntax/#input
建议看英文,中文有些方法没说名
目前可用的脚本(作者测试使用)
input node 运行时输入需要指定的参数
import java.text.SimpleDateFormat
node {
def options_result
def imageUrl
def customImage
def input_result
def branch_name
stage('git pull') {
println("master pull")
input_result = input message: '请选择', ok: 'ok', parameters: [
booleanParam(name: 'dev', defaultValue: true, description: '部署生产环境?'),
string(name: 'jvm', defaultValue: '-Xmx100m', description: '自定义JVM参数!'),
booleanParam(name: 'deploy', defaultValue: false),
choice(name: 'branch', choices: ['master', 'test', 'deploy'], description: '选择打包分支!')
]
println(input_result.branch)
branch_name=input_result.branch
sh "echo ${branch_name}"
}
}
import java.text.SimpleDateFormat
node {
try {
//名字这么写是为了可以发布到腾讯docker仓库,可随意更改
def dockerId = 'tengxun'
def dockerUrl = 'registry.cn-hangzhou.aliyuncs.com'
def dockerNamespace = 'amewin'
def dockerName = 'amewin'
def env = 'dev'
def dateFormat = new SimpleDateFormat('yyyyMMddHHmm')
def dockerTag = dateFormat.format(new Date())
def input_result // 用户输入项
def options_result
def imageUrl
def customImage
timeout(time: 10, unit: 'MINUTES') {
def options_result
def imageUrl
def customImage
def branch_name
stage('My Input') {
println("请输入/选择必要参数!")
input_result = input message: '请选择', ok: 'ok', parameters: [
booleanParam(name: 'dev', defaultValue: true, description: '部署生产环境?'),
string(name: 'jvm', defaultValue: '-Xmx100m', description: '自定义JVM参数!'),
booleanParam(name: 'deploy', defaultValue: false),
choice(name: 'branch', choices: ['master', 'test', 'deploy'], description: '选择打包分支!')
]
println(input_result.branch)
branch_name=input_result.branch
sh "echo ${branch_name}"
}
stage('git pull') {
sh 'pwd'
if (input_result.branch) {
echo 'master'
git (credentialsId: '3f16adb3-033b-4491-99d3-194af0dec3dc', url: 'https://gitee.com/amewin/amwin-boot.git', branch: 'origin/master', changelog: true)
}
if (input_result.branch) {
echo 'test'
git (credentialsId: '3f16adb3-033b-4491-99d3-194af0dec3dc', url: 'https://gitee.com/amewin/amwin-boot.git', branch: 'test', changelog: true)
}
}
stage('mvn install') {
sh 'pwd'
docker.image('maven:3.6.0-jdk-8-alpine').inside('-v /volume1/docker/.m2:/root/.m2') {
retry(3) {
sh 'mvn -B -DskipTests clean package'
}
}
}
stage('docker run') {
//切换目录
//dir("esms-main") {
sh 'pwd'
//sudo docker login --username=zsdf**c registry.cn-hangzhou.aliyuncs.com
imageUrl = "${dockerUrl}/${dockerNamespace}/${dockerName}:${dockerTag}"
// customImage = docker.build(imageUrl)
sh "docker rm -f ${dockerName} | true"
//--network esms-net配置网络信息,需要先docker network create esms-net,用于多个服务交互,可选
//docker network create amewin-net
customImage.run("-it -d --name ${dockerName} -p 8090:8080 --network amewin-net -e SPRING_PROFILES_ACTIVE=${env}")
// customImage.run("-it -d --name ${dockerName} -p 8044:9999 --network amewin-net ")
// }
}
stage('docker push aliyun') {
echo 'aliyun'
docker.withRegistry("https://${imageUrl}", '718bce9c-371d-4edb-acdf-96bbad7dd0fc') {
customImage.push()
}
sh """docker rmi \$(docker images | grep ${dockerName} | sed -n '4,\$p' | awk '{print \$3}') || true"""
}
currentBuild.result = 'SUCCESS'
}
} catch (e) {
currentBuild.result = 'FAILURE'
throw e
} finally {
//此处若想发布邮件,需要在系统管理-系统设置中配置邮件服务器
mail to: '891713***@qq.com',subject: "Jenkins: ${currentBuild.fullDisplayName},${currentBuild.result}",body:"${currentBuild.result}"
}
}
pipeline
入门
下面为入门语法
日后忘记可看
pipeline {
agent { docker 'maven:3.3.3' }
stages {
stage('build') {
steps {
sh 'mvn --version'
sh 'java -version'
}
}
}
}
进阶
pipeline {
agent none
agent {
docker { image 'maven:3.3.3' }
}
//环境变量
environment {
DISABLE_AUTH = 'true'
DB_ENGINE = 'sqlite'
}
stages {
stage('git pull'){
steps {
git(
branch: "master",
credentialsID: "004",
url : "https://gitee.com/amewin/amwin-boot.git",
changelog: true
)
}
}
stage('mvn install') {
sh 'pwd'
}
stage('打包') {
steps {
sh 'java -version'
}
}
}
post {
always {
//存储记录 文件的路径、文件名和 fingerprint 三个参数
//archiveArtifacts artifacts: 'build/libs/**/*.jar', fingerprint: true
echo 'This will always run'
}
success {
echo 'This will run only if successful'
deleteDir() /* clean up our workspace */
}
failure {
mail to: 'team@example.com',
subject: "Failed Pipeline: ${currentBuild.fullDisplayName}",
body: "Something is wrong with ${env.BUILD_URL}"
}
unstable {
echo 'This will run only if the run was marked as unstable'
}
changed {
echo 'This will run only if the state of the Pipeline has changed'
echo 'For example, if the Pipeline was previously failing but is now successful'
}
}
}
Node 写法(推荐)
原贴地址
登录镜像仓库
# 是否启动成功
docker ps | grep jenkins;
# 进入容器 使用【alpine】 存在区别 amewin bash
docker exec -it amewin /bin/sh
# 登录 su jenkins
sudo docker login --username=zsdf**c registry.cn-hangzhou.aliyuncs.com
Jenkinsfile
接收 cron 样式的字符串来定义一个固定的间隔,在这个间隔中,Jenkins 会检查新的源代码更新。如果存在更改, 流水线就会被重新触发。例如:
triggers { pollSCM('H */4 * * 1-5') }
pipeline {
agent any
tools {
maven 'apache-maven-3.0.1'
}
stages {
stage('Example') {
steps {
sh 'mvn --version'
}
}
}
triggers {
cron('H */4 * * 1-5')
}
environment {
CC = 'clang'
}
stages {
stage('Example') {
environment {
AN_ACCESS_KEY = credentials('my-prefined-secret-text')
}
steps {
sh 'printenv'
}
}
}
}
import java.text.SimpleDateFormat
node {
try {
//名字这么写是为了可以发布到腾讯docker仓库,可随意更改
def dockerId='tengxun'
def dockerUrl='registry.cn-hangzhou.aliyuncs.com'
def dockerNamespace='amewin'
def dockerName='amewin'
def env='dev'
def dateFormat = new SimpleDateFormat("yyyyMMddHHmm")
def dockerTag = dateFormat.format(new Date())
stage('git pull'){
sh 'pwd'
git credentialsId: '004', url: 'https://gitee.com/amewin/amwin-boot.git'
}
stage('mvn install') {
sh 'pwd'
docker.image('maven:3.6.0-jdk-8-alpine').inside('-v /volume1/docker/.m2:/root/.m2') {
sh 'mvn --version'
//sh 'mvn clean install'
sh 'mvn package -Dmavan.test.skip=true'
}
}
stage('docker run') {
//dir("esms-main") {
sh 'pwd'
//sudo docker login --username=zsdfccc registry.cn-hangzhou.aliyuncs.com
def imageUrl = "${dockerUrl}/${dockerNamespace}/${dockerName}:${dockerTag}"
def customImage = docker.build(imageUrl)
sh "docker rm -f ${dockerName} | true"
//--network esms-net配置网络信息,需要先docker network create esms-net,用于多个服务交互,可选
//docker network create amewin-net
//customImage.run("-it -d --name ${dockerName} -p 8090:8090 --network amewin-net -e SPRING_PROFILES_ACTIVE=${env}")
customImage.run("-it -d --name ${dockerName} -p 8044:9999 --network amewin-net ")
//only retain last 3 images,自动删除老的容器,只保留最近3个
sh """docker rmi \$(docker images | grep ${dockerName} | sed -n '4,\$p' | awk '{print \$3}') || true"""
// }
}
currentBuild.result="SUCCESS"
} catch (e) {
currentBuild.result="FAILURE"
throw e
} finally {
//此处若想发布邮件,需要在系统管理-系统设置中配置邮件服务器
}
大佬二
/*
在接触Jenkins流水线的时候最迷惑的就是语法中的pipelinee和node两种组织形式,
一开始使用的是pipeline,但是在看文档的时候又有很多node的写法就感到非常的难受,
总体感觉上node的写法似乎支持更多的插件并且语法更友好但是发现的时候已经差不多写完了也就没有更改
*/
def host() {
def remote = [:]
remote.name = 'test'
remote.host = 'xxxx'
remote.user = 'xxx'
remote.password = 'xxxx'
remote.allowAnyHosts = true
return remote
}
pipeline {
agent any
environment {
// 这里主要是配置整个流水线所需要的变量,核心思想是要复用流水线和部署脚本的代码而只更改参数
ENV = 'xx'
SERVICE_NAME = 'xx'
SERVER_IP = 'xx'
SERVER_PORT = 'xx'
SERVER_USER = 'xx'
SERVICE_VERSION = 'xx'
DOCKER_REPO = 'xx'
DOCKER_NAMESPACE = 'xx'
DOCKER_USERNAME = 'xx'
DOCKER_PASSWORD = 'xx'
NACOS_IP = 'xx'
NAMESPACE_ID = 'xx'
// jvm参数
JAVA_OPTS = 'xx'
}
stages {
stage('构建MAVEN项目') {
agent {
// docker in docker就是应用在这里了,使用maven的docker镜像来执行构建
docker {
image 'maven:3-alpine'
// 映射本地的maven仓库到docker里防止每次都去远程仓库下载jar
args '-v /var/jenkins_home/.m2:/root/.m2'
}
}
steps {
// maven package
sh 'mvn clean install -Dmaven.test.skip=true -Dproject.type=jar -Ptest package'
}
}
stage('构建docker镜像') {
agent {
docker {
image 'docker'
// 这里的挂载比较奇怪,因为在上一步maven构建完成之后并没有生成target(现在想来可能是docker的缘故),
// 所以把本地的maven仓库给挂载进来获取jar包使用了
args '-v /var/jenkins_home/.m2/repository/com/ghaoqi:/root/jar'
}
}
steps {
sh '''
rm -f docker/*.jar
cp /root/jar/${SERVICE_NAME}/${SERVICE_VERSION}-${ENV}/${SERVICE_NAME}-${SERVICE_VERSION}-${ENV}.jar ./docker/${SERVICE_NAME}.jar
cd docker
docker build -t ${SERVICE_NAME}:${SERVICE_VERSION} .
'''
}
}
stage('推送构建的镜像') {
steps {
// 这里使用了阿里云的容器镜像服务
sh '''
docker login -u ${DOCKER_USERNAME} -p ${DOCKER_PASSWORD} ${DOCKER_REPO}
docker tag ${SERVICE_NAME}:${SERVICE_VERSION} ${DOCKER_REPO}/${DOCKER_NAMESPACE}/${SERVICE_NAME}:${SERVICE_VERSION}
docker push ${DOCKER_REPO}/${DOCKER_NAMESPACE}/${SERVICE_NAME}:${SERVICE_VERSION}
docker image rm ${SERVICE_NAME}:${SERVICE_VERSION}
docker image rm ${DOCKER_REPO}/${DOCKER_NAMESPACE}/${SERVICE_NAME}:${SERVICE_VERSION}
'''
}
}
stage('部署到远程机器') {
steps {
// 使用sed的核心思路还是保证脚本能够复用而只需要修改参数
sh """
sed -e 's/__nacos_ip__/${NACOS_IP}/' \
-e 's/__serviceName__/${SERVICE_NAME}/' \
-e 's/__ip__/${SERVER_IP}/' \
-e 's/__port__/${SERVER_PORT}/' \
-e 's/__docker_repo__/${DOCKER_REPO}/' \
-e 's/__docker_namespace__/${DOCKER_NAMESPACE}/' \
-e 's/__docker_username__/${DOCKER_USERNAME}/' \
-e 's/__docker_password__/${DOCKER_PASSWORD}/' \
-e 's/__version__/${SERVICE_VERSION}/' \
-e 's/__user__/${SERVER_USER}/' \
-e 's#__JAVA_OPTS__#${JAVA_OPTS}#' \
-e 's/__namespaceId__/${NAMESPACE_ID}/' deploy.sh > replace.sh;
"""
// Jenkins自带的ssh插件
sshScript remote: host(), script: "replace.sh"
}
}
}
}