【linux】持续集成与持续发布CICD

文章目录

在这里插入图片描述

任务背景

公司的集群架构已越来越robust(健壮), 但应用服务器上的代码升级和新产品的发布效率不高,甚至有代码发布到生产服务器后BUG太多,客户反应强烈的情况出现。公司的产品项目从需求分析,设计,研发,代码测试到发布上线的流程有问题,开发者开发的代码提交后有BUG没有反馈,运维也没有在测试环境下做有效地压力测试, 都是导致问题的原因。

所以我们需要运用devops(开发与运维工作流有效结合)思路,通过CICD(持续集成持续交付)来实现自动化的集成与交付工作。
在这里插入图片描述

任务要求

1, 使用git提交代码到仓库

2, 实现自动代码发布系统

任务拆解

1, 了解DevOps的发展历程与思想

2, 学会git版本控制

3, 会使用github公有仓库与gitlab私有仓库

4, 了解CICD

5, 使用jenkins实现自动发布

学习目标

  • 了解DevOps的发展历程
  • 了解版本控制
  • 掌握git的安装
  • 掌握git的基本使用

DevOps的发展历程

​ DevOps是一种实现Dev(开发)与Ops(运维)工作流有效联合的思想。

​ 那么,我们为什么要了解什么是DevOps呢?因为我们下面所讲的课程内容最终的目的就是为了体现开发与运维有效结合方法,越是高级应用,越接近我们DevOps思想所阐述的做事方法。

​ 首先我们先来了解一下软件开发层面从软件开发出现时起至今,都经历了些什么?

原始开发时代

时代特色:软件程序员(单一物种)能做到一专多能,是多面小能手

软件程序员的公司那时还被称作实验室,程序员那时被叫做科学家

为了开发出一套优秀的软件,程序员们必须深入了解他们需要的应用相关的所有问题。

他们必须清楚知道这个软件应用在什么场合,这个软件是必须在什么系统上运行。

本质上说,程序员对所要开发的软件的所有环节都有透彻的了解,从规格说明书编写、到软件开发、到测试、到部署、再到技术支持。

随着技术发展,人类需要软件程序员在软件开发方面具备更快的速度、更全面的功能,以便获取更多的用户等

而软件程序员对自身的要求是一专多能,多面小能手,这样就制约了在软件开发方面的开发速度及添加更多功能的可能性。

当然人类不会允许这种情况出现的,如果因为一个软件程序员开发速度跟不上,那么就要想办法进行优化,把软件程序员的工作进行细化、分配。在分配的过程中,就逐渐衍生出了类软件程序员的新物种,例如:软件工程师、网络管理员、数据库开发者、网页开发者、系统架构师、测试工程师等。

随时新物种的诞生,被各物种划分的领域门头林立,各自为王,很少进行交流互动,只有在迫不得已的时刻才会进行沟通。

由于新物种之间的分隔,导致客户的项目开发过程中出现的问题一拖再拖,无法进行有效解决,更无法在交付日期进行准时交付,让客户付出了昂贵的开发代价,甚至项目以失败告终。

面对这种混乱的情况,有人想到了一种开发模式:瀑布开发。

瀑布开发时代

时代特色:各物种一专、多人瀑布流式协作

这是一个非常了不起的创意,因为它利用了不同团队的开发者们只在必须的时候才进行沟通的这个事实。当一个团队完成了他们的工作的时候,它就会和下游的团队进行交流并把任务进行往下传,如此一级接一级的传递下去,永不回首。
在这里插入图片描述

Analyse 分析

Design 设计

Code 开发

Test 测试

Deploy 部署

Fix/Maintain 加固/维护

这种方式在一段时间内发挥了效用,但很快,一如既往,客户又开始提出更多的诉求。他们希望能够更多地参加到整个软件的开发流程中来,不时的提出他们的建议,甚至在很晚的时候还提出改需求这种丧心病狂的事情来。结果就是如大家有目共睹的事实一样,软件项目非常容易失败这个说法已经作为一个行业标准被人们所接受。

数据表明超过50%的项目最终都是以失败告终的。更可悲的是,在当时看来,人们对这种情况是束手无策。

值得庆幸的是,每一个时代总会有那么几个思想开放的英雄如漆黑中的萤火虫般冒出来。他们知道这些不同团队的开发者们必须要找到一个可以协同工作、进行交流、并且能够弹性的向客户保证对方将会拿到最优的解决方案的方式。这就是敏捷开发。

敏捷开发时代

时代特色:物种一专、多人有效沟通、 协作、 拥抱变化

​ 最早可以追溯到1957年,伟大的约翰·冯·诺依曼和同行们的努力。但是我们最终却是等到2001年才收获到革命的果实,当时行业的十多个精英创造出了如今闻名世界的“敏捷宣言”。

敏捷宣言十二条原则:

  1. 首要任务是通过尽早地、持续地、交付可评价的软件来使客户满意
  2. 乐于接受需求变更,即使是在开发后期也应如此。敏捷过程能够驾驭变化,从而为客户赢得竞争优势。
  3. 频繁交付可使用的软件,交付间隔越短越好,可以从几个星期到几个月。
  4. 在整个项目开发期间,业务人员和开发人员必须朝夕工作在一起
  5. 围绕那些有推动力的人们来构建项目。给予他们所需的环境和支持,并且信任他们能够把工作完成好。
  6. 与开发团队以及在开发团队内部最快速、有效的传递信息的方法就是:面对面的交谈
  7. 可使用的软件是进度的主要衡量指标。
  8. 敏捷过程提倡可持续发展。出资人、开发人员以及使用者应该总是共同维持稳定的开发速度
  9. 为了增强敏捷能力,应持续关注技术上的杰出成果和良好的设计
  10. 简洁,做工作量减法。
  11. 最好的架构、需求和设计都源自自我组织的团队
  12. 团队应该定期反思如何能变得更有战斗力

在这里插入图片描述

敏捷宣言好处

​ 敏捷宣言是各物种间迈出各自领域很重要的第一步。这是在以往各物种很长的时间里隔阂后,第一次将不同的关键项目关系人连接在了一起。人们开始互相交流,进行基本的碰头会议,并开始不断的交流意见和看法。他们开始意识到他们是有着很多比想象中还多的共同点,客户也开始成为他们中的一员,而不再是像以往一样只是往项目砸钱然后开始求神拜佛祈求一切顺利如愿。

敏捷意味着开放和拥抱(需求)改变。但是,如果改变过多的话,人们就很难专注最终的目标交付上来。

此时精益软件开发就开始破土而出了。

精益开发时代

时代特色:精益求精

​ 软件开发行业向软件之外的行业进行学习,目的是为了进一步减少项目风险,实现快速交付。

​ 精益开发思想是从丰田汽车生产系统借鉴而来的,把他们的精益生产经验应用到软件开发上面。

精益7原则:

  1. 杜绝浪费

    通过杜绝浪费,达到发挥资源的效率。

  2. 内建质量

    质量把关,提升客户对产品整体质量良好感受。

  3. 增强学习能力

    通过轮岗方式使得员工取得多种工作技能。

  4. 延迟决策(尽量延迟决策)

    以不变,应万变;根据事实而非假设来做决策。

  5. 快速发布

    越早获得客户反馈,越早安排开发事项;越短开发周期,越快从市场获取实时信息,为应变市场变化获取时间。

  6. 授权与尊重

    让团队成员知道工作全貌;团队领导者要有支持和帮助,克服困难,维持团队合作默契。

  7. 系统思考

​ 鼓励人与人之间沟通,促进探讨如何生产最好的产品和服务,从而避免局部性思考带来的整合时出现相依性的问题。

​ 将这些放到敏捷开发上去的话,精益原则就能让人们在从精神上关注做正确的事情,同时还能够让整个开发流程拥有足够的弹性

​ 一旦敏捷和精益软件开发被软件开发团队采纳,那么下一步就是把这一套原则应用到IT团队上来。把IT也纳入到整体战略上,这就是我们前面给前面给大家提到的DevOps思想。

DevOps

​ 软件开发团队成员一般会包括项目经理,系统架构师、前端开发者,后端开发者,测试工程师,网络工程师,运维工程师等。软件先由后端开发者,前端开发者进行开发,当软件开发完成,需要部署时,软件会通过自动化手段达到系统架构师,运维工程师等这些运维人员的手上,由运维人员进行部署、发布即可。

如何让软件在开发、测试、运维及最终发布之间进行有效的流动,这就是DevOps所要关注的重点。

