LEMON

记录站

0%

JenKins

GitLab + Jenkins 基本过程

一、持续集成、持续交付、持续部署

1. 概述:

  • 软件开发周期中需要一些可以帮助开发者提升速度的自动化工具。其中工具最重要的目的是促进软件项目的持续集成与交付。通过CI/CD工具,开发团队可以保持软件更新并将其迅速的投入实践中。CI/CD也被认为是敏捷开发的最重要实践。

2. 持续集成(CI)

概述:【持续集成指的是,频繁地(一天多次)将代码集成到主干】

  • 持续集成(Continuous integration,简称CI),一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建 (包括推送代码,自动化集成,自动化测试,返回结果) 来验证,从而尽早地发现集成错误。

  • 整体流程:推送代码 – > 集成代码 – > 构建 –> 代码测试 – > 反馈结果

  • 持续集成的最终目的就是 让产品可以快速迭代,同时还能保持高质量,简化工作流程

image-20200519112017013

3. 持续交付(CD)

概述:【持续 将通过持续集成后的代码进行手动部署】

  • 持续交付(Continuous Delivery, CD)是一种软件工程的手段,让软件在短周期内产出,确保软件随时可以被可靠地发布。其目的在于更快、更频繁地构建、测试以及发布软件。通过加强对生产环境的应用进行渐进式更新,这种手段可以降低交付变更的成本与风险。一个简单直观的与可重复的部署过程对于持续交付来说是很重要的。

  • 整体流程:推送代码 – > 集成代码 – > 构建 –> 代码测试 — > 反馈结果 –> 测试 –> 手动 –> 部署到生产

  • 持续交付指的是在持续集成后的环境基础之上,将代码部署到预生产环境上。

image-20200519114326555

4. 持续部署(CD)

概述:【基于 集成 交付之上的,部署和交付的区别在于 无论何时 代码都是可以部署的 没有问题的】

  • 持续部署(Continuous Deployment,缩写为 CD)是持续交付的下一步,指的是代码通过评审以后,自动部署到生产环境;持续部署的目标是,代码在任何时刻都是可部署的,可以进入生产阶段。

  • 持续部署指的是持续交付的下一步,指代码可以在任何时刻都是可以部署的 没问题的,最后部署到生产环境下的过程

  • 整体流程:推送代码 – > 集成代码 – > 构建 –> 代码测试 — > 反馈结果 –> 测试 –> 自动 –> 部署到生产

image-20200519114904256

5. 集成 & 交付软件

概述:

  • 典型的部署流水线,CD 流水线由几个不同的阶段组成; 一个工具不能满足所有这些步骤。

image-20200519115644610

二、Git版本控制器

1. Git工作图

2. 四个区域和五种状态

1. 四个区域
  • 工作区(Working Area)
  • 暂存区(Stage)
  • 本地仓库(Local Repository)
  • 远程仓库(Remote Repository)
2. 五种状态
  • 未修改(Origin)
  • 已修改(Modified)&未追踪(Untracked)
  • 已暂存(Staged)
  • 已提交(Committed)
  • 已推送(Pushed)

3. 安装git

随便打开一台虚拟机用来练习git的使用

1
[root@git ~]# yum -y install git

4. 常见的 Git 命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
开始一个工作区(参见:git help tutorial)
clone 克隆一个仓库到一个新目录
init 创建一个空的 Git 仓库或重新初始化一个已存在的仓库

在当前变更上工作(参见:git help everyday)
add 添加文件内容至索引
mv 移动或重命名一个文件、目录或符号链接
reset 重置当前 HEAD 到指定状态
rm 从工作区和索引中删除文件

检查历史和状态(参见:git help revisions)
bisect 通过二分查找定位引入 bug 的提交
grep 输出和模式匹配的行
log 显示提交日志
show 显示各种类型的对象
status 显示工作区状态

扩展、标记和调校您的历史记录
branch 列出、创建或删除分支
checkout 切换分支或恢复工作区文件
commit 记录变更到仓库
diff 显示提交之间、提交和工作区之间等的差异
merge 合并两个或更多开发历史
rebase 本地提交转移至更新后的上游分支中
tag 创建、列出、删除或校验一个 GPG 签名的标签对象

协同(参见:git help workflows)
fetch 从另外一个仓库下载对象和引用
pull 获取并整合另外的仓库或一个本地分支
push 更新远程引用和相关的对象

5. 配置git

  • 你是谁,你的邮箱是什么。这样就知道是谁提交的代码了
1
2
3
[root@git ~]# git config --global user.name "lemon"                     #名字
[root@git ~]# git config --global user.email "lemon_row@163.com" #邮箱
[root@git ~]# git config --global color.ui true #颜色

6. 检查配置信息

  • 这个 .gitconfig 是在你当前的家目录下的一个隐藏文件
1
2
3
4
5
6
[root@git ~]# cat .gitconfig 
[user]
name = lemon
email = lemon_row@163.com
[color]
ui = true

7. 基本使用案例

实战(一)git如何快速的提交目录文件至本地仓库?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
[root@git ~]# mkdir project && cd project    #创建git工作目录
[root@git project]# git init #初始化该目录为git本地仓库
初始化空的 Git 版本库于 /root/project/.git/

[root@git project]# ls -a #初始化成功后会在该目录下生成一个.git的隐藏目录
. .. .git

[root@git project]# touch file{1..3}.txt #创建三个文件

[root@git project]# ls
file1.txt file2.txt file3.txt

[root@git project]# git status #查看暂存区状态
# 位于分支 master
#
# 初始提交
#
# 未跟踪的文件:
# (使用 "git add <file>..." 以包含要提交的内容)
#
# file1.txt
# file2.txt
# file3.txt
提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)

[root@git project]# git add . #将文件添加到暂存区
[root@git project]# git status #查看暂存区状态
# 位于分支 master
#
# 初始提交
#
# 要提交的变更:
# (使用 "git rm --cached <file>..." 撤出暂存区)
#
# 新文件: file1.txt
# 新文件: file2.txt
# 新文件: file3.txt
#

[root@git project]# git commit -m "NOW 1 add --> file1 file2 file3" #将其提交至本地仓库
[master(根提交) 75b88ee] NOW 1 add --> file1 file2 file3
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file1.txt
create mode 100644 file2.txt
create mode 100644 file3.txt

[root@git project]# git status
# 位于分支 master
无文件要提交,干净的工作区

