跳至主要內容

apzs...大约 55 分钟

目标:开发提交代码到git服务器后,Jenkins自动构建,并将其部署到测试服务器上

image-20230601104404720
image-20230601104404720

1、gitlab简单使用

1、安装gitlab

1、手动安装(不推荐)

1. 安装和配置必须的依赖项

在 CentOS 7上,下面的命令也会在系统防火墙中打开 HTTP、HTTPS 和 SSH 访问。这是一个可选步骤,如果您打算仅从本地网络访问极狐GitLab,则可以跳过它。

sudo yum install -y curl policycoreutils-python openssh-server perl
sudo systemctl enable sshd
sudo systemctl start sshd
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo systemctl reload firewalld

(可选)下一步,安装 Postfix 以发送电子邮件通知。如果您想使用其他解决方案发送电子邮件,请跳过此步骤并在安装极狐GitLab 后配置外部 SMTP 服务器open in new window

sudo yum install postfix
sudo systemctl enable postfix
sudo systemctl start postfix

在安装 Postfix 的过程中可能会出现一个配置界面,在该界面中选择“Internet Site”并按下回车。把“mail name”设置为您服务器的外部 DNS 域名并按下回车。如果还有其它配置界面出现,继续按下回车以接受默认配置。

2. 下载/安装极狐GitLab

配置极狐GitLab 软件源镜像。

curl -fsSL https://packages.gitlab.cn/repository/raw/scripts/setup.sh | /bin/bash

接下来,安装极狐GitLab。确保您已正确设置您的 DNSopen in new window,并更改 https://gitlab.example.com 为您要访问极狐GitLab 实例的 URL。安装包将在该 URL 上自动配置和启动极狐GitLab。

如果没有域名或者不想修改Hosts文件,可以使用能访问这台配置有GitLab的主机的ip

对于 https 站点,极狐GitLab 将使用 Let's Encrypt 自动请求 SSL 证书,这需要有效的主机名和入站 HTTP 访问。您也可以使用自己的证书或仅使用 http://(不带s)。

如果您想为初始管理员用户(root)指定自定义密码,请查看文档open in new window。如果未指定密码,将自动生成随机密码。

执行如下命令开始安装:

sudo EXTERNAL_URL="https://gitlab.example.com" yum install -y gitlab-jh
# 可以使用 ip addr 命令查看ip,然后使用ip访问这台主机
# sudo EXTERNAL_URL="192.168.56.11" yum install -y gitlab-jh
# 也可以修改端口
# sudo EXTERNAL_URL="192.168.56.11:8081" yum install -y gitlab-jh

如果发现url写错了可以执行以下命令

vi /etc/gitlab/gitlab.rb

修改该文件的external_url

image-20230514163310393
image-20230514163310393

然后再执行gitlab-ctl reconfigure重新加载配置

gitlab-ctl reconfigure

然后再重启gitlab

gitlab-ctl restart
3. 访问极狐GitLab 实例并登录
Notes:
Default admin account has been configured with following details:
Username: root
Password: You didn't opt-in to print initial root password to STDOUT.
Password stored to /etc/gitlab/initial_root_password. This file will be cleaned up in first reconfigure run after 24 hours.

除非您在安装过程中指定了自定义密码,否则将随机生成一个密码并存储在 /etc/gitlab/initial_root_password 文件中(出于安全原因,24 小时后,此文件会被第一次 gitlab-ctl reconfigure 自动删除,因此若使用随机密码登录,建议安装成功初始登录成功之后,立即修改初始密码)。使用此密码和用户名 root 登录。

执行cat /etc/gitlab/initial_root_password就可以看到密码为eoEPtKv4Sh1I1uYN1Mslp2kVgFU1tbqutXZYJj/2KOI=

[root@localhost ~]# cat /etc/gitlab/initial_root_password
# WARNING: This value is valid only in the following conditions
#          1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`, it was provided before database was seeded for the first time (usually, the first reconfigure run).
#          2. Password hasn't been changed manually, either via UI or via command line.
#
#          If the password shown here doesn't work, you must reset the admin password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password.

Password: eoEPtKv4Sh1I1uYN1Mslp2kVgFU1tbqutXZYJj/2KOI=

# NOTE: This file will be automatically deleted in the first reconfigure run after 24 hours.

如果出现了502,不用着急,等一下即可;如果一直这样你需要看以下是不是内存不足或808080等端口被占用

image-20230514160606167
image-20230514160606167
4、常用命令
gitlab-ctl start     #启动所有gitlab组件;
gitlab-ctl stop      #停止所有git1ab组件;
gitlab-ctl restart   #重启所有gitlab组件;
gitlab-ctl status    #查看服务状态;
gitlab-ctl reconfigure       #更新配置
vi /etc/gitlab/gitlab.rb   #修改默认的配置文件: 
gitlab-ctl tail      #查看日志;

2、docker安装(推荐)

可以执行如下命令,指定gatlab家目录的位置

export GITLAB_HOME=/mydata/gitlab

使用root用户执行以下命令(需要安装docker)

注意修改hostname为自己的主机ip,其中需要443端口的HTTPS80端口的HTTP22端口的ssh

我们还要使用ssh来上传代码和拉取代码,但是虚拟机的ssh的22端口已经被我们用来连接虚拟机了,因此我们将gitlab的ssh端口修改为2222,并映射到虚拟主机的2222端口

本次演示使用81端口来访问web服务,2222端口访问ssh

其实也可以修改为--publish 1443:443 --publish 81:80 --publish 2222:22,只修改访问虚拟机的端口,不修改容器内部实际应用使用的端口

sudo docker run --detach \
  --hostname 192.168.56.10:81 \
  --publish 1443:443 --publish 81:81 --publish 2222:2222 \
  --name gitlab \
  --restart always \
  --volume $GITLAB_HOME/config:/etc/gitlab:Z \
  --volume $GITLAB_HOME/logs:/var/log/gitlab:Z \
  --volume $GITLAB_HOME/data:/var/opt/gitlab:Z \
  --shm-size 256m \
  registry.gitlab.cn/omnibus/gitlab-jh:latest

使用如下命令进入容器内部

docker exec -it gitlab /bin/bash