DevOps是整个IT架构实施中使用敏捷开发及精益原则的结果,利用精益原则可以使用开发与运维无缝结合。

DevOps是一种文化,一种理念,是一种把开发(Dev)、测试(Test)、运维(Ops)及最终发布(CR)工作流进行联合的思想。

利用DevOps思想工作的三种方式及实践方法

第一种:系统思考

强调全局优化,而非局部改进。
大到部门职能划分(例如研发部和运维部门),小到个人(开发和系统工程师)。

这种方式将关注点放在整个业务价值流上。换句话说,整个团队应该关注在从需求被定义到开发,再到运维这个过程,直到价值被以服务的形式交付给最终用户。

将这种方式带到实践中的产出便是永远不要将已知的缺陷传递到下游工作,永远不要为了局部优化影响了整体价值流交付,总是为了增加价值流动努力,永远追求对架构的深刻理解。

实践方法

  • 所有环境和代码使用同一个仓库,将软件包纳入版本管理
  • 团队共同决定发布流程
  • 保持 DEV、TEST、PRODUCTION 环境的一致性
  • 自动化回归测试
  • 小步提交,每日部署;而不是一次部署大量变更
  • 更快、更频繁发布

回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。

第二种:放大反馈环

​ 创建从开发过程下游至上游的反馈环。几乎所有的流程改进都是为了从时间上缩短和从覆盖面上放大反馈循环,从而可以不断地进行必要的改正。

​ 产出是关注到价值流中所有涉及到的用户,包括价值流内部和外部的,缩短和放大反馈回路,并且可以随时定位到需要改进的地方。

实践方法

  • 代码审查及配置变更检查
  • 有纪律的自动化测试,使许多同时的小型敏捷团队能够有效地工作
  • 尽早设置监控预警
  • 修复 bug 为团队最高优先级
  • 团队成员之间高度互相信任
  • 团队之间保持沟通和良好合作

第三种:持续实验和学习的文化

​ 提倡持续做试验,承担风险、从失败中学习;通过反复实践来达到精通。

​ 我们需要实验和冒着失败的风险,及时不断地尝试将我们置于一个危险的境地,我们要通过反复试错来掌握使我们远离危险的技能。

实践方法

  • 对服务器正在承载的业务进行故障模拟,把人工错误引入系统中,加强系统的健壮性
  • 生产中部署一台服务器用于进行故障训练,以便练习服务器经常处于失效状态下的故障恢复能力。

DevOps清单

团队有没有按照DevOps的思想去工作,可以按以下清单进行对照即可

  • 开发团队和运维团队之间没有障碍。两者皆是DevOps统一流程的一部分。
  • 从一个团队流到另一个团队的工作都能够得到高质量的验证
  • 工作没有堆积,所有的瓶颈都已经被处理好。
  • 开发团队没有占用运维团队的时间,因为部署和维护都是处于同一个时间段。
  • 开发团队不会在周五下午5点后把代码交付进行部署,剩下运维团队周末加班加点部署
  • 开发环境标准化,运维人员可以很容易將之扩展并进行部署
  • 开发团队可以找到合适的方式交付新版本,且运维团队可以轻易的进行部署。
  • 每个团队之间的通信线路都很明确
  • 所有的团队成员都有时间去为改善系统进行试验和实践
  • 常规性的引入(或者模拟)缺陷到系统中来并得到处理。每次学习到的经验都应该文档化下来并分享给相关人员。事故处理成为日常工作的一部分,且处理方式是已知的

版本控制概念

什么是版本?

答: centos6.9,centos7.3,centos7.5这些属于操作系统的版本。

​ nginx-1.10,nginx1.14这些属于软件的版本。

​ 一个配置文件或一个代码文件被多次修改,也会有对应的版本。

什么是版本控制?

版本控制软件提供完备的版本管理功能,用于存储、追踪目录(文件夹)和文件的修改历史,是软件开发者的必备工具,是软件公司的基础设施。版本控制软件的最高目标,是支持软件公司的配置管理活动,追踪多个版本的开发和维护活动,及时发布软件。
在这里插入图片描述

在这里插入图片描述

常见的版本控制系统及比较

cvs,svn,git都是版本控制系统

腾讯 tapd, 百度 icafe, 阿里 云效等也是一站式的版本控制。

cvs和svn都是集中式版本控制系统,而git是分布式版本控制系统。

在这里插入图片描述

在这里插入图片描述

比较

  • 集中式版本控制系统必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的话,呵呵。分布式版本控制系统可以不连网工作, 因为版本库就在你自己的电脑上。
  • 集中式版本控制系统如果中央服务器挂了,就完蛋了。分布式版本控制系统可以没有中央服务器,每个人的电脑上都是一个完整的版本库,可靠性高。分布式版本控制系统也可以有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。

git的安装

官网: https://git-scm.com/
在这里插入图片描述

git安装

[root@vm1 ~]# yum install git

[root@vm1 ~]# git --version
git version 1.8.3.1

查看参数帮助

查看参数帮助
[root@vm1 ~]# git --help  
git的操作可以说只需要git一条命令加参数即可

git应用

git身份设置

因为git是分布式版本控制系统,不同的人提交代码需要区分,所以每个人都要设置一个身份标识。如果不设置的话谁会知道你这个开发者是张三,李四,还是王五呢?

[root@vm1 ~]# git config --global user.name "daniel"
[root@vm1 ~]# git config --global user.email "daniel@itcast.cn"
[root@vm1 ~]# git config --global color.ui true

[root@vm1 ~]# git config --list
user.name=daniel
user.email=daniel@itcast.cn
color.ui=true

创建本地仓库

工作目录(working directory): 也可叫工作区. 是存放项目代码文件的一个目录。

仓库(repository) : 也可叫版本库. 在git init命令初始化工作目录后会产生一个隐藏的子目录.git, 可以将其理解为git的仓库或版本库。

仓库分为本地仓库远程仓库

在这里插入图片描述

在这里插入图片描述

创建本地仓库的步骤:

  1. 创建工作目录
[root@vm1 ~]# mkdir GitTest
  1. 在对应的工作目录中创建本地仓库
[root@vm1 ~]# cd GitTest/
[root@vm1 GitTest]# git init
Initialized empty Git repository in /root/GitTest/.git/
会产生一个.git子目录,所有除代码数据外的相关数据都在此目录,不要修改它.
(它就是仓库或叫版本库)
[root@vm1 GitTest]# ls .git/
branches  config  description  HEAD  hooks  info  objects  refs

小结: mkdir创建一个工作目录, 然后cd进去, 使用git init就创建好了本地仓库。开发者就可以在工作目录里开发项目代码文件了。

暂存区

暂存区(stage或index): 也有叫**缓存区**

暂存区就看作是一个缓区区域,临时保存你的改动

如果在工作目录创建了一个新文件,需要将新文件添加到暂存区。

添加文件到暂存区

1, 准备一个文件

[root@vm1 GitTest]# cat 1.py 
print("hello world")

2, 使用git add命令提交到暂存区(逆向操作为git rm --cached 1.py)

[root@vm1 GitTest]# git add 1.py

3, 提交第一个文件后,版本库.git子目录里就多了一个index

[root@vm1 GitTest]# ls .git/
branches  config  description  HEAD  hooks  index  info  objects  refs

4, 使用strings命令查看可以看到git add的文件列表

[root@vm2 GitTest]# strings .git/index 
DIRC
1.py									这里可以看到1.py文件添加到了index文件里了

git版本控制

提交文件(第1个版本)

代码文件需要commit提交后才能纳入版本控制。

1, 可以使用git status查看工作目录里有哪些文件需要提交

[root@vm1 GitTest]# git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#	new file:   1.py
#

2, 使用git commit提交; -m 后接提交的说明信息

[root@vm1 GitTest]# git commit -m "提交1.py"
[master (root-commit) 4e67190] 提交1.py
 1 file changed, 1 insertion(+)
 create mode 100644 1.py

3, 再次git status查看状态,没有需要提交的文件了

[root@vm1 GitTest]# git status
# On branch master
nothing to commit, working directory clean

修改再提交(第2个版本)

1, 修改1.py文件,我这里加了一句print(“hello python”)

[root@vm1 GitTest]# cat 1.py
print("hello world")
print("hello python")

2, 使用git status查看,信息告诉我们1.py被修改了

[root@vm1 GitTest]# git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   1.py
#
no changes added to commit (use "git add" and/or "git commit -a")

3, 使用git diff查看修改了什么