实战(二)git 如何将文件改名并重新提交到本地仓库?

  • 分两种:

    • 使用 git mv 命令(推荐使用)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    [root@git project]# git mv file1.txt file.txt     #修改file.txt文件名为file1.txt
    [root@git project]# ls
    file2.txt file3.txt file.txt

    [root@git project]# git status
    # 位于分支 master
    # 要提交的变更:
    # (使用 "git reset HEAD <file>..." 撤出暂存区)
    #
    # 重命名: file1.txt -> file.txt
    #
    [root@git project]# git add .
    [root@git project]# git status
    # 位于分支 master
    # 要提交的变更:
    # (使用 "git reset HEAD <file>..." 撤出暂存区)
    #
    # 重命名: file1.txt -> file.txt
    #
    [root@git project]# git commit -m "NOW 2 rename file1 --> file.txt"
    [master dbff765] NOW 2 rename file1 --> file.txt
    1 file changed, 0 insertions(+), 0 deletions(-)
    rename file1.txt => file.txt (100%)

    [root@git project]# git status
    # 位于分支 master
    无文件要提交,干净的工作区
    • 使用 mv 命令(不推荐使用)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    [root@git project]# mv file.txt file1.txt    #修改file1.txt文件名为file.txt
    [root@git project]# ls
    file2.txt file3.txt file.txt

    [root@git project]# git status #查看一下暂存区状态
    # 位于分支 master
    # 尚未暂存以备提交的变更:
    # (使用 "git add/rm <file>..." 更新要提交的内容)
    # (使用 "git checkout -- <file>..." 丢弃工作区的改动)
    #
    # 删除: file.txt
    #
    # 未跟踪的文件:
    # (使用 "git add <file>..." 以包含要提交的内容)
    #
    # file1.txt
    修改尚未加入提交(使用 "git add" 和/或 "git commit -a"

    [root@git project]# git rm file.txt
    rm 'file.txt'

    [root@git project]# git add file1.txt

    [root@git project]# git status
    # 位于分支 master
    # 要提交的变更:
    # (使用 "git reset HEAD <file>..." 撤出暂存区)
    #
    # 重命名: file.txt -> file1.txt
    #

    [root@git project]# git commit -m "NOW 3 rename file --> file1.txt"
    [master 6e97421] NOW 3 rename file --> file1.txt
    1 file changed, 0 insertions(+), 0 deletions(-)
    rename file.txt => file1.txt (100%)

    [root@git project]# git status
    # 位于分支 master
    无文件要提交,干净的工作区

实战(三)如何比对 工作目录文件内容、暂存区文件内容、本地仓库文件内容之间的差役?

  • 使用 git diff 命令来 比对 工作目录文件内容 与 暂存区文件内容
  • 使用 git diff --cached 命令来 比对 暂存区文件内容、本地仓库文件内容

image-20200520101936824

1.工作区 file1 内容 与 暂存区 file1 内容比较之间的差异

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#给file1.txt文件加点内容 后并 提交到本地仓库
[root@git project]# echo 'aaaaa' >> file1.txt
[root@git project]# git add .
[root@git project]# git commit -m "NOW 4 read-in file1.txt --> aaaaa"
[master 3485684] NOW 4 read-in file1.txt --> aaaaa
1 file changed, 1 insertion(+)

#给file1.txt文件加点内容 不提交
[root@git project]# echo 'bbbbb' >> file1.txt
[root@git project]# git status
# 位于分支 master
# 尚未暂存以备提交的变更:
# (使用 "git add <file>..." 更新要提交的内容)
# (使用 "git checkout -- <file>..." 丢弃工作区的改动)
#
# 修改: file1.txt
#
修改尚未加入提交(使用 "git add" 和/或 "git commit -a"

#工作区与暂存区比较差役
[root@git project]# git diff file1.txt
diff --git a/file1.txt b/file1.txt
index ccc3e7b..be4e668 100644
--- a/file1.txt #表示变动前的版本
+++ b/file1.txt #表示变动后的版本
@@ -1 +1,2 @@
aaaaa
+bbbbb #加入的内容

2.暂存区 file1 内容 与 本地仓库 file1 内容比较之间的差异

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#将其修改的文件添加到暂存区中
[root@git project]# git add .
[root@git project]# git diff file1.txt
[root@git project]# 这个时候可以看到,工作区 与 缓存区 已经保持抑一致了

#暂存区与本地仓库比较差役
[root@git project]# git diff --cached file1.txt
diff --git a/file1.txt b/file1.txt
index ccc3e7b..be4e668 100644
--- a/file1.txt
+++ b/file1.txt
@@ -1 +1,2 @@
aaaaa
+bbbbb

#然后将其所有暂存区内容提交至本地仓库
[root@git project]# git commit -m "NOW 5 read-in file1.txt --> bbbbb"
[master fdf30db] NOW 5 read-in file1.txt --> bbbbb
1 file changed, 1 insertion(+)
[root@git project]#
[root@git project]# git diff --cached file1.txt
[root@git project]# 此时可以看到,暂存区 与 本地仓库 已经保持抑一致了

实战(四)如何理解git commit 提交操作?

  • 可以将其理解为虚拟机的快照功能,简单来说就是每次commit就是相当于对文件做了一次快照。

  • FQ:知道了commit相当于快照后,那如何得知该文件快照了多少次 都修改了哪些内容呢?

  • 答:使用 git log 或者 git reflog 查看历史的commit快照记录

  • 但是这种查看方式,输出的信息太过多余,我们可以使用 --oneline 选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#查看历史的git commit快照
[root@git project]# git log
commit fdf30db3870322636d06b79a74ed5feb399213ea #commit的id编号(唯一的)
Author: lemon <lemon_row@163.com> #是谁提交的
Date: Wed May 20 09:55:33 2020 +0800 #什么时间提交的

NOW 5 read-in file1.txt --> bbbbb #提交的信息描述

commit 34856846ee0540482ab21a3df4bf821dd2329961
Author: lemon <lemon_row@163.com>
Date: Wed May 20 09:51:53 2020 +0800

NOW 4 read-in file1.txt --> aaaaa

commit 2b1c545d923502f1bfd20c25a3f58ff8519a44f0
Author: lemon <lemon_row@163.com>
Date: Wed May 20 09:50:12 2020 +0800

NOW 3 rename file --> file1.txt

commit 0c943fc2c68773efea85a0ed0a26dcfbf973e351
Author: lemon <lemon_row@163.com>
Date: Wed May 20 09:49:20 2020 +0800

NOW 2 rename file1 --> file.txt

commit 75b88eeb1dc16a54b6da9419f5d8e872b900df0e
Author: lemon <lemon_row@163.com>
Date: Wed May 20 09:46:46 2020 +0800

NOW 1 add --> file1 file2 file3
(END)

##但是这种查看方式,输出的信息太过多余,我们可以使用--oneline选项
[root@git project]# git log --oneline
fdf30db NOW 5 read-in file1.txt --> bbbbb
3485684 NOW 4 read-in file1.txt --> aaaaa
2b1c545 NOW 3 rename file --> file1.txt
0c943fc NOW 2 rename file1 --> file.txt
75b88ee NOW 1 add --> file1 file2 file3

#还有git log -n 的方式,查看最近的n次快照
[root@git project]# git log --oneline -2
c652338 NOW 7 read-in file1 ---> ddddd
f405afa NOW 6 read-in file1 ---> ccccc

实战(五)git 保存了状态后,想回退怎么办?

  • 如果使用虚拟机的话,肯定想都不用想,直接还原快照就得了,那么 git 优势如何实现的呢?

1.如果本地工作目录修改文件错误像回退怎么办?【工作目录 与 暂存区的撤销】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#误操作
[root@git project]# > file1.txt

[root@git project]# git status
# 位于分支 master
# 尚未暂存以备提交的变更:
# (使用 "git add <file>..." 更新要提交的内容)
# (使用 "git checkout -- <file>..." 丢弃工作区的改动)
#
# 修改: file1.txt
#
修改尚未加入提交(使用 "git add" 和/或 "git commit -a"

#丢弃工作区的改动(恢复)
[root@git project]# git checkout file1.txt

[root@git project]# git status
# 位于分支 master
无文件要提交,干净的工作区

[root@git project]# cat file1.txt
aaaaa
bbbbb

2.工作文件误操作提交至暂存区中该怎么办?

使用 本地仓库 — 覆盖 — 暂存区 — 覆盖 — 工作仓库

git reset HEAD 文件名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#误操作
[root@git project]# > file1.txt
[root@git project]# git add .
[root@git project]# git status
# 位于分支 master
# 要提交的变更:
# (使用 "git reset HEAD <file>..." 撤出暂存区)
#
# 修改: file1.txt

[root@git project]# git reset HEAD file1.txt #取消这个暂存区的内容
重置后撤出暂存区的变更:
M file1.txt

[root@git project]# git status
# 位于分支 master
# 尚未暂存以备提交的变更:
# (使用 "git add <file>..." 更新要提交的内容)
# (使用 "git checkout -- <file>..." 丢弃工作区的改动)
#
# 修改: file1.txt
#
修改尚未加入提交(使用 "git add" 和/或 "git commit -a"

[root@git project]# git checkout file1.txt

[root@git project]# git status
# 位于分支 master
无文件要提交,干净的工作区

[root@git project]# cat file1.txt
aaaaa
bbbbb

实战(六)回滚版本,回滚之前的版本 和 回滚之后的版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
[root@git project]# echo 'ccccc' >> file1.txt 
[root@git project]# git add .
[root@git project]# git commit -m "NOW 6 read-in file1 ---> ccccc"

[root@git project]# echo 'ddddd' >> file1.txt
[root@git project]# git add .
[root@git project]# git commit -m "NOW 7 read-in file1 ---> ddddd"
[root@git project]# cat file1.txt
aaaaa
bbbbb
ccccc
ddddd

#比如我就想回退到ccccc的版本(回滚之前的版本)
[root@git project]# git log --oneline
c652338 NOW 7 read-in file1 ---> ddddd
f405afa NOW 6 read-in file1 ---> ccccc #使用前面第一段commit的id进行回滚操作
fdf30db NOW 5 read-in file1.txt --> bbbbb
3485684 NOW 4 read-in file1.txt --> aaaaa
2b1c545 NOW 3 rename file --> file1.txt
0c943fc NOW 2 rename file1 --> file.txt
75b88ee NOW 1 add --> file1 file2 file3

[root@git project]# git reset --hard f405afa #回滚
HEAD 现在位于 f405afa NOW 6 read-in file1 ---> ccccc

#查看是否已经回到这个版本
[root@git project]# git rev-parse HEAD
f405afac0930c1feb0ee86cfa8b4c6032afd4b69
[root@git project]# cat file1.txt
aaaaa
bbbbb
ccccc

#但是,有个问题,此时我又想回到ddddd的版本怎么办?(回滚之后的版本)
[root@git project]# git log --oneline #这次会发现ddddd的版本消失了
f405afa NOW 6 read-in file1 ---> ccccc
fdf30db NOW 5 read-in file1.txt --> bbbbb
3485684 NOW 4 read-in file1.txt --> aaaaa
2b1c545 NOW 3 rename file --> file1.txt
0c943fc NOW 2 rename file1 --> file.txt
75b88ee NOW 1 add --> file1 file2 file3

#答:使用git reflog
[root@git project]# git reflog
f405afa HEAD@{0}: reset: moving to f405afa
c652338 HEAD@{1}: commit: NOW 7 read-in file1 ---> ddddd #这次就可以找到了
f405afa HEAD@{2}: commit: NOW 6 read-in file1 ---> ccccc
fdf30db HEAD@{3}: commit: NOW 5 read-in file1.txt --> bbbbb
3485684 HEAD@{4}: commit: NOW 4 read-in file1.txt --> aaaaa
2b1c545 HEAD@{5}: commit: NOW 3 rename file --> file1.txt
0c943fc HEAD@{6}: commit: NOW 2 rename file1 --> file.txt
75b88ee HEAD@{7}: commit (initial): NOW 1 add --> file1 file2 file3

[root@git project]# git reset --hard c652338 #在进行回滚
HEAD 现在位于 c652338 NOW 7 read-in file1 ---> ddddd

[root@lemon project01]# git rev-parse HEAD
c652338f12a5102e9691dce3ecac4f57cf19639e
[root@git project]# cat file1.txt
aaaaa
bbbbb
ccccc
ddddd

8. Git 标签的 创建 删除

  • git 标签能起到什么作用?
    • 当git仓库内的数据有改善或功能时,我们经常会打一个类似于软件版本号的tag标签,这样就能通过标签将版本库中的某个版本给记录下来,便于我们后续将特定时期的数据取出来用。
    • 简单来说:标签也是一个版本库的一个快照,他与commit id 是绑定在一起的东西。
  • 为什么要使用git标签?
    • 既然都已经有了commit id了,为什么还要用tag标签?
    • 因为commit的id号不容易使人记忆,所以,使用tag标签就是因为他好记 v1.0.0
    • 绝大部分公司都是基于标签进行对代码版本的管理
  • git 标签的基本使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#为最新提交的代码创建标签
[root@git project]# git tag -a "v1.0.0" -m "latest"
[root@git project]# git tag #查看当前分支的所有标签
v1.0.0

[root@git project]# git show --oneline v1.0.0 #查看这个标签是基于哪个commit快照
tag v1.0.0

latest
c652338 NOW 7 read-in file1 ---> ddddd
diff --git a/file1.txt b/file1.txt
index d0bc53a..8dd8367 100644
--- a/file1.txt
+++ b/file1.txt
@@ -1,3 +1,4 @@
aaaaa
bbbbb
ccccc
+ddddd


#以指定的commit id 而创建标签
[root@lemon project01]# git log --oneline
c652338 NOW 7 read-in file1 ---> ddddd
f405afa NOW 6 read-in file1 ---> ccccc
fdf30db NOW 5 read-in file1.txt --> bbbbb
3485684 NOW 4 read-in file1.txt --> aaaaa
2b1c545 NOW 3 rename file --> file1.txt
0c943fc NOW 2 rename file1 --> file.txt
75b88ee NOW 1 add --> file1 file2 file3

[root@git project]# git tag -a 'v1.0.1' f405afa -m "NOW 6"
[root@git project]# git tag
v1.0.0
v1.0.1
[root@git project]# git show v1.0.1
tag v1.0.1
Tagger: lemon <lemon_row@163.com>
Date: Wed May 20 11:16:03 2020 +0800

NOW 6

commit f405afac0930c1feb0ee86cfa8b4c6032afd4b69
Author: lemon <lemon_row@163.com>
Date: Wed May 20 10:03:44 2020 +0800

NOW 6 read-in file1 ---> ccccc

diff --git a/file1.txt b/file1.txt
index be4e668..d0bc53a 100644
--- a/file1.txt
+++ b/file1.txt
@@ -1,2 +1,3 @@
aaaaa
bbbbb
+ccccc

#不小心打错了标签,怎么删除这个标签?
[root@git project]# git tag -d v1.0.1
已删除标签 'v1.0.1'(曾为 608f0e6)

[root@git project]# git tag
v1.0.0

9. Git 分支

1. 概念

  • 分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努力学习SVN。

  • 如果两个平行宇宙互不干扰,那对现在的你也没啥影响。不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了Git又学会了SVN!

image-20200519200256163

2. 创建与合并分支原理

  • 版本回退里,你已经知道,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即 master 分支。HEAD严格来说不是指向提交,而是指向mastermaster才是指向提交的,所以,HEAD指向的就是当前分支。

  • 一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:

image-20200505152246823

  • 每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长,当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:

  • 你看,Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!

  • 不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,master指针不变:

  • 假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

  • 所以Git合并分支也很快!就改改指针,工作区内容也不变!

  • 合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:

3. 常见的分支命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//创建分支
git branch <name> #基于当前commit创建test分支。.git/HEAD文件中记录了当前分支名字。

//删除分支
git branch -d test #删除本地test分支
git branch -D test #test分支还没有合入当前分支,所以要用-D参数才能删掉。
git push origin --delete test #删除远程test分支

//查看分支
git branch #列出当前分支清单
git branch -v #查看各个分支最后一个提交信息
git branch -a #查看远程分支和本地分支
git branch --merged #查看哪些分支被合并
git branch --no-merged #查看哪些分支未被合并

//融合及切换分支
git merge #融合分支
git checkout -b <name> #创建+切换分支
git checkout #切换分支

//拉取分支
git fetch origin #同步远程服务器的数据到本地
git checkout -b test origin/test_remote #将远程分支test_remote拉取下来到本地test分支
git checkout test #将远程分支test拉取下来到本地test分支
git pull test #从远程分支test中checkout下来的本地分支test成为跟踪分支,使用git pull或者git push就会操作到对应的远程分支test

4. 分支的使用演示

创建分支,开发新功能是不能在master分支上开发

1
2
[root@git test]# git branch about            #创建about分支
[root@git test]# git branch #查看分支

1
[root@git test]# git checkout about          #切换分支

1
[root@git test]# git status

1
[root@git test]# git log         #查看about分支的commit记录

1
[root@git test]# echo "about us" >> about.html         #在当前分支开发新功能

1
2
[root@git test]# git add .
[root@git test]# git commit -m "about"

1
[root@git test]# git log         #查看about分支的commit记录

1
2
[root@git test]# git checkout master          #切换到master分支
[root@git test]# git log #查看master分支的commit记录

1
2
[root@git test]# git merge about               #在master分支上合并about分支
//注意:在公司中可不是这么搞的,因为你不能保证master分支的线路会一直保持在原地,所以一般开发都是先在自己的分支上重新将master分支合并(相当于同步master分支内容),然后在测试有没有问题,没有问题后才会到master分支上将其开发好的分支合并到master上面,然后在删除合并到master的分支

1
[root@git test]# git log && ls

1
2
3
4
5
6
7
8
[root@git test]# git branch test                  #创建test分支
[root@git test]# git checkout test #切换到test分支进行开发
[root@git test]# echo "test" > test.html
[root@git test]# git add .
[root@git test]# git commit -m "test"

[root@git test]# git checkout master #切换至master分支
[root@git test]# git branch --merged #查看已经合并的分支

1
[root@git test]# git branch --no-merged            #查看未合并的分支

1
[root@git test]# git branch -D test                #删除test分支

5. 分支冲突

10. Git远程仓库 – github

1. github 是什么

  • GitHub是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名GitHub

  • GitHub于2008年4月10日正式上线,除了Git代码仓库托管及基本的 Web管理界面以外,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱(报表)、代码片段分享(Gist)等功能。目前,其注册用户已经超过350万,托管版本数量也是非常之多,其中不乏知名开源项目 Ruby on Rails、python 等。

  • 对于我们个人的话,GIT服务器并不需要我们搭建,使用github就可以满足我们的需求。官网:https://github.com/

2. 登陆 github

3. 创建远程仓库

  • 说明:

    • code:代码
    • issues:问题
    • pull requests:拉取要求
    • Actions:动作
    • projects:专案
    • Wiki:维基
    • Security:安全
    • lnsights:见解
    • settings:设置
  • 克隆仓库的两种协议:

    • https 协议:如果你这个仓库是私有的,克隆仓库时需要输入用户名 密码
    • ssh协议:需要在github上加入你机器上某个用户的ssh公钥才能使用
  • 常用的git远程仓库命令

    • git remote #查看当前的远程库
    • git remote -v #执行时加上 -v 参数,你还可以看到每个别名的实际链接地址。
    • git remote add [别名] url #添加一个远程仓库
    • git remote rm [别名] #删除远程仓库
    • git push -u origin master #推送本地到远程分支
    • git pull -u origin master #获取最新master代码到本地

4. 使用 github

  • 这里 https 的我就不掩饰了,很简单,这里我使用ssh协议的,而且使用 win10 展示

  • 为用户生成一个ssh的公钥 及 私钥 目录

  • 将其 公钥 拷贝到 github

image-20200520151538386

  • 克隆远程仓库
1
$ git clone git@github.com:lemonOps/project01.git 

  • 将本地仓库推送至远程仓库
1
2
3
$ git remote add origin git@github.com:lemonOps/project01.git    #添加好推送的仓库地址

$ git remote -v #查看当前的远程仓库

image-20200520152258943

1
2
3
4
5
6
7
$ echo "# 第一次提交至远程仓库" > README.md

$ git add .

$ git commit -m "NOW 1 add --> README.md"

$ git push -u origin master

  • 回到 github上查看

  • 给此次提交打上标签并再次推送至 github
1
2
3
4
5
6
7
8
9
$ git log --oneline

$ git tag -a "v1.0" 6de1296 -m "标签 1"

$ git tag

$ git show v1.0 --oneline

$ git push -u origin v1.0

11. git 推送代码的整体过程

  • 创建自己的dev01分支
1
2
Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git branch dev01
  • 模拟master主分支更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ echo "# NOW 2 lemon very good" > lemon.md

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git add .

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git commit -m "NOW 2 add --> lemon.md"
[master 87c2a24] NOW 2 add --> lemon.md
1 file changed, 1 insertion(+)
create mode 100644 lemon.md

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git reflog --oneline
87c2a24 (HEAD -> master) HEAD@{0}: commit: NOW 2 add --> lemon.md
94a2b68 (tag: v1.0, origin/master, origin/HEAD, dev01) HEAD@{1}: clone: from git@github.com:devopssss/project01.git

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git tag -a "v2.0" 87c2a24 -m "第二此提交"

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git tag
v1.0
v2.0

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git remote add origin git@github.com:devopssss/project01.git

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git remote -v
origin git@github.com:devopssss/project01.git (fetch)
origin git@github.com:devopssss/project01.git (push)

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git push -u origin master

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git push -u origin v2.0

  • 进行dev01分支的开发;(现在这个分支和master上的分支内容是不一致的 !!!)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git checkout dev01

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (dev01)
$ ls
README.md

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (dev01)
$ echo "dev01" > dev01.txt

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (dev01)
$ ls
dev01.txt README.md

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (dev01)
$ git add .

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (dev01)
$ git commit -m "dev01"
[dev01 01996d5] dev01
1 file changed, 1 insertion(+)
create mode 100644 dev01.txt
  • 使用git pull 在自己的分支上重新将master分支合并(相当于同步master分支内容),然后在测试有没有问题
1
2
3
4
5
6
Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (dev01)
$ git pull origin master

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (dev01)
$ ls
dev01.txt lemon.md README.md
  • 测试没有问题后才会到master分支上将其开发好的分支合并到master上面,然后在删除合并到master的分支
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (dev01)
$ git checkout master

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git merge dev01
Updating 87c2a24..aaed965
Fast-forward
dev01.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 dev01.txt

Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git branch -d dev01
Deleted branch dev01 (was aaed965).
  • 最后在推送至远程仓库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git log --oneline
aaed965 (HEAD -> master) Merge branch 'master' of github.com:devopssss/project01 into dev01
01996d5 dev01
87c2a24 (tag: v2.0, origin/master) NOW 2 add --> lemon.md
94a2b68 (tag: v1.0) NOW 1 add --> README.md


Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git tag -a "v3.0" aaed965 -m "标签 3"


Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git push -u origin master
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:devopssss/project01.git
87c2a24..aaed965 master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.


Administrator@DESKTOP-HK1R5KR MINGW64 ~/Desktop/project01 (master)
$ git push -u origin v3.0
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 8 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 678 bytes | 339.00 KiB/s, done.
Total 6 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), done.
To github.com:devopssss/project01.git
* [new tag] v3.0 -> v3.0

三、Gitlab 代码仓库

1. 简介概述

  • 与 GitHub 一样,GitLab 是一个基于Web的资源库管理器,可让团队协作处理代码,复制代码以安全地创建和编辑新项目,然后将完成的代码合并到现有项目中。

  • GitLab 是用Ruby编程语言编写的,包含Wiki 和问题跟踪功能。它有不同的版本:GitLab 社区版(CE),企业版(EE) 和 GitLab托管版本GitLab.com。

  • 它拥有超过1400名贡献者,并被阿里巴巴,美国宇航局,欧洲核子研究中心等主要组织使用。

2. 什么是 Gitlab

  • GitLab 是一个开源分布式版本控制系统

  • 开发语言: Ruby

  • 功能:管理项目源代码、版本控制、代码复用与查找

3. GitLab 与 GitHub 的不同

  • Github 分布式在线代码托管仓库,个人版本可直接在线免费使用,企业版本收费且需要服务器安装。
  • Gitlab 分布式在线代码仓库托管软件,分社区免费版本与企业收费版本,都需要服务器安装。

4. Gitlab 的优势和应用场景

  • 开源免费,适合中小型公司将代码放置在该系统中

  • 品差异化的版本管理,离线同步以及强大分支管理功能

  • 便捷的GUI操作界面以及强大账户权限管理功能

  • 集成度很高,能够集成绝大多数的开发工具,支持内置HA,保证在高并发下仍旧实现高可用性

5. GitLab 主要服务构成

  • Nginx 静态Web服务器
  • Gitlab-workhorse 轻量级的反向代理服务器
  • Gitlab-shell 用于处理Git命令和修改authorized keys列表
  • Logrotate 日志文件管理工具
  • Postgresql 数据库
  • Redis 缓存服务器

6. GitLab 的工作流程

  • 创建并克隆项目
  • 创建项目某Feature分支
  • 编写代码并提交至该分支
  • 推送改项目分支至远程Gitlab 服务器
  • 进行代码检查并提交Master主分支合并申请
  • 项目领导审查代码并确认合并申请

7. 安装 Gitlab 仓库系统

打开一台虚拟机:192.168.2.1

添加hosts解析文件

1
2
3
4
5
[root@gitlab ~]# cat <<END>> /etc/hosts
192.168.2.1 gitlab.lemon.com
192.168.2.2 jenkins.lemon.com
192.168.2.3 lb.lemon.com
END

安装 Gitlab 依赖

1
2
[root@gitlab ~]# yum install -y policycoreutils openssh-server openssh-clients postfix lsof
[root@gitlab ~]# systemctl start postfix;systemctl enable postfix #开启邮箱服务

安装 Gitlab-12.0.3 版本

由于国内网络偏慢,这里使用清华大学的镜像源进行安装gitlab-ce

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@gitlab ~]# cat <<END>> /etc/yum.repos.d/gitlab-ce.repo
[gitlab-ce]
name=gitlab-ce
baseurl=http://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7
repo_gpgcheck=0
gpgcheck=0
enabled=1
\#gpgkey=
END

[root@gitlab ~]# yum clean all && yum makecache

[root@gitlab ~]# yum -y install gitlab-ce-12.0.3-ce.0.el7

Gitlab 管理命令

1
2
3
4
5
6
7
8
9
[root@gitlab ~]# gitlab-ctl stop           #关闭gitlab

[root@gitlab ~]# gitlab-ctl start #启动gitlab

[root@gitlab ~]# gitlab-ctl restart #重启gitlab

[root@gitlab ~]# gitlab-ctl status #状态gitlab

[root@gitlab ~]# gitlab-ctl reconfigure #重载配置文件并启动glitlab

修改配置文件并启动 Gitlab

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@gitlab ~]# vim /etc/gitlab/gitlab.rb
#配置gitlab的URL或IP地址
external_url 'http://gitlab.lemon.com'
#配置邮箱
### Email Settings
gitlab_rails['gitlab_email_enabled'] = true
gitlab_rails['gitlab_email_from'] = 'lemon_row@163.com' #邮箱账号
gitlab_rails['gitlab_email_display_name'] = 'Gitlab-lemon' #发送人显示名称
### GitLab email server settings
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.163.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "lemon_row@163.com"
gitlab_rails['smtp_password'] = "TZVLGNYMVOEWCIHR" #授权码
gitlab_rails['smtp_domain'] = "163.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
:wq
[root@gitlab ~]# gitlab-ctl reconfigure #初始化gitlab,第一次会很慢

image-20200505123253144

注意:重新配置应用程序。修改了 gitlab 服务配置文件后,都需要执行一下这个命令。让各个服务的配置文件,重新加载一下配置文件。这里等个4分钟左右。

1
[root@gitlab ~]# gitlab-ctl status                   #查看gitlab状态

提示:gitlab 需要使用到80端口,所以得保证80端口不被占用,或者改端口

1
[root@gitlab ~]# lsof -i:80

汉化 Gitlab

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//查看gitlab的版本
[root@gitlab ~]# cat /opt/gitlab/embedded/service/gitlab-rails/VERSION
11.2.3

//下载对应版本的汉化包,解压汉化包,查看汉化包的版本
[root@gitlab ~]# cd /usr/local/src/
[root@gitlab src]# tar xf gitlab-v12.0.3-zh.tar.gz
[root@gitlab src]# rm -rf gitlab-v12.0.3-zh.tar.gz
[root@gitlab src]# cat gitlab-v12.0.3-zh/VERSION
12.0.3

//先备份,避免汉化失败后gitlab瘫痪
[root@gitlab src]# mkdir gitlab.bak
[root@gitlab src]# cp -r /opt/gitlab/embedded/service/gitlab-rails/* /usr/local/src/gitlab.bak

//将下载好的汉化包覆盖拷贝过去
[root@gitlab src]# \cp -rf gitlab-v12.0.3-zh/* /opt/gitlab/embedded/service/gitlab-rails/
cp: 无法以目录"gitlab-v12.0.3-zh/log" 来覆盖非目录"/opt/gitlab/embedded/service/gitlab-rails/log"
cp: 无法以目录"gitlab-v12.0.3-zh/tmp" 来覆盖非目录"/opt/gitlab/embedded/service/gitlab-rails/tmp"

//重新配置gitlab
[root@gitlab src]# gitlab-ctl reconfigure

//重启gitlab
[root@gitlab src]# gitlab-ctl restart

//检查是否启动成功
[root@gitlab src]# gitlab-ctl status
[root@gitlab src]# lsof -i:80

访问浏览器测试

注释:如果后期 web 界面访问时,总报 502的话,就把防火墙清空规则,另外内存要大于4G,不然以后内存不足,也报 502!

image-20200505123953743

** Gitlab 默认用户是root,拥有最高权限,密码我设置的是“abc123..”,最少八位数。**

image-20200505154721731

登陆 Gitlab

image-20200519160034791

image-20200519160253275

image-20200520163224918

至此gitlab安装完成!

8. Gitlab 权限管理

创建Group,User,Project

  • 三者层级关系如下图:

创建一个组,组名为java

1
2
3
4
5
#Gitlab中的组和项目有三种访问权限:Private、Internal、Public

- Private:只有组成员才能看到
- Internal:只要登录的用户就能看到,开源项目和组设置的是Internal
- Public:所有人都能看到

创建一个PM的用户作为项目管理者并加入到java组内

  • 注意:这里的邮箱在公司里一定要写上真实的,我这里为了方便,就随便写上了一个

修改pm用户秘密: abc123..

将pm管理用户加入到java组内

Gitlab 权限管理:

Gitlab 用户在组中有五种权限:Guest、Reporter、Developer、Master、Owner

  1. Guest:可以创建issue、发表评论,不能读写版本库。
  2. Reporter:可以克隆代码,不能提交,QA、PM可以赋予这个权限。
  3. Developer:可以克隆代码、开发、提交、push,RD可以赋予这个权限。
  4. Maintainer:可以创建项目、添加tag、保护分支、添加项目成员、编辑项目,核心RD负责人可以赋予这个权限。
  5. Owner:可以设置项目访问权限 Visibility Level、删除项目、迁移项目、管理组成员,开发组leader能赋予这个权限。

用PM用户创建一个项目app1

在 gitlab 登陆页面下创建 dev1 dev2 用户,并作为开发者加入到 app1 项目中

image-20200520171340537

  • 创建完了之后这两个用户很明显是看不到 app1 这个项目的

  • 所以需要登陆pm或root用户将其创建的用户添加到 java 组里面中或者 app1 项目中(授权)

  • 组成员添加完了之后 看一下 app1 项目中有没有添加这两个用户

image-20200520175513606

  • 随便登陆这两个其中一个账号验证是否能够看到app1项目

9. gitlab 的基本使用

将 dev1 持有人的公钥放到 dev1 账号下

  • 开启一台虚拟机,192.168.2.6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#添加hosts解析文件
[root@dev1 ~]# cat <<END>> /etc/hosts
192.168.2.1 gitlab.lemon.com
192.168.2.2 jenkins.lemon.com
192.168.2.3 lb.lemon.com
END
[root@dev1 ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:R5PUO4f4FLhExQ6YaD6B20GMn1Fdgzw98YXtEX/jfMo root@dev1
The key's randomart image is:
+---[RSA 2048]----+
| =.o.*oO=. +o|
| o B o.O.*o.oo|
| * = .+* =.o+|
| . * .o.* + +|
| .S .o o o.|
| . .. ..|
| E |
| |
| |
+----[SHA256]-----+
[root@dev1 ~]# cat .ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDzzBDqVPZ9H0nVKucS3B3QNx318tAan06c17dZ0npQpsoAZaMUFxneMH+zoEjd+cG5Ee7f2D2n+iqV0wLGYDs9CY/8RqsSZ9SSx9K2aM9I1XFP6AUpuM5ddI/b3nhBVcbFjzpEckXPMz3O4C0twO1/aRD4byFtyivfdrry/KDNrYEMGojzv7PuktIvC/Qp0vKpvNG7msD6ePg4eHKCunHNGIboojL/vckpJZkvDt0MuDbeHdIE8Gj1XNkoudyWrCVwNTj8TEUkZE6pE7fYfBOzC1gOWv/+evROmwYLioprRJx+ZklRe4YmJzHw7Qiia4CluidQyUquMT5geGIme/3 root@dev1

以ssh协议推送代码至远程仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
[root@dev1 ~]# git config --global user.name "dev1"
[root@dev1 ~]# git config --global user.email "dev1@163.com"

[root@dev1 ~]# git clone git@gitlab.lemon.com:java/app1.git
正克隆到 'app1'...
warning: 您似乎克隆了一个空版本库。

[root@dev1 ~]# cd app1
[root@dev1 app1]# echo '# 第一次提交 测试' >> README.md
[root@dev1 app1]# git add .
[root@dev1 app1]# git commit -m "NOW 1 add README.md"
[master(根提交) e4c5af0] NOW 1 add README.md
1 file changed, 1 insertion(+)
create mode 100644 README.md

[root@dev1 app1]# git tag -a 'v1.0' -m '版本 1'
[root@dev1 app1]# git show --oneline v1.0
tag v1.0

版本 1
e4c5af0 NOW 1 add README.md
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e4460ab
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# 第一次提交 测试

[root@dev1 app1]# git push -u origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 241 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@gitlab.lemon.com:java/app1.git
* [new branch] master -> master
分支 master 设置为跟踪来自 origin 的远程分支 master。

[root@dev1 app1]# git push -u origin v1.0
Counting objects: 1, done.
Writing objects: 100% (1/1), 157 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@gitlab.lemon.com:java/app1.git
* [new tag] v1.0 -> v1.0

下面以PM用户进行创建开发计划分配给dev2

  • 开启一台虚拟机,192.168.2.7
1
2
3
4
5
6
#添加hosts解析文件
[root@dev2 ~]# cat <<END>> /etc/hosts
192.168.2.1 gitlab.lemon.com
192.168.2.2 jenkins.lemon.com
192.168.2.3 lb.lemon.com
END
开发一个 官网 V1.0 版本,包含首页和新闻

(1)创建里程碑(Milestone)

(2)依次把任务首页,新闻添加到里程碑,并进行任务分配给dev2开发者

使用dev2用户登录查看,会有任务提示

dev2 开发者收到任务,进行开发
  • 将 dev2 持有人的公钥放到 dev2 账号下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@dev2 ~]# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:WC/AYWsXe0QwQDQtL7wlTJUzjGvAtyqAWd17tNwYZvk root@dev2
The key's randomart image is:
+---[RSA 2048]----+
| o +B*==o |
| . +o*+%= |
|.o *=@+O. |
|+ .X=BoE |
| . o.*S . |
| . . . . |
| . |
| |
| |
+----[SHA256]-----+
[root@dev2 ~]# cat .ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDE1Wu54a56ryKqGRf5ctaJ71ZcApTV2KNxuG03ykSzZkcp7JSwUNxNRxrWu+XtbjKyCjkJnnBJ+Op18ixN17r69WY5edRxz3c50trNma2PDGm62fdzC0cdZLHnIKCRyizen5UrPxiPMkeJ6Gi2Z6ZmEZhxWhv6ePn3XE53lJg5PMyeSctMTZcikJ9qV0v3l3cZ8XD/fNaJnVQnYUswCxxg+JDEah5G8+sR5sKTJntTKxEjdJOd5/rsZFDGWzlMgieVzYYhPUWejLc2Fw+xQJRmGSQ5+TaKcNNwND/UYlJvzce+AkstgMiocXLN1pW9AFdX4dNo1+LjnjIHfbHobZlP root@dev2
将客户端公钥(id_rsa.pub)放进 dev2 账户中

进行开发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[root@dev2 ~]# git config --global user.name "dev2"
[root@dev2 ~]# git config --global user.email "dev2@163.com"
[root@dev2 ~]# git clone git@192.168.2.1:java/app1.git
正克隆到 'app1'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 4 (delta 0), reused 0 (delta 0)
接收对象中: 100% (4/4), done.
[root@dev2 ~]# cd app1/ && ls
README.md
[root@dev2 app1]# git checkout -b shouye
切换到一个新分支 'shouye'
[root@dev2 app1]# echo "<h1> www.lemon.com" > index.html
[root@dev2 app1]# git add .
[root@dev2 app1]# git commit -m "shouye" #创建并切换首页分支
[shouye aa7b19c] shouye
1 file changed, 1 insertion(+)
create mode 100644 index.html
[root@dev2 app1]# git push origin shouye
Counting objects: 4, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 282 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote:
remote: To create a merge request for shouye, visit:
remote: http://gitlab.lemon.com/java/app1/merge_requests/new?merge_request%5Bsource_branch%5D=shouye
remote:
To git@192.168.2.1:java/app1.git
* [new branch] shouye -> shouye
回到 gitlab 上可以看到有刚才创建的分支,点击”Merge request”合并分支请求,之后PM用户登录处理合并请求。此时,一个功能的开发流程就完成。

登陆PM用户合并请求

验证分支是否合并

10. Gitlab 的备份和恢复

创建备份目录,并授权
1
2
[root@gitlab ~]# mkdir /data/backups/gitlab -p
[root@gitlab ~]# chown -R git.git /data/
修改 gitlab 配置
1
2
3
4
5
[root@gitlab ~]# vim /etc/gitlab/gitlab.rb 
299 gitlab_rails['backup_path'] = "/data/backups/gitlab" #备份路径
307 gitlab_rails['backup_keep_time'] = 604800 #备份7天

[root@gitlab ~]# gitlab-ctl reconfigure
备份
1
[root@gitlab ~]# gitlab-rake gitlab:backup:create

11. 整体总结

  • PM在 gitlab 创建任务,分配给开发人员

  • 开发人员领取任务后,在本地使用git clone拉取代码库

  • 开发人员创建开发分支(git checkout -b dev),并进行开发

  • 开发人员完成之后,提交到本地仓库(git commit )

  • 开发人员在gitlab界面上申请分支合并请求(Merge request)

  • PM在gitlab上查看提交和代码修改情况,确认无误后,确认将开发人员的分支合并到主分支(master)

  • 开发人员在gitlab上Mark done确认开发完成,并关闭issue。这一步在提交合并请求时可以通过描述中填写”close #1”等字样,可以直接关闭issue。

四、部署 jenkins

  • 开启一台虚拟机,192.168.2.2

1. 安装 JDKMaven

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#添加hosts解析文件
[root@jenkins ~]# cat <<END>> /etc/hosts
192.168.2.1 gitlab.lemon.com
192.168.2.2 jenkins.lemon.com
192.168.2.3 lb.lemon.com
END
[root@jenkins ~]# tar xf jdk-8u181-linux-x64.tar.gz
[root@jenkins ~]# tar xf apache-maven-3.5.4-bin.tar.gz
[root@jenkins ~]# mv jdk1.8.0_181 /usr/local/java
[root@jenkins ~]# mv apache-maven-3.5.4 /usr/local/maven
[root@jenkins ~]# vi /etc/profile
export JAVA_HOME=/usr/local/java
export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib
export PATH=$JAVA_HOME/bin:$PATH
export MAVEN_HOME=/usr/local/maven
export PATH=$PATH:$MAVEN_HOME/bin
[root@jenkins ~]# source /etc/profile

[root@jenkins ~]# java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

[root@jenkins ~]# mvn -v
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-18T02:33:14+08:00)
Maven home: /usr/local/maven
Java version: 1.8.0_181, vendor: Oracle Corporation, runtime: /usr/local/java/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-693.el7.x86_64", arch: "amd64", family: "unix"