进入容器后,执行如下命令查看管理员密码(需要及时修改管理员密码,密码类似于+9meeRS9aMclaHyqbHsHFcumRNpMflJaagS2r+ZobCs=

cat /etc/gitlab/initial_root_password

使用如下命令查看剩余内存

free -m

我们可以执行vi /etc/gitlab/gitlab.rb进入/etc/gitlab/gitlab.rb文件来修改配置

vi /etc/gitlab/gitlab.rb

在命令模式下,输入/external_url即可进行查找,输入n查找下一个,输入N查找上一个

然后将external_url的注释打开,修改为如下配置;或者也可以想我一样,重新另起一行

这里修改对应的是--publish 81:81里的第一个81,也就是外部访问本虚拟机的81端口

external_url 'http://192.168.56.10:81'
image-20230521110406056
image-20230521110406056

然后继续修改nginx['listen_port']

这里的修改对应的是--publish 81:81里的第二个81,也就是本容器运行nginx实际使用的的端口

nginx['listen_port'] = 81
image-20230521110619272
image-20230521110619272

然后继续修改gitlab_rails['gitlab_shell_ssh_port']

这里的修改对应的是--publish 2222:2222里的第一个2222,也就是外部访问本虚拟机的2222端口

gitlab_rails['gitlab_shell_ssh_port'] = 2222
image-20230521110744671
image-20230521110744671

然后进入/assets/sshd_config文件里,修改Port

这里的修改对应的是--publish 2222:2222里的第二个2222,也就是本容器运行sshd实际使用的端口

vi /assets/sshd_config
image-20230521110839263
image-20230521110839263

然后执行如下命令,重新加载配置并重启gitlab

gitlab-ctl reconfigure
gitlab-ctl restart

访问Monitoring项目,点击克隆即可查看sshhttp的端口

image-20230528121708916
image-20230528121708916

如果发现访问不了,可以执行gitlab-ctl tail命令查看日志,看运行的端口对不对

gitlab-ctl tail

请添加:Z参数,否则执行docker logs gitlab查看日志,将显示如下错误

Thank you for using GitLab Docker Image!
Current version: gitlab-jh=15.11.3-jh.0
Configure GitLab for your system by editing /etc/gitlab/gitlab.rb file
And restart this container to reload settings.
To do it use docker exec:
docker exec -it gitlab editor /etc/gitlab/gitlab.rb
docker restart gitlab
For a comprehensive list of configuration options please see the Omnibus GitLab readme
https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md
If this container fails to start due to permission problems try to fix it by executing:
docker exec -it gitlab update-permissions
docker restart gitlab
Cleaning stale PIDs & sockets
cat: /var/opt/gitlab/gitlab-rails/VERSION: No such file or directory
Installing gitlab.rb config...
cp: cannot create regular file '/etc/gitlab/gitlab.rb': Permission denied

极狐GitLab Docker 镜像 所有级别私有化部署open in new window

极狐GitLab Docker 镜像是极狐GitLab 的整体镜像,在单个容器中运行所有必要的服务。

Docker 镜像不包括邮件传输代理 (MTA)。推荐的解决方案是添加在单独容器中运行的 MTA(例如 Postfix 或 Sendmail)。作为另一种选择,您可以直接在极狐GitLab 容器中安装 MTA,但这会增加维护开销,因为您可能需要在每次升级或重新启动后重新安装 MTA。

您不应在 Kubernetes 中部署极狐GitLab Docker 镜像,因为它会造成单点故障。

Docker for Windows 不受官方支持。存在卷权限的已知问题,以及潜在的其他未知问题。

先决条件

Docker 是必需的。查看官方安装文档open in new window

设置卷位置

在设置其他所有内容之前,请配置一个新的环境变量 $GITLAB_HOME,指向配置、日志和数据文件所在的目录。 确保该目录存在并且已授予适当的权限。

对于 Linux 用户,将路径设置为 /srv/gitlab

export GITLAB_HOME=/srv/gitlab

对于 macOS 用户,使用用户的 $HOME/gitlab 目录:

export GITLAB_HOME=$HOME/gitlab

极狐GitLab 容器使用主机装载的卷来存储持久数据:

本地位置容器位置使用
$GITLAB_HOME/data/var/opt/gitlab用于存储应用程序数据。
$GITLAB_HOME/logs/var/log/gitlab用于存储日志。
$GITLAB_HOME/config/etc/gitlab用于存储极狐GitLab 配置文件。

安装

极狐GitLab Docker 镜像可以通过多种方式运行:

使用 Docker Engine 安装极狐GitLab

您可以微调这些目录以满足您的要求。 一旦设置了 GITLAB_HOME 变量,您就可以运行镜像:

sudo docker run --detach \
  --hostname gitlab.example.com \
  --publish 443:443 --publish 80:80 --publish 22:22 \
  --name gitlab \
  --restart always \
  --volume $GITLAB_HOME/config:/etc/gitlab \
  --volume $GITLAB_HOME/logs:/var/log/gitlab \
  --volume $GITLAB_HOME/data:/var/opt/gitlab \
  --shm-size 256m \
  registry.gitlab.cn/omnibus/gitlab-jh:latest

这将下载并启动极狐GitLab 容器,并发布访问 SSH、HTTP 和 HTTPS 所需的端口。所有极狐GitLab 数据将存储在 $GITLAB_HOME 的子目录中。系统重启后,容器将自动 restart

如果您使用的是 SELinux,请改为运行以下命令:

sudo docker run --detach \
  --hostname gitlab.example.com \
  --publish 443:443 --publish 80:80 --publish 22:22 \
  --name gitlab \
  --restart always \
  --volume $GITLAB_HOME/config:/etc/gitlab:Z \
  --volume $GITLAB_HOME/logs:/var/log/gitlab:Z \
  --volume $GITLAB_HOME/data:/var/opt/gitlab:Z \
  --shm-size 256m \
  registry.gitlab.cn/omnibus/gitlab-jh:latest

这将确保 Docker 进程有足够的权限在挂载的卷中创建配置文件。

如果您使用 Kerberos 集成 ,您还必须发布您的 Kerberos 端口(例如,--publish 8443:8443)。否则会阻止使用 Kerberos 进行 Git 操作。

初始化过程可能需要很长时间。 您可以通过以下方式跟踪此过程:

sudo docker logs -f gitlab

启动容器后,您可以访问 gitlab.example.com(如果您在 macOS 上使用 boot2docker,则可以访问 http://192.168.59.103)。Docker 容器开始响应查询可能需要一段时间。

访问极狐GitLab URL,并使用用户名 root 和来自以下命令的密码登录:

sudo docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password

密码文件将在 24 小时后的第一次重新配置运行中自动删除。

2、修改语言

登录成功后,可以在PreferencesLocalization里修改语言

image-20230514162004930
image-20230514162004930

3、修改密码

可以点击三个横杠 -> 管理员 用户 -> Administrator -> 编辑里修改密码

apzs20001118
GIF 2023-5-14 16-26-09
GIF 2023-5-14 16-26-09

4、修改头像

头像无法显示是因为被墙了,执行如下命令修改/var/opt/gitlab/gitlab-rails/etc/gitlab.yml文件

vi /etc/gitlab/gitlab.rb

修改plain_urlssl_url为如下内容

gitlab_rails['gravatar_ssl_url'] = 'https://sdn.geekzu.org/avatar/%{hash}?s=%{size}&d=identicon'
gitlab_rails['gravatar_ssl_url'] = 'https://sdn.geekzu.org/avatar/%{hash}?s=%{size}&d=identicon'
image-20230514231621243
image-20230514231621243
image-20230514164748799
image-20230514164748799

然后再执行gitlab-ctl reconfigure重新加载配置(执行时间稍微长一点)

gitlab-ctl reconfigure

再执行gitlab-ctl restart重启服务

gitlab-ctl restart

5、提交代码

1、生成密钥

可以使用如下命令生成一个ssh密钥,这个密钥在C:\Users\[用户名]\.ssh下,-C参数为你的邮箱

ssh-keygen -t rsa -C '[email protected]'
image-20230520212202774
image-20230520212202774

如果你以前已经生成过ssh密钥,想给gitlab单独申请一个密钥可以执行如下命令,再增加一个gitlab_id_rsa密钥

ssh-keygen -t rsa -C '[email protected]' -f ~/.ssh/gitlab_id_rsa
image-20230520212558349
image-20230520212558349

如果你有多个密钥,需要增加一个config文件

image-20230530204010553
image-20230530204010553
# github
Host github.com
HostName github.com
User git
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa

# gitlab
Host gitlab
HostName 192.168.56.10
Port 2222
User git
PreferredAuthentications publickey
IdentityFile ~/.ssh/gitlab_id_rsa

然后可以使用如下命令复制id_rsa.pub文件的内容(如果生成的是gitlab_id_rsa,别忘了修改文件为gitlab_id_rsa.pub

clip < ~/.ssh/id_rsa.pub    #windows系统
pbcopy < ~/.ssh/id_rsa.pub  #mac os系统

然后在gitlab里添加密钥

image-20230520214929834
image-20230520214929834

2、测试连接

可以使用如下命令测试连接

使用别名(~/.ssh/config里配置的Host)会查找~/.ssh/config文件,然后按照配置使用指定的端口和密钥进行连接

ssh -T git@gitlab

如果直接使用ip进行访问,则不会按照~/.ssh/config文件里的配置进行连接,需要在命令中添加需要的所有参数

ssh -T -i ~/.ssh/gitlab_id_rsa -p 2222 [email protected]

第一次连接时,需要手动输入yes,后续则不用。出现Welcome to GitLab就证明成功了

$ ssh -T git@gitlab
The authenticity of host '[192.168.56.10]:2222 ([192.168.56.10]:2222)' can't be established.
ED25519 key fingerprint is SHA256:GzNOzBP26KNqIJeqfRySNTdOo3OwuM4WZ+T7j13TQeY.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[192.168.56.10]:2222' (ED25519) to the list of known hosts.
Welcome to GitLab, @root!

无名氏@DESKTOP-UF6T5IH MINGW64 ~/.ssh
$ ssh -T -i ~/.ssh/gitlab_id_rsa -p 2222 [email protected]
Welcome to GitLab, @root!

3、创建项目

然后新建一个空白项目

image-20230517212929458
image-20230517212929458

然后复制ssh链接

image-20230530213930378
image-20230530213930378

然后使用IDEA新建一个SpringBoot项目

image-20230517213325617

先写个简单的hello,注意添加@RestController注解

image-20230601103138456
image-20230601103138456

然后测试一下能不能访问

image-20230601103108088
image-20230601103108088

然后打包一下,看能不能构建成功,构建成功了再提交代码

image-20230531223423975
image-20230531223423975

然后点击VCS里的Create Git Repository...

image-20230517213700275

然后选择自己的项目

image-20230517213805764

然后点击Git里的Manage Remotes...

image-20230517213928459

直接使用ip不行,前面已经说过了。使用别名(~/.ssh/config里配置的Host)会查找~/.ssh/config文件,然后按照配置使用指定的端口和密钥进行连接,而直接使用ip不行

image-20230530213730505
image-20230530213730505

使用~/.ssh/config里配置的gitlab对应的Host就可以了

image-20230530213840900
image-20230530213840900

然后将项目代码添加到版本控制

image-20230530214959315
image-20230530214959315

然后提交代码

image-20230530215048473
image-20230530215048473
image-20230530220523013
image-20230530220523013

然后提交代码

image-20230530220022407
image-20230530220022407

已经提交成功了

image-20230530220459587
image-20230530220459587

2、安装其他软件

1、安装jenkins

官方中文文档:https://www.jenkins.io/zh/doc/

执行yum search java | grep jdk命令查看可以下载的jdk

yum search java | grep jdk
image-20230528101922264

执行yum install -y java-1.8.0-openjdk下载jdk1.8(这个其实安装的是jdk)

yum install -y java-1.8.0-openjdk

我们执行完上面的命令后可以再使用如下命令安装jdk

yum install -y java-devel

jenkins官网open in new window里,最新的长久支持版最少需要jdk11,因此我们可以下载2.346.2open in new window这个版本,这是最后一个支持jdk1.8的版本

image-20230528104059249
image-20230528104059249

可以使用如下命令,使用本地的当前用户将存在D盘的jenkins.war文件,使用远程的root用户传到192.168.56.10这台主机的/root目录,期间会提示输入远程的root用户的密码

scp D:\jenkins.war [email protected]:/root

或者也可以使用一些工具上传

上传好后执行java -jar jenkins.war命令即可,jenkins会运行在8080端口;如果该端口被占用可以执行如下命令,让jenkins运行在8888端口

java -jar jenkins.war --httpPort=8888

也可以使用nohup命令将Jenkins作为后台进程启动,并将输出重定向到nohup.out文件中。这样可以在后台运行Jenkins的同时继续使用终端。

nohup java -jar jenkins.war --httpPort=8888 &

使用以下命令可以找到Jenkins进程的PID:

ps -ef | grep jenkins

使用kill命令终止jenkins进程:

kill <PID>

请将上述命令中的<PID>替换为上一步中找到的Jenkins进程的PID。

运行成功后,会在控制台显示admin用户的密码,信息可以在当前用户目录的.jenkins/secrets/initialAdminPassword文件里查看

image-20230528105215469
image-20230528105215469

然后在浏览器上访问http://121.40.49.203:8888,输入密码即可

image-20230528110007762
image-20230528110007762

然后选择安装推荐的插件

image-20230528110219765
image-20230528110219765

然后一直等待就好了

image-20230528110314930
image-20230528110314930

下载插件完成后,输入用户名密码等信息,密码直接输入123456就可以,点击保存并完成

image-20230528112121710
image-20230528112121710

然后检查一下url,点击保存并完成

image-20230528112108286
image-20230528112108286

然后点击开始使用jenkins

image-20230528112257017
image-20230528112257017

然后就来到了后台界面

image-20230528112402776
image-20230528112402776

2、安装maven

由于jenkins需要使用maven,因此我们还有安装maven,在官网open in new window下载最新的tar.gz格式的压缩包,然后放到运行jenkins的机器上

image-20230528110549702
image-20230528110549702

然后执行如下命令解压压缩包

tar -zxvf apache-maven-3.9.2-bin.tar.gz
image-20230528112815558
image-20230528112815558

然后执行mv命令,将apache-maven-3.9.2文件夹里的内容移到/usr/local/maven目录下

mkdir /usr/local/maven
mv apache-maven-3.9.2/* /usr/local/maven

进入到/usr/local/maven/bin目录下

cd /usr/local/maven/bin

执行./mvn -v命令即可看到使用的jdk的版本号

./mvn -v
image-20230528113906482
image-20230528113906482

3、下载插件

由于默认不能构建maven项目,因此我们需要下载一个maven插件。

点击Manage Jenkins里的Manage Plugins即可管理插件

image-20230528114347288
image-20230528114347288

然后再可选插件里输入maven,然后勾选 Maven Integration这个插件,选择Install without restart即可安装插件

image-20230528114630507
image-20230528114630507

然后划到最下面,即可查看刚刚安装的插件的状态

image-20230528114806411
image-20230528114806411

3、新建maven项目任务

1、新建任务

点击新建任务

image-20230531202040049
image-20230531202040049

然后输入项目名,选择构建一个maven项目,然后点击确定

image-20230531202125253
image-20230531202125253

2、配置git

然后需要添加git仓库,由于需要使用git,因此我们需要在安装jenkins的机器上安装git

image-20230531204806614
image-20230531204806614

使用yum install -y git命令安装git

yum install -y git

然后使用如下命令生成密钥文件

ssh-keygen -t rsa -C '[email protected]'

然后使用如下命令查看公钥文件,由于没有GUI,所以没有复制到剪贴板的命令,因此需要我们手动复制

cat ~/.ssh/id_rsa.pub

然后在gitlab上粘贴即可(由于自己运行gitlab比较占内存,就没用自己的了)

image-20230531210556386
image-20230531210556386

然后可以使用ssh -T [email protected]测试能否连接。第一次连接时,需要手动输入yes,后续则不用。出现Welcome to GitLab就证明成功了

详细内容

[root@iZbp1asdy4uxt0pu8ywpiqZ ~]# ssh -T [email protected]
The authenticity of host 'gitlab.com (172.65.251.78)' can't be established.
ECDSA key fingerprint is SHA256:HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw.
ECDSA key fingerprint is MD5:f1:d0:fb:46:73:7a:70:92:5a:ab:5d:ef:43:e2:1c:35.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'gitlab.com,172.65.251.78' (ECDSA) to the list of known hosts.
Welcome to GitLab, @apzs!
image-20230531211824799
image-20230531211824799

填上地址后,如果出现如下错误,刷新一下页面就行了

image-20230531211357336
image-20230531211357336
**An internal error occurred during form field validation (HTTP 403). Please reload the page and if the problem persists, ask the administrator for help.**

刷新后,再次填入就不报错了

image-20230531211559743
image-20230531211559743

由于我的主分支是master分支,因此不用修改Branches to build配置

如果你的是main分支需要修改Branches to build*/main

image-20230531210857178
image-20230531210857178
image-20230531203627289
image-20230531203627289

3、配置maven

接着我们需要修改maven

image-20230531211918377
image-20230531211918377

往下滑到底,点击新增Maven,取消勾选自动安装,输入自己的maven安装路径,然后保存即可

image-20230531212924901
image-20230531212924901

配置完成刷新构建一个maven项目页面,将前面配置的git再重新添加一下

由于我这个pom.xm就是再根目录,因此不需要修改Root POM

如果你的pom.xml文件位置为demo-1/pom.xml,则需要修改Root POM的值为demo-1/pom.xml

image-20230531213329200
image-20230531213329200
image-20230531213151982
image-20230531213151982

然后点击保存即可

image-20230531214048397
image-20230531214048397

4、构建任务

我们返回Dashboard,点击这个名称右边的运行按钮,就可以在左下角的构建执行状态里看到构建任务,点击这个构建任务

image-20230531214639048
image-20230531214639048

然后再点击左下角的这个任务的时间这个地方

image-20230531214817843
image-20230531214817843

然后带你就控制台输出即可看到输出信息

image-20230531215011269
image-20230531215011269

如果安装的是jre,会报如下的错误,这是因为我们安装的其实是jre,而不是jdk

可以使用如下命令安装jdk(注意不要删除前面安装的jre)

yum install -y java-devel

完整错误(如果不是这个错误,证明在下载jar包的时候就报错了)

[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/3.5.0/plexus-utils-3.5.0.jar (267 kB at 29 kB/s)
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/thoughtworks/qdox/qdox/2.0.3/qdox-2.0.3.jar (334 kB at 29 kB/s)
[INFO] Changes detected - recompiling the module! :dependency
[INFO] Compiling 1 source file with javac [debug release 17] to target/classes
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  05:12 min
[INFO] Finished at: 2023-05-31T21:51:38+08:00
[INFO] ------------------------------------------------------------------------
Waiting for Jenkins to finish collecting data
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.11.0:compile (default-compile) on project demo: Compilation failure
[ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
[JENKINS] Archiving /root/.jenkins/workspace/first/pom.xml to com.example/demo/0.0.1-SNAPSHOT/demo-0.0.1-SNAPSHOT.pom
channel stopped
Finished: FAILURE
image-20230531215344860
image-20230531215344860

最后面告诉我们pom文件的位置为/root/.jenkins/workspace/first/pom.xml

我们可以自己执行maven命令进行构建

cd /root/.jenkins/workspace/first

/usr/local/maven/bin/mvn clean package -Dmaven.test.skip=true
image-20230531225340345
image-20230531225340345
image-20230531224859642
image-20230531224859642

能够构建成功了,再使用jenkins进行构建

image-20230531224549870
image-20230531224549870

我们可以看到jar包位置为/root/.jenkins/workspace/first/target/demo-0.0.1-SNAPSHOT.jar,我们可以进到这个目录执行这个jar包,由于jenkins默认用的也是8080端口,因此需要修改一下端口

cd /root/.jenkins/workspace/first/target/
java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8088
image-20230601103511406
image-20230601103511406

访问一下,发现可以访问成功

image-20230601104107373
image-20230601104107373

4、修改配置

如果需要修改配置,需要返回到Dashboard,点击这个名称

image-20230531214242444
image-20230531214242444

然后点击配置即可修改这次的任务配置

image-20230531214404262
image-20230531214404262
image-20230531214214192
image-20230531214214192

4、运行到测试服务器

1、添加测试服务器

我们可以安装一个Publish Over SSH插件

image-20230601104815577
image-20230601104815577

安装完成后在系统管理里,选择系统配置

image-20230601105342998
image-20230601105342998

然后一直划到最后,找到SSH Servers,点击新增

image-20230601105653028
image-20230601105653028

输入Name、主机的ip、和主机的用户名,和家目录后,点击高级

image-20230601105807088
image-20230601105807088

点击高级后,勾选Use password authentication, or use a different key,然后输入密码

image-20230601110142073
image-20230601110142073

如果需要代理服务器才能访问测试机,则还需要添加代理配置。

配置完后点击Test Configuration后出现Success就证明成功了,然后点击保存即可

image-20230601110545258
image-20230601110545258

2、修改配置

修改firstAdd post-build stepSend files or execute commands over SSH

image-20230601110709330
image-20230601110709330

我们选择刚刚添加的测试服务器;Source files默认的根目录为workspace目录,也就是/root/.jenkins/workspace/first。可以输入**/*.jar也就是上传所有的jar包

这个workspace可以在运行任务时看到

image-20230604155651253
image-20230601111251628
image-20230601111251628

最好点击Send files or execute commands over SSH里的SSH Publishers里的SSH Server里的高级

image-20230604164828148
image-20230604164828148

Verbose output in console勾选上,这样就能够看到连接ssh后执行的命令和执行命令后的结果了

image-20230604164831621
image-20230604164831621

Exec command可以简单输一个echo 1,然后点击保存。

image-20230601113059417
image-20230601113059417

点击高级,我们可以配置执行的超时时间,默认为2分钟,如果文件比较大或执行命令的时间比较长可以适当修改超时时间

image-20230601121926746
image-20230601121926746

然后再次执行一下first任务,查看控制台,可以看到文件已经传输成功了。

默认会把项目放到测试服务器的root目录下(我们前面添加测试服务器的时候指定了Remote directoryroot),例如jenkinsjar包位置为/root/.jenkins/workspace/first/target/demo-0.0.1-SNAPSHOT.jar,那上传到测试服务器的路径就为/root/target/demo-0.0.1-SNAPSHOT.jar

image-20230601112440558
image-20230601112440558

打开测试服务器,执行java -jar demo-0.0.1-SNAPSHOT.jar,可以看到已经运行成功了

测试服务器注意安装jre

yum install -y java-1.8.0-openjdk
[root@iZuf64go38e6sks55pfasaZ ~]# cd /root/target
[root@iZuf64go38e6sks55pfasaZ target]# ls
demo-0.0.1-SNAPSHOT.jar
[root@iZuf64go38e6sks55pfasaZ target]# java -jar demo-0.0.1-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.7.1)

2023-06-01 11:27:10.986  INFO 13062 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication v0.0.1-SNAPSHOT using Java 1.8.0_372 on iZuf64go38e6sks55pfasaZ with PID 13062 (/root/target/demo-0.0.1-SNAPSHOT.jar started by root in /root/target)
image-20230601112729241
image-20230601112729241

访问一下,可以发现能够访问

image-20230601120943518
image-20230601120943518

注意关闭测试服务器运行的java项目

我们可以修改Remove prefixtargetRemote directory/mydata

这样原本的/root/target/demo-0.0.1-SNAPSHOT.jar路径就变为了/root/mydata/demo-0.0.1-SNAPSHOT.jar

添加测试服务器配置的目录 + 这个构建任务配置的目录 + (/root/.jenkins/workspace/first后面的目录 - Remove prefix配置的目录前缀)】

image-20230601113721560
image-20230601113721560

然后再次构建这个任务,报了如下错误

Waiting for Jenkins to finish collecting data
[JENKINS] Archiving /root/.jenkins/workspace/first/pom.xml to com.example/demo/0.0.1-SNAPSHOT/demo-0.0.1-SNAPSHOT.pom
[JENKINS] Archiving /root/.jenkins/workspace/first/target/demo-0.0.1-SNAPSHOT.jar to com.example/demo/0.0.1-SNAPSHOT/demo-0.0.1-SNAPSHOT.jar
channel stopped
SSH: Connecting from host [iZbp1asdy4uxt0pu8ywpiqZ]
SSH: Connecting with configuration [TestServer] ...
SSH: Disconnecting configuration [TestServer] ...
ERROR: Exception when publishing, exception message [Failed to remove prefix from file named [.mvn/wrapper/maven-wrapper.jar]. Prefix [target/] must be present in all file paths]
Build step 'Send files or execute commands over SSH' changed build result to UNSTABLE
Finished: UNSTABLE
image-20230601114557764
image-20230601114557764

这是因为我们还有一个.mvn/wrapper/maven-wrapper.jar的jar包

image-20230601114648874

我们可以修改一下Source files**/target/*.jar,只传输target目录下的jar

image-20230601115219033
image-20230601115219033

重新构建就构建成功了

image-20230601115215050
image-20230601115215050

进入到测试服务器,可以发现能够正常运行

[root@iZuf64go38e6sks55pfasaZ ~]# cd /root/mydata
[root@iZuf64go38e6sks55pfasaZ mydata]# ls
demo-0.0.1-SNAPSHOT.jar
[root@iZuf64go38e6sks55pfasaZ mydata]# java -jar demo-0.0.1-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.7.1)

2023-06-01 11:51:51.500  INFO 13379 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication v0.0.1-SNAPSHOT using Java 1.8.0_372 on iZuf64go38e6sks55pfasaZ with PID 13379 (/root/mydata/demo-0.0.1-SNAPSHOT.jar started by root in /root/mydata)
image-20230601115210597
image-20230601115210597

访问一下,可以发现能够访问

image-20230601120943518
image-20230601120943518

注意关闭测试服务器运行的java项目

我们可以需改一下Exec commandnohup java -jar /root/mydata/demo*.jar &,让传输文件完成后,以后台的方式运行程序

nohup java -jar /root/mydata/demo*.jar &

如果测试服务器已经以后台运行的方式运行过这个jar包了,不管以前的jar包是否在运行再次执行都会卡住(卡住用于提示我们日志输出在默认的nohup.out文件,需要再次敲一下回车才会进入到命令输入状态),导致连接超时。下面有解决办法

输入命令后的状态

image-20230601123159908
image-20230601123159908

回车后的状态

image-20230601123228703
image-20230601123228703
image-20230601120059188
image-20230601120059188

重新构建,如果显示的为如下信息就证明成功了

[WARNING] For more or less details, use 'maven.plugin.validation' property with one of the values (case insensitive): [BRIEF, DEFAULT, VERBOSE]
[WARNING] 
Waiting for Jenkins to finish collecting data
[JENKINS] Archiving /root/.jenkins/workspace/first/pom.xml to com.example/demo/0.0.1-SNAPSHOT/demo-0.0.1-SNAPSHOT.pom
[JENKINS] Archiving /root/.jenkins/workspace/first/target/demo-0.0.1-SNAPSHOT.jar to com.example/demo/0.0.1-SNAPSHOT/demo-0.0.1-SNAPSHOT.jar
channel stopped
SSH: Connecting from host [iZbp1asdy4uxt0pu8ywpiqZ]
SSH: Connecting with configuration [TestServer] ...
SSH: Disconnecting configuration [TestServer] ...
ERROR: Exception when publishing, exception message [Exec timed out or was interrupted after 120,001 ms]
Build step 'Send files or execute commands over SSH' changed build result to UNSTABLE
Finished: UNSTABLE
image-20230601120738678
image-20230601120738678

查看测试服务器,可以看到java已经占用8080端口了,并且进程就是demo-0.0.1-SNAPSHOT.jar

[root@iZuf65a756qrqtm37hr12kZ ~]# cd /root/mydata
[root@iZuf65a756qrqtm37hr12kZ mydata]# ls
demo-0.0.1-SNAPSHOT.jar
[root@iZuf65a756qrqtm37hr12kZ mydata]# netstat -tulnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1098/sshd           
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      1954/java           
udp        0      0 127.0.0.1:323           0.0.0.0:*                           560/chronyd         
udp        0      0 0.0.0.0:68              0.0.0.0:*                           796/dhclient        
udp6       0      0 ::1:323                 :::*                                560/chronyd         
[root@iZuf65a756qrqtm37hr12kZ mydata]# jps
1954 demo-0.0.1-SNAPSHOT.jar
11908 Jps
image-20230601121527358
image-20230601121527358

访问一下测试服务器的8080端口,可以直接访问

image-20230601120911765
image-20230601120911765

3、优化配置

1、防止后台运行卡住

如果测试服务器已经以后台运行的方式运行过这个jar包了,不管以前的jar包是否在运行再次执行都会卡住(卡住用于提示我们日志输出在默认的nohup.out文件,需要再次敲一下回车才会进入到命令输入状态),而执行如下命令指定输出的文件可以让程序不会被卡住

数据流重定向 数据流重定向就是将某个命令执行后应该要出现在屏幕上的数据传输到其他地方 标准输入(stdin) :代码为0,使用<或<<; 标准输出(stdout) :代码为1,使用>或>>;(>表示覆盖,>>表示追加) 标准错误输出(stderr) :代码为2,使用2>或2>>

nohup java -jar /root/mydata/demo*.jar >mylog.log 2>&1 &

# 或者执行以下简化写法
nohup java -jar /root/mydata/demo*.jar &>mylog.log &
image-20230601123905850
image-20230601123905850

修改一下Post Steps即可

image-20230601141046408
image-20230601141046408

2、清理以前的文件

我们在执行构建之前还需要清理以前的文件,并把之前运行的程序停掉,因此我们需要使用shell脚本来完成这个功能

执行shell脚本的难点在于如何获取到那个java程序的pid

我们可以执行ps -ef | grep demo命令筛选有demo,可以看到执行命令后有两个结果,一个是java,另一个是grep

我们可以再次执行ps -ef | grep demo | grep 'java -jar'命令在筛选出有java -jar的,这样就只有一个结果了

或者我们可以执行ps -ef | grep demo | grep -v grep命令过滤掉带有grep的,grep -v是执行过滤操作,与grep相反

然后再执行ps -ef | grep demo | grep 'java -jar' | awk '{printf $2}',获取第二列的结果就获取到这个pid了

[root@iZbp1asdy4uxt0pu8ywpiqZ ~]# cd /root/mydata
[root@iZbp1asdy4uxt0pu8ywpiqZ mydata]# ps -ef | grep demo
root     23693     1  1 21:45 ?        00:00:06 java -jar /root/mydata/demo-0.0.1-SNAPSHOT.jar
root     23736 23393  0 21:55 pts/2    00:00:00 grep --color=auto demo
[root@iZbp1asdy4uxt0pu8ywpiqZ mydata]# ps -ef | grep demo | grep 'java -jar'
root     23693     1  1 21:45 ?        00:00:06 java -jar /root/mydata/demo-0.0.1-SNAPSHOT.jar
[root@iZbp1asdy4uxt0pu8ywpiqZ mydata]# ps -ef | grep demo | grep -v grep
root     23693     1  1 21:45 ?        00:00:06 java -jar /root/mydata/demo-0.0.1-SNAPSHOT.jar
[root@iZbp1asdy4uxt0pu8ywpiqZ mydata]# ps -ef | grep demo | grep 'java -jar' | awk '{printf $2}'
23693[root@iZbp1asdy4uxt0pu8ywpiqZ mydata]# 
image-20230601215728390
image-20230601215728390

因此我们可以在测试服务器的/root目录下新增x.sh文件,内容为如下(我们可以在root目录下执行./x.sh demo命令删除文件并杀死进程)

注意将x.sh文件的访问权限修改为777

chmod 777 x.sh
# 声明使用bash执行命令,按照规范应该添加
#!/bin/bash

# 删除/root/mydata目录里的文件
rm -rf /root/mydata/*

# 获取传进来的第一个参数,将值赋给appname
appname=$1

# 获取pid,注意等号前后没有空格
pid=`ps -ef | grep $1 | grep 'java -jar' | awk '{printf $2}'`
# 输出pid
echo $pid

# 如果pid为空,提示一下,否则执行kill命令。注意"-z $pid"前后都要留空格
if [ -z $pid ];
# 使用-z 做空值判断
    then
        echo "$appname not started"
    else
        kill -9 $pid
        echo "$appname stoping..."
# 闭口(结束if)
fi
# -w表示精确匹配,防止误杀其他含有该数字的进程
check=`ps -ef | grep -w $pid | grep java`

if [ -z $check ];
# 使用-z 做空值判断
    then
        echo "$appname pid:$pid is stop"
    else
        echo "$appname stop failed"
# 闭口(结束if)
fi

可以看到执行这个脚本能够杀死指定的进程,并删除/root/mydata里的文件

[root@iZbp1asdy4uxt0pu8ywpiqZ ~]# jps
23859 Jps
15196 war
23693 demo-0.0.1-SNAPSHOT.jar
[root@iZbp1asdy4uxt0pu8ywpiqZ ~]# ./x.sh demo
23693
demo stoping...
demo pid:23693 is stop
[root@iZbp1asdy4uxt0pu8ywpiqZ ~]# jps
23884 Jps
15196 war
[root@iZbp1asdy4uxt0pu8ywpiqZ ~]# cd /root/mydata
[root@iZbp1asdy4uxt0pu8ywpiqZ mydata]# ls
[root@iZbp1asdy4uxt0pu8ywpiqZ mydata]
image-20230601221235498
image-20230601221235498

我们在构建之前还需要将前面构建的程序停止,并且删掉前面上传的文件,我们可以在Pre Steps里执行命令,做一些构建之前的事情

image-20230601142010683
image-20230601142010683

修改Exec command./x.sh demoSource files报红不用管,至少填写Source filesExec command其中一个即可,然后点击保存,然后再次测试可以发现已经能将/root/mydata里的文件删掉,并将以前的程序停掉,构建成功后,能够自动运行程序。

image-20230601150801730
image-20230601150801730

最好点击Send files or execute commands over SSH里的SSH Publishers里的SSH Server里的高级

image-20230604165225912
image-20230604165225912

Verbose output in console勾选上,这样就能够看到连接ssh后执行的命令和执行命令后的结果了

image-20230604165231604
image-20230604165231604

4、提交代码后自动构建

我们这个任务的构建触发器里勾选触发远程构建,然后配置身份验证令牌,然后浏览器访问JENKINS_URL/job/first/build?token=TOKEN_NAME(也就是 http://121.40.49.203:8888/job/first/build?token=123123 )

image-20230601152212021
image-20230601152212021

可以看到当同一个浏览器访问 http://121.40.49.203:8888/job/first/build?token=123123 后,会执行这个任务

image-20230601152250731
image-20230601152250731

但是当其他浏览器访问时,会提示我们需要进行登录

image-20230601152458382
image-20230601152458382

为了解决这个问题我们需要安装Build Authorization Token Root这个插件

image-20230601221828874
image-20230601221828874

安装插件完成后,需要将url修改为buildByToken/build?job=NAME&token=SECRET

image-20230601222418685
image-20230601222418685

也就是 http://121.40.49.203:8888/buildByToken/build?job=first&token=123123open in new window 就可以匿名访问了

image-20230601222309534
image-20230601222309534

然后在项目的设置里点击Webhooks,输入URL,勾选推送事件合并请求事件,取消勾选启用SSL验证,然后点击添加Webhooks即可

(工作中最好使用推送到指定的分支合并请求事件不推荐,因为合并请求事件已有的合并请求被更新有新的合并请求被创建合并请求被合并时都会触发。只不过为了测试方便我们勾选了推送所有分支事件合并请求事件

image-20230601223045058
image-20230601223045058

如果使用的是本地的url,会报Url is blocked: Requests to the local network are not allowed的错误

image-20230601223652293
image-20230601223652293

我们可以切换到管理员身份,然后在设置 -> 网路里,把允许来自web hooks和服务对本地网络的请求勾上

image-20230601223901931
image-20230601223901931

我们可以点击测试里的推送事件,可以看到已经能够自动化运行了

image-20230601224257011
image-20230601224257011

我们修改一下接口返回的内容,然后提交代码后,可以发现能够自动化构建

GIF 2023-6-1 22-46-55.gif
GIF 2023-6-1 22-46-55.gif

访问一下就可以访问成功了,返回的内容也修改了

如果自动构建成功,但是请求返回的内容没有改变,有可能是因为jenkins里拉取的是main分支,而提交的是master分支。我们可以修改一下拉取的分支,或者将master分支合并到main分支

image-20230601224257012
image-20230601224257012

5、其他自动化构建方式

  • Build whenever a SNAPSHOT dependency is built:当依赖的快照版本库被构建时,构建此任务

假设您正在开发一个Java Web应用程序,并且您的应用程序依赖于一个名为"my-lib"的Maven库。在您的项目的pom.xml文件中,您将指定"my-lib"库的版本号为1.0-SNAPSHOT。每当您在"my-lib"库的源代码中进行更改并构建该库时,Jenkins将自动触发您的应用程序构建作业。这对于确保您的应用程序与最新版本的"my-lib"库兼容非常有用。如果您没有使用SNAPSHOT依赖项,那么您将需要手动触发构建作业以确保您的应用程序与最新版本的"my-lib"库兼容。

image-20230602202221171
image-20230602202221171
  • 触发远程构建:当gitlab上有提交、合并等事件时,gitlab调用我们配置的jenkins接口,以完成构建
image-20230602202806513
image-20230602202806513
  • 其他工程构建后触发:当父项目构建后,构建此子项目(或者其他项目构建完成后,想构建此项目,不一定是父子项目)
image-20230602203024732
image-20230602203024732
  • 定时构建:使用corn表达式,定时进行构建
image-20230602203310126
image-20230602203310126
  • GitHub hook trigger for GITScm polling:跟我们前面的gitlab类似,当github上有提交、合并等事件时,github调用我们配置的jenkins接口,以完成构建
image-20230602203341540
image-20230602203341540
  • 轮询 SCM:jenkins主动定时查看git服务器的jenkins拉取的分支的代码有没有更改,如果有更改则进行构建
image-20230602203450435
image-20230602203450435

标准的corn表达式网站: https://crontab.guru/

corn有很多种,标准的corn表达式有5个参数,最多的有7个参数依次为 <秒> <分> <小时> <日> <月> <星期> <年>

名称允许值特殊值
0-59*,-/
0-59*,-/
0-23*,-/
每月第几天1-31*,-/
1-12 或 JAN-DEC*,-/
每周第几天0-6 (7:不标准的周日) 或 SUN-SAT*,-/
1970-2099*,-/

*:表示任意,例如 * * * * * * *每秒执行一次,0 * * * * * *当秒值为0,其他为任意时执行

,:使用逗号分割多组,例如 0,10 * * * * * *当秒值为0或10,其他为任意时执行

-:表示范围,例如0 0 0 * * 1-6 *0 0 0 * * MON-SAT * 表示周一到周六各执行一次,每周共六次。

0 0 0 0 1-6,10-12 * *:1-6月10-12月各执行一次,共9次(表达式的1-6,10-12表示1到6月或6到12月共9个月)

/:表示每隔一段时间执行一次,例如*/5 * * * * * *表示每隔5秒执行一次

*/10 * * * * * * (标准)表示每隔10秒执行一次任务。(一般是从0秒开始)

0/10 * * * * * * (不标准)表示从每分钟的0秒开始,每隔10秒执行一次任务

1/10 * * * * * * (不标准)表示从每分钟的1秒开始,每隔10秒执行一次任务

0-20/5 * * * * * * (标准)表示0-20秒之间,从0秒开始每隔5秒执行一次,即当秒为 0 5 10 15 20 时执行一次

1-20/5 * * * * * * (标准)表示1-20秒之间,从1秒开始每隔5秒执行一次,即当秒为 1 6 11 16 时执行一次

0/10 不是标准的corn表达式,使用 */100/10 可能会产生略微不同的行为,但在大多数情况下,它们的效果是相同的。

SUN-SAT为如下意义:

  • SUN:代表Sunday(星期日)
  • MON:代表Monday(星期一)
  • TUE:代表Tuesday(星期二)
  • WED:代表Wednesday(星期三)
  • THU:代表Thursday(星期四)
  • FRI:代表Friday(星期五)
  • SAT:代表Saturday(星期六)

JAN-DEC为如下意义:

  • JAN:代表January(一月)
  • FEB:代表February(二月)
  • MAR:代表March(三月)
  • APR:代表April(四月)
  • MAY:代表May(五月)
  • JUN:代表June(六月)
  • JUL:代表July(七月)
  • AUG:代表August(八月)
  • SEP:代表September(九月)
  • OCT:代表October(十月)
  • NOV:代表November(十一月)
  • DEC:代表December(十二月)

定时任务

jenkins支持的corn有五个参数:<分> <小时> <日> <月> <星期>

由于*/10 * * * *每隔10分钟执行一次,这样会导致所有任务都在同一刻触发,因此jenkins引入了H,即任务名的hash值,我们可以配置为H(0-5)/10 * * * *,这样会每隔10分钟执行一次但是每个任务的开始时间不一样,但都在0-5(左闭右闭)之间,这样可以防止同一时刻运行大量任务

任务名不变H(0-5)去的值就不会变

1/10 * * * *:从1分钟开始每隔10分钟执行一次,1 11 21 31 41 51 分钟会执行

H * * * *:每月每天每小时的某一分钟执行一次,比如 在分钟为 26 的时候执行一次

H(0-5)/10 * * * *:每隔10秒执行一次,但开始分钟数是在0-5之间。比如分钟数在0 10 20 30 40 501 11 21 31 41 515 15 25 35 45 55 等会执行

在 Jenkins 的 cron 表达式中,H(0-5)/10 * * * * 表示的是一个任务在每小时的 0 到 5 分钟之间,按照 10 分钟的间隔触发一次。这里的 0-5 是左闭右闭的区间,即包含 0 和 5 这两个数字。

这个表达式中的 H 是一个哈希化的取值,它将任务的名称或其他唯一标识符映射到 0 到 5 之间的一个值,然后将结果除以 10。这样可以将任务均匀地分布在这个时间区间内,避免了所有任务都在同一时间开始执行。

因此,H(0-5)/10 * * * * 的含义是:在每小时的 0 到 5 分钟之间,基于任务名称的哈希值和 10 分钟间隔,触发一次任务。

Cron表达式结构 1.Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义。 2.Corn从左到右(用空格隔开):{秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)}。

Cron字段值范围 1.{秒数}:值【0-59】或特殊字符【, - * /】 2.{分钟}:值【0-59】或特殊字符【, - * /】 3.{小时}:值【0-23】或特殊字符【, - * /】 4.{日期}:值【1-31】或特殊字符【,- * ? / L W C】 5.{月份}:值【1-12】或特殊字符【, - * /】 6.{星期}:值【0-6】或【SUN-SAT】(0或7都是SUN)或特殊字符【, - * ? / L C #】 7.{年份}:值【1970~2099】或特殊字符【, - * /】

Cron特殊字符解释 1.【】:表示匹配该域的任意值。假如在{分钟}域使用, 即表示每分钟都会触发事件。 2.【?】:只能用在{日期}{星期}两个域。它也匹配域的任意值,但实际不会。因为{日期}和{星期}会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。 3.【-】:表示范围。例如在{分钟}域使用5-20,表示从5分到20分钟每分钟触发一次。 4.【/】:表示起始时间开始触发,然后每隔固定时间触发一次。例如在{分钟}域使用5/20,则意味着5分钟触发一次,然后隔20s触发,即25,45等分别触发一次。 5.【,】:表示列出枚举值。例如:在{分钟}域使用5,20,则意味着在5和20分每分钟触发一次。 6.【L】:表示最后,只能出现在{星期}和{日期}域。如果在{星期}域使用5L,意味着在最后的一个星期五触发。如果在{日期}域使用L,意味着在每月的最后一天触发 7.【W】:表示有效工作日(周一到周五),只能出现在{日期}域,系统将在离指定日期的最近的有效工作日触发事件。例如:在{日期}使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份。 8.【LW】:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。 9.【#】:用于确定每个月第几个星期几,只能出现在{日期}域。例如在4#2,表示某月的第二个星期四。

5、邮箱通知

目标:使用网易邮箱的SMTP服务,给qq邮箱发送消息

1、开启SMTP服务

点击网易邮箱的设置里的POP3/SMTP/IMAP,开启POP3/SMTP服务

image-20230603111435058
image-20230603111435058

点击继续开启

image-20230603111454990
image-20230603111454990

可以使用浏览器或者其他软件扫描二维码,然后跳转到短信,然后点击发送即可

image-20230603111440287
image-20230603111440287

或者可以点击手动发送短信,自己手输电话号和短信内容

image-20230603111501507
image-20230603111501507

发送完成后,点击我已发送就会出来一个授权码,复制该授权码

BBCAQKAKUXWTQDVD
image-20230603111604842
image-20230603111604842

2、配置管理员邮箱

在jenkins的系统管理 -> 系统配置里的Jenkins Location里输入自己的系统管理员邮件地址

image-20230603112038438
image-20230603112038438

3、添加自定义邮件服务

然后在Extended E-mail Notification里添加smtp服务器地址,这里添加的是自定义的邮箱通知

如果没有,是因为没有安装推荐的插件,可以下载Email Extension这个插件

image-20230603112921340
image-20230603112921340

SMTP服务器地址在邮件服务商的POP3/SMTP/IMAP的相关位置都会写

image-20230603112936313

然后点击高级,选择添加Jenkins凭据提供者

image-20230603113838106
image-20230603113838106

然后输入用户名和密码

注意这里的密码是给的用户凭证,不是邮箱的密码

image-20230603114041605
image-20230603114041605

然后选择刚刚添加的邮箱

image-20230603114324109
image-20230603114324109

我们可以在Default Content里定制化一些内容

image-20230603114443493
image-20230603114443493

如果使用的是国内的邮件服务器默认禁止使用25端口,因此我们需要修改SMTP端口为465,并勾选Use SSL,以使用SSL进行连接

image-20230603211133292
image-20230603211133292

可以在Default Triggers里配置哪些情况下会被触发

image-20230603114550984
image-20230603114550984

4、添加系统级邮件服务

在邮件通知里俗人SMTP服务器,然后点击高级

image-20230603115106242
image-20230603115106242

然后勾选使用SMTP认证

然后输入用户名和密码

注意这里的密码是给的用户凭证,不是邮箱的密码

image-20230603114836170
image-20230603114836170

可以点击通过发送测试邮件测试配置,填写qq邮箱地址进行测试

我的机器部署在阿里云上,报了如下错误

Caused: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.163.com, 25; timeout 60000;
  nested exception is:
	java.net.SocketTimeoutException: connect timed out
image-20230603120359248
image-20230603120359248

我以为是安全组的问题,所以添加了如下安全组(其实添加安全组没什么用,安全组是配置别人允许访问我们哪些端口,而SMTP是我们使用我们的25端口访问别人的服务)

image-20230603121510383
image-20230603121510383

然后还是报错,测试一下连接,发现阿里云禁用了25号端口。可以申请25号端口解封,不过大部分都会被拒绝

image-20230603123435539
image-20230603123435539

我们可以使用ssl465端口(其实配不配都无所谓,安全组是配置别人允许访问我们哪些端口,而SMTP是我们使用我们的465端口(ssl加密)访问别人的服务)

image-20230603123255090
image-20230603123255090

我们可以勾选使用SSL协议SMTP端口修改为465,再次测试就显示发送邮件成功了

image-20230603205204408
image-20230603205204408

登录qq邮箱,已经接收到邮件了

image-20230603205242043
image-20230603205242043

因此,我们还要修改前面配置的自定义邮件服务的SMTP端口为465,并勾选Use SSL

image-20230603211133292
image-20230603211133292

我在阿里云ECS上安装了Jenkins,然后使用163邮箱的哦邮件服务器给qq邮箱发送邮件,那么jenkins与邮件服务器通讯时双方使用的分别是什么端口?邮件服务器与qq邮箱通讯时双方使用的分别是什么端口?

在阿里云ECS上安装的Jenkins与163邮箱服务器通信时,通常会使用以下端口:

  1. SMTP(Simple Mail Transfer Protocol)协议用于发送邮件。对于163邮箱,通常使用的端口有25(非加密)、465(SSL加密)和994(TLS加密)。Jenkins可能会使用这些端口之一发送邮件到163邮箱服务器。

  2. IMAP(Internet Message Access Protocol)协议用于接收邮件。对于163邮箱,通常使用的端口有143(非加密)和993(SSL加密)。Jenkins可能会使用这些端口之一从163邮箱服务器接收邮件。

在163邮箱服务器与qq邮箱通信时,通常会使用以下端口:

  1. SMTP协议用于发送邮件。对于qq邮箱,通常使用的端口有25(非加密)、465(SSL加密)和587(TLS加密)。163邮箱服务器可能会使用这些端口之一发送邮件到qq邮箱。

  2. IMAP协议用于接收邮件。对于qq邮箱,通常使用的端口有143(非加密)和993(SSL加密)。163邮箱服务器可能会使用这些端口之一从qq邮箱接收邮件。

需要注意的是,在实际应用中,端口的使用可能会受到网络环境、防火墙策略等因素的影响。请根据实际情况选择合适的端口。

5、添加任务构建后操作

然后修改我们的first任务,在构建后操作里,点击增加构建后操作步骤,选择Editable Email Notihcation

image-20230603211718848
image-20230603211718848

然后点击Advanced Settings...

image-20230603211857761
image-20230603211857761

然后在TriggersAlwaysFailure - AnySuccessSend To里都添加上Build User

image-20230603212036386
image-20230603212036386
image-20230603212039466
image-20230603212039466
image-20230603212042053
image-20230603212042053

6、测试

然后我们构建first项目,在控制台可以看到已经将构建的信息发送邮箱了,这个邮箱就是最开始初始化jenkins时配置的邮箱

image-20230603213404623
image-20230603213404623

此时邮件已经收到消息了

image-20230604142629810
image-20230604142629810

如果想要修改邮箱,可以点击自己用户名右边的设置

image-20230603212655694
image-20230603212655694

下滑找到E-mail,在这里可以修改我们的邮箱

image-20230603213011284
image-20230603213011284

6、使用docker

一般使用jenkins自动化运行到docker有3种方式

第一种(小型公司):可以让docker容器的某个目录挂载到宿主主机的某个目录,然后我们使用jenkins停止docker容器,删除宿主主机的目录里的jar文件并推送新的jar文件,最后再重启dokcer容器即可,这种方式比较轻量、简单,适合比较小的项目

第二种(中型公司):使用jenkins推送dockerfilejar包,然后再制作镜像、生成容器、运行容器。这种方式比较重量,但非常适合云原生环境。

第三种(大厂):使用jenkins推送dockerfilejar包,然后制作镜像,将镜像推送到harbor私服里,然后再使用k8s构建docker集群

方式一

1、挂载目录

方式一(推荐)

我们需要在测试服务器上安装好docker,然后运行一个docker容器

如果镜像创建失败,可以使用如下命令,运行一个临时的容器,并设置执行/bin/bash进入控制台,当关闭后容器将被删除

docker run --rm -it --entrypoint=/bin/bash image-name

我们可以在/root目录下创建dockerfile文件,然后引入/root/mydata目录下的demo-0.0.1-SNAPSHOT.jar文件,之所以要将dockerfile文件放在/root目录下,是因为jenkins在向测试服务器发送jar包之前,会将/root/mydata目录里的文件都删掉

注意1:在宿主机的/root/mydata目录下,要有一个遵循demo*.jar通配符的文件,比如demo-0.0.1-SNAPSHOT.jar。如果写成ADD mydata/demo*.jar /root/demo01.jar那么只允许有一个匹配通配符的文件。如果想要复制多个jar包可以写为ADD mydata/demo*.jar /root/即将匹配的文件全部放到/root目录下,不过执行java -jar /root/demo*.jar也只能运行第一个匹配的jar包

注意2:由于ENTRYPOINT命令不能使用通配符,也就是不能写成ENTRYPOINT ["java","-jar","/root/demo*.jar"]这样,即不能直接运行java -jar /root/demo*.jar这个命令。因此可以指定为ENTRYPOINT ["sh", "-c", "java -jar /root/demo*.jar"]这样,即运行sh - c 'java -jar /root/demo*.jar',这样运行sh命令就没有通配符了(我们使用通配符的目的就是为了在更新版本信息后仍能运行这个项目)

在root目录下编写 dockerfile 文件

FROM openjdk:11
EXPOSE 8080

WORKDIR /root

ADD mydata/demo*.jar /root/demo01.jar
ENTRYPOINT ["sh", "-c", "java -jar /root/demo*.jar"]

然后在root目录构建镜像

docker build -t demo .

然后使用这个镜像运行一个容器

docker run -d --name demo -p 8080:8080 -v /root/mydata:/root demo

使用如下命令查看所有容器

docker ps -a
方式二(不推荐)

我们可以使用如下命令直接启动一个容器,而不需要镜像,这样的缺点就是当我们变更版本后,需要在jenkins里修改这个命令

docker run -d --name demo -p 8080:8080 -v /root/mydata/demo-0.0.1-SNAPSHOT.jar:/app.jar openjdk:11 java -jar app.jar

2、修改jenkins任务

修改first任务的Pre Steps的Exec command,先停止容器,然后移除/root/mydata里的文件

docker stop demo
rm -rf /root/mydata/*

如果是方式二,我们还需要

docker stop demo
rm -rf /root/mydata/*
docker rm demo
docker rmi demo
image-20230604160808649
image-20230604160808649

然后修改first任务的Post Steps的Exec command,启动demo容器

docker start demo
image-20230604155059562
image-20230604155059562

3、修改版本

我们可以再我们的项目里修改一下版本

image-20230604180055473
image-20230604180055473

然后修改一下hello接口的返回内容

image-20230604180136531
image-20230604180136531

此时直接提交代码并构建jenkins任务会发现jenkins会向测试服务器发送demo-0.0.1-SNAPSHOT.jardemo-0.0.2-SNAPSHOT.jar两个文件

image-20230604180438838
image-20230604180438838

这是因为我们在更改版本号后,没有执行mvn clean命令,导致target目录里面原来的文件没有删除

[root@iZbp1asdy4uxt0pu8ywpiqZ ~]# cd /root/.jenkins/workspace/first
[root@iZbp1asdy4uxt0pu8ywpiqZ first]# cd target
[root@iZbp1asdy4uxt0pu8ywpiqZ target]# ls
classes                           demo-0.0.2-SNAPSHOT.jar           generated-test-sources  surefire-reports
demo-0.0.1-SNAPSHOT.jar           demo-0.0.2-SNAPSHOT.jar.original  maven-archiver          test-classes
demo-0.0.1-SNAPSHOT.jar.original  generated-sources                 maven-status
image-20230604174002294
image-20230604174002294

就像我们在IDEA里执行isntall命令一样,并不会删除target文件里的目录

image-20230604174946549

如果我们使用IDEA,可以运行cleaninstall命令,但是jenkins不行啊。因此我们可以给项目添加一个maven-clean-plugin插件(添加后别忘了提交代码到远程仓库)

<plugin>
    <artifactId>maven-clean-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <id>auto-clean</id>
            <phase>initialize</phase>
            <goals>
                <goal>clean</goal>
            </goals>
        </execution>
    </executions>
</plugin>
image-20230604180848505
image-20230604180848505

这样直接执行install命令就能将target目录里的文件删除了

image-20230604180958491

4、测试

修改版本前:

[root@iZuf67qk2gigu0s3sn5fs2Z mydata]# pwd
/root/mydata
[root@iZuf67qk2gigu0s3sn5fs2Z mydata]# ls
demo-0.0.1-SNAPSHOT.jar
[root@iZuf67qk2gigu0s3sn5fs2Z mydata]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
f3b80165733e        demo                "sh -c 'java -jar ..."   24 seconds ago      Up 23 seconds       0.0.0.0:8080->8080/tcp   demo
image-20230604175234428
image-20230604175234428
image-20230604175237547
image-20230604175237547

修改版本后:可以看到修改版本后jar包名修改了,接口返回的内容也修改了

[root@iZuf67qk2gigu0s3sn5fs2Z ~]# cd /root/mydata
[root@iZuf67qk2gigu0s3sn5fs2Z mydata]# ls
demo-0.0.2-SNAPSHOT.jar
[root@iZuf67qk2gigu0s3sn5fs2Z mydata]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
f3b80165733e        demo                "sh -c 'java -jar ..."   27 minutes ago      Up 3 minutes        0.0.0.0:8080->8080/tcp   demo
image-20230604175237546
image-20230604175237546
image-20230604175237548
image-20230604175237548

方式二

image-20230604182856330
image-20230604182856330
image-20230605213934828
image-20230605213934828
docker stop demo
docker rm demo
docker rmi demo
rm -rf /root/mydata/*
image-20230604183308293
image-20230604183308293

删除Exec command,然后点击Add Transfer Set

image-20230604183012771
image-20230604183012771

然后我们再添加一个

注意:我们把dockerfile文件放到了/root/mydata目录下,由于执行命令是在/root目录,因此创建镜像时文件的路径为./mydata,也就是/root/mydata(使用这种方式dockerfile文件)

docker build -t demo ./mydata
docker run -d --name demo -p 8080:8080 -v /root/mydata:/root demo
image-20230604183523519
image-20230604183523519
SSH: EXEC: STDOUT/STDERR from command [docker build -t demo ./mydata
docker run -d --name demo -p 8080:8080 -v /root/mydata:/root demo] ...
SSH: EXEC: connected
Sending build context to Docker daemon 17.62 MB

Step 1/5 : FROM openjdk:11
 ---> 47a932d998b7
Step 2/5 : EXPOSE 8080
 ---> Using cache
 ---> 03e0f935f99b
Step 3/5 : WORKDIR /root
 ---> Using cache
 ---> bfd8401bbd46
Step 4/5 : ADD mydata/demo*.jar /root/demo01.jar
No source files were specified
image-20230605213420809
image-20230605213420809
[root@iZuf606rgryt1n8gpd88spZ ~]# docker build -t demo ./mydata
Sending build context to Docker daemon 17.62 MB
Step 1/5 : FROM openjdk:11
 ---> 47a932d998b7
Step 2/5 : EXPOSE 8080
 ---> Using cache
 ---> 03e0f935f99b
Step 3/5 : WORKDIR /root
 ---> Using cache
 ---> bfd8401bbd46
Step 4/5 : ADD mydata/demo*.jar /root/demo01.jar
No source files were specified
[root@iZuf606rgryt1n8gpd88spZ ~]# mv /root/mydata/dockerfile /root
[root@iZuf606rgryt1n8gpd88spZ ~]# ls
dockerfile  mydata  userdata.txt
[root@iZuf606rgryt1n8gpd88spZ ~]# docker build -t demo .
Sending build context to Docker daemon 17.63 MB
Step 1/5 : FROM openjdk:11
 ---> 47a932d998b7
Step 2/5 : EXPOSE 8080
 ---> Using cache
 ---> 03e0f935f99b
Step 3/5 : WORKDIR /root
 ---> Using cache
 ---> bfd8401bbd46
Step 4/5 : ADD mydata/demo*.jar /root/demo01.jar
 ---> b83170d78500
Removing intermediate container 5a2207342fd3
Step 5/5 : ENTRYPOINT sh -c java -jar /root/demo*.jar
 ---> Running in 90c90c3f35fb
 ---> 2e2fafb48f27
Removing intermediate container 90c90c3f35fb
Successfully built 2e2fafb48f27
image-20230605212338143
image-20230605212338143
[root@iZuf606rgryt1n8gpd88spZ ~]# cat dockerfile
FROM openjdk:11
EXPOSE 8080

WORKDIR /root/mydata

ADD demo*.jar /root/demo01.jar
ENTRYPOINT ["sh", "-c", "java -jar /root/demo*.jar"]
[root@iZuf606rgryt1n8gpd88spZ ~]# pwd
/root
[root@iZuf606rgryt1n8gpd88spZ ~]# mv dockerfile /root/mydata
[root@iZuf606rgryt1n8gpd88spZ ~]# docker build -t demo ./mydata
Sending build context to Docker daemon 17.62 MB
Step 1/5 : FROM openjdk:11
 ---> 47a932d998b7
Step 2/5 : EXPOSE 8080
 ---> Using cache
 ---> 03e0f935f99b
Step 3/5 : WORKDIR /root/mydata
 ---> 79603f738a13
Removing intermediate container ba959f26dbd4
Step 4/5 : ADD demo*.jar /root/demo01.jar
 ---> c5fd5e65e95a
Removing intermediate container d713f88c14be
Step 5/5 : ENTRYPOINT sh -c java -jar /root/demo*.jar
 ---> Running in dbcbcedaef22
 ---> ff3f7cf42fb7
Removing intermediate container dbcbcedaef22
Successfully built ff3f7cf42fb7

image-20230605212734741image-20230605212734883

我们可以修改项目的docker/dockerfile文件,并将修改推送到远程仓库

FROM openjdk:11
EXPOSE 8080

WORKDIR /root/mydata

ADD demo*.jar /root/demo01.jar
ENTRYPOINT ["sh", "-c", "java -jar /root/demo*.jar"]
image-20230605213526696
image-20230605213526696
image-20230605234615822
image-20230605234615822
[root@iZbp1asdy4uxt0pu8ywpiqZ ~]# cd mydata
[root@iZbp1asdy4uxt0pu8ywpiqZ mydata]# ls
demo-0.0.2-SNAPSHOT.jar  dockerfile  mydata
[root@iZbp1asdy4uxt0pu8ywpiqZ mydata]# docker exec -it demo /bin/bash
root@d4ed0b5a958b:~/mydata# ls
root@d4ed0b5a958b:~/mydata# cd ..
root@d4ed0b5a958b:~# ls
demo-0.0.2-SNAPSHOT.jar  dockerfile  mydata
image-20230606085930623
image-20230606085930623
image-20230605234615821
image-20230605234615821
Step 5/5 : ENTRYPOINT sh -c java -jar /root/demo*.jar
 ---> Running in 9275b8925c41
 ---> 8d3794f4c2cc
Removing intermediate container 9275b8925c41
Successfully built 8d3794f4c2cc
0ac00e88c033163b83365203b93067253b8ba4e734003657517f9ca309c4d938
/usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:290: starting container process caused "chdir to cwd (\"/root/mydata\") set in config.json failed: no such file or directory".
image-20230605221128662
image-20230605221128662
[root@iZuf606rgryt1n8gpd88spZ ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@iZuf606rgryt1n8gpd88spZ ~]# docker run -d --name demo -p 8080:8080 -v /root/mydata:/root demo
83683fc622777c5b2855cedf22250d5c301f837d814e982439d3472c43971308
/usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:290: starting container process caused "chdir to cwd (\"/root/mydata\") set in config.json failed: no such file or directory".
image-20230605222220917
image-20230605222220917

7、集群

image-20230604201147685
image-20230604201147685

新建节点

image-20230604201209903
image-20230604201209903

Number of executors 为当前节点允许的并发执行的个数

image-20230604203931942
image-20230604203931942

指定远程工作目录和标签,标签比较有用,以后我们指定在哪台机器上运行时,可以使用标签

image-20230604201550734
image-20230604201550734

在这里输入登录这台主机的用户名和密码

image-20230604201748131
image-20230604201748131

然后选择我们刚刚添加的,再点击报错即可

image-20230604201845913
image-20230604201845913
image-20230604202034839
image-20230604202034839

我们点击这个节点,在日志里就可以看到这台主机正在干嘛

image-20230604202047284
image-20230604202047284

再添加一个节点

image-20230604202359111
image-20230604202359111

指定远程工作目录和标签,标签比较有用,以后我们指定在哪台机器上运行时,可以使用标签

image-20230604201550734
image-20230604201550734

在这里输入登录这台主机的用户名和密码

image-20230604201748131
image-20230604201748131

注意选择最下面的这个凭证

image-20230604203319250
image-20230604203319250
[06/04/23 20:28:45] [SSH] WARNING: No entry currently exists in the Known Hosts file for this host. Connections will be denied until this new host and its associated key is added to the Known Hosts file.
Key exchange was not finished, connection is closed.
SSH Connection failed with IOException: "Key exchange was not finished, connection is closed.", retrying in 15 seconds. There are 1 more retries left.
Searching for 139.196.238.44 in /root/.ssh/known_hosts
Searching for 139.196.238.44:22 in /root/.ssh/known_hosts
[06/04/23 20:29:00] [SSH] WARNING: No entry currently exists in the Known Hosts file for this host. Connections will be denied until this new host and its associated key is added to the Known Hosts file.
Key exchange was not finished, connection is closed.
ERROR: Connection is not established!
java.lang.IllegalStateException: Connection is not established!
	at com.trilead.ssh2.Connection.getRemainingAuthMethods(Connection.java:988)
	at com.cloudbees.jenkins.plugins.sshcredentials.impl.TrileadSSHPasswordAuthenticator.canAuthenticate(TrileadSSHPasswordAuthenticator.java:83)
image-20230604203047664
image-20230604203047664
image-20230604203131546
image-20230604203131546
image-20230604203207585
image-20230604203207585
image-20230604205336138
image-20230604205336138

我们可以选择在必要的时候并发构建,这样就会随机分配一个节点

image-20230604210027848
image-20230604210027848

让我们点击多次,可以看到这些任务能够并发构建

image-20230604210331879
image-20230604210331879

我们还可以选择限制项目的运行节点,这样就只在jenkins-02jenkins-03中的一个节点运行了

jenkins-02  || jenkins-03
image-20230604205928263
image-20230604205928263
image-20230604205959551
image-20230604205959551

mypipeline

pipeline:整条流水线
agent:指定执行器
stages:所有阶段
stage:某一阶段,可有多个
steps:阶段内的每一步, 可执行命令
image-20230604210756288
image-20230604210756288
pipeline {
    agent any

    stages {
        stage('拉取代码') {
            steps {
                echo '拉取成功'
            }
        }
		
		stage('执行构建') {
            steps {
                echo '构建完成'
            }
        }
    }
}

取消使用 Groovy 沙盒的选中状态,然后点击保存

image-20230604211657437
image-20230604211657437

然后执行这个任务,再点击这个任务即可看到执行的这一次构建所使用的时间

image-20230604212053796
image-20230604212053796

点击这个构建,然后点击Console Output,可以看到控制台信息,而且这个控制台信息可以点击

image-20230604212314611
image-20230604212314611

我们还可以从指定阶段重新运行

image-20230604212406109
image-20230604212406109

我们可以下载Blue Ocean这个插件,这个插件有更加友好的界面和更加丰富的功能

image-20230604212623896
image-20230604212623896

我们点击打开 Blue Ocean就能看到非常美观的页面

image-20230604212759466
image-20230604212759466
image-20230604212955452
image-20230604212955452
image-20230604213002086
image-20230604213002086
image-20230604213006379
image-20230604213006379

post 流水线完成后可执行的任务

  • always 无论流水线或者阶段的完成状态。
  • changed 只有当流水线或者阶段完成状态与之前不同时。
  • failure 只有当流水线或者阶段状态为"failure '运行。
  • success 只有当流水线或者阶段状态为"success' "运行。
  • unstable只有当流水线或者阶段状态为"unstable"运行。例如:测试失败。
  • aborted 只有当流水线或者阶段状态为"aborted "运行。例如:手动取消。

2、

image-20230605195248308
image-20230605195248308
image-20230605195225799
image-20230605195225799
image-20230605195054108
image-20230605195054108

注意修改为自己项目的分支

image-20230605195218863
image-20230605195218863

然后我们点击生成流水线脚本,就可以看到了

image-20230605195808934
image-20230605195808934

由于我的jenkins的这台机器已经配置了git的ssh密钥了,因此不需要凭证

image-20230605195918596
image-20230605195918596

然后我们写在steps里

pipeline {
    agent any

    stages {
        stage('拉取代码') {
            steps {
                git '[email protected]:apzs/demo.git'
                echo '拉取成功'
            }
        }
		
		stage('执行构建') {
            steps {
                echo '构建完成'
            }
        }
    }
}
image-20230605200230185
image-20230605200230185

由于在bash我们可以直接使用git命令,但是我们不能直接使用maven的相关命令,需要引入相关的maven配置才行

这个maven我们在全局工具配置里已经添加了,我们需要复制这个名字

image-20230605200523118
image-20230605200523118

我们可以使用 tools { maven "maven3" },表示我们需要maven3这个工具(这里的maven3是全局工具配置里添加的maven的名字)

如果我们想要执行条命令可以写sh """ 要执行的命令 """在三引号里面写命令即可(注意要换行,这是groovy的写法),由于执行这条命令的目录在/root/.jenkins/workspace/mypipeline,而我们拉取的代码也在这个目录,并且我们的pom.xml文件也在这个目录,因此我们直接执行sh "mvn clean package"就行了,如果项目的pom.xml文件不在根目录,可以向下面一样,执行多条shell命令

pipeline {
    agent any

	tools {
		maven "maven3"
	}
	
    stages {
        stage('拉取代码') {
            steps {
                git '[email protected]:apzs/demo.git'
                echo '拉取成功'
            }
        }
		
		stage('执行构建') {
            steps {
				// sh "mvn clean package"
				sh """
				  cd .
				  mvn clean package
				"""
                echo '构建完成'
            }
        }
    }
}
image-20230605202433574
image-20230605202433574

在片段生成器的示例步骤里选择sshPublisher: Send build artifacts over SSH,然后设置和first任务的Pre Step里一样的配置

image-20230609113811443
image-20230609113811443
pipeline {
    agent any

	tools {
		maven "maven3"
	}
	
    stages {
        stage('拉取代码') {
            steps {
                git '[email protected]:apzs/demo.git'
                echo '拉取成功'
            }
        }
		
        stage('删除文件') {
            steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: 'TestServer', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''docker stop demo
                docker rm demo
                docker rmi demo
                rm -rf /root/mydata/*''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/mydata', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }
        }

		stage('执行构建') {
            steps {
				// sh "mvn clean package"
				sh """
				  cd .
				  mvn clean package
				"""
                echo '构建完成'
            }
        }
    }
}
image-20230609120300258
image-20230609120300258
pipeline {
    agent any

	tools {
		maven "maven3"
	}
	
    stages {
        stage('拉取代码') {
            steps {
                git '[email protected]:apzs/demo.git'
                echo '拉取成功'
            }
        }
		
        stage('删除文件和容器') {
            steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: 'TestServer', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''docker stop demo
                docker rm demo
                docker rmi demo
                rm -rf /root/mydata/*''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/mydata', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }
        }

		stage('执行构建') {
            steps {
				// sh "mvn clean package"
				sh """
				  cd .
				  mvn clean package
				"""
                echo '构建完成'
            }
        }
        stage('生成容器并启动') {
            steps {
               sshPublisher(publishers: [sshPublisherDesc(configName: 'TestServer', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/mydata', remoteDirectorySDF: false, removePrefix: 'target', sourceFiles: '**/target/*.jar'), sshTransfer(cleanRemote: false, excludes: '', execCommand: '''docker build -t demo ./mydata
               
               docker run -d --name demo -p 8080:8080 -v /root/mydata:/root demo''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/mydata', remoteDirectorySDF: false, removePrefix: 'docker', sourceFiles: 'docker/dockerfile')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }
        }
    }
}
image-20230609140734583
image-20230609140734583
image-20230609115625094
image-20230609115625094
image-20230609140816137
image-20230609140816137
image-20230609120300259
image-20230609120300259

9、多分支job

image-20230605203731556
image-20230605203731556
image-20230612170050709
image-20230612170050709
pipeline {
    agent any

    stages {
        stage('Master拉取代码') {
            steps {
                echo '拉取Master分支代码成功'
            }
        }

		stage('执行构建') {
            steps {
                echo '构建完成'
            }
        }
    }
}
image-20230612170935936
image-20230612170935936
image-20230612170807110
image-20230612170807110
image-20230612171305267
image-20230612171305267
image-20230612171301164
image-20230612171301164
image-20230612171341797
image-20230612171341797
image-20230612172135860
image-20230612172135860
image-20230612172140180
image-20230612172140180
image-20230612172417915
image-20230612172417915
image-20230612172517046
image-20230612172517046
image-20230612172456536
image-20230612172456536
image-20230612172500336
image-20230612172500336
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.0.0-alpha.8