[root@vm1 GitTest]# git diff 1.py
diff --git a/1.py b/1.py
index 8cde782..5da7641 100644
--- a/1.py
+++ b/1.py
@@ -1 +1,2 @@
 print("hello world")
+print("hello python")

4, 提交修改(add+commit)

[root@vm1 GitTest]# git add 1.py
[root@vm1 GitTest]# git commit -m "添加了一行代码打印hello python"
[master 0e9371b] 添加了一行代码打印hello python
 1 file changed, 1 insertion(+)

再修改再提交(第3个版本)

再增加一句代码print("hello linux")
[root@vm1 GitTest]# cat 1.py
print("hello world")
print("hello python")
print("hello linux")

[root@vm1 GitTest]# git add 1.py

[root@vm1 GitTest]# git commit -m "添加了一行代码打印hello linux"
[master b679b01] 添加了一行代码打印hello linux
 1 file changed, 1 insertion(+)

小结:

  • 工作目录中写好的代码文件需要先git add 文件名添加到暂存区,再git commit 文件名提交。以后每次修改都要重复前两步。
  • git status查看工作目录中的状态
  • git diff 文件名查看文件修改了什么

查看提交历史

1, 使用git log查看提交的历史版本信息

[root@vm1 GitTest]# git log
commit b679b01f2ee42c1c4a7e14ed5d37e02da131a98e
Author: daniel <daniel@itcast.cn>
Date:   Wed Jan 16 14:00:44 2019 +0800

    添加了一行代码打印hello linux

commit 0e9371bfdbc27049c31017773248ae8333b5bf3f
Author: daniel <daniel@itcast.cn>
Date:   Tue Jan 15 23:43:58 2019 +0800

    添加了一行代码打印hello python

commit 4e67190ec3c57f1708702c9eca5aebe88017bdd2
Author: daniel <daniel@itcast.cn>
Date:   Tue Jan 15 23:23:26 2019 +0800

    提交1.py

2, 使用git log --pretty=oneline查看提交的历史版本信息, 查看的显示信息更简洁。

​ 前面字符串你可以看作就是一个版本号(commit id)。

[root@vm1 GitTest]# git log --pretty=oneline
b679b01f2ee42c1c4a7e14ed5d37e02da131a98e 添加了一行代码打印hello linux
0e9371bfdbc27049c31017773248ae8333b5bf3f 添加了一行代码打印hello python
4e67190ec3c57f1708702c9eca5aebe88017bdd2 提交1.py

版本回退与还原

1, 使用git reset --hard HEAD^回退到上一个版本(也就是第2个版本)

[root@vm1 GitTest]# git reset --hard HEAD^
HEAD is now at 0e9371b 添加了一行代码打印hello python

[root@vm1 GitTest]# cat 1.py 
print("hello world")
print("hello python")

2, 使用git reset --hard 第3个版本号 还原到第3个版本。

​ 但如果我忘了第3个版本号是什么了,使用git reflog查看所有的操作历史。

[root@vm1 GitTest]# git reflog
0e9371b HEAD@{0}: reset: moving to HEAD^
b679b01 HEAD@{1}: commit: 添加了一行代码打印hello linux
0e9371b HEAD@{2}: commit: 添加了一行代码打印hello python
4e67190 HEAD@{3}: commit (initial): 提交1.py

3, 还原到第3个版本

[root@vm1 GitTest]# git reset --hard b679b01
HEAD is now at b679b01 添加了一行代码打印hello linux

[root@vm1 GitTest]# cat 1.py 
print("hello world")
print("hello python")
print("hello linux")

4, 回退到上上一个版本, 也就是回退两个版本,使用git reset --hard HEAD^^

回退三个版本,使用git reset --hard HEAD^^^, 以此类推。

如果回退100个版本,那用100个^符号不方便,可以换成git reset --hard HEAD~100

[root@vm1 GitTest]# git reset --hard HEAD^^
HEAD is now at 4e67190 提交1.py

[root@vm1 GitTest]# cat 1.py 
print("hello world")

小结:

  • 提交后的代码文件,使用git log查看当前版本及以前的历史版本。
  • 使用git reset --hard HEAD^或者git reset --hard HEAD~100实现版本回退。
  • 使用git reflog查看提交的所有操作及版本号
  • 使用git reset --hard 版本号你可以自由的在不同版本之间来回切换。

git工作流再次理解与应用拓展

  • 工作目录里任何修改或增加的文件,都要git add到暂存区,让暂存区和工作目录的状态一致,这样才能提交一个版本。
  • git commit提交的是在暂存区里的所有文件状态。也就是说是整个工作目录里的状态保存为一个版本,而不是某一个文件
  • git版本控制不仅仅是用于项目开发,你也可以用于一个软件包仓库的版本控制。

撤销修改

如果开发者状态不好,今天写的代码一团乱,想吃后悔药,git也提供了撤销的方法。

1, 准备一行或一段写错的代码

[root@vm1 GitTest]# cat 1.py 
print("hello world")
print("hello python")
print("hello linux")
print("hey,xxx is a gay")				这是写错的代码,需要反悔

想要撤销修改有以下方法:

  • 直接把写错的代码删除就好, 但如果改变的代码很多,开发者自己都忘了具体改了哪些代码,这种做法就不方便了
  • 使用git checkout -- 文件名就可以直接撤销修改了
  • 如果写乱了代码,添加暂存区但还没有commit提交。使用git reset HEAD 文件名取消暂存区添加,再git checkout -- 文件名来撤销修改
  • 如果写乱了代码,添加暂存区并提交了。则使用版本回退

误删恢复

1, 只要文件git add到了暂存区, 无论有没有git commit提交。误删除后都可以使用 git checkout -- 文件名来恢复。

[root@vm1 GitTest]# touch 2.py
[root@vm1 GitTest]# git add 2.py
[root@vm1 GitTest]# rm 2.py  -rf
[root@vm1 GitTest]# ls
1.py
[root@vm1 GitTest]# git checkout -- 2.py
[root@vm1 GitTest]# ls
1.py  2.py

2, 如果文件没有git add到暂存区, 误删除了就没了。

[root@vm1 GitTest]# touch 3.py
[root@vm1 GitTest]# rm 3.py  -rf

下面命令恢复报错
[root@vm1 GitTest]# git checkout -- 3.py
error: pathspec '2.py' did not match any file(s) known to git.

文件删除

1, 没有git add到暂存区的文件直接rm删除就ok

2, git add添加到暂存区,但没有git commit提交的文件。需要rm删除本地,还要git rm 文件名删除

[root@vm1 GitTest]# touch 3.py
[root@vm1 GitTest]# git add 3.py

[root@vm1 GitTest]# rm 3.py -rf
[root@vm1 GitTest]# git rm 3.py
rm '3.py'

3, git add添加到暂存区,并且已经git commit提交的文件。需要rm删除本地,再git rm 文件名删除,最后再提交删除

[root@vm1 GitTest]# touch 3.py
[root@vm1 GitTest]# git add 3.py
[root@vm1 GitTest]# git commit -m "提交了3.py"
[master 0236aef] 提交了3.py
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 3.py


[root@vm1 GitTest]# rm 3.py -rf
[root@vm1 GitTest]# git rm 3.py
rm '3.py'
[root@vm1 GitTest]# git commit -m "删除了3.py"
[master dc4ee5e] 删除了3.py
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 3.py

git版本控制小结

在这里插入图片描述

git分支管理

先来考虑一个问题: 开发者A开发软件的某一个功能模块, 还没有开发完成,但害怕进度丢失就提交。假设另一位开发者B并不知道A没有完成, 而直接使用了A开发的文件,这造成了问题。

解决方法: 开发者A创建一个属于自己的分支,这个分支只属于A,不会影响其他人。开发完成后,合并到项目主分支即可。

分支可以看作为平行空间
在这里插入图片描述

查看分支

默认只有一个master分支, 前面有*号的代表为当前分支。

[root@vm1 GitTest]# git branch
* master

创建分支

使用git branch 分支名来创建分支

[root@vm1 GitTest]# git branch dev

[root@vm1 GitTest]# git branch 
  dev
* master

切换分支

使用git checkout 分支名来切换分支

[root@vm1 GitTest]# git checkout dev
Switched to branch 'dev'
[root@vm1 GitTest]# git branch 
* dev
  master

合并分支

1, 在dev分支上新开发了一个代码文件,添加并提交

[root@vm1 GitTest]# git branch 
* dev						确认为dev分支
  master