#将maven的下载源换成国内的
[root@jenkins ~]# vim /usr/local/maven/conf/settings.xml +159
#在159行的上面添加以下内容
<mirror>
<id>aliyunmaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/repository/public </url>
</mirror>
:wq!

2. 下载 jenkins-rpm 包并安装

1
2
3
4
5
6
7
8
9
10
11
12
13
//安装jenkins
[root@jenkins ~]# yum -y install jenkins-2.233-1.1.noarch.rpm

//修改jenkins配置文件
[root@jenkins ~]# vim /etc/sysconfig/jenkins
19 JENKINS_JAVA_CMD="/usr/local/java/bin/java"
29 JENKINS_USER="root" #这里为了方便,使用root用户运行jenkins
65 JENKINS_LISTEN_ADDRESS="192.168.2.2"

//启动jenkins
[root@jenkins ~]# systemctl start jenkins
[root@jenkins ~]# netstat -anptu|grep "8080"
tcp6 0 0 192.168.2.2:8080 :::* LISTEN 67706/java

3. jenkins 的目录介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@gitlab ~]# rpm -ql jenkins
/etc/init.d/jenkins #jenkins的启动文件
/etc/logrotate.d/jenkins #记载Jenkins日至位置的文件
/etc/sysconfig/jenkins #jenkins的配置文件
/usr/lib/jenkins #jenkins的war包,升级就是在这做的
/usr/lib/jenkins/jenkins.war #jenkins的程序war包
/usr/sbin/rcjenkins #jenkins的为二进制文件
/var/cache/jenkins #jenkins的程序文件,运行程序解压出来的
/var/lib/jenkins #jenkins的主目录
/var/log/jenkins #jenkins的日志文件
/var/lib/jenkins/workspace #拉取代码的存放路径
/var/lib/jenkins/plugins/ #这个目录下是我们安装所有的插件
/var/lib/jenkins/secrets/initialAdminPassword #管理员密码文件

