https://www.bagevent.com/event/6243820?bag_track=bagevent #Gdevops2020
https://www.bagevent.com/event/DevOpsDays-SH #DevOpsDays 2019
DevOps 是 Development 和 Operations 的组合,也就是开发和运维的简写。
DevOps 是针对企业中的研发人员、运维人员和测试人员的工作理念,是他们在应用开发、 代码部署和质量测试等整条生命周期中协作和沟通的最佳实践, DevOps 强调整个组织的合作以及交付和基础设施变更的自动化、从而实现持续集成(开发)、持续部署(运维)和持续交付。
DevOps 四大平台:代码托管(gitlab/svn)、项目管理(jira)、运维平台(腾讯蓝鲸/开源平
台)、持续交付(Jenkins/gitlab)
DevOps 强调团队协作、 相互协助、持续发展,然而传统的模式是开发人员只顾开发程序,运维只负责基础环境管理和代码部署及监控等, 其并不是为了一个共同的目标而共同实现最终的目的, 而 DevOps 则实现团队作战,即无论是开发、运维还是测试,都为了最终的代码发布、 持续部署和业务稳定而付出各自的努力, 从而实现产品设计、开发、 测试和部署的良性循环, 实现产品的最终持续交付。
持续集成是指多名开发者在开发不同功能代码的过程当中,可以频繁的将代码行合并到一起并切相互不影响工作。
是基于某种工具或平台实现代码自动化的构建、测试和部署到线上环境以实现交付高质量的产品,持续部署在某种程度上代表了一个开发团队的更新迭代速率。
持续交付是在持续部署的基础之上, 将产品交付到线上环境, 因此持续交付是产品值的一种交付, 是产品价值的一种盈利的实现。
上图说明:一堆软件的结合
计划阶段用JIRA做项目管理,用git来做代码仓库,构建工具使用Maven和Ant较多,测试阶段用Selenium,持续集成用Jenkins,部署使用Saltstack或者Ansible、scp(比较慢)、rsync;运营阶段使用elastic,监控使用Zabbix或者Prometheus
开发自己上传–最原始的方案
开发给运维手动上传–运维自己手动部署
运维使用脚本复制–半自动化
结合 web 界面一键部署–自动化
在公司的服务器安装某种程序,该程序用于按照特定格式和方式记录和保存公司多名开发人员不定期提交的源代码,且后期可以按照某种标记Tag及方式对用户提交的数据进行还原。
早期的集中式版本控制系统,现已基本淘汰
会出现数据提交后不完整的情况
2000 年开始开发,目标就是替代 CVS 集中式管理,依赖于网络,一台服务器集中管理目前依然有部分公司在使用
Linus 在 1991 年创建了开源的 Linux 内核,从此 Linux 便不断快速发展, 不过 Linux 的壮大是离不开全世界的开发者的参与,这么多人在世界各地为 Linux 编写代码,那Linux 内核的代码是如何管理的呢?事实是,在 2002 年以前,世界各地的志愿者把源代码文件通过 diff 的方式发给 Linus,然后由 Linus 本人通过手工方式合并代码!你也许会想,为什么 Linus 不把 Linux 代码放到版本控制系统里呢?不是有 CVS、 SVN 这些免费的版本控制系统吗?因为 Linus 坚定地反对 CVS 和 SVN,这些集中式的版本控制系统不但速度慢,且必须联网才能使用, 但是也有一些商用的版本控制系统,虽然比CVS、 SVN 好用,但那是付费的,和 Linux 的开源精神不符,不过,到了 2002 年, Linux系统已经发展了十年了,代码库之大让 Linus 很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是 Linus 选择了一个商业的版本控制系统BitKeeper, BitKeeper 的东家 BitMover 公司出于人道主义精神,授权 Linux 社区免费使用这个版本控制系统,但是安定团结的大好局面在 2005 年就被打破了,原因是 Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气, 开发 Samba 的 Andrew 试图破解 BitKeeper 的协议(这么干的其实也不只他一个),被 BitMover 公司发现了(监控工作做得不错!),于是 BitMover 公司怒了,要收回 Linux 社区的免费使用权,这时候其实 Linus 可以向 BitMover 公司道个歉,保证以后严格管教弟兄们, 但这是不可能的, 而且实际情况是 Linus 自己花了两周时间自己用 C 写了一个分布式版本控制系统,这就是 Git!一个月之内, Linux 内核的源码已经由 Git 管理了!牛是怎么定义的呢?大家可以体会一下,然后 Git 迅速成为最流行的分布式版本控制系统,尤其是 2008 年,GitHub 网站上线了,它为开源项目免费提供 Git 存储,无数开源项目开始迁移至 GitHub,包括 jQuery, PHP, Ruby 等等。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D5FX8XBU-1626502809246)(C:\Users\cui\Desktop\课程截图\38.DevOps之基于Jenkins实现的CI与CD_图片\gettyimages-532505754.jpg)]
gitlab 企业版
任何的提交和回滚都依赖于连接服务器 SVN 服务器是单点
Git 在每个用户都有一个完整的服务器,然后在有一个中央服务器,用户可以先将代码提交到本地,没有网络也可以先提交到本地,然后在有网络的时候再提交到中央服务器,这样就大大方便了开发者的代码提交和回滚,而相比 CVS 和 SVN 都是集中式的版本控制系统,工作的时候需要先从中央服务器获取最新的代码,改完之后需要提交,如果是一个比较大的文件则需要足够快的网络才能快速提交完成,而使用分布式的版本控制系统,每个用户都是一个完整的版本库,即使没有中央服务器也可以提交代码或者回滚,最终再把改好的代码提交至中央服务器进行合并即可。
https://about.gitlab.com/install/ # Gitlab 服务的安装文档
https://docs.gitlab.com/ce/install/requirements.html #安装环境要求
存储:8*600G=4.8T%50=2T 10K 15K 或固态
cpu:8c 16C
内存:16G 32G
gitlab使用,group user和project配置
jack@ubuntu:~$ sudo su - root
[sudo] password for jack:
root@ubuntu:~# passwd
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
root@ubuntu:~# vim /etc/ssh/sshd_config
http/https/ssh/git
PermitRootLogin yes
PasswordAuthentication yes
root@ubuntu:~# cat /etc/netplan/01-netcfg.yaml
# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: no
addresses: [192.168.8.2/21]
gateway4: 192.168.15.254
nameservers:
addresses: [192.168.15.254]
root@ubuntu:~# cat /etc/hostname
jenkins.example.com
root@ubuntu:~# reboot
root@ubuntu:~#vim /etc/apt/sources.list
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe
multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
root@jenkins:~# apt update
root@jenkins:~# apt install iproute2 ntpdate tcpdump telnet traceroute nfs-kernel-server nfs-common lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute gcc openssh-server lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute iotop unzip zip ipmitool
最小化服务器安装,配置如下
# yum install vim gcc gcc-c++ wget net-tools lrzsz iotop lsof iotop bash-completion -y
# yum install curl policycoreutils openssh-server openssh-clients postfix -y
# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
# systemctl disable firewalld
# sed -i '/SELINUX/s/enforcing/disabled/' /etc/sysconfig/selinux
# hostnamectl set-hostname gitlab.example.com
# reboot
安装包下载地址 https://packages.gitlab.com/gitlab/gitlab-ce
rpm 包国内下载地址 https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/
ubuntu 国内下载地址 https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/ubuntu/pool/
V11.11.8 linux38
[root@gitlab src]#dpkg -i gitlab-ce_13.1.10-ce.0_amd64.deb
#公司里推荐使用域名
[root@gitlab ~]#grep "^[a-Z]" /etc/gitlab/gitlab.rb
external_url 'http://10.0.78.101'
encpnupnpbongcbi
#可选邮件通知设置
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.qq.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "[email protected]"
gitlab_rails['smtp_password'] = "ooejgzgofwzdihdh"
gitlab_rails['smtp_domain'] = "qq.com"
gitlab_rails['smtp_authentication'] = :login
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = "[email protected]"
user["git_user_email"] = "[email protected]"
执行配置并启动服务
# gitlab-ctl reconfigure #修改完配置文件要执行此操作
#gitlab 相关的目录有哪些
/etc/gitlab #配置文件目录
/run/gitlab #运行 pid 目录
/opt/gitlab #安装目录
/var/opt/gitlab #数据目录
/var/log/gitlab #日志目录
# gitlab-rails #用于启动控制台进行特殊操作,比如修改管理员密码、打开数据库控制
台( gitlab-rails dbconsole)等
root@gitlab:~# gitlab-rails dbconsole
psql (9.6.11)
Type "help" for help.
gitlabhq_production=>
# gitlab-rails --help
# gitlab-psql #数据库命令行
root@s1:~# gitlab-psql
psql (9.6.11)
Type "help" for help.
gitlabhq_production=# \db
List of tablespaces
Name | Owner | Location
------------+-------------+----------
pg_default | gitlab-psql |
pg_global | gitlab-psql |
(2 rows)
# gitlab-rake #数据备份恢复等数据操作
# gitlab-ctl #客户端命令行操作行
# gitlab-ctl stop #停止 gitlab
# gitlab-ctl start #启动 gitlab
# gitlab-ctl restar #重启 gitlab
# gitlab-ctl status #查看组件运行状态
# gitlab-ctl tail nginx #查看某个组件的日志
80 端口是在初始化 gitlib 的时候启动的,因此如果之前的有程序占用会导致初始化失败或无法访问!
http://x.x.x.x/
登录 web 页面并设置密码,最少 8 位
登录,默认用户为 root
默认情况下可以直接注册账号,因此一般都关闭此功能,由运维工程师来创建,防止恶意注册
取消账户注册功能之后点 save
再创建一个tangtang
第一次使用新账号登录要设置密码
通过邮件重置用户密码
设置密码
使用管理员 root 创建组,一个组里面可以有多个项目分支,可以将开发添加到组里面进行设置权限,不同的组就是公司不同的开发项目或者服务模块,不同的组添加不同的开发即可实现对开发设置权限的管理。
使用管理员创建项目
创建后的项目效果
https://docs.gitlab.com/ee/user/permissions.html (更多权限)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gBHQeTc6-1626502809342)(C:\Users\cui\Desktop\课程截图\38.DevOps 之基于 Jenkins 实现的 CI 与 CD_图片\image-20200915160057525.png)]
找到项目界面
添加一个页面
[root@web3 opt]#git clone http://10.0.78.101/magedu/web1.git
Cloning into 'web1'...
Username for 'http://10.0.78.101': qinghe
Password for 'http://[email protected]':
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
[root@web3 opt]#cat web1/index.html
<h2>magedu web1 version11111111111111111</h2>
编辑文件并测试提交
[root@web3 opt]#vim web1/index.html
[root@web3 opt]#cat web1/index.html
<h2>magedu web1 version11111111111111111</h2>
<h2>magedu web2 version22222222222222222</h2>
[root@web3 opt]#cd web1/
[root@web3 web1]#git add index.html
[root@web3 web1]#git commit -m "v2"
[master f428c8e] v2
Committer: root <[email protected]>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly. Run the
following command and follow the instructions in your editor to edit
your configuration file:
git config --global --edit
After doing this, you may fix the identity used for this commit with:
git commit --amend --reset-author
1 file changed, 2 insertions(+), 1 deletion(-)
[root@web3 web1]#git push
Username for 'http://10.0.78.101': qinghe
Password for 'http://[email protected]':
Counting objects: 3, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 276 bytes | 276.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://10.0.78.101/magedu/web1.git
13ede10..f428c8e master -> master
SVN 与 CVS:
每次提交的文件都单独保存, 即按照文件的提交时间区分不同的版本, 保存至不同的逻辑存储区域,后期恢复的时候直接基于之前版本恢复。
Gitlab:
Gitlab 与 SVN 的数据保存方式不一样, gitlab 虽然也会在内部对数据进行逻辑划分保存,但是当后期提交的数据如果和之前提交过的数据没有变化,其就直接快照之前的文件,而不是在将文件重新上传一份在保存一遍,这样既节省了空间又加快了代码提交速度。
使用 git 命令下载代码与提交代码等操作。
上图说明:
工作区指的就是Windows上的一个目录(上面例子的web1目录),add之后是放在了暂存区,再用commit命令提交到本地工作区(本机仓库,没有网也可以提交),一旦提交到本地仓库就会产生一个tag信息(标记,代码恢复时使用),最后再push到git仓库(上图少了一步),这样别的开发才能拿到你写的代码
git config --global user.name "name" #设置全局用户名,并不一定是真实的,但一定要有,最好写真实的
git config --global user.email [email protected] #设置全局邮箱,同上
git config --global --list #列出用户全局设置
git add index.html / . #添加指定文件、 目录或当前目录下所有数据到暂存区
git commit -m "11" #提交文件到工作区
git status #查看工作区的状态
git push #提交代码到服务器
git pull #获取代码到本地
git log #查看操作日志,里面会有commit标记(回滚时使用的),非常重要!!!
vim .gitignore #定义忽略文件上传至 gitlab
#以下是运维相关
git reset --hard HEAD^^ #git 版本回滚, HEAD 为当前版本,加一个^为上一个, ^^为上上一个版本;必须是在不影响用户访问的前提下再进行代码部署
git reflog # #获取每次提交的 ID,可以使用--hard 根据提交的 ID 进行版本回退
git reset --hard 5ae4b06 #回退到指定 id 的版本,前八位即可
#git branch #查看当前所处的分支
#git checkout -b develop #创建并切换到一个新分支
#git checkout develop #切换分支
工作区: clone 的代码或者开发自己编写的代码文件所在的目录, 通常是代码所在的一个服务的目录名称。
暂存区: 用于存储在工作区中对代码进行修改后的文件所保存的地方, 使用 git add 添加。
本地仓库: 用于提交存储在工作区和暂存区中改过的文件地方,使用 git commit 提交。
远程仓库: 多个开发共同协作提交代码的仓库,即 gitlab 服务器。
[root@gitlab ~]#gitlab-ctl stop unicorn
[root@gitlab ~]#gitlab-ctl stop sidekiq
ok: down: sidekiq: 0s, normally up
[root@gitlab ~]#gitlab-rake gitlab:backup:create #在任意目录即可备份当前 gitlab 数据
[root@gitlab ~]#gitlab-ctl start #备份完成后启动 gitlab
/var/opt/gitlab/backups/ # Gitlab 数据备份目录, 需要使用命令备份的
/var/opt/gitlab/nginx/conf #nginx 配置文件
/etc/gitlab/gitlab.rb #gitlab 配置文件
/etc/gitlab/gitlab-secrets.json #key 文件
[root@gitlab ~]#ll /var/opt/gitlab/backups/
total 392
drwx------ 2 git root 4096 Sep 15 21:36 ./
drwxr-xr-x 21 root root 4096 Sep 14 20:56 ../
-rw------- 1 git git 194560 Sep 15 21:33 1600176792_2020_09_15_13.1.10_gitlab_backup.tar
-rw------- 1 git git 194560 Sep 15 21:36 1600176968_2020_09_15_13.1.10_gitlab_backup.tar
#1600176968是时间戳,从1970年开始计算的,以秒为单位,这样备份的文件就不会重名
#13.1.10是gitlab的版本号
删除一些数据,测试能否恢复
[root@gitlab ~]#gitlab-ctl stop unicorn
[root@gitlab ~]#gitlab-ctl stop sidekiq #恢复数据之前停止服务
root@s1:~# gitlab-rake gitlab:backup:restore BACKUP=备份文件名
#以下为实验示例
[root@gitlab ~]#gitlab-rake gitlab:backup:restore BACKUP=1600176968_2020_09_15_13.1.10
确认恢复数据
[root@gitlab ~]#gitlab-ctl start sidekiq
ok: run: sidekiq: (pid 57185) 0s
[root@gitlab ~]#gitlab-ctl start unicorn
虽然不推荐,但是有需求, 基于第三方开发爱好者实现
通过指定版本的语言包汉化
https://gitlab.com/xhang/gitlab/-/archive/v12.3.5-zh/gitlab-v12.3.5-zh.tar.gz
https://gitlab.com/xhang/gitlab/-/archive/v11.11.5-zh/gitlab-v11.11.5-zh.tar
https://gitlab.com/xhang/gitlab/-/archive/v11.9.8-zh/gitlab-v11.9.8-zh.tar
https://gitlab.com/xhang/gitlab
首次安装 gitlab 步骤
# vim /etc/gitlab/gitlab.rb #修改配置
# gitlab-ctl reconfigure
已经安装 gitlab 步骤
# gitlab-ctl stop
# tar xvf gitlab-vX.Y.Z-zh.tar
# cp -rp /opt/gitlab/embedded/service/gitlab-rails /opt/gitlab-rails.bak #备份源文件
# cp -rf gitlab-vX.Y.Z-zh/* /opt/gitlab/embedded/service/gitlab-rails/ #替换文件
# gitlab-ctl reconfigure
# gitlab-ctl start
Web 界面更改语言:
右上角的账户下拉框选 Settings 然后左侧 Preferences 设置项,然后语言选择中文
保存后刷新界面
https://gitlab.com/xhang/gitlab #汉化包地址
# gitlab-ctl stop
# git clone https://gitlab.com/xhang/gitlab.git
# head -1 /opt/gitlab/version-manifest.txt #查看当前 gitlab 版本
# cd gitlab
# git diff v11.9.8 v11.9.8-zh
# git diff v12.3.5 v12.3.5-zh
# git diff v11.9.8 v11.9.8-zh > /root/v11.9.8-zh.diff
# gitlab-ctl stop
# patch -f -d /opt/gitlab/embedded/service/gitlab-rails -p1 < /root/v11.9.8-zh.diff
# gitlab-ctl reconfigure
# gitlab-ctl start
v11.11.8 汉化效果
v.12.2.8 汉化效果
V12.3.5 汉化效果:
蓝绿部署指的是不停老版本代码(不影响上一个版本访问), 而是在另外一套环境部署新版本然后进行测试,测试通过后将用户流量切到新版本, 其特点为业务无中断,升级风险相对较小。需要大量服务器的支撑
具体过程:
1、 当前版本业务正常访问(V1)
2、 在另外一套环境部署新代码(V2),代码可能是增加了功能或者是修复了某些 bug
3、 测试通过之后将用户请求流量切到新版本环境
4、 观察一段时间,如有异常直接切换旧版本
5、 下次升级, 将旧版本升级到新版本(V3)
蓝绿部署适用的场景:
1、不停止老版本,额外部署一套新版本,等测试发现新版本 OK 后,删除老版本。
2、蓝绿发布是一种用于升级与更新的发布策略,部署的最小维度是容器,而发布的最小维度是应用。
3、蓝绿发布对于增量升级有比较好的支持,但是对于涉及数据表结构变更等等不可逆转的升级,并不完全合适用蓝绿发布来实现,需要结合一些业务的逻辑以及数据迁移与回滚的策略才可以完全满足需求。
非常适合于中小企业
金丝雀发布也叫灰度发布, 是指在黑与白之间,能够平滑过渡的一种发布方式, 灰度发布是增量发布的一种类型,灰度发布是在原有版本可用的情况下,同时部署一个新版本应用作为“金丝雀” (小白鼠),测试新版本的性能和表现,以保障整体系统稳定的情况
下,尽早发现、调整问题。
“金丝雀”的由来 17 世纪,英国矿井工人发现,金丝雀对瓦斯这种气体十分敏感。空气中哪怕有极其微量的瓦斯,金丝雀也会停止歌唱;而当瓦斯含量超过一定限度时,虽然鲁钝的人类毫无察觉,金丝雀却早已毒发身亡。当时在采矿设备相对简陋的条件下,工人们每次下井都会带上一只金丝雀作为“瓦斯检测指标”,以便在危险状况下紧急撤离。
金丝雀发布、灰度发布步骤组成:
1、准备好部署各个阶段的工件,包括 构建工件,测试脚本,配置文件和部署清单文件。
2、从负载均衡列表中移除掉“金丝雀”服务器。
3、升级“金丝雀”应用(排掉原有流量并进行部署)。
4、对应用进行自动化测试。
5、将“金丝雀”服务器重新添加到负载均衡列表中(连通性和健康检查)。
6、如果“金丝雀”在线使用测试成功,升级剩余的其他服务器。(否则就回滚)
灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。
灰度发布/金丝雀部署适用的场景:
1、不停止老版本,额外搞一套新版本,不同版本应用共存。
2、灰度发布中,常常按照用户设置路由权重,例如 90%的用户维持使用老版本, 10%的用户尝鲜新版本。
3、经常与 A/B 测试一起使用,用于测试选择多种方案。
下图中,左下方的少部分用户就被当作“金丝雀”来用于测试新上线的1.1版本。如果新版本出现问题,“金丝雀”们会报警,但不会影响其他用户业务的正常运行。
逐步推送示例:
滚动发布,一般是取出一个或者多个服务器停止服务,执行更新,并重新将其投入使用。周而复始,直到集群中所有的实例都更新成新版本。
A/B 测试也是同时运行两个 APP 环境,但是蓝绿部署完全是两码事, A/B 测试是用来测试应用功能表现的方法,例如可用性、受欢迎程度、可见性等等,蓝绿部署的目的是安全稳定地发布新版本应用,并在必要时回滚, 即蓝绿部署是一套正式环境环境在线, 而A/B 测试是两套正式环境在线。
各 web 服务器准备 tomcat 运行环境
# useradd www -u 2000
# mkdir /apps && cd /apps
[root@web1 src]#tar xvf jdk-8u261-linux-x64.tar.gz
[root@web1 jdk1.8.0_261]#ln -sv /usr/local/src/jdk1.8.0_261/ /usr/local/jdk
# vim/etc/profile
export HISTTIMEFORMAT="%F %T `whoami` "
export export LANG="en_US.utf-8"
export JAVA_HOME=/apps/jdk
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
# source /etc/profile && java -version
[root@web1 apps]#tar xvf apache-tomcat-8.5.57.tar.gz
[root@web1 apps]#ln -sv /apps/apache-tomcat-8.5.57 /apps/tomcat
#方便以后做升级
# cp /root/tomcat /etc/init.d/
部署 web 服务器并确认各 web 服务器访问正常
# groupadd -g 2020 magedu && useradd -m -g magedu -u 2020 -s /bin/bash magedu
# 创建web 账户
# useradd www -u 2019 #centos 创建web 启动账户
# mkdir /data/tomcat/tomcat_appdir -p #保存 web 压缩包
# mkdir /data/tomcat/tomcat_webdir #保存解压后的 web 目录
# mkdir /data/tomcat/tomcat_webapps #tomcat app 加载目录,在 server.xml 定义
# mkdir /data/tomcat/tomcat_webdir/myapp #Java 代码目录
# echo SERVER_IP > /data/tomcat/tomcat_webdir/myapp/index.html
[root@web1 ~]#vim /apps/tomcat/conf/server.xml
<Host name="localhost" appBase="/data/tomcat/tomcat_webapps" unpackWARs="false" autoDeploy="false">
#修改权限,切换到普通用户magedu
[root@web1 ~]#chown magedu.magedu /apps/tomcat /apps/apache-tomcat-8.5.57 /data/tomcat/ -R
[root@web1 ~]#su - magedu
magedu@web1:~$/etc/init.d/tomcat start
编译过程如下
# yum install libnfnetlink-devel libnfnetlink ipvsadm libnl libnl-devel libnl3 libnl3-devel lm_sensors-libs net-snmp-agent-libs net-snmp-libs open server openssh-clients openssl openssldevel automake iproute
# cd keepalived-2.0.7 && ./configure --prefix=/usr/local/keepalived --disable-fwmark
# make && amke install
# # mkdir /usr/local/keepalived/etc/sysconfig – p && cp keepalived/etc/init.d/keepalived.rh.init /usr/local/keepalived/etc/sysconfig/keepalived
# cp keepalived/keepalived.service /usr/lib/systemd/system/
# mkdir /usr/local/keepalived/sbin && cp bin/keepalived /usr/local/keepalived/sbin/keepalived
# mkdir /etc/keepalived
# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 80
priority 100
advert_int 1
unicast_src_ip 192.168.7.103
unicast_peer {
192.167.7.104
}
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.7.100 dev eth0 label eth0:0
}
}
yum安装如下:
[root@jenkins-slave1 ~]#apt install keepalived -y
[root@jenkins-slave1 ~]#cp /usr/share/doc/keepalived/samples/keepalived.conf.vrrp /etc/keepalived/keepalived.conf
[root@jenkins-slave1 ~]#cat /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER
interface eth0
garp_master_delay 10
smtp_alert
virtual_router_id 90
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.78.188 dev eth0 label eth0:1
}
}
#backup的级别调低一点,降为80
[root@jenkins-slave2 ~]#vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER
interface eth0
garp_master_delay 10
smtp_alert
virtual_router_id 90
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.78.188 dev eth0 label eth0:1
}
}
[root@jenkins-slave1 ~]#systemctl restart keepalived.service
[root@jenkins-slave1 ~]#systemctl enable keepalived.service
#最好验证keepalived的可用性,把优先级高的先停了,看看地址会不会飘过去,再开启,看会不会抢占回去
# tar xvf haproxy-1.8.13.tar.gz
# cd haproxy-1.8.13
# make ARCH=x86_64 TARGET=linux2628 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_CPU_AFFINITY=1 PREFIX=/usr/local/haproxy
# make install PREFIX=/usr/local/haproxy
# vim /usr/lib/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target
[Service]
#支持多配置文件读取,类似于从侧面是实现配置文件的 include 功能。
ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf -c -q
ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf -p /run/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID
[Install]
WantedBy=multi-user.target
# mkdir /etc/haproxy
测试 haproxy 反向代理 web 服务器
编辑本机 hosts 文件,将 myapp.web.com 解析到对应的 IP 负载 IP
C:\Windows\System32\drivers\etc\hosts
192.168.7.100 myapp.web.com
记录 HAProxy 访问日志
vim/etc/rsyslog.conf
14 # Provides UDP syslog reception
15 $ModLoad imudp #去掉注释
16 $UDPServerRun 514 #去掉注释
18 # Provides TCP syslog reception
19 $ModLoad imtcp #去掉注释
20 $InputTCPServerRun 514 #去掉注释
93 local3.* /var/log/haproxy.log
systemctl restart rsyslog
log 127.0.0.1 local3 info #global 部分
listen web_port
bind 0.0.0.0:80
mode http
log global
option httplog
server 192.168.7.103 192.168.7.103:8080 check inter 3000 fall 2 rise 5
server 192.168.7.104 192.168.7.104:8080 check inter 3000 fall 2 rise 5
重启 rsyslog 和 haproxy 服务,验证/var/log/haproxy.log 可以记录日志
[root@jenkins-slave2 src]#vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1
[root@jenkins-slave2 src]#sysctl -p
net.ipv4.ip_nonlocal_bind = 1
[root@jenkins-slave2 src]#ss -ntl |grep 80
LISTEN 0 128 10.0.78.188:80 0.0.0.0:*
#此时再去访问vip,就能转发到两个web服务器上去
http://myapp.web.com:9009/haproxy-status
做一次域名解析:
http://myapp.web.com/myapp/
https://jenkins.io/zh/
root@jenkins:/usr/local/src# tar xvf jdk-8u192-linux-x64.tar.gz
root@jenkins:/usr/local/src# ln -sv /usr/local/src/jdk1.8.0_192/ /usr/local/jdk
root@jenkins:/usr/local/src# ln -sv /usr/local/jdk/bin/java /usr/bin/ #java 命令软连接
root@jenkins:/usr/local/src# vim /etc/profile
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
root@jenkins:/usr/local/src# source /etc/profile
root@jenkins:/usr/local/src# java -version
java version "1.8.0_192"
Java(TM) SE Runtime Environment (build 1.8.0_192-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.192-b12, mixed mode)
apt安装过程如下:
[root@jenkins-master ~]#apt install -y openjdk-8-jdk
[root@jenkins-master ~]#java -version
openjdk version "1.8.0_265"
OpenJDK Runtime Environment (build 1.8.0_265-8u265-b01-0ubuntu2~18.04-b01)
OpenJDK 64-Bit Server VM (build 25.265-b01, mixed mode)
[root@jenkins-master ~]#apt install daemon
[root@jenkins-master ~]#dpkg -i jenkins_2.235.5_all.deb
https://mirrors.tuna.tsinghua.edu.cn/jenkins/debian-stable/ #ubuntu 安装包下载
# java \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=12345 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Djava.rmi.server.hostname="192.168.8.2 " \
-jar jenkins-2.138.3.war &
[root@s1 ~]# grep -v "#" /etc/sysconfig/jenkins | grep -v "^$"
JENKINS_HOME="/var/lib/jenkins"
JENKINS_JAVA_CMD=""
JENKINS_USER="jenkins"
JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=12345 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Djava.rmi.server.hostname="192.168.7.101" \
"
JENKINS_PORT="8080"
JENKINS_LISTEN_ADDRESS=""
JENKINS_HTTPS_PORT=""
JENKINS_HTTPS_KEYSTORE=""
JENKINS_HTTPS_KEYSTORE_PASSWORD=""
JENKINS_HTTPS_LISTEN_ADDRESS=""
JENKINS_DEBUG_LEVEL="5"
JENKINS_ENABLE_ACCESS_LOG="no"
JENKINS_HANDLER_MAX="100"
JENKINS_HANDLER_IDLE="20"
JENKINS_ARGS=""
可选启动参数
JENKINS_JAVA_OPTIONS="--server -Xms1g -Xmx1g -Xss512k -Xmn1g
-XX:CMSInitiatingOccupancyFraction=65
-XX:+UseFastAccessorMethods
-XX:+AggressiveOpts -XX:+UseBiasedLocking
-XX:+DisableExplicitGC -XX:MaxTenuringThreshold=10
-XX:NewSize=2048M -XX:MaxNewSize=2048M -XX:NewRatio=2
-XX:PermSize=128m -XX:MaxPermSize=512m -XX:CMSFullGCsBeforeCompaction=5
-XX:+ExplicitGCInvokesConcurrent -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled -Djava.awt.headless=true
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=12345
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname="192.168.7.102"
解决插件安装慢的解决方式,通过 Nginx 进行 rewrite 或者反向代理,如下
127.0.0.1 updates.jenkins-ci.org
location /download/plugins {
proxy_set_header Host mirrors.tuna.tsinghua.edu.cn;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
rewrite /download/plugins(.*) /jenkins/plugins/$1 break;
proxy_pass http://mirrors.tuna.tsinghua.edu.cn;
}
如果现实 jenkins 已离线,将以下文件中的更新检查地址改成国内清华大学地址, 然后
重启 jenkins 即可 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
# cat /var/lib/jenkins/hudson.model.UpdateCenter.xml
<?xml version='1.1' encoding='UTF-8'?>
<sites>
<site>
<id>default</id>
<url>https://updates.jenkins.io/update-center.json</url>
</site>
http://updates.jenkins-ci.org/download/plugins/ #插件下载地址
插件安装过程中。。, 如果因为某种原因导致有有安装失败的插件, 没有关系,可以后期再单独安装
插件下载地址 http://updates.jenkins-ci.org/download/plugins/
搜索需要 gitlab 的插件并安装
gitlab 和 Blue Ocean
基于角色的权限管理,先创建角色和用户, 给角色授权,然后把用户管理到角色。
Role-based #基于角色的认证策略
Jenkins—系统管理—管理用户
Jenkins—系统管理—全局安全配置
默认创建的用户登录后可以做任何操作,取决于默认的认证授权方式。
Jenkins—系统管理–Manage and Assign Roles(管理和分配角色)
修改权限
登录成功之的界面,没有系统管理权限,只能执行被授权过的 job且没有了管理员权限。
Jenkins—系统管理—系统设置
[root@jenkins-master ~]#ssh-keygen
[root@jenkins-master ~]#ll /root/.ssh/
total 20
drwx------ 2 root root 4096 Sep 16 22:30 ./
drwx------ 5 root root 4096 Sep 16 22:30 ../
-rw------- 1 root root 1679 Sep 16 22:30 id_rsa
-rw-r--r-- 1 root root 415 Sep 16 22:30 id_rsa.pub
-rw-r--r-- 1 root root 222 Sep 16 22:30 known_hosts
#查看公钥
[root@jenkins-master ~]#cat /root/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGo6lz3IRWvzWTWpDo+Cy3Y24UvYWQC1xM3ypcofbaN4F1SRa4x0BvVhMZdCoNtixC5ePEC7oXhJBQ4FbBhnZadVkzAZ7GfXl2sjGd7pjh0acycvg8yB72W97CTsYGsuv24hS0EKwWxb8VJNSdzZt6a2lRoFRQmOf45a1LxPka7zoPy8nurNOxuep9rhX3NrQAFNAVYh4rhaX7Bx4RW/NqSXpxdpjJLQuMns5LkSvVbDJqfqINuU94BUnkECO6fWmlRgrT+kbYlaAtZGjRgwgPSaa2r0BIiEMTo8O3UkBuo5v26H7AZML8pojlHftBeDBYx1Oj5VkNULMJW7DbykIX [email protected]
ssh key 只用于免认证获取代码
测试可以不使用用户名密码后直接获取代码,仅用于代码部署,不能用于提交
Jenkins-凭据-jenkins—全局凭据—添加凭据
添加完成的证书没有报错表示认证通过
先做好key验证:
[root@jenkins-master ~]#ssh-copy-id [email protected]
[root@jenkins-master ~]#ssh-copy-id [email protected]
#验证
[root@jenkins-master ~]#ssh [email protected]
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-117-generic x86_64)
magedu@web2:~$
构建执行 shell, 脚本内容:
cd /var/lib/jenkins/workspace/linux36-job1/
tar czvf code.tar.gz index.html
scp code.tar.gz [email protected]:/data/tomcat/tomcat_appdir/
scp code.tar.gz [email protected]:/data/tomcat/tomcat_appdir/
ssh [email protected] "/etc/init.d/tomcat stop && rm -rf
/data/tomcat/tomcat_webdir/myapp/* && cd /data/tomcat/tomcat_appdir && tar
xvf code.tar.gz -C /data/tomcat/tomcat_webdir/myapp/"
ssh [email protected] "/etc/init.d/tomcat stop && rm -rf
/data/tomcat/tomcat_webdir/myapp/* && cd /data/tomcat/tomcat_appdir && tar xvf
code.tar.gz -C /data/tomcat/tomcat_webdir/myapp/"
ssh [email protected] "/etc/init.d/tomcat start"
ssh [email protected] "/etc/init.d/tomcat start"
第一次构建之后
升级一次代码在进行构建
[root@jenkins-master opt]#git clone http://10.0.78.101/magedu/web1.git
Cloning into 'web1'...
Username for 'http://10.0.78.101': tangtang
Password for 'http://[email protected]':
remote: Enumerating objects: 15, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 15 (delta 3), reused 15 (delta 3), pack-reused 0
Unpacking objects: 100% (15/15), done.
[root@jenkins-master opt]#vim web1/index.html
<h2>magedu web1 version11111111111111111</h2>
<h2>magedu web1 version22222222222222222</h2>
<h2>magedu web1 version33333333333333333</h2>
<h2>magedu web1 version44444444444444444</h2>
<h2>magedu web1 version55555555555555555</h2>
<h2>magedu web1 version66666666666666666</h2>
#代码修改后进行提交
[root@jenkins-master web1]#git add .
[root@jenkins-master web1]#git commit -m "v6" ``
[master 79f9525] v6
Committer: root <[email protected]>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly. Run the
following command and follow the instructions in your editor to edit
your configuration file:
git config --global --edit
After doing this, you may fix the identity used for this commit with:
git commit --amend --reset-author
1 file changed, 5 insertions(+), 4 deletions(-)
[root@jenkins-master web1]#git push
Username for 'http://10.0.78.101': root
Password for 'http://[email protected]':
Counting objects: 3, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 297 bytes | 297.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To http://10.0.78.101/magedu/web1.git
87d5dd4..79f9525 master -> master
脚本不建议放在Jenkins中,不太安全也不太直观,很多人进来之后都可以改;建议放在Jenkins服务器上,单独创建一个目录,如下:
[root@jenkins-master opt]#mkdir /data/scripts -p
[root@jenkins-master opt]#cd /data/scripts
#每个项目再单独创建一个目录
[root@jenkins-master scripts]#mkdir qinghe
[root@jenkins-master scripts]#cd qinghe/
[root@jenkins-master qinghe]#vim web-deploy.sh
[root@jenkins-master qinghe]#cat web-deploy.sh
#!/bin/bash
cd /var/lib/jenkins/workspace/qinghe-job1
tar czvf web1.tar.gz ./*
scp web1.tar.gz [email protected]:/data/tomcat/tomcat_appdir/
scp web1.tar.gz [email protected]:/data/tomcat/tomcat_appdir/
ssh [email protected] "/etc/init.d/tomcat stop && rm -rf /data/tomcat/tomcat_webapps/web1/* && cd /data/tomcat/tomcat_appdir/ && tar xvf web1.tar.gz -C /data/tomcat/tomcat_webapps/web1/"
ssh [email protected] "/etc/init.d/tomcat stop && rm -rf /data/tomcat/tomcat_webapps/web1/* && cd /data/tomcat/tomcat_appdir/ && tar xvf web1.tar.gz -C /data/tomcat/tomcat_webapps/web1/"
ssh [email protected] "/etc/init.d/tomcat start"
ssh [email protected] "/etc/init.d/tomcat start"
[root@jenkins-master qinghe]#chmod +x web-deploy.sh
[root@jenkins-master qinghe]#ll /data/scripts/qinghe/web-deploy.sh
-rwxr-xr-x 1 root root 684 Sep 16 23:53 /data/scripts/qinghe/web-deploy.sh*
再一次构建之后:
构建触发器(webhook), 有的人称为钩子, 实际上是一个 HTTP 回调,其用于在开发人员向 gitlab 提交代码后能够触发 jenkins 自动执行代码构建操作。
以下为新建一个开发分支, 只有在开发人员向开发(develop)分支提交代码的时候才会触发代码构建, 而向主分支提交的代码不会自动构建, 需要运维人员手动部署代码到生产环境。(一般是在凌晨,不影响用户访问)
由开发先把代码提交到开发分支,再把开发分支的代码部署到测试环境
此实验翻车,原因可能是gitlab版本太旧,Jenkins版本太新
#系统管理-管理插件-可选插件-Gitlab Hook 和 Gitlab Authentication
注意事项:
https://jenkins.io/security/advisory/2018-05-09/#SECURITY-263
系统管理—全局安全设置–授权策略
以下为旧版本需要的操作,本次实验中并没有此项
保存以上配置
构建命令为简单的测试命令,比如输出当前的账户信息
生产 token 认证
[root@jenkins-master ~]#openssl rand -hex 12
d082dbd1b373e4eb5e2b9ae7
[root@jenkins-master ~]#vim /var/lib/jenkins/jobs/qinghe-job1/config.xml
root@jenkins-master:~# curl http://10.0.78.102:8080/job/qinghe-job1/build?token=d082dbd1b373e4eb5e2b9ae7
Admin area—groups/project—System Hooks
执行结果 (老师视频翻车)
将开发分支的执行 shell 命令更改为正式脚本
cd /var/lib/jenkins/workspace/linux36-job1-develop
tar czvf code.tar.gz index.html
scp code.tar.gz [email protected]:/data/tomcat/tomcat_appdir/
scp code.tar.gz [email protected]:/data/tomcat/tomcat_appdir/
ssh [email protected] "/etc/init.d/tomcat stop && rm -rf
/data/tomcat/tomcat_webdir/myapp/* && cd /data/tomcat/tomcat_appdir && tar
xvf code.tar.gz -C /data/tomcat/tomcat_webdir/myapp/"
ssh [email protected] "/etc/init.d/tomcat stop && rm -rf
/data/tomcat/tomcat_webdir/myapp/* && cd /data/tomcat/tomcat_appdir && tar xvf
code.tar.gz -C /data/tomcat/tomcat_webdir/myapp/"
ssh [email protected] "/etc/init.d/tomcat start"
ssh [email protected] "/etc/init.d/tomcat start"
root@gitlab:/opt# git clone -b develop http://192.168.7.101/linux36/web1.git
root@gitlab:/opt# cd web1/
root@gitlab:/opt/web1# vim index.html
root@gitlab:/opt/web1# git add index.html
root@gitlab:/opt/web1# git commit -m "v7"
root@gitlab:/opt/web1# git push
Username for 'http://192.168.7.101': user1
Password for 'http://[email protected]':
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 291 bytes | 291.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote:
remote: To create a merge request for develop, visit:
remote:
http://192.168.7.101/linux36/web1/merge_requests/new?merge_request%5Bsource_
branch%5D=develop
remote:
To http://192.168.7.101/linux36/web1.git
9432b30..5110a70 develop -> develop
用于多个 job 相互关联,需要串行执行多个 job 的场景, 可以通过安装插件 Parameterized Trigger 触发执行其他 project。用的并不多
构建完成后触发另外一个 project
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MVpOpOHo-1626502810064)(C:\Users\cui\Desktop\课程截图\38.DevOps之基于Jenkins实现的CI与CD_图片\image-20200922103722162.png)]
在众多 Job 的场景下,单台 jenkins master 同时执行代码 clone、编译、 打包及构建,其性能可能会出现瓶颈从而会影响代码部署效率,影响 jenkins 官方提供了 jenkins 分布式构建, 将众多 job 分散运行到不同的 jenkins slave 节点, 大幅提高并行 job 的处理能力。
Slave 服务器创建工作目录, 如果 slave 需要执行编译 job,则也需要配置 java 环境并且安装 git、 svn、 maven 等与 master 相同的基础运行环境,另外也要创建与 master 相同的数据目录,因为脚本中调用的路径只有相对一 master 的一个路径,此路径在master 与各 node 节点必须保持一致。
# mkdir -p /var/lib/jenkins #创建数据目录
# jenkins home location
JENKINS_HOME=/var/lib/$NAME #工作目录配置与 master 保持一致
# vim /etc/profile
export HISTTIMEFORMAT="%F %T `whoami` "
export export LANG="en_US.utf-8"
export JAVA_HOME=/usr/local/jdk
export
CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
Jenkins—系统管理—节点管理—新建节点
添加 slave 节点
部分 jenkins slave 信息
或者选择不校验证书(推荐)
正常状态
时间不同步状态
官方介绍; https://jenkins.io/2.0/ #jenkins 2.X 管官方介绍
https://jenkins.io/zh/doc/book/pipeline/ #官方 pipline 示例
pipline 是帮助 Jenkins 实现 CI 到 CD 转变的重要角色,是运行在 jenkins 2.X 版本的核心插件,简单来说 Pipline 就是一套运行于 Jenkins 上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂发布流程, 从而实现单个任务很难实现的复杂流程编排和任务可视化, Pipeline 的实现方式是一套Groovy DSL,任何发布流程都可以表述为一段 Groovy 脚本。
基本流程:
Stage:阶段,一个 pipline 可以划分为若干个 stage,每个 stage 都是一个操作步骤,比如 clone 代码、代码编译、 代码测试和代码部署, 阶段是一个逻辑分组, 可以跨多个 node 执行。
Node:节点,每个 node 都是一个 jenkins 节点,可以是 jenkins master 也可以是 jenkins agent, node 是执行 step 的具体服务器。
Step:步骤, step 是 jenkins pipline 最基本的操作单元, 从在服务器创建目录到构建容器镜像,由各类 Jenkins 插件提供实现, 一个 stage 中可以有多个 step, 例如 sh “make”
可持续性 jenkins 的重启或者中断后不影响已经执行的 Pipline Job
支持暂停 pipline 可以选择停止并等待人工输入或批准后再继续执行。
可扩展 通过 groovy 的编程更容易的扩展插件。
并行执行 通过 groovy 脚本可以实现 step, stage 间的并行执行,和更复杂的相互依赖关系。
Pipeline 测试命令:
node {
stage("clone 代码"){
echo "代码 clone"
}
stage("代码构建"){
echo "代码构建"
}
stage("代码测试"){
echo "代码测试"
}
stage("代码部署"){
echo "代码部署"
}
}
Jenkins Web 界面配置
点击 流水线语法 跳转至生成脚本 URL
生成流水线脚本
node {
stage("clone 代码"){
//sh "cd /data/git/linux41/ && rm -rf web1 && git clone -b master [email protected]:magedu/web1.git"
//sh "cd /data/git/linux41/ && rm -rf web1"
sh "cd /var/lib/jenkins/workspace/qinghe-pipline-job1 && rm -rf ./*"
git credentialsId: '04bed6a5-7277-4599-b485-9e0773a19d59', url: '[email protected]:magedu/web1.git'
}
stage("代码构建"){
echo "代码构建"
}
stage("代码测试"){
echo "代码测试"
}
stage("代码部署"){
echo "代码部署"
}
}
node {
stage("clone 代码"){
sh "cd /var/lib/jenkins/workspace/qinghe-pipline-job1 && rm -rf ./*"
git credentialsId: '04bed6a5-7277-4599-b485-9e0773a19d59', url: '[email protected]:magedu/web1.git'
}
stage("代码构建"){
sh 'cd /var/lib/jenkins/workspace/qinghe-pipline-job1 && tar czvf web1.tar.gz ./*'
}
stage("代码测试"){
echo "代码测试"
}
stage("代码部署"){
echo "代码部署"
}
}
node {
stage("clone 代码"){
sh "cd /var/lib/jenkins/workspace/qinghe-pipline-job1 && rm -rf ./*"
git credentialsId: '04bed6a5-7277-4599-b485-9e0773a19d59', url: '[email protected]:magedu/web1.git'
}
stage("代码构建"){
sh 'cd /var/lib/jenkins/workspace/qinghe-pipline-job1 && tar czvf web1.tar.gz ./*'
}
stage("代码复制"){
sh 'cd /var/lib/jenkins/workspace/qinghe-pipline-job1 && scp web1.tar.gz [email protected]:/data/tomcat/tomcat_appdir/'
sh 'cd /var/lib/jenkins/workspace/qinghe-pipline-job1 && scp web1.tar.gz [email protected]:/data/tomcat/tomcat_appdir/'
}
stage("停止 tomcat 服务"){
sh 'ssh [email protected] "/etc/init.d/tomcat stop"'
sh 'ssh [email protected] "/etc/init.d/tomcat stop"'
echo "web服务停止完成,即将开始代码替换"
}
stage("代码部署"){
sh 'ssh [email protected] "rm -rf /data/tomcat/tomcat_webapps/web1/* && cd /data/tomcat/tomcat_appdir/ && tar xvf web1.tar.gz -C /data/tomcat/tomcat_webapps/web1/"'
sh 'ssh [email protected] "rm -rf /data/tomcat/tomcat_webapps/web1/* && cd /data/tomcat/tomcat_appdir/ && tar xvf web1.tar.gz -C /data/tomcat/tomcat_webapps/web1/"'
}
stage("启动 tomcat 服务"){
sh 'ssh [email protected] "/etc/init.d/tomcat start"'
sh 'ssh [email protected] "/etc/init.d/tomcat start"'
}
}
在 gitlab 提交代码, 执行 pipline job 并验证代码是否最终部署到了 web 服务器。
node 节点需要安装 git 命令
jenkins node1:
# apt-get install git -y
jenkins node2 :
# apt-get install git -y
node 节点需要打通与 web server 免密钥登录
jenkins node1:
[root@jenkins-slave1 ~]#ssh-keygen
[root@jenkins-slave1 ~]#ssh-copy-id [email protected]
[root@jenkins-slave1 ~]#ssh-copy-id [email protected]
jenkins node2
[root@jenkins-slave2 ~]#ssh-keygen
[root@jenkins-slave2 ~]#ssh-copy-id [email protected]
[root@jenkins-slave2 ~]#ssh-copy-id [email protected]
jenkins pipeline 代码 :
node("Jenkins-node1"){
stage("clone 代码"){
sh "cd /var/lib/jenkins/workspace/qinghe-pipline-job1 && rm -rf ./*"
git credentialsId: '04bed6a5-7277-4599-b485-9e0773a19d59', url: '[email protected]:magedu/web1.git'
}
stage("代码构建"){
sh 'cd /var/lib/jenkins/workspace/qinghe-pipline-job1 && tar czvf web1.tar.gz ./*'
}
stage("代码复制"){
sh 'cd /var/lib/jenkins/workspace/qinghe-pipline-job1 && scp web1.tar.gz [email protected]:/data/tomcat/tomcat_appdir/'
sh 'cd /var/lib/jenkins/workspace/qinghe-pipline-job1 && scp web1.tar.gz [email protected]:/data/tomcat/tomcat_appdir/'
}
stage("停止 tomcat 服务"){
sh 'ssh [email protected] "/etc/init.d/tomcat stop"'
sh 'ssh [email protected] "/etc/init.d/tomcat stop"'
echo "web服务停止完成,即将开始代码替换"
}
stage("代码部署"){
sh 'ssh [email protected] "rm -rf /data/tomcat/tomcat_webapps/web1/* && cd /data/tomcat/tomcat_appdir/ && tar xvf web1.tar.gz -C /data/tomcat/tomcat_webapps/web1/"'
sh 'ssh [email protected] "rm -rf /data/tomcat/tomcat_webapps/web1/* && cd /data/tomcat/tomcat_appdir/ && tar xvf web1.tar.gz -C /data/tomcat/tomcat_webapps/web1/"'
}
stage("启动 tomcat 服务"){
sh 'ssh [email protected] "/etc/init.d/tomcat start"'
sh 'ssh [email protected] "/etc/init.d/tomcat start"'
}
}
Gitlab 重新提交代码并测试代码部署
视图可用于归档 job 进行分组显示, 比如将一个业务的视图放在一个视图显示, 安装完成 build pipeline 插件之后将会有一个+号用于创建视图。
插件安装完成
列表视图使用场景比较多, 用于将一个业务的 job 保存至一个列表视图进行分类管理,即不同业务的 job 放在不同的列表视图中。
列表视图是对众多 job 推荐使用的分类功能。
我的视图会显示当前账户有权限访问的 job,因此需要提前划分好权限。用的较少
创建后点保存,就会直接看到当前账户有权限的 job。
官方网站:http://www.sonarqube.org/
SonarQube 是一个用于代码质量管理的开放平台,通过插件机制, SonarQube可以集成不同的测试工具,代码分析工具,以及持续集成工具,例如 Hudson/Jenkins 等。
下载地址:https://www.sonarqube.org/downloads/
七个维度检测代码质量
7.9.x 版本不再支持 MySQL
https://docs.sonarqube.org/latest/setup/upgrade-notes/
MySQL No Longer Supported
SonarQube no longer supports MySQL. To migrate from MySQL to a supported database, see the
free MySQL Migrator tool.
下载官方安装文件
https://docs.sonarqube.org/6.7/Requirements.html
SonarQube 6.7.X LTS 版本要求数据库要使用 MySQ 5.6 及以上版本,不支持 5.5 及更早的版
本, 7.9.X LTS 版本不再使用 MySQL。
6.7.X 需要使用 Oracle JRE8
7.9.X 需要使用
[root@sonarqube ~]#groupadd -g 2020 sonarqube
[root@sonarqube ~]#useradd -r -m -s /bin/bash -g 2020 -u 2020 sonarqube #使用普通账户启动 sonarqube
[root@sonarqube ~]#vim /etc/sysctl.conf
vm.max_map_count=262144
fs.file-max=65536
[root@sonarqube ~]#sysctl -p
[root@sonarqube ~]#vim /etc/security/limits.conf
sonarqube - nofile 65536
sonarqube - nproc 2048
CPU/内存/磁盘
root@s4:~# apt-get install mysql-server mysql-client
root@s4:~# vim /etc/mysql/mysql.conf.d/mysqld.cnf #配置文件路径
root@s4:~# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.26-0ubuntu0.18.04.1 (Ubuntu)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
#创建数据库默认编码 utf-8 并授权
mysql> create database sonar default character set utf8 collate utf8_general_ci;
Query OK, 1 row affected (0.00 sec)
mysql> GRANT ALL PRIVILEGES ON sonar.* TO 'sonar'@'%' IDENTIFIED BY
'123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)
root@s4:~# mysql -usonar -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.26-0ubuntu0.18.04.1 (Ubuntu)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema || sonar |
+--------------------+
2 rows in set (0.00 sec)
sonar 依赖于 java 环境,而且 java 版本必须是 1.8 版本或更高,否则 sonar 启动失败
6.7.X 版本的 sonar 需要调用 elasticsearch, 而且默认需要使用普通用户启动
root@s4:~# cd /usr/local/src/
root@s4:/usr/local/src# unzip sonarqube-6.7.7.zip
root@s4:/usr/local/src# ln -sv /usr/local/src/sonarqube-6.7.7 /usr/local/sonarqube
'/usr/local/sonarqube' -> '/usr/local/src/sonarqube-6.7.7'
root@s4:/usr/local/src# chown sonarqube.sonarqube /usr/local/src/sonarqube-6.7.7
/usr/local/sonarqube -R #更改目录权限属主和属组为 sonarqube
root@s4:/usr/local/src# cd /usr/local/sonarqube
root@s4:/usr/local/sonarqube# ll #验证权限属主和属组都为 sonarqube
root@s4:/usr/local/sonarqube# su – sonarqube # 切换为 sonarqube 账户
sonarqube@s4:~$ cd /usr/local/sonarqube
sonarqube@s4:/usr/local/sonarqube$ vim conf/sonar.properties
sonarqube@s4:/usr/local/sonarqube$ grep "^[a-Z]" conf/sonar.properties
sonar.jdbc.username=sonar
sonar.jdbc.password=123456
sonar.jdbc.url=jdbc:mysql://127.0.0.1:3306/sonar?useUnicode=true&characterEncoding
=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
sonar.web.host=0.0.0.0
sonar.web.port=9000
sonarqube@s4:/usr/local/sonarqube$ ./bin/linux-x86-64/sonar.sh start
Starting SonarQube…
Started SonarQube.
验证日志
点击有上角 login 登录,默认用户名密码都是 admin
#插件本地路径安装中文插件
sonarqube@s4:~$ ll /usr/local/sonarqube/extensions/plugins/
total 40476
drwxr-xr-x 2 sonarqube sonarqube 4096 Jul 22 18:06 ./
drwxr-xr-x 5 sonarqube sonarqube 4096 Jul 22 18:07 ../
-rw-r--r-- 1 sonarqube sonarqube 92 Apr 16 15:39 README.txt
-rw-r--r-- 1 sonarqube sonarqube 2703958 Apr 15 18:38 sonar-csharp-plugin-6.5.0.3866.jar
-rw-r--r-- 1 sonarqube sonarqube 1618672 Apr 15 18:38 sonar-flex-plugin-2.3.jar
-rw-r--r-- 1 sonarqube sonarqube 6759535 Apr 15 18:38 sonar-java-plugin-4.15.0.12310.jar
-rw-r--r-- 1 sonarqube sonarqube 3355702 Apr 15 18:38 sonar-javascript-plugin-
3.2.0.5506.jar
-rw-r--r-- 1 sonarqube sonarqube 3022870 Apr 15 18:38 sonar-php-plugin-2.11.0.2485.jar
-rw-r--r-- 1 sonarqube sonarqube 4024311 Apr 15 18:38 sonar-python-plugin-1.8.0.1496.jar
-rw-r--r-- 1 sonarqube sonarqube 3625962 Apr 15 18:38 sonar-scm-git-plugin-1.3.0.869.jar
-rw-r--r-- 1 sonarqube sonarqube 6680471 Apr 15 18:38 sonar-scm-svn-plugin-1.6.0.860.jar
-rw-r--r-- 1 sonarqube sonarqube 2250667 Apr 15 18:38 sonar-typescript-plugin-
1.1.0.1079.jar
-rw-r--r-- 1 sonarqube sonarqube 7368250 Apr 15 18:38 sonar-xml-plugin-1.4.3.1027.jar
administration- Marketplace,在后面的搜索框搜索插件 chinese,然后点 install 安装
或 在 插 件 目 录 /usr/local/sonarqube/extensions/plugins/ 执 行以下命令
# wget https://github.com/SonarQubeCommunity/sonar-l10nzh/releases/download/sonar-l10n-zh-plugin-1.11/sonar-l10n-zh-plugin-1.11.jar
Web 界面安装完成插件后或者在插件目录下载插件后需要重启 sonarquebe 服务生效 :
sonarqube@s4:~$ /usr/local/sonarqube/bin/linux-x86-64/sonar.sh restart
Stopping SonarQube...
Waiting for SonarQube to exit...
Stopped SonarQube.
Starting SonarQube...
Started SonarQube.
或者在 web 界面重启
Sonarquebe 对代码的扫描都基于插件实现,因此要安装要扫描的开发语言插件
Php
Java
Python
内存不足的截图
[root@sonarqube ~]#apt-cache madison openjdk-11-jdk
openjdk-11-jdk | 11.0.8+10-0ubuntu1~18.04.1 | http://mirrors.huaweicloud.com/ubuntu bionic-security/main amd64 Packages
openjdk-11-jdk | 11.0.8+10-0ubuntu1~18.04.1 | http://mirrors.huaweicloud.com/ubuntu bionic-updates/main amd64 Packages
openjdk-11-jdk | 10.0.1+10-3ubuntu1 | http://mirrors.huaweicloud.com/ubuntu bionic/main amd64 Packages
openjdk-lts | 10.0.1+10-3ubuntu1 | http://mirrors.huaweicloud.com/ubuntu bionic/main Sources
openjdk-lts | 11.0.8+10-0ubuntu1~18.04.1 | http://mirrors.huaweicloud.com/ubuntu bionic-security/main Sources
openjdk-lts | 11.0.8+10-0ubuntu1~18.04.1 | http://mirrors.huaweicloud.com/ubuntu bionic-updates/main Sources
[root@sonarqube ~]#apt install -y openjdk-11-jdk
[root@sonarqube ~]#java -version
openjdk version "11.0.8" 2020-07-14
OpenJDK Runtime Environment (build 11.0.8+10-post-Ubuntu-0ubuntu118.04.1)
OpenJDK 64-Bit Server VM (build 11.0.8+10-post-Ubuntu-0ubuntu118.04.1, mixed mode, sharing)
[root@sonarqube ~]#apt-cache madison postgresql
postgresql | 10+190ubuntu0.1 | http://mirrors.huaweicloud.com/ubuntu bionic-security/main amd64 Packages
postgresql | 10+190ubuntu0.1 | http://mirrors.huaweicloud.com/ubuntu bionic-updates/main amd64 Packages
postgresql | 10+190 | http://mirrors.huaweicloud.com/ubuntu bionic/main amd64 Packages
postgresql-common | 190 | http://mirrors.huaweicloud.com/ubuntu bionic/main Sources
postgresql-common | 190ubuntu0.1 | http://mirrors.huaweicloud.com/ubuntu bionic-security/main Sources
postgresql-common | 190ubuntu0.1 | http://mirrors.huaweicloud.com/ubuntu bionic-updates/main Sources
[root@sonarqube ~]#apt install postgresql -y
切换到 postgres 操作, PostgresSQL 安装后会自动创建 postgres 用户且没有密码。
root@sonarqube-server:~# su - postgres
postgres@sonarqube-server:~$登录 postgresql 数据库:
postgres@sonarqube-server:~$ psql -U postgres
psql (10.12 (Ubuntu 10.12-0ubuntu0.18.04.1))
Type "help" for help.
创建数据库并进行授权普通用户访问:
postgres=# CREATE DATABASE sonar; #创建数据库
CREATE DATABASE
postgres=# CREATE USER sonar WITH ENCRYPTED PASSWORD '123456'; #创建用户
CREATE ROLE
postgres=# GRANT ALL PRIVILEGES ON DATABASE sonar TO sonar; #授权用户
GRANT
postgres=# ALTER DATABASE sonar OWNER TO sonar; #执行变更
ALTER DATABASE
postgres=# \q
#修改监听地址
[postgres@sonarqube ~]$vim /etc/postgresql/10/main/postgresql.conf
59 listen_addresses = '*'
#开启远程访问
root@sonarqube-server:~# vim /etc/postgresql/10/main/pg_hba.conf
85:local all postgres peer
90:local all all peer
92:host all all 0.0.0.0/0 md594:host all all ::1/128 md5
97:local replication all peer
98:host replication all 127.0.0.1/32 md5
99:host replication all ::1/128 md5
root@sonarqube-server:~# systemctl restart postgresql
[root@sonarqube ~]#mkdir /apps
[root@sonarqube ~]#cd /apps
[root@sonarqube apps]#unzip sonarqube-7.9.4.zip
[root@sonarqube apps]#ln -sv /apps/sonarqube-7.9.4 /apps/sonarqube
'/apps/sonarqube' -> '/apps/sonarqube-7.9.4'
[root@sonarqube sonarqube]#chown sonarqube.sonarqube /apps/sonarqube* -R
[root@sonarqube sonarqube]#su - sonarqube
sonarqube@sonarqube:~$ cd /apps/sonarqube
sonarqube@sonarqube:/apps/sonarqube$ vim conf/sonar.properties
sonar.jdbc.username=sonar
sonar.jdbc.password=123456
sonar.jdbc.url=jdbc:postgresql://10.0.78.108/sonar
\#sonar.jdbc.url=jdbc:postgresql://172.31.0.106/sonarqube?currentSchema=my_schema
sonarqube@sonarqube:/apps/sonarqube$ ./bin/linux-x86-64/sonar.sh --help
Usage: ./bin/linux-x86-64/sonar.sh { console | start | stop | force-stop | restart | status | dump }
sonarqube@sonarqube:/apps/sonarqube$ ./bin/linux-x86-64/sonar.sh start
Starting SonarQube...
Started SonarQube.
sonarqube@sonarqube:/apps/sonarqube$ tail logs/* -f
[root@sonarqube ~]#cat /etc/systemd/system/sonarqube.service
[Unit]
Description=SonarQube service
After=syslog.target network.target
[Service]
Type=simple
User=sonarqube
Group=sonarqube
PermissionsStartOnly=true
ExecStart=/usr/bin/nohup /usr/bin/java -Xms32m -Xmx32m -Djava.net.preferIPv4Stack=true -jar /apps/sonarqube-7.9.4/lib/sonar-application-7.9.4.jar
StandardOutput=syslog
LimitNOFILE=65536
LimitNPROC=8192
TimeoutStartSec=5
Restart=always
[Install]
WantedBy=multi-user.target
[root@sonarqube ~]#systemctl daemon-reload
[root@sonarqube ~]#systemctl start sonarqube.service
登录账户名和密码默认都是 admin
下载地址 https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/
官方文档 https://docs.sonarqube.org/latest/analysis/scan/sonarscanner/
sonarqube 通过调用扫描器 sonar-scanner 进行代码质量分析,即扫描器的具体工作就是扫描代码
root@jenkins-master:~# cd /apps
[root@jenkins-master apps]#unzip sonar-scanner-cli-4.3.0.2102-linux.zip
[root@jenkins-master apps]#ln -sv /apps/sonar-scanner-4.3.0.2102-linux/ /apps/sonar-scanner
'/apps/sonar-scanner' -> '/apps/sonar-scanner-4.3.0.2102-linux/'
[root@jenkins-master apps]#vim sonar-scanner/conf/sonar-scanner.properties
#----- Default SonarQube server
sonar.host.url=http://10.0.78.108:9000
#----- Default source code encoding
sonar.sourceEncoding=UTF-8
# unzip sonar-examples-master.zip
# cd sonar-examples-master/
# cd projects/languages/php/php-sonar-runner
# pwd
/usr/local/src/sonar-examples-master/projects/languages/php/php-sonar-runner
# ll
total 24
drwxr-xr-x 3 root root 4096 Jul 25 2016 ./
drwxr-xr-x 4 root root 4096 Jul 25 2016 ../
-rw-r--r-- 1 root root 453 Jul 25 2016 README.md
-rw-r--r-- 1 root root 331 Jul 25 2016 sonar-project.properties
drwxr-xr-x 2 root root 4096 Jul 25 2016 src/
-rw-r--r-- 1 root root 272 Jul 25 2016 validation.txt
# cat sonar-project.properties 以下为默认生成的配置文件
# Required metadata
sonar.projectKey=org.sonarqube:php-simple-sq-scanner #自定义项目 key
sonar.projectName=PHP :: Simple Project :: SonarQube Scanner #项目名称, 会显示在web
sonar.projectVersion=1.0 #项目版本
# Comma-separated paths to directories with sources (required)
sonar.sources=src #源代码目录
# Language
sonar.language=php #代码语言类型
# Encoding of the source files
sonar.sourceEncoding=UTF-8 #编码格式
#最终配置
# Required metadata
sonar.projectKey=qinghe-web1-key
sonar.projectName=qinghe-web1-name
sonar.projectVersion=0.1
# Comma-separated paths to directories with sources (required)
sonar.sources=src
# Language
sonar.language=py
# Encoding of the source files
sonar.sourceEncoding=UTF-8
#手动在当前项目代码目录执行扫描,以下是扫描过程的提示信息,扫描的配置文件
sonar-project.propertie 每个项目都要有
# pwd
/usr/local/src/sonar-examples-master/projects/languages/php/php-sonar-runner
# /usr/local/sonar-scanner/bin/sonar-scanner
安装插件 SonarQube Scanner,然后配置 SonarQube server, 系统管理-系统设置。
Jenkins—系统管理—系统设置–SonarQube servers
添加扫描器
Jenkins–系统管理-全局工具配置
/apps/sonar-scanner-4.3.0.2102-linux/
选择自己的项目( linuxNN-job1-develop) -构建-execute sonarqube scanner,将配置文件的
内容修改成如下格式填写完成后点保存
sonar.projectKey=qinghe-web1-key
sonar.projectName=qinghe-web1-name
sonar.projectVersion=0.1
sonar.sources=src
sonar.language=py
sonar.sourceEncoding=UTF-8
点击项目的立即构建,下图是执行成功的信息
Started by user jenkinsadmin
Building on master in workspace /var/lib/jenkins/workspace/linux36-job1-develop
[WS-CLEANUP] Deleting project workspace...
[WS-CLEANUP] Deferred wipeout is used...
[WS-CLEANUP] Done
using credential 0e23c215-2853-4bdf-9198-481f28ac0e1b
Cloning the remote Git repository
Cloning repository [email protected]:linux36/web1.git
\> git init /var/lib/jenkins/workspace/linux36-job1-develop # timeout=10
Fetching upstream changes from [email protected]:linux36/web1.git
\> git --version # timeout=10
using GIT_SSH to set credentials
\> git fetch --tags --progress [email protected]:linux36/web1.git +refs/heads/*:refs/remotes/origin/*
\> git config remote.origin.url [email protected]:linux36/web1.git # timeout=10
\> git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
\> git config remote.origin.url [email protected]:linux36/web1.git # timeout=10
Fetching upstream changes from [email protected]:linux36/web1.git
using GIT_SSH to set credentials
\> git fetch --tags --progress [email protected]:linux36/web1.git +refs/heads/*:refs/remotes/origin/*
\> git rev-parse refs/remotes/origin/develop^{commit} # timeout=10
\> git rev-parse refs/remotes/origin/origin/develop^{commit} # timeout=10
Checking out Revision 5110a701d0490d6aa2232ad40f8a245b23c52b5f (refs/remotes/origin/develop)
\> git config core.sparsecheckout # timeout=10
\> git checkout -f 5110a701d0490d6aa2232ad40f8a245b23c52b5f
Commit message: "v7"
\> git rev-list --no-walk 5110a701d0490d6aa2232ad40f8a245b23c52b5f # timeout=10
[linux36-job1-develop] $ /usr/local/src/sonar-scanner-4.0.0.1744-linux/bin/sonar-scanner -
Dsonar.host.url=http://192.168.7.104:9000 -Dsonar.language=php -Dsonar.projectName=job1-
develop -Dsonar.projectVersion=1.0 -Dsonar.sourceEncoding=UTF-8 -Dsonar.projectKey=job1-develop -
Dsonar.sources=./ -Dsonar.projectBaseDir=/var/lib/jenkins/workspace/linux36-job1-develop
INFO: Scanner configuration file: /usr/local/src/sonar-scanner-4.0.0.1744-linux/conf/sonarscanner.properties
INFO: Project root configuration file: NONE
INFO: SonarQube Scanner 4.0.0.1744
INFO: Java 11.0.3 AdoptOpenJDK (64-bit)
INFO: Linux 4.15.0-20-generic amd64
INFO: User cache: /root/.sonar/cache
INFO: SonarQube server 6.7.7
INFO: Default locale: "en_US", source code encoding: "UTF-8"
INFO: Publish mode
INFO: Load global settings
INFO: Load global settings (done) | time=69ms
INFO: Server id: 577C9AC7-AWwZJiIb-_VXsQd7E0lh
INFO: User cache: /root/.sonar/cache
INFO: Load plugins index
INFO: Load plugins index (done) | time=57ms
INFO: Plugin [l10nzh] defines 'l10nen' as base plugin. This metadata can be removed from manifest of
l10n plugins since version 5.2.
INFO: Process project properties
INFO: Load project repositories
INFO: Load project repositories (done) | time=92ms
INFO: Load quality profiles
INFO: Load quality profiles (done) | time=39ms
INFO: Load active rules
INFO: Load active rules (done) | time=913ms
INFO: Load metrics repository
INFO: Load metrics repository (done) | time=36ms
INFO: Project key: job1-develop
INFO: ------------- Scan job1-develop
INFO: Load server rules
INFO: Load server rules (done) | time=83ms
INFO: Base dir: /var/lib/jenkins/workspace/linux36-job1-develop
INFO: Working dir: /var/lib/jenkins/workspace/linux36-job1-develop/.scannerwork
INFO: Source paths: .
INFO: Source encoding: UTF-8, default locale: en_US
INFO: Language is forced to php
INFO: Index files
WARN: File '/var/lib/jenkins/workspace/linux36-job1-develop/index.html' is ignored because it doesn't
belong to the forced language 'php'
INFO: 0 files indexed
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by net.sf.cglib.core.ReflectUtils$1
(file:/root/.sonar/cache/3c43ca34b48e025530485308ddac54a2/sonar-javascript-plugin-
3.2.0.5506.jar) to method
java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of net.sf.cglib.core.ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
INFO: Sensor SonarJavaXmlFileSensor [java]
INFO: Sensor SonarJavaXmlFileSensor [java] (done) | time=0ms
INFO: Sensor Analyzer for "php.ini" files [php]
INFO: Sensor Analyzer for "php.ini" files [php] (done) | time=16ms
INFO: Sensor Zero Coverage Sensor
INFO: Sensor Zero Coverage Sensor (done) | time=0ms
INFO: Sensor CPD Block Indexer
INFO: Sensor CPD Block Indexer (done) | time=0ms
INFO: Calculating CPD for 0 files
INFO: CPD calculation finished
INFO: Analysis report generated in 186ms, dir size=22 KB
INFO: Analysis reports compressed in 19ms, zip size=5 KB
INFO: Analysis report uploaded in 42ms
INFO: ANALYSIS SUCCESSFUL, you can browse http://192.168.7.104:9000/dashboard/index/job1-
develop
INFO: Note that you will be able to access the updated dashboard once the server has processed the
submitted analysis report
INFO: More about the report processing at
http://192.168.7.104:9000/api/ce/task?id=AWwZi39XBenn7N3kRArM
INFO: Task total time: 4.319 s
INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 6.714s
INFO: Final Memory: 7M/24M
INFO: ------------------------------------------------------------------------
[linux36-job1-develop] $ /bin/sh -xe /tmp/jenkins5134965889873889449.sh
\+ cd /var/lib/jenkins/workspace/linux36-job1-develop
\+ tar czvf code.tar.gz index.html
index.html
\+ scp code.tar.gz [email protected]:/data/tomcat/tomcat_appdir/
\+ scp code.tar.gz [email protected]:/data/tomcat/tomcat_appdir/
\+ ssh [email protected] /etc/init.d/tomcat stop && rm -rf /data/tomcat/tomcat_webdir/myapp/*
&& cd /data/tomcat/tomcat_appdir && tar xvf code.tar.gz -C /data/tomcat/tomcat_webdir/myapp/
正在判断服务状态,请稍等 3 秒钟!
3
将代码部署到 web 服务器
新建一个项目叫 test-deploy 用于代码发布,上一个项目 testdemo 可用于代码 测试,当测试阶段出现问题的时候也不会立即进行发布,只有当测试通过之后才执行发布的项目
即可
如何将代码发布到 web 服务器?
可以通过执行命令或脚本的方式进行代码发布,在各 web 服务器包括Jenkins 服务器创建一个 www 用户,保持 id 一致,用于启动 web 服务并进行代码发布
# useradd www
# echo “123456” | passwd --stdin www
# su -www
$ ssh-keygen
添加 Jenkins 服务器 www 用户的公钥到 git 服务器项目当中
确认 www 用户的 key 可以拉取代码
关于权限
一般使用非 root 用户启动 web 服务及完成代码发布,默认 Jenkins 运行使用的是 Jenkins 用户,因此需要赋予 Jenkins 用户一定的权限,另外发布的脚本可以在本机也可以不在 本机,需要使用 Jenkins 用户 ssh到发布服务器执行 shell 脚本。
将脚本放在/home/www 用户家目录, git 代码也放在家目录,因此需要jenkins 服务器 远程到代码发布服务器执行远程命令,需要做免登陆认证,将 jenkins 服务器 root 和
www 用 户 的 公 钥 放 在 代 码 部 署 服 务 器 的 www 用 户 家 目录.ss/authorized_keys 文件中
# su -www
$ vim/home/www/.ssh/authorized_keys
• $ chmod 600 authorized_keys
在 root 用户和 www 用户下 ssh 到本机的 www 用户,确认可以免密码登录,以 便让部署服务器将用户的 key 添加到 know_keys,否则报错 Hostkey verification failed
假如 jenkins 使用普通用户 jenkins 或其他普通用户启动,则要授予 sudo 权限, root 不
需要设置。
# vim/etc/sudoers
56 #Defaults requiretty #不需要 tty
99jenkinsALL=(ALL) NOPASSWD: /usr/bin/ssh #不需要使用密码即可执行 ssh
脚本内容:
$ cd /home/www/
$ vim deploy.sh
\#!/bin/bash
echo $USER
cd /home/www/myweb1
git pull
scp -r ./* [email protected]:/apps/tomcat/webapps/myapp
scp -r ./* [email protected]:/apps/tomcat/webapps/myapp
#在 test-deploy 项目的构建步骤调用,项目-配置-构建
执行结果
复制 www 用户公钥到各 web 服务器的 www 用户
$ssh-copy-id [email protected]
$ssh-copy-id [email protected]
在另外一台服务器编辑代码后重新提交
# git clone http://192.168.10.130/web/myweb1.git
# echo “xxx” >> index.html
# git addindex.html
# git commitindex.html
# gitpush
在 jenkins 执行项目构建
构建项目之前要在 www 用下的 xxx 项目里面进行 git pull 命令。否则第一次更新提示输入yes 会导致部署失败
再次提交代码
构建结果
访问负载测试
代码测试的项目执行成功之后自动调用代码发布的项目完成代码部署安装 Parameterized 插件, 系统管理-管理插件-可选插件,搜索Parameterized, 如果插件在线安装不成功可以下载插件到此目录,然后把属主属组改成Jenkins在重启Jenkins服务即可完成安装
配置项目 test-demo 的构建后操作, demo 构建完成后自动构建
demp-deploy 项目
添加构建后操作
安装 pipeline 插
添加视图
定
配置视图
GitLab 触发 jenkins 构建项目
目的为在公司的测试环境当中一旦开发向 gitlab 仓库提交成功代码, gitlab 通知jenkins 进行构建项目、代码质量测试然后部署至测试环境,注意这只是测试环境,而生产环境依然需要手动部署代码
安装 Gitlab Hook Plugin 插件
# 系 统 管 理 - 管 理 插 件 - 可 选 插 件 -Gitlab Hook Plugin 和 Build
AuthorizationTokenRoot
Plugin
# openssl rand -hex 12
f7d0ead5398bd808ee139067
测试成功
# 插 件 使 用 介 绍 , https://wiki.jenkinsci.org/display/JENKINS/Build+Token+Root+Plugin
\
#选择项目-设置-webhooks
http://192.168.10.131:8080/buildByToken/build?job=testdemo&token=f7d0ead5398bd808ee139067
格式如下
http://X.X.X.X:8080/buildByToken/build?job=项目名&token=随机数
保存后进行测试
在另一台向 git 服务器提交代码,验证是否可以自动部署
# echo “ccc” >>index.html
# git addindex.html
# git commit -m"ccc“
# git push
验证是否自动构建
实现在 haproxy 动态增减服务器
在 Jenkins 服务器复制 www 用户的公钥到 haproxy 服务器
$ ssh-copy-id [email protected]
# ssh-copy-id [email protected]
Haproxy 服务器编辑# vim /etc/sudoers 必须要 tty
# vim/etc/sudoers
root ALL=(ALL) ALL
jenkinsALL=(ALL) NOPASSWD: /usr/bin/ssh
www ALL=(ALL) ALL
测试 www 和 root 用户的 ssh 功能
验证:
开启功能
# vim/etc/haproxy/haproxy.cfg
stats socket /usr/local/haproxy/stats mode 600 level admin
安装命令并测试
yum install socat
#echo "help"| socat stdio /usr/local/haproxy/stats
# echo "show info"| socat stdio /usr/local/haproxy/stats
#echo "show stat"| socat stdio /usr/local/haproxy/stats
# echo "disable server myapp_host/web2"|socat stdio /usr/local/haproxy/stats
分组是为了在代码分批次上线的时候对后端服务器的一种筛选方法:
编写 shell 脚本实现自动化部署与回 滚