[root@vm1 GitTest]# echo "new feature" > 5.py
[root@vm1 GitTest]# git add 5.py
[root@vm1 GitTest]# git commit -m "增加了新特性"
[dev 4a0c78e] 增加了新特性
 1 file changed, 1 insertion(+)
 create mode 100644 5.py

2, 切换到master上分支后,却发现根本没有这个文件

[root@vm1 GitTest]# git checkout master
Switched to branch 'master'
[root@vm1 GitTest]# cat 5.py 
cat: 5.py: No such file or directory

3, 合并分支,再查看能在master分支上查看到了

[root@vm1 GitTest]# git merge dev
Updating dc4ee5e..4a0c78e
Fast-forward
 5.py | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 5.py
 
[root@vm1 GitTest]# cat 5.py 
new feature

分支冲突

有些复杂的情况会造成冲突,这个时候git就不能帮我们自动的合并分支。我们就要手动处理冲突。

1, 在dev分支修改文件

[root@vm1 GitTest]# git checkout dev
Switched to branch 'dev'
[root@vm1 GitTest]# echo "冲突测试" >> 5.py 
[root@vm1 GitTest]# cat 5.py 
new feature
冲突测试

2, 提交dev分支上的修改

[root@vm1 GitTest]# git add 5.py
[root@vm1 GitTest]# git commit -m "冲突测试"
[dev de5075c] 冲突测试
 1 file changed, 1 insertion(+)

3, 切回master分支,也修改相同的文件

[root@vm1 GitTest]# git checkout master
Switched to branch 'master'
[root@vm1 GitTest]# echo "哈哈" >> 5.py 
[root@vm1 GitTest]# cat 5.py 
new feature
哈哈

4, 提交master分支上的修改

[root@vm1 GitTest]# git add 5.py
[root@vm1 GitTesgit commit -m "冲突测试"
[master c17f325] 冲突测试
 1 file changed, 1 insertion(+)

5, 合并dev分支到master,就会出现冲突了

[root@vm1 GitTest]# git merge dev
Auto-merging 5.py
CONFLICT (content): Merge conflict in 5.py
Automatic merge failed; fix conflicts and then commit the result.

6, 手工解决冲突

git使用<<<<<<<<<,=========,>>>>>>>>符号分割冲突的内容,手动删除这些符号,并修改成你想要的内容

解决冲突前:
[root@vm1 GitTest]# cat 5.py 
new feature
<<<<<<< HEAD
哈哈
=======
冲突测试
>>>>>>> dev

解决冲突后:
[root@vm1 GitTest]# cat 5.py 
new feature
冲突解决

7, 解决冲突后添加并提交,最后再合并

[root@vm1 GitTest]# git add 5.py
[root@vm1 GitTest]# git commit -m "冲突解决"
[master fb05c2f] 冲突解决
[root@vm1 GitTest]# git merge dev
Already up-to-date.

删除分支

使用git branch -d 分支名来删除分支。注意: 不能删除当前使用的分支.

[root@vm1 GitTest]# git branch
  dev
* master

[root@vm1 GitTest]# git branch -d dev
Deleted branch dev (was de5075c).

[root@vm1 GitTest]# git branch
* master

windows版git(拓展)

windows上安装git

在这里插入图片描述

windows上安装git
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

windows上使用git

在这里插入图片描述

在这里插入图片描述

github

学习目标

  • 能够使用GitHub创建远程仓库并使用
  • 能够安装部署GitLab服务器
  • 能够使用GitLab创建仓库并使用
  • 掌握CI/CD的概念
  • 掌握蓝绿部署, 滚动更新,灰度发布的概念

GitHub是目前最火的开源项目代码托管平台。它是基于web的Git仓库,提供公有仓库和私有仓库,但私有仓库是需要付费的。

GitLab可以创建免费的私有仓库。

GitLab是利用 Ruby开发的一个开源的版本管理系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目。它拥有与Github类似的功能,能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库。团队成员可以利用内置的简单聊天程序(Wall)进行交流。它还提供一个代码片段收集功能可以轻松实现代码复用,便于日后有需要的时候进行查找。

注册github账号

github官网地址: https://www.github.com
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

登录注册账号时填写的邮箱,找到github发的邮件,打开并点击里面的Verify email address
在这里插入图片描述

在这里插入图片描述

创建项目

在这里插入图片描述

在这里插入图片描述

我们就创建好了第一个项目。
在这里插入图片描述

使用github远程仓库

第1步: 在gibhub上获取克隆地址
在这里插入图片描述

第2步: 克隆项目到本地linux,默认克隆到当前目录

[root@vm1 ~]# git clone https://github.com/linux-daniel/daniel_project.git
Cloning into 'daniel_project'...
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@vm1 ~]# ls daniel_project/
README.md

[root@vm1 ~]# cat daniel_project/README.md 
# daniel_project
教学测试项目

第3步: 提交代码文件

在克隆下来的仓库里准备一个代码文件
[root@vm1 ~]# cd daniel_project/
[root@vm1 daniel_project]# vim hello.py 
print("hello world")

[root@vm1 daniel_project]# git add hello.py
[root@vm1 daniel_project]# git commit -m "提交hello.py"
[master b59e1d6] 提交hello.py
 1 file changed, 1 insertion(+)
 create mode 100644 hello.py

第4步: 使用git push推送到github

[root@vm1 daniel_project]# git push -u origin master
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Username for 'https://github.com': linux-daniel					这里输入你的github账号名
Password for 'https://linux-daniel@github.com': 				再输入你的github密码
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 302 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/linux-daniel/daniel_project.git
   2ff4805..b59e1d6  master -> master

第5步: 回到github验证
在这里插入图片描述

补充:

使用下面的命令可以实现https的密码缓存(下次不用再输密码了)

# git config --global credential.helper store

免密push

免密push其实就是利用了ssh免密登录的原理:

  1. 在本地产生空密码密钥对
  2. 本地保留私钥,把公钥给对方
  3. 实现本地到远程的免密

第1步: 开发者电脑产生ssh空密码密钥对

[root@vm1 daniel_project]# ssh-keygen -t rsa -f /root/.ssh/id_rsa -C "root@daniel.cluster.com"  -N ""

第2步: 把公钥文件的内容复制到剪贴板

[root@vm1 daniel_project]# cat /root/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCz2rKSMbJwvdRN5VnsaRA0ydDDtm0ruTQY0ZVsynuj15RcFuKjrlYAEF3rU2AowL7n68xWabf3lC9l6WZjLa6cibfjW1wNnroPE2kzZADSoxcAAYxKVg/wkG2j5lPC4jJRPiSLg/yCyDA7go567ShvUCH8goMXMyMzKx1eIaU2nZoLnh7ulBv4URs5jPSE9kwhQ9MnUIzihQRvz9tqURYKIzmthSkm0CyXAlT6qufTdaNp/KmoH2Idj+rXufEsLF5qHD0lKaSM4bKZvqWNhd4a6XrF9DpoeSpeI63P3ZZkVTbmTSFgbBM8+KgxvGyUxfvjimo8Ed8TY5TGA6qC+g7F root@daniel.cluster.com

第3步: github上添加开发者的公钥

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

第4步: 获取ssh克隆方式地址

在这里插入图片描述
在这里插入图片描述

第5步: 开发者再git clone项目到本地

[root@vm1 ~]# rm daniel_project/ -rf
[root@vm1 ~]# git clone git@github.com:linux-daniel/daniel_project.git
Cloning into 'daniel_project'...
The authenticity of host 'github.com (13.229.188.59)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
RSA key fingerprint is MD5:16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,13.229.188.59' (RSA) to the list of known hosts.
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 0), reused 3 (delta 0), pack-reused 0
Receiving objects: 100% (6/6), done.

第6步: 再准备一个新的代码文件, 添加并提交

[root@vm1 ~]# cd daniel_project/

我这里准备一个haha.py文件
[root@vm1 daniel_project]# cat haha.py 
print("haha")

[root@vm1 daniel_project]# git add haha.py
[root@vm1 daniel_project]# git commit -m "提交haha.py"
[master 2186bae] 提交haha.py
 1 file changed, 1 insertion(+)
 create mode 100644 haha.py

第7步: 这次再使用git push就会发现不需要输入账号密码了

[root@vm1 daniel_project]# git push

第8步: github上验证

在这里插入图片描述

小结: github有两种连接方式:

  1. Clone with HTTPS
  2. Clone with SSH(通过ssh免密密钥对实现免密push)

github分支(拓展)

第1步: 在github上创建一个新的dev分支
在这里插入图片描述