4. 跳过 jenkins 插件安装

1
2
[root@jenkins ~]# cat /var/lib/jenkins/secrets/initialAdminPassword
3b99cdf79df747e494484426efb8bd1c #管理员密码

image-20200505192734398

image-20200520231715521

image-20200520231751361

image-20200520231819993

image-20200520231859006

  • 修改admin用户密码

image-20200520212137256

image-20200520212217903

image-20200520231957176

5. 更换jenkins插件下载源

image-20200520212258589

image-20200520212328361

image-20200520212447372

  • 完事之后将网页关掉并down掉 jenkins,替换完官方的 json 文件之后在启动。

  • 注:系统重启后,default.json 文件会还原,所以只要系统重启就执行下面这个命令

1
2
3
4
5
6
[root@jenkins ~]# systemctl stop jenkins
[root@jenkins ~]# cd /var/lib/jenkins/updates/
[root@jenkins updates]# sed -i 's/http:\/\/updates.jenkins-ci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json && sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json
[root@jenkins updates]# systemctl start jenkins
[root@jenkins updates]# netstat -anptu|grep "java"
tcp6 0 0 192.168.2.2:8080 :::* LISTEN 11591/java

6.离线安装 jenkins 插件

1
2
3
4
5
[root@jenkins ~]# systemctl stop jenkins
[root@jenkins ~]# rm -rf /var/lib/jenkins/plugins/
[root@jenkins ~]# tar xf jenkins-2.233_plugins.tar.gz -C /var/lib/jenkins/
[root@jenkins ~]# chown -R jenkins:jenkins /var/lib/jenkins/plugins/
[root@jenkins ~]# systemctl start jenkins
  • jenkins 插件安装完成

