第1天-分布式版本控制系统
一、Git、Github、Gitlab 的区别
Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
Github是在线的基于Git的代码托管服务。 GitHub是2008年由Ruby on Rails编写而成。GitHub同时提供付费账户和免费账户。这两种账户都可以创建公开的代码仓库,只有付费账户可以创建私有的代码仓库。 Gitlab解决了这个问题, 可以在上面创建免费的私人repo。
git 是一套软件 可以做本地私有仓库
github 本身是一个代码托管网站 公有和私有仓库(收费) 不能做本地私有仓库
gitlab 本身也是一个代码托管的网站 功能上和github没有区别 公有和私有仓库(免费) 可以部署本地私有仓库
二、Git 与 SVN 区别
GIT不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等。
如果你是一个具有使用SVN背景的人,你需要做一定的思想转换,来适应GIT提供的一些概念和特征。
Git 与 SVN 区别
- Git是分布式的,svn不是:这是GIT和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别。
- GIT把内容按元数据方式存储,而SVN是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn,.cvs等的文件夹里。
- GIT分支和SVN的分支不同:分支在SVN中一点不特别,就是版本库中的另外的一个目录。
- GIT没有一个全局的版本号,而SVN有:目前为止这是跟SVN相比GIT缺少的最大的一个特征。
- GIT的内容完整性要优于SVN:GIT的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
git 是分布式的版本控制器 没有客户端和服务器端的概念
svn 它是C/S结构的版本控制器 有客户端和服务器端 服务器如果宕机而且代码没有备份的情况下 完整代码就会丢失
三、部署Git 服务
创建git仓库
git-server上的操作:
1 | [root@qfedu.com ~]# yum install git git-core gitweb -y |
git仓库测试
git-client上的操作:
1 | [root@qfedu.com ~]# ssh-keygen |
四、Git工作流程
一般工作流程如下:
克隆 Git 资源作为工作目录。
在克隆的资源上添加或修改文件。
如果其他人修改了,你可以更新资源。
在提交前查看修改。
提交修改。
在修改完成后,如果发现错误,可以撤回提交并再次修改并提交。
Git 的工作流程示意图:
五、Git基本概念
- 工作区:就是你在电脑里能看到的目录。
- 暂存区:英文叫stage, 或index。一般存放在”git目录”下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
- 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
工作区、版本库中的暂存区和版本库之间的关系的示意图:
- 图中左侧为工作区,右侧为版本库。在版本库中标记为 “index” 的区域是暂存区(stage, index),标记为 “master” 的是 master 分支所代表的目录树。
- 图中我们可以看出此时 “HEAD” 实际是指向 master 分支的一个”游标”。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
- 图中的 objects 标识的区域为 Git 的对象库,实际位于 “.git/objects” 目录下,里面包含了创建的各种对象及内容。
- 当对工作区修改(或新增)的文件执行 “git add” 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
- 当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
- 当执行 “git reset HEAD” 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
- 当执行 “git rm –cached
“ 命令时,会直接从暂存区删除文件,工作区则不做出改变。
- 当执行 “git checkout .” 或者 “git checkout –
“ 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。
- 当执行 “git checkout HEAD .” 或者 “git checkout HEAD
“ 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
六、Git 客户端安装使用
1、 Git 安装配置
1 | [root@qfedu.com ~]# yum -y install curl-devel expat-devel gettext-devel openssl-devel zlib-devel |
2、Git 配置
Git 提供了一个叫做 git config 的工具,专门用来配置或读取相应的工作环境变量。
这些环境变量,决定了 Git 在各个环节的具体工作方式和行为。这些变量可以存放在以下三个不同的地方:
/etc/gitconfig
文件:系统中对所有用户都普遍适用的配置。若使用git config
时用--system
选项,读写的就是这个文件。~/.gitconfig
文件:用户目录下的配置文件只适用于该用户。若使用git config
时用--global
选项,读写的就是这个文件。- 当前项目的 Git 目录中的配置文件(也就是工作目录中的
.git/config
文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以.git/config
里的配置会覆盖/etc/gitconfig
中的同名变量。
1、Git 用户信息
配置个人的用户名称和电子邮件地址:
1 | [root@qfedu.com ~]# git config --global user.name "qfedu" |
如果用了 –global 选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。
如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 –global 选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。
2、文本编辑器
设置Git默认使用的文本编辑器, 一般可能会是 Vi 或者 Vim。如果你有其他偏好,比如 Emacs 的话,可以重新设置
1 | [root@qfedu.com ~]# git config --global core.editor emacs |
3、差异分析工具
还有一个比较常用的是,在解决合并冲突时使用哪种差异分析工具。比如要改用 vimdiff 的话:
1 | [root@qfedu.com ~]# git config --global merge.tool vimdiff |
Git 可以理解 kdiff3,tkdiff,meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,和 opendiff 等合并工具的输出信息。
当然,你也可以指定使用自己开发的工具
4、查看配置信息
要检查已有的配置信息,可以使用 git config –list 命令:
1 | [root@qfedu.com ~]# git config --list |
有时候会看到重复的变量名,那就说明它们来自不同的配置文件(比如 /etc/gitconfig 和 ~/.gitconfig),不过最终 Git 实际采用的是最后一个。
这些配置我们也可以在 ~/.gitconfig 或 /etc/gitconfig 看到,如下所示:
1 | [root@qfedu.com ~]# vim ~/.gitconfig |
显示内容如下所示:
1 | [http] |
也可以直接查阅某个环境变量的设定,只要把特定的名字跟在后面即可,像这样:
1 | [root@qfedu.com ~]# git config user.name |
3、Git 使用
1、ssh 链接
客户机上产生公钥上传到gitlab的SSH-Keys里,git clone下载和git push上传都没问题,这种方式很安全
2、http 链接(两种方式实现)
1、修改代码里的 .git/config 文件添加登录用户名密码
1 | [root@qfedu.com ~]# cd .git |
2、 执行命令设置登录用户和密码
1 | cd到根目录,执行 |
3、设置身份验证
注意:设定本机用户名,绑定邮箱,让远程服务器知道机器的身份
1 | [root@qfedu.com ~]# git config --global user.name "user_name" |
4、本地项目与远程服务器项目之间的交互
1、如果你没有最新的代码,希望从头开始
1 | [root@qfedu.com ~]# git clone git@XXX.git # 这里是项目的地址(可从项目主页复制),将远程服务器的内容完全复制过来 |
2、如果你已经有一个新版代码,希望直接把本地的代码替换到远程服务器
1 | [root@qfedu.com ~]# cd existing_folder #进入代码存在的文件夹,或者直接在该文件夹打开 |
git 中 clone过来的时候,git 不会对比本地和服务器的文件,也就不会有冲突,
建议确定完全覆盖本地的时候用 clone,不确定会不会有冲突的时候用 git pull,将远程服务器的代码download下来
git pull=git fetch+git merge
实验如下:
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本地代码内容如下:
[root@node1 shell]# cat mem.sh
free -m | awk 'NR==2{print $4}'
echo hello
echo ni hao
远程Git服务器代码内容如下:
[root@node1 shell]# cat mem.sh
free -m | awk 'NR==2{print $4}'
echo hello
echo ni hao
echo ha ha
本地机器做fetch操作:
[root@node1 shell]# git fetch origin master:test
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From master:/git-test/shell
* [new branch] master -> test
b522245..10f9569 master -> origin/master
fetch是把远程代码作为本地的一个其他分支下载到本地,并不更新本地分支,这里的命令是把远程的”master“分支下载到本地作为一个新的分支”test“存在
查看本地文件并没有发生变化
[root@node1 shell]# ls
mem.sh
[root@node1 shell]# cat mem.sh
free -m | awk 'NR==2{print $4}'
echo hello
echo ni hao
用diff查看本地master分支和fetch下来的test分支有什么区别:
[root@node1 shell]# git diff master test
diff --git a/mem.sh b/mem.sh
index 7ce0803..c0c8cef 100644
--- a/mem.sh
+++ b/mem.sh
@@ -1,3 +1,4 @@
free -m | awk 'NR==2{print $4}'
echo hello
echo ni hao
+echo ha ha
如果发现fetch下来的代码没什么问题,可以选择和本地分支进行合并
[root@node1 shell]# git merge
Updating eb8645c..10f9569
Fast-forward
mem.sh | 1 +
1 file changed, 1 insertion(+)
[root@node1 shell]# cat mem.sh
free -m | awk 'NR==2{print $4}'
echo hello
echo ni hao
echo ha ha
5、常用的git 命令
1 | [root@qfedu.com ~]# git init # 初始化 |
6、版本穿梭
1、版本回退
1 | 用 git log 命令查看: |
1 | [root@qfedu.com ~]# git reflog # 查看命令历史,以便确定要回到哪个版本 |
2、分支管理
1、创建分支
1 | [root@qfedu.com ~]# git checkout -b dev #创建dev分支,然后切换到dev分支 |
2、分支切换
1 | [root@qfedu.com ~]# git checkout master #切换回master分支 |
3、合并分支
1 | [root@qfedu.com ~]# git merge dev #把dev分支的工作成果合并到master分支上 |
1 | 注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。 |
1 | [root@qfedu.com ~]# git branch -d dev #删除dev分支了: |
3、解决冲突
1 | [root@qfedu.com ~]# git checkout -b feature1 # 创建新的feature1分支 |
1 | readme.txt文件存在冲突,必须手动解决冲突后再提交。 |
七、Github 远程仓库
1、github.com 注册账户
2、github 上创建仓库
3、本地服务器生成 ssh 公钥
1 | [root@qfedu.com ~]# ssh-keygen -t rsa -C 'meteor@163.com' # 邮箱要与github上注册的相同 |
4、 github 添加 ssh 公钥
复制以上的公钥,在 github 中添加ssh key
5、测试连接
1 | [root@qfedu.com ~]# yum install git |
6、连接远程仓库(创建一个测试存储库)
1 | 在 github 网站新建一个仓库,命名为linux |
八、Gitlab Server 部署
1、环境配置
关闭防火墙、SELinux
开启邮件服务
1 | [root@qfedu.com ~]# systemctl start postfix |
2、部署 Gitlab
1、安装 gitlab 依赖包
1 | centos7: |
2、添加官方源
1 | [root@qfedu.com ~]# curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash |
因为官方源太慢,可以使用国内清华yum源,配置如下
1 | [root@qfedu.com ~]# vim /etc/yum.repos.d/gitlab-ce.repo |
3、安装 Gitlab
1 | [root@qfedu.com ~]# yum -y install gitlab-ce # 自动安装最新版 |
4、配置 Gitlab
1、查看Gitlab版本
1 | [root@qfedu.com ~]# head -1 /opt/gitlab/version-manifest.txt |
2、Gitlab 配置登录链接
1 | 设置登录链接 |
3、初始化 Gitlab
配置语言环境
gitlab要求语言环境为英文环境,必须切换,切换方法如下:
1 | 注意:可以先尝试以下方案 |
第一次使用配置时间较长
1 | [root@qfedu.com ~]# gitlab-ctl reconfigure |
4、启动 Gitlab 服务
1 | [root@qfedu.com ~]# gitlab-ctl start |
5、Gitlab 设置 HTTPS 方式 (缺少配置)
- 如果想要以上的 https 方式正常生效使用,则需要把 letsencrypt 自动生成证书的配置打开,这样在执行重新让配置生效命令 (gitlab-ctl reconfigure) 的时候会自动给域名生成免费的证书并自动在 gitlab 自带的 nginx 中加上相关的跳转配置,都是全自动的,非常方便。
1 | [root@qfedu.com ~]# vim /etc/gitlab/gitlab.rb |
6、Gitlab 添加smtp邮件功能
1 | [git@qfedu.com ~]# vim /etc/gitlab/gitlab.rb |
7、Gitlab 发送邮件测试
1 | [git@qfedu.com ~]# gitlab-rails console |
去qq邮箱web界面查看是否收到邮件
3、Gitlab 的使用
在浏览器中输入 http://192.168.1.178/ ,然后 change password: ,并使用root用户登录 即可 (后续动作根据提示操作)
1、Gitlab 命令行修改密码
1 | [root@qfedu.com ~]# gitlab-rails console production |
2、Gitlab服务管理
1 | [root@qfedu.com ~]# gitlab-ctl start # 启动所有 gitlab 组件; |
3、登陆 Gitlab
如果需要手工修改nginx的port ,可以在gitlab.rb中设置 nginx[‘listen_port’] = 8000 ,然后再次 gitlab-ctl reconfigure即可
登录 gitlab 如下所示(首次登陆设置 root 密码):
4、创建项目组 group
组名为plat-sp ,
5、去掉用户的自动注册功能(安全)
admin are -> settings -> Sign-up Restrictions 去掉钩钩,然后拉到最下面保存,重新登录
九、Gitlab 开发代码提交处理流程
1、公司代码提交合并流程
PM(项目主管/项目经理)在gitlab创建任务,分配给开发人员
开发人员领取任务后,在本地使用git clone拉取代码库
开发人员创建开发分支(git checkout -b dev),并进行开发
开发人员完成之后,提交到本地仓库(git commit )
开发人员在gitlab界面上申请分支合并请求(Merge request)
PM在gitlab上查看提交和代码修改情况,确认无误后,确认将开发人员的分支合并到主分支(master)
开发人员在gitlab上Mark done确认开发完成,并关闭issue。这一步在提交合并请求时可以通过描述中填写”close #1”等字样,可以直接关闭issue
2、创建项目管理用户 Tompson
同样的方法,再创建 Eric 、Hellen 用户。用户添加完毕后,gitlab 会给用户发一封修改密码的邮件,各用户需要登录自己的邮箱,并点击相关的链接,设置新密码。
3、将 Tompson 用户添加到组中,指定T为本组的 owner
4、同样的方法将用户Eric、Hellen 添加到组中,并指定为Developer
5、使用 Tompson 用户的身份与密码登录到 gitlab 界面中,并创建项目 Project
6、指定项目的存储路径和项目名称
把客户端的公钥添加到这里之后才会出现下图的内容
7、为项目创建 Dev分支
注意:因为版本的原因,需要先在项目里面添加一个文件,才能显示下图中创建分支的操作
8、在 client 上添加 Tompson 的用户
1 | [git@qfedu.com ~]# useradd Tompson |
9、将 Tompson 的公钥复制到 gitlab 中
使用 Tompson 用户的身份与密码登录到 gitlab界面中,然后在 ssh-key 中添加相关的key
10、为 Tompson 用户配置 git
1 | [Tompson@qfedu.com ~]$ git config --global user.email "222@qq.com" |
11、创建新文件,添加内容,并提交到 master 分支
1 | [Tompson@qfedu.com chathall]$ vim test.sh |
12、使用 Eric 用户登录,并 clone 项目
1 | [git@qfedu.com ~]# su - Eric |
13、同样需要使用Eric用户登录gitlab web 界面,并添加相应的ssh-key。然后设置git ,并clone项目
1 | [Eric@qfedu.com ~]$ git config --global user.email "Eric@domain.cn" |
14、切换到dev分支,修改文件内容,并将新 code 提交到 dev分支 (Developer角色默认并没有提交master的权限)
1 | [Eric@qfedu.com chathall]$ git checkout dev |
15、使用Eric 用户登录gitlab web,在界面中 创建一个合并请求
提交合并请求:
16、使用Tompson用户登录 gitlab web ,找到“合并请求” ,然后将dev分支合并到master分支
十、Gitlab 备份与恢复
1、查看系统版本和软件版本
1 | [root@qfedu.com gitlab]# cat /etc/redhat-release |
2、数据备份
1、查看备份相关的配置项
1 | [root@qfedu.com ~]# vim /etc/gitlab/gitlab.rb |
该项定义了默认备份出文件的路径,可以通过修改该配置,并执行 gitlab-ctl reconfigure 或者 gitlab-ctl restart 重启服务生效。
2、执行备份命令进行备份
1 | [root@qfedu.com ~]# /opt/gitlab/bin/gitlab-rake gitlab:backup:create |
3、添加到 crontab 中定时执行
1 | [root@qfedu.com ~]# crontab -e |
可以到/data/gitlab/backups找到备份包,解压查看,会发现备份的还是比较全面的,数据库、repositories、build、upload等分类还是比较清晰的。
4、设置备份保留时长
防止每天执行备份,有目录被爆满的风险,打开/etc/gitlab/gitlab.rb配置文件,找到如下配置:
1 | [root@qfedu.com ~]# vim /etc/gitlab/gitlab.rb |
设置备份保留7天(7360024=604800),秒为单位,如果想增大或减小,可以直接在该处配置,并通过gitlab-ctl restart 重启服务生效。
备份完成,会在备份目录中生成一个当天日期的tar包。
3、数据恢复
1、安装部署 gitlab server
具体步骤参见上面:gitlab server 搭建过程
2、恢复 gitlab
1、查看备份相关的配置项
1 | [root@qfedu.com ~]# vim /etc/gitlab/gitlab.rb |
修改该配置,定义了默认备份出文件的路径,并执行 gitlab-ctl reconfigure 或者 gitlab-ctl restart 重启服务生效。
2、恢复前需要先停掉数据连接服务
1 | [root@qfedu.com ~]# gitlab-ctl stop unicorn |
- 如果是台新搭建的主机,不需要操作,理论上不停这两个服务也可以。停这两个服务是为了保证数据一致性。
3、同步备份文件到新服务器
将老服务器/data/gitlab/backups目录下的备份文件拷贝到新服务器上的/data/gitlab/backups
1 | [root@qfedu.com gitlab]# rsync -avz 1530773117_2019_03_05_gitlab_backup.tar 192.168.95.135:/data/gitlab/backups/ |
- 注意权限:600权限是无权恢复的。 实验环境可改成了777,生产环境建议修改属主属组
1 | [root@qfedu.com backups]# pwd |
4、执行命令进行恢复
后面再输入两次 yes 就完成恢复了。
1 | [root@qfedu.com ~]# gitlab-rake gitlab:backup:restore BACKUP=1530773117_2018_07_05_gitlab_backup.tar |
5、恢复完成启动服务
恢复完成后,启动刚刚的两个服务,或者重启所有服务,再打开浏览器进行访问,发现数据和之前的一致:
1 | [root@qfedu.com ~]# gitlab-ctl start unicorn |
注意:通过备份文件恢复gitlab必须保证两台主机的gitlab版本一致,否则会提示版本不匹配
十一、利用Gitlab管理k8s集群
1、权限设置
2、获取k8s集群API地址
1 | [root@master ~]# kubectl cluster-info | grep 'Kubernetes master' | awk '/http/ {print $NF}' |
3、获取k8s集群默认CA证书
1 | [root@master ~]# kubectl get secrets |
default-token-cvfqx 为上面获取到的secrets的名称,用以下命令查看证书
1 | [root@master ~]# kubectl get secret default-token-cvfqx -o jsonpath="{['data']['ca\.crt']}" | base64 --decode |
4、设置rbac
1 | [root@master ~]# vim gitlab-admin-service-account.yaml |
5、获取gitlab-admin的token
1 | [root@master ~]# kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep gitlab-admin | awk '{print $1}') |
6、添加k8s集群