第2步: 开发者电脑的dev分支上开发,并上传到github的dev分支 (这里可以再次git clone,也可以直接在本地对应的创建dev分支,还可以git pull进行同步更新)

[root@vm1 daniel_project]# git pull
[root@vm1 daniel_project]# git branch dev
[root@vm1 daniel_project]# git checkout dev
Switched to branch 'dev'
[root@vm1 daniel_project]# echo "新功能" > new.py
[root@vm1 daniel_project]# git add new.py
[root@vm1 daniel_project]# git commit -m "增加了发红包功能"
[dev 2d38f8e] 增加了发红包功能
 1 file changed, 1 insertion(+)
 create mode 100644 new.py
[root@vm1 daniel_project]# git push -u origin dev
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 295 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To git@github.com:linux-daniel/daniel_project.git
   2186bae..2d38f8e  dev -> dev
Branch dev set up to track remote branch dev from origin.

第3步: 在github上创建pull request将dev分支的新代码merge到master分支
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

第4步: 验证最终效果
在这里插入图片描述

多人协作(拓展)

如果有多个开发者开发项目的话,如何代码合并呢? 下面我们来演示这样的过程

fork me on github

clone与fork的区别:

clone: 任何人都可以下载作者的整个项目,但非作者不能push到作者的项目里(因为没有作者的账号密码)

fork:

  • 张三fork了作者的项目,相当于可以下载作者的一个项目副本。
  • 张三开发完后再上传到张三自己的账号里
  • 张三请求合并到作者的账号项目里
  • 作者可以同意或拒绝这个请求

第1步: 再申请一个github账号模拟第二位开发者(我这里新申请的账号为linux-daniel2),登录后查找linux-daniel第一位开发者的项目
在这里插入图片描述

第2步: 第二位开发者Fork第一们开发者的项目,就会在自己的账号里得到项目代码的副本
在这里插入图片描述
在这里插入图片描述

第3步: 第二位开发者使用自己的电脑(这里我使用vm5来模拟)进行开发,然后上传

[root@vm5 ~]# git clone https://github.com/linux-daniel2/daniel_project.git
Cloning into 'daniel_project'...
remote: Enumerating objects: 13, done.
remote: Counting objects: 100% (13/13), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 13 (delta 1), reused 9 (delta 1), pack-reused 0
Unpacking objects: 100% (13/13), done.

[root@vm5 ~]# cd daniel_project/

[root@vm5 daniel_project]# git branch dev
[root@vm5 daniel_project]# git checkout dev
Switched to branch 'dev'

[root@vm5 daniel_project]# echo "分享功能" > new2.py
[root@vm5 daniel_project]# git add new2.py


[root@vm5 daniel_project]# git commit -m "增加了分享功能"


[root@vm5 daniel_project]# git push -u origin dev
Username for 'https://github.com': linux-daniel2
Password for 'https://linux-daniel2@github.com':
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 313 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/linux-daniel2/daniel_project.git
   2d38f8e..1c95bf2  dev -> dev
Branch dev set up to track remote branch dev from origin.

第4步: 第二位开发者确认开发的代码上传到自己的github仓库成功

在这里插入图片描述

第5步: 第二位开发者创建pull request将代码请求合并到第一位开发者的原项目里去
在这里插入图片描述
在这里插入图片描述

第6步: 回到第一位开发者的账号,对第二位开发者的请求进行合并确认
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第7步: 因为是合并到原项目的dev分支,如果没问题的话,还需要合并到master分支。(请小伙伴们自行完成)

最终结果图如下:
在这里插入图片描述

步骤小结:

开发者1为项目拥有者, 开发者2帮开发者1开发新功能

  1. 开发者2 Fork 开发者1的项目(相当于copy一个副本)
  2. 开发者2使用git clone这个项目副本到自己的开发电脑
  3. 开发者2开发新功能,并push到项目副本
  4. 开发者2使用pull request将开发好的新功能请求合并到开发者1的项目仓库
  5. 开发者1确认

gitlab

gitlab下载

在这里插入图片描述
在这里插入图片描述

gitlab安装与配置

准备一台新虚拟机来安装(内存可适当调大点,比如1.5G)

安装

[root@vm2 ~]# rpm -ivh gitlab-ce-11.8.2-ce.0.el7.x86_64.rpm

配置

[root@vm2 ~]# vim /etc/gitlab/gitlab.rb
13 external_url 'http://10.1.1.12'				修改成gitlab服务器的IP地址,对外服务

初始化

[root@vm2 ~]# gitlab-ctl reconfigure			
时间较久,需要3分钟左右时间,会自动帮助配置各个组件,并启动

查看状态

[root@vm2 ~]# gitlab-ctl status	
run: alertmanager: (pid 10563) 36s; run: log: (pid 10234) 64s
run: gitaly: (pid 10343) 39s; run: log: (pid 9380) 163s
run: gitlab-monitor: (pid 10417) 38s; run: log: (pid 10082) 80s
run: gitlab-workhorse: (pid 10364) 39s; run: log: (pid 9835) 104s
run: logrotate: (pid 9916) 93s; run: log: (pid 9952) 90s
run: nginx: (pid 9876) 99s; run: log: (pid 9908) 96s
run: node-exporter: (pid 10399) 38s; run: log: (pid 10003) 84s
run: postgres-exporter: (pid 10585) 35s; run: log: (pid 10267) 60s
run: postgresql: (pid 9499) 158s; run: log: (pid 9562) 157s
run: prometheus: (pid 10452) 37s; run: log: (pid 10161) 70s
run: redis: (pid 9275) 170s; run: log: (pid 9296) 169s
run: redis-exporter: (pid 10426) 38s; run: log: (pid 10127) 74s
run: sidekiq: (pid 9787) 111s; run: log: (pid 9808) 110s
run: unicorn: (pid 9731) 117s; run: log: (pid 9781) 114s

gitlab登录

设置密码(密码需要最少8位)
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

gitlab设置

配置邮箱服务的用途:

  • 账号注册时,邮件验证
  • 有合并请求时,邮件通知
  • 修改密码时,通过邮件修改
    在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

开发者设置ssh密钥

第1步: 在开发者电脑上产生空密码密钥

(注意: 可以直接使用上面实验的github开发者的密钥,也可以模拟新的开发者重新产生,再做一遍。这里我们再做一次)

[root@vm1 ~]# ssh-keygen -t rsa -f /root/.ssh/id_rsa -C "dev1@itcast.cn" -N ""

第2步: 查看并复制公钥

[root@vm1 ~]# cat /root/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAJW+LIFdcC0DI6oM6eOf6+EPks2ODyPaR/cAWKeFcfnSvuU84ZFYtziQyJYf1RdXwxo6vH+XyBNwOGrTLB1m33RvAgUznVhBH3KA9l1OimYSqEdQJ+4g+LVDkrgj/vIRc1dv7wDglyYGOOFfRftRK/QEHK911MOyJCK1nH0rr7eE7sP33aD6I6DoIfaSC0UUDPfwHDg/bQUDsF/ez4tEPOTSeJ2jVyytArHOAjtflL1+ZvP25F4osdSXju6IG8i7HHiZ0sz1WuQEYH8KzrY/zf8DBFrnOB4vl2UTNwP/NjT06TY78gKMJqcpf1maZR3YIeYlA03ccSOWSZuqq50eP dev1@itcast.cn

第3步: 在gitlab界面添加公钥
在这里插入图片描述
在这里插入图片描述

gitlab创建仓库

第1步: 在gitlab上创建项目(其实也就是存放代码的仓库)
在这里插入图片描述

第2步: 自定义项目名称,描述等
在这里插入图片描述

第3步: 验证创建好的项目
在这里插入图片描述

克隆远程仓库到本地

第1步: 查看gitlab上的帮助
在这里插入图片描述

第2步: 在开发者电脑上设置身份标识

[root@vm1 ~]# git config --global user.name "daniel"
[root@vm1 ~]# git config --global user.email "daniel@itcast.cn"
[root@vm1 ~]# git clone git@10.1.1.12:root/mywebsite.git

第3步: 在开发者电脑上使用git命令clone,并上传项目

[root@vm1 ~]# cd mywebsite/

[root@vm1 mywebsite]# echo "test web" > README.md
[root@vm1 mywebsite]# git add .
[root@vm1 mywebsite]# git commit -m "add README.md"

[root@vm1 mywebsite]# git push -u origin master

第4步: 验证

在这里插入图片描述

小结

git 分布式版本控制工具

github和gitlab都属于远程仓库