image-20200520213421856

image-20200520213450701

五、Jenkins 集成 Gitlab(持续集成)

整体思路:

image-20210402172434327

1. 在 gitlab 上创建项目并将代码推送上去

  • 使用pm用户基于 java 组创建 monitor项目

image-20200520235036801

image-20200520235313198

  • 使用 dev1 或者 dev2 开发用户将monitor代码推送至此项目中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[root@dev1 ~]# unzip monitor_html.zip                #解压我本地的项目代码
[root@dev1 ~]# ll
总用量 13688
drwxr-xr-x 9 root root 4096 5月 20 08:57 monitor
-rw-r--r-- 1 root root 14008331 5月 20 08:59 monitor_html.zip
[root@dev1 ~]# cd monitor #进入解压后的代码目录中
[root@dev1 monitor]# git init #初始化monitor目录
重新初始化现存的 Git 版本库于 /root/monitor/.git/
[root@dev1 monitor]# git add . #加入到暂存区
[root@dev1 monitor]# git status #查看暂存区状态
[root@dev1 monitor]# git commit -m "NOW 1" #提交至本地仓库
[master 9c1c324] NOW 1
110 files changed, 65709 insertions(+), 65709 deletions(-)

[root@dev1 monitor]# git remote add origin git@gitlab.lemon.com:java/monitor.git #添加远程仓库
[root@dev1 monitor]# git remote -v #查看远程仓库(ssh协议的)
origin git@gitlab.lemon.com:java/monitor.git (fetch)
origin git@gitlab.lemon.com:java/monitor.git (push)
[root@dev1 monitor]# git push -u origin master #推送代码至远程仓库
Counting objects: 564, done.
Compressing objects: 100% (497/497), done.
Writing objects: 100% (564/564), 9.03 MiB | 0 bytes/s, done.
Total 564 (delta 159), reused 363 (delta 54)
remote: Resolving deltas: 100% (159/159), done.
To git@gitlab.lemon.com:java/monitor.git
* [new branch] master -> master
分支 master 设置为跟踪来自 origin 的远程分支 master。
  • 查看是否推送至monitor项目中

image-20200521002049018

2. 下载集成 gitlab 的插件

  • 这些插件我都已经在上面安装好了,所以这一步可以跳过

image-20200521002447884

3. 在 jenkins 里配置实现持续集成

进入主页–创建一个新任务

image-20200521003043921

输入项目名称 freestyle-monitor—构建一个自由风格的软件项目—确认

image-20200521002958391

General–填写项目描述–Discard old builds

image-20200521003526153

源码管理–Git–添加 gitlab 项目的URL–授权认证

image-20200521003803292

