Jenkins踩坑

最近弄了下jenkins,就是为了部署方便点,然后也遇到一些麻烦,顺便记录下

安装Jenkins

直接

1
> apt install jenkins

docker

1
2
> docker pull jenkins/jenkins
> docker run -d -p 8080:8080 -p 50000:50000 -v jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock jenkins/jenkins:latest

插件

然后进入之后插件什么的装一下就妥了,安装插件之前可以先升级下站点的地址,也就是插件的地址,自带那个有点慢,例如这个https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/current/update-center.json,在插件管理/高级/升级站点贴上就行了

额外要安装的插件:

  1. Publish Over SSH,用于远程登录机器用的
  2. Generic Webhook Trigger,用来做触发器的

其他的点点就行了

任务

新建任务的时候,可以选择自由风格的软件或者pipeline,后面分别说下,这两个还是有点区别的

自由风格

这个用一个html项目做例子,完了就是一个纯静态的文件,然后发送到对应的服务器对应的位置就行了

  1. 源码管理:填写上项目的地址即可,GitHub项目https地址可以不用秘钥就能直接访问,当然我们构建只需要可读即可,所以这样最简单,例如https://github.com/xxx/jenkins-html.git

  2. 构建环境:这一步可以添加一个触发器,其他的参数之类的都可以不填,按需填上即可,但是要填好token,这是一个随意的字符串,然后在github项目的settingsWebhooks增加一个webohook,在Payload URL中填写http://JENKINS_URL/generic-webhook-trigger/invoke?token=?,具体的替换下就行了;如果不用触发器这一步可以什么都不做

  3. 构建:增加一个shell执行即可,然后写上构建的时候需要的一些命令即可,例如:

    1
    2
    3
    4
    5
    6
    7
    echo $PATH
    node -v
    npm -v
    npm install
    npm run build
    rm -rf testhtml.tar.gz
    tar -zcvf testhtml.tar.gz dist index.html
  4. 构建后操作:选择Send build artifacts over SSH,在这之前需要先在系统设置中的Publish over SSH配置下SSH Server,这个配置只要填写远端服务器的host, 登录用户,文件发送的远端位置,要确保这个文件夹存在,然后勾选Use password authentication, or use a different key,密码或者私钥填一个。再到SSH Publishers中选上刚才配置的服务器名称,source files填一个要传输的文件,例如*.tar.gzExec command填上在远端服务器要执行的命令。

在这些都好了之后执行构建即可,稳妥~

Pipeline

流水线的构建例子也是上面那个项目,只不过把构建过程写在文件中,这样流程也是全自己控制了

流水线:这里选择Pipeline script from SCM,这样可以在项目中写Jenkinsfile配置,脚本路径可以指定脚本名称,默认就是Jenkinsfile.SCM中选择GIT之后填上github项目地址https://github.com/xxx/jenkins-html.git,然后就结束了

这里重点说下Jenkinsfile写法,直接贴出来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
pipeline{
agent any

parameters {
string(name: 'ZIPNAME', defaultValue: 'test', description: 'zip package name')
}

stages {
stage('Prepare'){
steps{
sh 'node -v'
sh 'npm -v'
}
}
stage('Build'){
steps {
sh 'npm install'
sh 'npm run build'
}
}
stage('Zip'){
steps{
sh "rm -rf ${ZIPNAME}.tar.gz"
sh 'tar -zcvf ${ZIPNAME}.tar.gz dist index.html'
}
}
stage('Deploy'){
steps{
sh 'chmod +x deploy.sh'
timeout(time: 3, unit: 'MINUTES') {
retry(3) {
sh "./deploy.sh ${ZIPNAME}"
}
}
}
}
}

post {
always {
echo 'I will always say Hello again!'
}
}
}

项目中还有deploy.sh脚本,这个是部署用的,主要是传输打包文件到目标机器上然后进行部署操作

这个文件可能是没有执行权限,所以执行下chmod +x deploy.sh

deploy.sh内容如下:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

scp "$1.tar.gz" username@host:/root/html/
ssh username@host << EOF
cd /usr/share/nginx/html
whoami
hostname
rm -rf test && echo 'remove test'
mkdir test && echo 'mkdir test'
tar -zxvf "/root/html/$1.tar.gz" -C ./test
EOF

重点

  1. ssh之后的代码都要用EOF包住,说明是在远端机器登录后要执行的命令,否则都会在本地执行

  2. 如果执行出现Host key verification failed.,需要执行下面的一波操作,因为jenkins运行的时候用的是jenkins这个用户….

    1
    2
    3
    4
    5
    6
    su jenkins
    ssh-keygen
    //将公钥放到目标机器的~/.ssh/authorized_keys
    ssh-copy-id username@host
    //需要输入密码
    //或者直接copy

这个特别坑…

最后

如果打包Docker镜像的话,更加简单,项目中写好Dockerfile即可,然后写一点镜像build的命令即可,可以直接往服务器发送镜像,也可以发送到Dockerhub之类的镜像托管平台,再通知服务器拉取镜像运行