git clone: 把远程仓库的项目代码下载到本地

git push: 把本地的项目代码上传到远程仓库

git pull: 把远程仓库的项目代码更新到本地

远程仓库两种访问方法:

  • http
  • ssh 使用空密码密钥做免密

持续集成(CI)

Continuous integration,简称CI

​ 是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。
在这里插入图片描述

目的

​ 持续集成的目的不是减少build失败的次数,而是**尽早发现问题,在最短的时间内解决问题**,减少风险和浪费。从而让产品开发流程更加敏捷,缩短产品开发周期,在产品上线后,让用户用得更加顺畅。

​ 在没有应用持续集成之前,传统的开发模式是项目一开始就划分模块,每个开发人员分别负责一个模块,等所有的代码都开发完成之后再集成到一起提交给测试人员,随着软件技术团队的发展,软件已经不能简单地通过划分模块的方式来开发,需要项目内部相互协作,划分模块这种传统的模式的弊端也越来越明显。由于很多bug在项目早期的设计、编码阶段就引入,到最后集成测试时才发现问题,开发人员需要花费大量的时间来定位bug,加上软件的复杂性,bug的定位就更难了,甚至出现不得不调整底层架构的情况。这种情况的发生不仅仅对测试进度造成影响,而且会拖长整个项目周期。

​ 而持续集成可以有效解决软件开发过程中的许多问题,在集成测试阶段之前就帮助开发人员发现问题,从而可以有效的确保软件质量,减小项目的风险,使软件开发团队从容的面对各种变化。持续集成报告中可以体现目前项目进度,哪部分需要已经实现,哪些代码已经通过自动化测试,代码质量如何,让开发团队和项目组了解项目的真实状况。

持续交付(CD)

Continuous Delivery,简称CD

​ 持续交付是指软件开发过程,从原始需求到最终产品开发过程中,较短周期内以需求的小颗粒度(小批量)频繁提交的过程。主要指集成后的代码在类生产环境(测试环境,预发布环境等)中测试并及时反馈的过程.

在这里插入图片描述

目的

  1. 开发过程的快速迭代,小步快跑,及时纠正偏离主线
  2. 小颗粒度实现,避免颗粒度大,出现问题解决麻烦
  3. 迅速反馈软件功能,避免方向性错误
  4. 团队角色(含客户)协作密切,减少时间浪费

持续部署

Continuous Deployment,简称CD

​ 基于持续交付的基础上,把功能稳定,符合产品需求的版本有方法地部署至生产环境中。可以看作是持续交付的最后一环。
在这里插入图片描述

持续发布

Continuous Release,简称CR

​ 发布是周期性或不定期地对项目在部署后,进行整体软件版本的更新,例如,更新新功能或展示页面框架等。

目的

  1. 产品的快速迭代,小步快跑
  2. 适应市场变化
  3. 匹配市场策略
  4. 应对市场风险

持续测试

Continuous Testing,简称CT

​ 持续测试是贯穿着整个软件开发过程,验证程序员提交代码,检验合规性及降低bug,减少最终错误,实现敏捷及精益开发。

目的

  1. 为了降低开发、部署、发布等可能出现的错误
  2. 防止代码出错
  3. 防止功能出错
  4. 防止业务逻辑出错等

代码更新方法

蓝绿部署

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

海豚的秘密
在这里插入图片描述

大家都知道海豚是一种可爱的海洋动物。但又有多少人知道,海豚可以永远不睡觉

是什么样的能力,使得海豚可以永远保持清醒呢?

依靠的是海豚大脑特殊的运作方式。

像人一样,海豚的大脑也分为左脑和右脑两个部分。
在这里插入图片描述

在海豚活跃的状态下,左脑和右脑都是清醒的:
在这里插入图片描述

当然,海豚也是血肉之躯,也是需要休息的。在海豚休息的状态下,其中一半大脑会进入睡眠,另一半大脑仍然保持清醒,以面对各种外界情况。
在这里插入图片描述

每隔两个小时,这种一半睡眠一半清醒的状态会进行交替,比如这一刻左脑睡眠右脑清醒,下一刻左脑清醒右脑睡眠。
在这里插入图片描述

这就是海豚永远不会真正睡觉的秘密。
在这里插入图片描述

蓝绿部署,英文名Blue Green Deployment,是一种可以保证系统在不间断提供服务的情况下上线代码的部署方式。

如何保证系统不间断提供服务呢?

蓝绿部署的模型中包含两个集群,就好比海豚的左脑和右脑。

在这里插入图片描述

在正常情况下(没有上线操作),集群A和集群B的代码版本是一致的,并且同时对外提供服务。
在这里插入图片描述

在有项目代码上线的时候,我们首先把一个集群(比如集群A)从负载列表中摘除,进行新版本的部署。集群B仍然继续提供服务。
在这里插入图片描述

当集群A升级完毕,我们把负载均衡重新指向集群A,再把集群B从负载列表中摘除,进行新版本的部署。集群A重新提供服务。
在这里插入图片描述

最后,当集群B也升级完成,我们把集群B也恢复到负载列表当中。这个时候,两个集群的版本都已经升级,并且对外的服务几乎没有间断过。
在这里插入图片描述
在这里插入图片描述

滚动更新

滚动更新,英文Rolling update,同样是一种可以保证系统在不间断提供服务的情况下上线代码的部署方式。

和蓝绿部署不同的是,滚动部署对外提供服务的版本并不是非此即彼,而是在更细的粒度下平滑完成版本的升级。

如何做到细粒度平滑升级版本呢?

滚动部署只需要一个集群,集群下的不同节点可以独立进行版本升级。比如在一个16节点的集群中,我们选择每次升级4个节点:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

以此类推,最终所有的节点都升级了版本。

蓝绿部署与滚动更新对比

在这里插入图片描述

灰度发布(A/B测试、金丝雀部署)

灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式。

AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。

灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度,而我们平常所说的金丝雀部署也就是灰度发布的一种方式。
在这里插入图片描述

灰度发布/金丝雀部署步骤:

  1. 准备好部署各个阶段的工件,包括:构建工件,测试脚本,配置文件和部署清单文件。
  2. 从负载均衡列表中移除掉“金丝雀”服务器。
  3. 升级“金丝雀”应用(排掉原有流量并进行部署)。
  4. 对应用进行自动化测试。
  5. 将“金丝雀”服务器重新添加到负载均衡列表中(连通性和健康检查)。
  6. 如果“金丝雀”在线使用测试成功,升级剩余的其他服务器。(否则就回滚)

除此之外灰度发布还可以设置路由权重,动态调整不同的权重来进行新老版本的验证。

17世纪,英国矿井工人发现,金丝雀对瓦斯这种气体十分敏感。空气中哪怕有极其微量的瓦斯,金丝雀也会停止歌唱;而当瓦斯含量超过一定限度时,虽然鲁钝的人类毫无察觉,金丝雀却早已毒发身亡。当时在采矿设备相对简陋的条件下,工人们每次下井都会带上一只金丝雀作为“瓦斯检测指标”,以便在危险状况下紧急撤离。

jenkins

学习目标

  • 知道jenkins应用场景
  • 能够安装部署jenkins服务器
  • 能够实现git+github+jenkins手动构建
  • 能够实现git+gitlab+jenkins自动发布系统

​ Jenkins是一个可扩展的持续集成引擎,是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。Jenkins非常易于安装和配置,简单易用。

官网:https://jenkins.io/

jenkins应用场景

场景1:
在这里插入图片描述

  • 研发人员上传开发好的代码到github代码仓库
  • 需要将代码下载到nginx服务器部署
    • 运维人员手动下载再部署
    • 运维人员使用脚本下载再部署

场景2:
在这里插入图片描述
在这里插入图片描述

jenkins下载

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

jenkins安装

准备一台服务器安装jenkins(我这里IP为10.1.1.13)

  • 静态IP(要求能上外网)
  • 主机名
  • 关闭防火墙,selinux
  • 时间同步
  • 确认openjdk1.8版本已经安装
[root@jenkins_server ~]# java -version
openjdk version "1.8.0_161"
OpenJDK Runtime Environment (build 1.8.0_161-b14)
OpenJDK 64-Bit Server VM (build 25.161-b14, mixed mode)

第1步: 将下载好的软件包拷贝到jenkins服务器上直接rpm命令安装

[root@jenkins_server ~]# rpm -ivh jenkins-2.150.3-1.1.noarch.rpm

第2步: 启动服务并验证端口