image-20200521004019949

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//在jenkins服务器上生成私钥,马上就用
[root@jenkins ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:cYOfmb21FU4/mqzakUqAqwFPW1G7Mz2hmLti6eDfia8 root@jenkins
The key's randomart image is:
+---[RSA 2048]----+
| . |
| . .. |
| . .o.o o |
| = ++.* o o|
| . . = *So= . .oo|
| + o o + . oooo.|
| . +.o . o.+. |
|. .+= o . o o |
| .+E+= o.o |
+----[SHA256]-----+

[root@jenkins ~]# cat .ssh/id_rsa.pub #公钥
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDj13aUUWlOxpLv/tGDHF7v1dBUrs0wVirnxKXbFwetXUECnqGyd9UOHSrkkEiKW512ommbXDziX+TEa6S5QULZCrS0dM3tN4WCLyouhPbPzjiOA+HHJj0XpgXxnSz6MobeAVPByS0l9LhJkISIxl+gmz+e/VvMcSOmwOXHm70kIngA59X6xy5t2xeb0vwkQXGmoA5bQdQx32mugDT4HA1IBpoRRV3h6cfjhSW85wjdgWRGWFIRFLfLKCyBPBaGxGY7XJB9Fpu3SaMfBb85EYBk///L1Ha8dEKLkmiECrDo6SgQHWoF7GVcyzATku80NHR6boZFC4belELS2rPmTfe9 root@jenkins

[root@jenkins ~]# cat .ssh/id_rsa #私钥
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA49d2lFFpTsaS7/7Rgxxe79XQVK7NMFYq58Sl2xcHrV1BAp6h
snfVDh0q5JBIiluddqJpm1w84l/kxGukuUFC2Qq0tHTN7TeFgi8qLoT2z844jgPh
xyY9F6YF8Z0s+jKG3gFTwcktJfS4SZCEiMZfoJs/nv1bzHEjpsDlx5u9JCJ4AOfV
+scubdsXm9L8JEFxpqAOW0HUMd9proA0+BwNSAaaEUVd4enH44UlvOcI3YFkRlhS
ERS3yygsgTwWhsRmO1yQfRabt0mjHwW/ORGAZP//y9R2vHRCi5JohAqw6OkoEB1q
BexlXMswE5LvNDR0em6GRQuG3pRC0tqz5k33vQIDAQABAoIBAQDcu22CG60uSGsq
X3CS2PWQ3VBL+l2HqrM+fuE/9HvXlTTaWNzGjhm25sMbVD0y7bcLrCUsApxppAV5
1d9sKrGcnCadfVvTqaqKiS8QiniismNQEqq1yXH+azXu8hsU+cZ3ZknCwCghUYkI
nB4KdEVIz58/ZK1+z01+y/rQ+yyux3GQQq7ZM+gQDhAmrgma+r/lov0itCM86Eo5
PN9ZQ5I7m23ACQsZNjZOQ9yxIqjsYYAo+iJuT96ZUlOkPnzTwQ2mtI1SaMgPUZJb
gjb4A3FaU0rVru+bsQX93mZEEWAQqBzr1JkE8gd4P5VCMmjxlNxQwzThKMaGsvU9
ijqXDZaBAoGBAPzZ7y/UDLd5cMgljPtGG3buk9vWKmL32DTRShj2OdrXJO49QGy3
uMUi9qQ3j8ShmvclKdQ3LXofEFruwBmkP0F/oEYJ5/MEXkgi1+dE8RgjIg6v7+Ww
sAhFJrhnK+rGbVSABJ5O9bb9qmEKgZq+2W1/4Y6RF/+DSSN/jxXllP3JAoGBAOat
zO34RMHemgQoRQCW6NOTHnWOpn1ubhMR21rNHfgwmsyaPMv/LDkBQObyKMLb4VgC
D7jD2NW9DlTcKiZjqmjgDALxR1tt3mXZ2znTWEDI774Tc2QebJCpRIdQqKG1nm5H
d131E5CS72cNCVmacVc9xi7kO107e6bc+34g8hRVAoGAe8/PcpEYBQN/OVJB3Yyv
yCX82unc6YdJJFvTN7PiEonE+K+fi1zPKiD7ut/GE1e6xQg6mkLGjwUFAjHkeOnX
W6A9/+272WCrNhFxvToiAFq7w4tdIhDJsdMCqctDUvwE7xqcqFQrt4Yw1sHJQtfv
KdIzxZbAtIo51xsQGn3H3hkCgYAZhpnqq1JQcaVxWFNqYUiaQOlZ8NMThijAC3XO
cmwijp5Sja60lCP8mtrns1w3U8V3y6KZu3I/FJCFa2duoBC3UjOCD9jpkRrPAnBz
0aMuaA2/Zr+aEJPK3jArGQ3P9xz07wuSZhAoK1o6eQLT23c3RCqt/atkAbUJHeLm
bhbbkQKBgFytaJklEVRibl0iiDYZfkzIhD/v1I43JyUmuv+VuTwGDYFx4b0jBOAm
EeKnpRzyvmSbG52XHcJeaGt0iLaZVnpby/y04aowJC+2sQ7fGKE61PYy9WDasHBr
uRuMiY5YzMC9LsGeSs4gF/oVt6d80M2itaqf+MSRZpT3VVpqGXw9
-----END RSA PRIVATE KEY-----
  • jenkins 服务器上的公钥放到 gitlab 的 pm 账户上用来拉取代码

image-20200521004915704

image-20200521004934281

  • 验证 jenkins 服务器能否克隆这个项目
1
2
3
4
5
6
7
8
9
10
11
12
[root@jenkins ~]# git clone git@gitlab.lemon.com:java/monitor.git
正克隆到 'monitor'...
remote: Enumerating objects: 564, done.
remote: Counting objects: 100% (564/564), done.
remote: Compressing objects: 100% (392/392), done.
remote: Total 564 (delta 159), reused 564 (delta 159)
接收对象中: 100% (564/564), 9.03 MiB | 0 bytes/s, done.
处理 delta 中: 100% (159/159), done.

[root@jenkins ~]# rm -rf monitor/

//很明显,jenkins服务器已经能够克隆gitlab上的项目了
  • 再回到 jenkins 的web页面上将他自己的私钥放到 jenkins 凭据上

image-20200521010030412

Credentials—选择 root

image-20200521010337874

image-20200521010815380

4. 点击立即构建

image-20200521011053244

5. 构建成功后点击 控制台输出 和 工作区

  • 点击控制台输出

控制台输出,SUCCESS则构建成功

image-20200521011929942

image-20200521012036181

  • 点击工作去

image-20200521011356399

image-20200521011658186

  • 查看 jenkins 服务器上的 /var/lib/jenkins/workspace/ 目录是否下载了代码

image-20200521011751571

可以看到,在工作目录下边有部署的代码;上面只是完成了第一步,也就是持续集成,下面我们先开始搭建集群,在修改此任务的配置(持续集成 + 持续部署)。

六、搭建web集群

打开三台虚拟机

IP host_name role
192.168.2.3 LB nginx充当负载均衡
192.168.2.4 web01 nginx充当web服务
192.168.2.5 Web02 nginx充当web服务

1. 在这三台节点上都安装nginx(操作相同)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#添加hosts解析文件
cat <<END>> /etc/hosts
192.168.2.1 gitlab.lemon.com
192.168.2.2 jenkins.lemon.com
192.168.2.3 lb.lemon.com
END

wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

yum clean all
yum makecache

yum -y install nginx

#修改这三台的主配置文件(配置相同)
vim /etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 0;
include /etc/nginx/conf.d/*.conf;
}

2. 配置 lb 主机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[root@lb ~]# cd /etc/nginx/conf.d/
[root@lb conf.d]# gzip default.conf #将默认的虚拟主机文件注释掉

[root@lb conf.d]# vim proxy_lb.lemon.com.conf
upstream lb {
server 192.168.2.4:80;
server 192.168.2.5:80;
}

server {
listen 80;
server_name lb.lemon.com;
root /code;
location / {
proxy_pass http://lb;
proxy_set_header Host $http_host;
proxy_set_header X-Forward-For $remote_addr;
}
}
:wq!

[root@lb conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

[root@lb conf.d]# systemctl start nginx;systemctl enable nginx
[root@lb conf.d]# netstat -anptu|grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 16216/nginx: master

3. 配置 web01 主机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@web01 ~]# cd /etc/nginx/conf.d/
[root@web01 conf.d]# gzip default.conf
[root@web01 conf.d]# vim nginx_01.conf
server {
listen 80;
server_name localhost;
root /code/web;

location / {
index index.html;
}
}
:wq!

[root@web01 conf.d]# mkdir -p /code/web

[root@web01 conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

[root@web01 conf.d]# systemctl start nginx;systemctl enable nginx
[root@web01 conf.d]# netstat -anptu|grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 16171/nginx: master

4. 配置 web02 主机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@web02 ~]# cd /etc/nginx/conf.d/
[root@web02 conf.d]# gzip default.conf
[root@web02 conf.d]# vim nginx_02.conf
server {
listen 80;
server_name localhost;
root /code/web;

location / {
index index.html;
}
}
:wq!

[root@web02 conf.d]# mkdir -p /code/web

[root@web02 conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

[root@web02 conf.d]# systemctl start nginx;systemctl enable nginx
[root@web02 conf.d]# netstat -anptu|grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 16171/nginx: master

5. 将 jenkins 服务器上的代码拷贝到两台web节点上

1
2
3
[root@jenkins ~]# cd /var/lib/jenkins/workspace/freestyle-monitor
[root@jenkins freestyle-monitor]# scp -r ./* root@192.168.2.4:/code/web
[root@jenkins freestyle-monitor]# scp -r ./* root@192.168.2.5:/code/web

6. 查看并访问 http://lb.lemon.com/

image-20200521024919442

image-20200521024935986

image-20200521025224964

  • 思考一个问题:
    • 如果我更新了一次代码,是不是还得要再来一次上面的操作步骤?
    • 是的,所以就要用到下面 jenkins 的持续集成 + 持续部署 功能了。

七、配置freestyle-monitor任务 持续集成 + 持续部署

1. 将手动部署代码的操作编写成shell脚本,在由 jenkins 调度将其代码推送至web集群

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[root@jenkins ~]# mkdir /jekins_scripts                   #创建jenkins脚本存放目录
[root@jenkins ~]# mkdir /jekins_code_tar #创建jenkins代码打包存放目录
[root@jenkins ~]# vim /jekins_scripts/monitor_html.sh #创建jenkins任务的相关脚本存放目录
#!/bin/bash

#时间戳
DATE=`date +%Y-%m-%d-%H-%M-%S`

#jenkins的项目目录,这里也可以直接用jenkins自身的 WORKSPACE 变量
JENKINS_DIR="/var/lib/jenkins/workspace/freestyle-monitor"

#web集群的站点存放目录
WEB_DIR="/code"

#web集群IP地址
WEB_IP="192.168.2.4 192.168.2.5"

#进入到jenkins项目目录,并进行代码打包至/jekins_code_tar目录下,在将内容通过scp至web集群 并 进行新的代码上线
env_build() {
cd ${JENKINS_DIR} && tar zcf /jekins_code_tar/web-${DATE}.tar.gz ./*
for hosts in $WEB_IP;do
ssh root@${hosts} "if [ ! -d /web_backup ]; then mkdir /web_backup ; fi"
scp /jekins_code_tar/web-${DATE}.tar.gz root@${hosts}:/web_backup
ssh root@${hosts} "rm -rf ${WEB_DIR}/* && mkdir -p ${WEB_DIR}/web-${DATE}"
ssh root@${hosts} "tar xf /web_backup/web-${DATE}.tar.gz -C ${WEB_DIR}/web-${DATE}"
ssh root@${hosts} "ln -s ${WEB_DIR}/web-${DATE} ${WEB_DIR}/web"
done
}

#调用env_build函数
env_build

[root@jenkins ~]# chmod -R +x /jekins_scripts

#配置web节点免登
[root@jenkins ~]# ssh-copy-id root@192.168.2.4
[root@jenkins ~]# ssh-copy-id root@192.168.2.5

2. 配置 freestyle-monitor 项目

  • 构建 – Execute shell

image-20200521114008140

image-20200521114243497

3. 构建此项目

  • 在构建之前先将web集群的页面和 jenkins 之前拉取下的代码全都删除,以便验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#jenkins服务器上
[root@jenkins ~]# ll /var/lib/jenkins/workspace/
总用量 0
[root@jenkins ~]# ll /jekins_code_tar/
总用量 0

#web01服务器上
[root@web01 ~]# ll /code/
总用量 0
[root@web01 ~]# ll /web_backup
ls: 无法访问/web_backup: 没有那个文件或目录

#web02服务器上
[root@web02 ~]# ll /code/
总用量 0
[root@web01 ~]# ll /web_backup
ls: 无法访问/web_backup: 没有那个文件或目录
  • 现在访问lb.lemon.com就会报错

image-20200521114546597

4. 模拟开发更新代码推送至远程仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@dev1 ~]# cd monitor
[root@dev1 monitor]# vim index.html +43
<a class="logo pull-left" href="index.html" style="width: 233px">lemon管理平台</a>
:wq!
[root@dev1 monitor]# git add .
[root@dev1 monitor]# git commit -m "test"
[master 6cc63b2] test
1 file changed, 1 insertion(+), 1 deletion(-)
[root@dev1 monitor]# git push origin master
Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 282 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To git@gitlab.lemon.com:java/monitor.git
481be52..6cc63b2 master -> master

5. jenkins构建项目

image-20200521114623360

image-20200521114714801

image-20200522005243240

6. 然后在访问一下lb.lemon.com

image-20200522011420421

7. 查看对应的目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#jenkins服务器上
[root@jenkins ~]# ll /var/lib/jenkins/workspace/
总用量 4
drwxr-xr-x 9 root root 4096 5月 22 00:50 freestyle-monitor
drwxr-xr-x 2 root root 6 5月 22 00:50 freestyle-monitor@tmp
[root@jenkins ~]# ll /jekins_code_tar/
总用量 4552
-rw-r--r-- 1 root root 4659825 5月 22 00:50 web-2020-05-22-00-50-30.tar.gz

#web01服务器上
[root@web01 ~]# ll /code/
总用量 4
lrwxrwxrwx 1 root root 29 5月 22 00:50 web -> /code/web-2020-05-22-00-50-30
drwxr-xr-x 8 root root 4096 5月 22 00:50 web-2020-05-22-00-50-30
[root@web01 ~]# ll /web_backup
总用量 4552
-rw-r--r-- 1 root root 4659825 5月 22 00:50 web-2020-05-22-00-50-30.tar.gz

#web02服务器上
[root@web02 ~]# ll /code/
总用量 4
lrwxrwxrwx 1 root root 29 5月 22 00:50 web -> /code/web-2020-05-22-00-50-30
drwxr-xr-x 8 root root 4096 5月 22 00:50 web-2020-05-22-00-50-30
[root@web02 ~]# ll /web_backup
总用量 4552
-rw-r--r-- 1 root root 4659825 5月 22 00:50 web-2020-05-22-00-50-30.tar.gz

8. 注意事项:

1. Jenkins的启动用户得是root,不然会报错!因为ssh免登用的是root用户做的

2. 如果做了上面的步骤后还是报错,就执行命令删除rm -rf known_hosts。

3. 以上就是一个简单的不能再简单的静态页面 持续集成 + 持续部署项目

9. 现在这个项目的配置还存在一些问题

  • 怎么指定要构建的版本?

    • 答:需要定义 参数化构建过程的(Choice Parameter 和 Git Parameter)
  • 怎么不让已经构建成功后项目 构建?

    • 答:使用 jenkins 自带的两个变量进行判断

10. 解决上面两个存在的问题

  • 由于之前的上线方式是直接获取最新代码,它会对后期版本回退的困难。
  • 如果采用tag方式,比如第一次上线 v1.1 、第二次上线 v1.2 ,如果上线 v1.2 出现问题后,我们还可以使用tag快速回退至上一个版本的 v1.1 。

12. 实现tag版本上线的思路

  1. 开发如果需要发布新版本上线,必须将当前的版本打上一个标签。
  2. 配置jenkins任务的参数化构建过程;Choice Parameter 和 Git Parameter
  3. jenkins需要让其脚本支持传参,比如:用户传递 v1.1 则拉取项目的 v1.1 标签

13. jenkins配置tag版本的部署

  • 首先安装 Git Parameter插件,然后配置jenkins参数化构建,再让用户构建时选择对应的tag版本。

image-20200521213401721

  • 添加 参数化构建过程(This project is parameterized)—> Choice Parameter —> Git Parameter

image-20200521215729330

  • 配置 Choice Parameter 选项参数

image-20200522021453925

  • 配置 Git Parameter 并 修改源码管理的 Git分支参数

image-20200522013349907

image-20200522013610814

  • 修改jenkins上的 monitor_html.sh 脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
[root@jenkins ~]# vim /jekins_scripts/monitor_html.sh
#!/bin/bash

#时间戳
DATE=`date +%Y-%m-%d-%H-%M-%S`
DATE_TAG=${DATE}-${GIT_VERSION}

#jenkins的项目目录,这里也可以直接用jenkins自身的 WORKSPACE 变量
JENKINS_DIR="/var/lib/jenkins/workspace/freestyle-monitor"

#web集群的站点存放目录
WEB_DIR="/code"

#web集群IP地址
WEB_IP="192.168.2.4 192.168.2.5"

#进入到jenkins项目目录,并进行代码打包至/jekins_code_tar目录下,在将内容通过scp至web集群 并 进行新的代码上线
env_build() {
cd ${JENKINS_DIR} && tar zcf /jekins_code_tar/web-${DATE_TAG}.tar.gz ./*
for hosts in $WEB_IP;do
ssh root@${hosts} "if [ ! -d /web_backup ]; then mkdir /web_backup ; fi"
scp /jekins_code_tar/web-${DATE_TAG}.tar.gz root@${hosts}:/web_backup
ssh root@${hosts} "rm -rf ${WEB_DIR}/* && mkdir -p ${WEB_DIR}/web-${DATE_TAG}"
ssh root@${hosts} "tar xf /web_backup/web-${DATE_TAG}.tar.gz -C ${WEB_DIR}/web-${DATE_TAG}"
ssh root@${hosts} "ln -s ${WEB_DIR}/web-${DATE_TAG} ${WEB_DIR}/web"
done
}

#jenkins这边保留最近提交的五个代码tar包,其余的全部删掉,web那里只保留三个tar包
env_clear() {
#-----------清除web节点的tar包(只保留三个)------
for hosts in $WEB_IP;do
ssh root@${hosts} "bash -x /opt/clear_latest.sh"
done
#-----------清除jenkins节点的tar包(只保留五个)--
ReservedNum=5
FileDir=/jekins_code_tar
FileNum=$(ls -l $FileDir|grep ^- |wc -l)
while(( $FileNum > $ReservedNum));do
OldFile=$(ls -rt $FileDir| head -1)
rm -rf $FileDir/$OldFile
let "FileNum--"
done
}

#判断到底是调用env_build函数 还是调用evn_clear函数;其实这里的值就是根据上面的 Choice Parameter 选项而定的
if [ $BUILD_CLEAR == "build" ];then
env_build
elif [ $BUILD_CLEAR == "clear" ];then
env_clear
fi
  • 在web节点上的opt目录下编写 clear_latest.sh 脚本(在此只实例web01,一样的内容)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@dev1 ~]# vim /opt/clear_latest.sh 
#!/bin/bash
#保留文件数,这里只保留最新的前三个版本
ReservedNum=3
FileDir=/web_backup
date=$(date "+%Y%m%d-%H%M%S")

FileNum=$(ls -l $FileDir|grep ^- |wc -l)

while(( $FileNum > $ReservedNum));do
OldFile=$(ls -rt $FileDir| head -1)
echo $date "Delete File:"$OldFile
rm -rf $FileDir/$OldFile
let "FileNum--"
done

[root@web01 ~]# chmod a+x /opt/clear_latest.sh
  • 开发更新代码,推送至远程仓库并打上标签(这里我实际上推送了三个tag标签)
1
2
3
4
5
6
7
8
9
[root@dev1 ~]# cd monitor
[root@dev1 monitor]# vim index.html +43
<a class="logo pull-left" href="index.html" style="width: 233px">lemon管理平台 v1.1</a>
:wq!
[root@dev1 monitor]# git add .
[root@dev1 monitor]# git commit -m "v1.1"
[root@dev1 monitor]# git push origin master
[root@dev1 monitor]# git tag -a "v1.1" -m "v1.1"
[root@dev1 monitor]# git push origin v1.1
  • 查看一下效果 并 进行构建 并查看 控制台信息

image-20200522030745369

image-20200522032613859

  • 访问web服务查看是否更新到我想要的版本中

image-20200522032725481

  • 查看我构建的tar包有多少了,然后使用clear清除(注意:此功能在工作环境上要慎重使用!!!!)

image-20200522033011358

image-20200522033030405

image-20200522033044114

  • 调用clear构建 –> 就是在运行脚本中的env_clear函数 —> 查看 控制台信息

image-20200522033129964

image-20200522034347752

  • 与上面对比一下可以看到,这个功能也实现了

image-20200522040612025

image-20200522033703796

image-20200522033717301

14. 解决项目重复构建 和 无法精确回滚 的问题 (可在生产环境使用)

  • 在jenkins任务中的参数化构建中的选项构建那里 在添加一个rollback的选项参数

image-20200522094542164

  • 修改脚本
    • 在脚本中添加一个 env_rollabck 的函数,并在脚本中使用 Jenkins自带的 GIT_COMMITGIT_PREVIOUS_SUCCESSFUL_COMMIT 进行判断
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
[root@jenkins ~]# vim /jekins_scripts/monitor_html.sh
#!/bin/bash

#时间戳
DATE=`date +%Y-%m-%d-%H-%M-%S`
DATE_TAG=${DATE}-${GIT_VERSION}

#jenkins的项目目录,这里也可以直接用jenkins自身的 WORKSPACE 变量
JENKINS_DIR="/var/lib/jenkins/workspace/freestyle-monitor"

#web集群的站点存放目录
WEB_DIR="/code"

#web集群IP地址
WEB_IP="192.168.2.4 192.168.2.5"

#进入到jenkins项目目录,并进行代码打包至/jekins_code_tar目录下,在将内容通过scp至web集群 并 进行新的代码上线
env_build() {
cd ${JENKINS_DIR} && tar zcf /jekins_code_tar/web-${DATE_TAG}.tar.gz ./*
for hosts in $WEB_IP;do
ssh root@${hosts} "if [ ! -d /web_backup ]; then mkdir /web_backup ; fi"
scp /jekins_code_tar/web-${DATE_TAG}.tar.gz root@${hosts}:/web_backup
ssh root@${hosts} "rm -rf ${WEB_DIR}/* && mkdir -p ${WEB_DIR}/web-${DATE_TAG}"
ssh root@${hosts} "tar xf /web_backup/web-${DATE_TAG}.tar.gz -C ${WEB_DIR}/web-${DATE_TAG}"
ssh root@${hosts} "ln -s ${WEB_DIR}/web-${DATE_TAG} ${WEB_DIR}/web"
done
}

#回滚函数
env_rollback() {
ROLL_BACKUP=`ssh root@192.168.2.4 "find /web_backup -maxdepth 1 -type f -name "*${GIT_VERSION}*" "`
for hosts in $WEB_IP;do
ssh root@${hosts} "rm -rf ${WEB_DIR}/* && mkdir -p ${WEB_DIR}/web-${DATE_TAG}"
ssh root@${hosts} "tar xf ${ROLL_BACKUP} -C ${WEB_DIR}/web-${DATE_TAG}"
ssh root@${hosts} "ln -s ${WEB_DIR}/web-${DATE_TAG} ${WEB_DIR}/web"
done
}

#jenkins这边保留最近提交的五个代码tar包,其余的全部删掉,web那里只保留三个tar包
env_clear() {
#-----------清除web节点的tar包(只保留三个)------
for hosts in $WEB_IP;do
ssh root@${hosts} "bash -x /opt/clear_latest.sh"
done
#-----------清除jenkins节点的tar包(只保留五个)--
ReservedNum=5
FileDir=/jekins_code_tar
FileNum=$(ls -l $FileDir|grep ^- |wc -l)
while(( $FileNum > $ReservedNum));do
OldFile=$(ls -rt $FileDir| head -1)
rm -rf $FileDir/$OldFile
let "FileNum--"
done
}

#判断到底是调用env_build函数 还是调用evn_clear函数,并且在构建的时候会先判断一下此
#次构建的版本之前有没有构建够,如果构建过,那么将不再构建,如果没有,就构建此项目
if [ $BUILD_CLEAR == "build" ];then
if [ ${GIT_COMMIT} == ${GIT_PREVIOUS_SUCCESSFUL_COMMIT} ];then
echo "你已经成功构建过web-${DATE_TAG}项目了"
echo "你可以直接使用rollback的方式进行回滚web-${DATE_TAG}项目版本"
exit 1
else
env_build
fi
elif [ $BUILD_CLEAR == "rollback" ];then
env_rollback
elif [ $BUILD_CLEAR == "clear" ];then
env_clear
fi
  • 开发在重新推送两个新的分支
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@dev1 ~]# cd monitor
[root@dev1 monitor]# vim index.html +43
<a class="logo pull-left" href="index.html" style="width: 233px">lemon管理平台 v1.4 </a>
:wq!
[root@dev1 monitor]# git add .
[root@dev1 monitor]# git commit -m "v1.4"
[root@dev1 monitor]# git push origin master
[root@dev1 monitor]# git tag -a "v1.4" -m "v1.4"
[root@dev1 monitor]# git push origin v1.4

[root@dev1 monitor]# vim index.html +43
<a class="logo pull-left" href="index.html" style="width: 233px">lemon管理平台 v1.5 </a>
:wq!
[root@dev1 monitor]# git add .
[root@dev1 monitor]# git commit -m "v1.5"
[root@dev1 monitor]# git push origin master
[root@dev1 monitor]# git tag -a "v1.5" -m "v1.5"
[root@dev1 monitor]# git push origin v1.5
  • 重复构建一下v1.5的版本

image-20200522101126718

image-20200522103032311

image-20200522103116779

image-20200522102810984

  • 那比如我想在使用构建回到了v1.4的版本中,怎么才可以重新再回到v1.5版本的?
    • 答:使用我上面定义好的rollback函数会退就行了

image-20200522103401222

image-20200522103858070

image-20200522110221733

  • 再来测试清空tar包的功能还能否使用(注意:此功能在工作环境上要慎重使用!!!!)

image-20200522110429290

image-20200522110438627

image-20200522110453895

image-20200522110520679

image-20200522110533954

image-20200522110545403

注意:如果此时在想回退到v1.1 和v1.3 版本的时候会失败的,因为web节点上的这两个版本包已经被被我清空了,所以 clear这个函数在公司的时候要慎重使用!!!!【最好就别写这个函数方法最好】

至此,jenkins的使用就算是基本完成了,只要上面的内容会了,那么至于java项目那块基本上和上面的操作没有太大的区别

八、GitLab + Jenkins + Sonar Qube 持续集成

1. java项目部署的基本概述

1. 什么是 java 项目?

  • 简单来说就是用 java 编写的代码,我将其称为 java 项目

2. 为什么java项目需要Maven编译?

  • 由于 java 编写的代码是无法直接在服务器上运行的,需要使用Maven工具进行构建打成war包后才能在服务器上运行
  • 简单理解:java 源代码就是你在菜市场的买回家的菜,你买了之后并不是直接放嘴里就吃的,而是先回到家里进行一次加工后(Maven)才吃的。

2. jenkins手动部署java项目至web集群

1. 搭建Nginx + Tomcat + MySQL + Sonar Qube 集群

  • 这里前 nginx 和 tomcat 这两部分的机器我们就不用考虑了,因为我们在上面就已经准备好了,我们只需要重新配置一下 nginx 负载均衡并在另外两台机器上安装一下Tomcat就行了。至于 MySQL 和 Sonar Qube 的话,我这里因机器不够用了,所以就直接把 MySQL 部署到 dev1 主机上 Sonar Qube 部署到 dev2 上就行了,不会有什么影响。
  1. 修改lb的 nginx 配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@lb ~]# vim /etc/nginx/conf.d/proxy_lb.lemon.com.conf
upstream lb {
server 192.168.2.4:8080;
server 192.168.2.5:8080;
}

server {
listen 80;
server_name lb.lemon.com;
root /code;
location / {
proxy_pass http://lb;
proxy_set_header Host $http_host;
proxy_set_header X-Forward-For $remote_addr;
}
}

[root@lb ~]# systemctl restart nginx
  • 现在访问负载均衡的话会报502错误,这很正常,因为我们还没有部署tomcat

image-20200523092927454

  1. 在另外两台web节点上关闭 nginx 服务 并安装启动 Tomcat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
systemctl stop nginx
tar xf jdk-8u181-linux-x64.tar.gz
mv jdk1.8.0_181 /usr/local/java
cat <<END>> /etc/profile
export JAVA_HOME=/usr/local/java
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib
END
source /etc/profile
tar xf apache-tomcat-8.5.32.tar.gz
mv apache-tomcat-8.5.32 /usr/local/tomcat
/usr/local/tomcat/bin/startup.sh
netstat -anptu|grep "8080"
tcp6 0 0 :::8080 :::* LISTEN 1353/java
  • 在访问一下负载均衡

image-20200523093055372

  • 但是看不出来是否已经负载均衡了,我们去修改两个tomcat的页面就行了
1
2
3
4
5
6
7
[root@web01 ~]# vim /usr/local/tomcat/webapps/ROOT/index.jsp +52
<h2>Tomcat web01-192.168.2.4</h2>
#最好重启一下tomcat

[root@web02 ~]# vim /usr/local/tomcat/webapps/ROOT/index.jsp +52
<h2>Tomcat web02-192.168.2.5</h2>
#最好重启一下tomcat
  • 再来访问

image-20200523093517896

image-20200523093549527

  1. 提前先在 dev1 节点上部署好 MySQL ,一会用的 Sonar Qube 的时候会使用,现在还用不上
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@dev1 ~]# yum -y install mariadb-server
[root@dev1 ~]# systemctl start mariadb;systemctl enable mariadb
[root@dev1 ~]# mysqladmin -u root password '123123'
[root@dev1 ~]# mysql -uroot -p123123
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 5.5.65-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec)

MariaDB [(none)]> exit

2. 新建一个gitlab的 hello world 项目仓库

image-20200523095831415

image-20200523095953535

3. 使用git将其java代码上传到hello-world仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@dev1 hello-world]# pwd
/root/hello-world

[root@dev1 hello-world]# ll -a
总用量 16
-rw-r--r-- 1 root root 700 12月 23 2018 .classpath
-rw-r--r-- 1 root root 1113 12月 23 2018 pom.xml
-rw-r--r-- 1 root root 1081 12月 23 2018 .project
drwxr-xr-x 2 root root 322 6月 11 16:31 .settings
drwxr-xr-x 3 root root 18 6月 11 16:31 src
drwxr-xr-x 5 root root 56 6月 11 16:31 target
-rw-r--r-- 1 root root 491 12月 20 2018 time.java

[root@dev1 hello-world]# git init
初始化空的 Git 版本库于 /root/hello-world/.git/
[root@dev1 hello-world]# git add .
[root@dev1 hello-world]# git commit -m "Initial commit"
[root@dev1 hello-world]# git remote add origin git@gitlab.lemon.com:java/hello-world.git
[root@dev1 hello-world]# git push origin master
[root@dev1 hello-world]# git tag -a "v1.1" -m "v1.1"
[root@dev1 hello-world]# git push origin v1.1

image-20200611163415669

4. 在jenkins上拉取gitlab代码后手动编译成war包

  • 安装maven,由于我之前就安装过了 JDKmaven,所以这里就不用安装了,直接跳过

  • 克隆刚才上传的 java 项目 并 手动编译成war包

1
2
3
4
[root@jenkins ~]# git clone git@gitlab.lemon.com:java/hello-world.git
[root@jenkins ~]# cd hello-world/

[root@jenkins hello-world]# mvn package -D maven.test.skip=true #-D 跳过测试用例

image-20200523103930568

  • 将其编译好的 war包 scp 到web节点的对应位置下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#停止两台tomcat服务
[root@web01 ~]# /usr/local/tomcat/bin/shutdown.sh

#删除tomcat默认页面
[root@jenkins hello-world]# for i in 192.168.2.{4..5};do ssh root@$i "rm -rf /usr/local/tomcat/webapps/ROOT"; done

#将编译好的test1.war包scp至web节点上
[root@jenkins hello-world]# for i in 192.168.2.{4..5};do scp target/test1.war root@$i:/usr/local/tomcat/webapps/ROOT.war; done

#查看war包是否拷贝过去
[root@jenkins hello-world]# for i in 192.168.2.{4..5};do ssh root@$i "ls -h /usr/local/tomcat/webapps/ROOT*"; done
/usr/local/tomcat/webapps/ROOT.war
/usr/local/tomcat/webapps/ROOT.war

#启动两台tomcat服务;会自动生成一个ROOT网站目录
[root@web01 ~]# /usr/local/tomcat/bin/startup.sh
[root@web01 ~]# ll /usr/local/tomcat/webapps/
总用量 32
drwxr-x--- 14 root root 4096 6月 11 16:20 docs
drwxr-x--- 6 root root 83 6月 11 16:20 examples
drwxr-x--- 5 root root 87 6月 11 16:20 host-manager
drwxr-x--- 5 root root 103 6月 11 16:20 manager
drwxr-x--- 4 root root 54 6月 11 17:00 ROOT
-rw-r--r-- 1 root root 24711 6月 11 16:59 ROOT.war
  • 访问

image-20200523105432256

以上就是手动部署 java 代码的流程

3. jenkins 自动化部署 java 项目至web集群

-------------本文结束感谢您的阅读-------------