[root@jenkins_server ~]# systemctl start jenkins
[root@jenkins_server ~]# chkconfig jenkins on

[root@jenkins_server ~]# lsof -i:8080
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    4334 jenkins  163u  IPv6  45095      0t0  TCP *:webcache (LISTEN)

第3步: 查看密码文件里的密码(此为初始管理员用户admin的密码)。通过浏览器访问填上密码(地址为服务器ip的8080端口)

[root@jenkins_server ~]# cat /var/lib/jenkins/secrets/initialAdminPassword
d750b101634b453b87deccfd06365fc9

在这里插入图片描述

第4步: 选择安装推荐的插件(如果是offline状态,或者报错找不到XXX插件,请参考下面的插件安装小节)
在这里插入图片描述

在这里插入图片描述

第5步: 创建新管理员用户(创建了新的管理员用户后,原来的admin用户就不能用了),也可直接使用初始管理员admin登录
在这里插入图片描述

第6步:确认访问地址

在这里插入图片描述

在这里插入图片描述

第7步: 进入jenkins主页面
在这里插入图片描述

退出登录的密码问题

1, log out登出后,再次登录使用admin用户, 密码为cat /var/lib/jenkins/secrets/initialAdminPassword得到字符串

2, 如果要修改密码,按下面图示操作:
在这里插入图片描述
在这里插入图片描述

3, 如果忘记密码, 按下面方法可以免出验证进行登录

[root@jenkins_server ~]# cp  /var/lib/jenkins/config.xml /备份目录/config.xml.bak
先备份一下

[root@jenkins_server ~]# vim /var/lib/jenkins/config.xml
打开此文件,然后把下面的一段注释(使用<!--  -->来注释)或删除

  8   <useSecurity>true</useSecurity>
  9   <authorizationStrategy class="hudson.security.FullControlOnceLoggedInAuthorizationStrategy">
 10     <denyAnonymousReadAccess>true</denyAnonymousReadAccess>
 11   </authorizationStrategy>
 12   <securityRealm class="hudson.security.HudsonPrivateSecurityRealm">
 13     <disableSignup>true</disableSignup>
 14     <enableCaptcha>false</enableCaptcha>
 15   </securityRealm>

[root@jenkins_server ~]# systemctl stop jenkins
[root@jenkins_server ~]# systemctl start jenkins
重启服务后,web访问就不需要密码验证了

插件安装(拓展)

1, 因为下载插件的官方在国外,网络可能会不稳定。如果在安装插件那一步出现offline或者找不到XXX插件的报错,可以换个网络试试。或者休息一下,换个时间再试。还不行可以试试下面的方法

[root@jenkins_server ~]# vim /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>
</sites>

把上面的https改为http的访问
保存后重启jenkins服务再尝试

2, 如果实在是无法下载插件,可以将别人下载好的插件打包给你,解压到/var/lib/jenkins/plugins/目录。需要重启jenkins服务,才能在web界面读取到解压的插件。

3, 可以在下面地址下载插件(插件为.hpi结尾的文件), 然后上传到jenkins.(这种方法适合单个插件安装)

插件地址:http://updates.jenkins-ci.org/download/plugins
在这里插入图片描述

git+github+jenkins

架构图

在这里插入图片描述

实验架构图
在这里插入图片描述

开发者电脑准备

第1步: 在开发者电脑上安装git工具

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

第2步: 在开发者电脑上创建空密码密钥对
在这里插入图片描述

[root@vm1 ~]# ssh-keygen -t rsa -f /root/.ssh/id_rsa -C "dev1@itcast.cn" -N ""

第3步: 在开发者电脑上查看并复制公钥

[root@vm1 ~]# cat /root/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+8f9vVJ8kskBojsxqaA95DQzLemCuA3o9nWE1sCjHHy/xxT4Ev57WbVCCPnCy3/pR49o5i7RE+5/dA4Ct+QXpj02pE2mPiehMIGFmjolhYFqIq7lnTSQ+zVtetIxnn2zmOx0qz+Zdr/wSCh/Czl7+Y2RClSq2sgD80/eF/uBpdlku2ejXAnIKFn3NekbqM4gYao/XTDLMW7D7pyQ0CFaI0xwEdXroy7ozAyFo76kvxs4IztAslcUeEj/CGha3WsLATRTeDNK5YGlI8jcw0WEcZocEhbS2RhkikQjACGgrae3WpJY/szH9BQeH8rIF2vR5s0DlPy9PJtBAxuUe8hJ/ dev1@itcast.cn

第4步: 将开发者公钥添加到github

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

github上新建项目仓库

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

开发者提交文件测试

第1步: 在github上获取ssh免密地址
在这里插入图片描述

第2步: 开发者电脑上设置开发者身份

[root@vm1 ~]# git config --global user.name "dev"
[root@vm1 ~]# git config --global user.email "dev@itcast.cn"
[root@vm1 ~]# git config --global color.ui true

第3步: clone项目到开发者本地电脑

[root@vm1~]# git clone git@github.com:linux-daniel/jenkins.git
Cloning into 'jenkins'...
The authenticity of host 'github.com (52.74.223.119)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
RSA key fingerprint is MD5:16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,52.74.223.119' (RSA) to the list of known hosts.
warning: You appear to have cloned an empty repository.

第4步: 提交测试代码文件

[root@vm1 ~]# cd jenkins/
[root@vm1 jenkins]# echo "test" >> README.md

[root@vm1 jenkins]# git add README.md
[root@vm1 jenkins]# git commit -m "add README.md"

[root@vm1 jenkins]# git push -u origin master

第5步: github上验证

在这里插入图片描述

nginx服务器准备

在nginx服务器上安装nginx,并启动服务

[root@nginx ~]# yum install epel-release
[root@nginx ~]# yum install nginx -y
[root@nginx ~]# systemctl start nginx
[root@nginx ~]# systemctl enable nginx

jenkins安装插件

jenkins图形确认安装git pluginpublish over ssh插件

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

配置jenkins通过publish over ssh免密连接nginx

第1步: 在jenkins服务器上生成空密码密钥对

[root@jenkins_server ~]# ssh-keygen -t rsa -f /root/.ssh/id_rsa -C "jenkins-server@itcast.cn" -N ""

第2步: 查看并复制私钥

[root@jenkins_server ~]# cat /root/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAvWekHSkS23a/8kN6SkDTjFdcdw5zuupaVY9KJd2Ejnfg7/ZU
6fqOO1b8bAzYMkf8aKTcStKEwBWV6TYA/ljGG/6oAz1UGwBke/Sw6wASp7wN4MUQ
HQDeHKv+odPHuSloK47e3LrjzCssXYPrvNmzsLKXIzbmiGJNAZYznYMBtnDNxpiy
1L+4zQeSTOfT0MCbF/KTgbyffRCNHC/m8Ow89NF1XW37he3XV8wimM6NrGtndw1N
YVZMyx85xEsK9m2Wxee+P7KgIdL5nmbGJOBbTUi4dlt9j4T+mOxr4AF9oaZKS0o2
oJlJyyl9TKtHQM6d2Qw8BGXOGMDVSB8WT1Q5UwIDAQABAoIBAHsCS4iQu2mDBwhN
IKgG0B2OQ0QjQ7A6Ma7tn6dV5ZgtbQ4Lenx3OFZ7mPaHpQWK0PgZUeTaMlMZ8cGD
TEPj3c4ipnVsKCpdJ+WFNj15T6RWMuEuutdLT/VpEreA9m5f4QKhCEZsrjNUOr0F
R13gOZ5hblz1c+VRilekeCMtCTi1jKkDdVNFRcdQe8m8kttFVC2hSPB7tJxEoxmp
kAPkPBwU0E/6pA591JYCUk7lNQ9eBDgoBbb9cglEa4tn3Hh7AoyXcJTvYoC1vH1M
zN/1MLHyME76a/intrQM9frYwgM1gUdZU5i5kt4/SFQfd/qM8Axvy7s0qcFf5jxo
Ey4Ob4kCgYEA9HkCeBMexLZnVbZrDNiaapANdPafY9PILduZ9nVQmWh4rRcu47r0
D1V6yDtBS8+p/sPJu/4KYEn/8yDWHjxd3O194XaAKl9xgqUPP23txohp99pHy2mL
21eqthC0QKk2bH23jAQxjd0MAz5mK4uO1r/BFhSnJpK4i5/jVIHqm3cCgYEAxlXq
lqSruCYzwzMX/7Gv1lqexmUGmXiqQ4LWtOlQIaL+BoPOajp2mJjJMsIF1qkQwZnp
L+WdP02j7esBD1hI9G+lISCyqjTG+OCdNFiQ3SFJDZoLrcBN1uByjgANPleMiP9y
zq+xa+zBQ2YEtAEA8gp37QzfA2P6zihCNQqmUAUCgYEAgcrFHs635SQaFI12pClT
QgQcwN42nR9RBdezFAAQvIGUoADQ6iLVdFajiy66ae9kh1eXAPHMvHZNJt1mEENo
aeTEkjEBtn1ZnEzZnYlVVbQS3n3K5BmzIM6YWXTg3ft4Y30TN4j6biDPQeGdCL1d
JnJDpt9sJrR6udY3MSSQU90CgYEAnqnkvRaG+Q42opWhQUAYdtaP5g6ztNq++rsU
oC11mTMXHIcc/gY/EdxIOH7WxN8DNJ232kVKAnZOCerSMkBiPImEBHhv9ZG7CyZF
HLctTHlwQ51Ucm9A1gFAIzEPZywKlR4l7grHWJtSEGTwpj+XTgnp3o1JayD0Zy/1
pxEZ8zECgYEAnS/PHs+164GYPkWlYxGw04UE4SlQGa0QqT1WfctFPctU5PVqpwHi
imEFS+V89p1N+bQpgEI+WqlRGgODcjIE0ho8DqhsKaqu0AeVPN91Dgi20giJE8xo
TnYioS3qpxXtPiwrVR8PUZ/WZ/YtM0jwvYXowsSHeqVfCUBNGHqvwEA=
-----END RSA PRIVATE KEY-----

第3步: 在jenkins中添加ssh私钥
在这里插入图片描述

在这里插入图片描述

第4步: 在jenkins服务器上配置对nginx服务器的免密登录

[root@jenkins_server ~]# ssh-copy-id -i 10.1.1.14
10.1.1.14为nginx服务器的IP

第5步: 然后填写连接nginx信息,测试连接成功后保存
在这里插入图片描述

添加Jenkins服务器公钥到github

添加过程见上面笔记(这里省略,直接看下面结果)

在这里插入图片描述

为jenkins服务器添加凭据

凭据是jenkins给自己的构建项目授权用的。

我们本项目案例里jenkins是通过ssh免密去找github的项目仓库clone或pull项目代码。

在前面的配置里已经把jenkins服务器的公钥添加到了github仓库上, 在jenkins服务器上root用户使用git clone 项目地址都可以成功。

但是jenkins服务本身并不允许使用自己的私钥去访问github的公钥, 给个凭据, 让它能做就解决问题了

总结: 凭据是一种和第三方程序(如github,gitlab等)通讯的权限授权。本案例的凭据就是允许使用ssh免密

​ 你可以把这个凭据在jenkins里授予给任何需要ssh免密通讯的构建项目。

第1步: 在jenkins界面添加凭据

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

第2步: 添加凭据信息
在这里插入图片描述

在这里插入图片描述

jenkins任务创建

第1步: 创建新任务
在这里插入图片描述

第2步: 自定义任务名称与风格

在这里插入图片描述

第3步: 自定义任务描述

在这里插入图片描述

第4步: 定义源码管理

在这里插入图片描述

第5步:定义构建方法
在这里插入图片描述

第6步: 定义构建的源码,目标主机和目标目录

在这里插入图片描述

第7步: 设置完毕,保存,并验证

在这里插入图片描述

在这里插入图片描述

手动构建

第1步: 立即构建

在这里插入图片描述

第2步: 在workspace工作区间查看

在这里插入图片描述
在这里插入图片描述

第3步: 查看控制台输出信息

在这里插入图片描述

第4步: nginx服务器上验证文件是否被传到nginx家目录

[root@nginx ~]# ls /usr/share/nginx/html/
404.html  index.html      poweredby.png
50x.html  nginx-logo.png  README.md
可以看到README.md被传过来了

练习: 在开发者电脑上再次上传文件,并构建测试

小结

在这里插入图片描述

自动发布系统

在这里插入图片描述

Gitlab上创建自动构建仓库

第1步: gitlab上创建新仓库
在这里插入图片描述

第2步: 自定义项目名称等
在这里插入图片描述

第3步: 确认创建成功
在这里插入图片描述

在开发者电脑clone创建好的项目,进行开发

# git clone git@10.1.1.12:root/auto_build_web.git
# cd auto_build_web

开发者要产生ssh空密码密钥对,把公钥添加到gitlab(过程省略)

jenkins安装对应插件

jenkins安装gitlab与gitlab hook插件

在这里插入图片描述

在这里插入图片描述

添加Jenkins服务器公钥到gitlab

第1步: jenkins产生root用户的ssh空密码密钥对(步骤省略)

添加公钥到gitlab

在这里插入图片描述

第2步: 复制gitlab上自动发布项目地址
在这里插入图片描述

第3步: 在jenkins服务器上克隆仓库,确认连接OK

[root@jenkins-server ~]# git clone git@10.1.1.12:root/auto_build_web.git
Cloning into 'auto_build_web'...
The authenticity of host '10.1.1.12 (10.1.1.12)' can't be established.
ECDSA key fingerprint is SHA256:Sp1FZaHscluT1mTIKFUiFQPoqcsSL2urGiujjlUN4lE.
ECDSA key fingerprint is MD5:8b:95:f9:83:8c:ea:e8:43:e4:58:36:9b:8f:c5:ba:96.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.1.1.12' (ECDSA) to the list of known hosts.
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.

jenkins创建自动构建任务

在这里插入图片描述

在这里插入图片描述

凭据使用的是上面实验的凭据(如果ssh密钥对重新产生了,就需要重配置凭据)
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

注意: 执行此脚本不再是使用publish over ssh插件,而是**使用jenkins服务器上的jenkins用户来执行的**

#!/bin/bash

#源目录为jenkins存放任务文件的目录 
SOURCE_DIR=/var/lib/jenkins/workspace/$JOB_NAME/
#目标目录为nginx服务器的家目录
DEST_DIR=/usr/share/nginx/html
#使用rsync同步源到nginx服务器家目录(需要免密登录),IP为nginx服务器IP
/usr/bin/rsync -av --delete $SOURCE_DIR root@10.1.1.14:$DEST_DIR

问题: 既然是使用jenkins服务器上的jenkins用户来执行,为什么rsync不传给10.1.1.14的jenkins用户,而是传给它的root用户?

答: 因为10.1.1.14上没有jenkins用户,就算有jenkins用户,/usr/share/nginx/html也没有写权限

配置jenkins服务器上的jenkins用户

[root@jenkins-server ~]# grep jenkins /etc/passwd
jenkins:x:988:982:Jenkins Automation Server:/var/lib/jenkins:/bin/false

[root@jenkins-server ~]# usermod -s /bin/bash jenkins

[root@jenkins-server ~]# grep jenkins /etc/passwd
jenkins:x:988:982:Jenkins Automation Server:/var/lib/jenkins:/bin/bash
[root@jenkins-server ~]# su - jenkins
-bash-4.2$ ssh-keygen -t rsa -C "jenkins user" -N ""

-bash-4.2$ ssh-copy-id -i root@10.1.1.14

jenkins全局安全配置

在这里插入图片描述

在这里插入图片描述

配置gitlab允许本地网络使用webhook

gitlab默认在本地网络不能使用webhook,所以需要我们配置允许(注意要使用管理员配置,普通用户看不到下图的扳手图标)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

为gitlab自动构建项目添加webhook

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

代码自动发布测试

开发者电脑上使用git提交测试文件(确认前面clone过项目仓库)

[root@vm1 ~]# cd auto_build_web/
[root@vm1 auto_build_web]# echo "auto_build_web" > index.html
[root@vm1 auto_build_web]# git add index.html
[root@vm1 auto_build_web]# git commit -m "add index.html"
[root@vm1 auto_build_web]# git push -u origin master

在nginx服务器上验证

[root@nginx ~]# cat /usr/share/nginx/html/index.html 
auto_build_web

小结

在这里插入图片描述

pycharm与自动发布系统结合(拓展)

开发者开发代码一般会使用IDE集成开发工具(比如pycharm这种),那么使用pycharm开发的代码能否直接利用自动发布系统发布到业务服务器上呢? 答案是肯定的。

这次使用windows模拟开发者电脑
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

nginx服务器上测试验证

[root@nginx ~]# cat /usr/share/nginx/html/index.html 
auto_build_web
pycharm测试
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值