一、Devops 简介:

Devops 是 Development 和 Operations的组合 ,也就是运维和开发的简写,主要针对企业中的研发人员、运维人员、和测试人员在应用。

Devops 强调整个组织的的合作和基础设施变的更加自动化,从而实现持续集成、持续部署、持续交付。

CI / CD 的区别 :

CI 代表持续集成:多名开发者在开发不同代码的过程中,频繁的将代码合并到一个地方。(针对开发)

CD 代表持续部署: 基于某种工具或者平台实现代码的自动化构建、测试和部署到上线环境实现交付保质量的产品,代表这开发端对的更新迭代速率(针对运维)

持续交付: 在持续部署的基础之上,将产品交付到线上环境,因此持续交付是产品价值的一种交付,是产品价值的一种盈利的表现

1.1:常见的部署方式

  1. 开发自己上传 –> 最原始方案 (不标准,用户不统一)
  2. 开发给运维手动上传 –>运维自己手动部署
  3. 运维使用脚本复制 –> 半自动化
  4. 结合web界面一键部署 –> 自动化
  5. 结合 crontab 实现代码的全自动部署 –全自动化

成功或者失败以后需要有邮件发送,部署成功后的版本是多少

二、Gitlab简介安装

Gitlab官网安装连接 ,Gitlab 清华源安装连接

环境要求,内存建议8G以上,磁盘要求较高可以使用SSD,CPU建议8C

这里使用Ubuntu 1804安装

1
2
3
4
- 清华源下载地址  下载安装包
$ wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/ubuntu/pool/bionic/main/g/gitlab-ce/gitlab-ce_14.0.7-ce.0_amd64.deb
- 安装Gitlab,安装成功以后会有Gitla的Logo,dpkg -c 查看目录
$ dpkg -i gitlab-ce_14.0.7-ce.0_amd64.deb

修改配置文件

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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
$ cat /etc/gitlab/gitlab.rb |egrep -v "^#|^$"
external_url 'http://10.0.0.11'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.qq.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "1419946323@qq.com"
gitlab_rails['smtp_password'] = "rvgzzxecmvvkgfbg"
gitlab_rails['smtp_domain'] = "qq.com"
gitlab_rails['smtp_authentication'] = :login
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = "1419946323@qq.com"
user["git_user_email"] = "1419946323@qq.com"



##生产环境配置
$egrep -v "^$|^#" /home/ubuntu/gitlab/config/gitlab.rb
external_url "https://gitlab.corp.cootek.com"
gitlab_rails['time_zone'] = 'Asia/Shanghai'
gitlab_rails['gitlab_email_display_name'] = 'Gitlab'
gitlab_rails['gitlab_default_can_create_group'] = false
gitlab_rails['gitlab_username_changing_enabled'] = false
gitlab_rails['ldap_enabled'] = true
gitlab_rails['ldap_servers'] = YAML.load <<-'EOS' # remember to close this block with 'EOS' below
main: # 'main' is the GitLab 'provider ID' of this LDAP server
label: 'LDAP User Login'
host: '122.224.103.147'
port: 636
uid: 'sAMAccountName'
method: 'ssl' # "tls" or "ssl" or "plain"
verify_certificates: false
bind_dn: 'CN=Pydio,OU=ServiceAccount,DC=corp,DC=cootek,DC=com'
password: 'CooTek1023'
active_directory: true
allow_username_or_email_login: false
block_auto_created_users: false
base: 'DC=corp,DC=cootek,DC=com'
user_filter: '(memberOf=CN=gitlab,CN=Users,DC=corp,DC=cootek,DC=com)'
attributes:
username: ['sAMAccountName']
email: ['mail']
name: 'displayName'
first_name: 'givenName'
last_name: 'sn'
EOS
gitlab_rails['omniauth_enabled'] = false
gitlab_rails['omniauth_allow_single_sign_on'] = ['saml']
gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'saml'
gitlab_rails['omniauth_block_auto_created_users'] = false
gitlab_rails['omniauth_auto_link_ldap_user'] = false
gitlab_rails['omniauth_auto_link_saml_user'] = true
gitlab_rails['omniauth_providers'] = [
{
"name" => "saml",
"label" => 'Login Gitlab SSO',
"args" => {
assertion_consumer_service_url: 'https://gitlab.corp.cootek.com/users/auth/saml/callback',
#idp_cert_fingerprint: 'c9:42:73:36:43:0f:9a:57:92:78:83:d1:50:8a:90:c5:83:df:fe:2f',
idp_cert_fingerprint: '9a:96:97:2c:10:8e:26:a5:2e:b3:8b:4e:88:8f:16:20:e4:e0:2e:77',
idp_sso_target_url: 'https://idcsso.corp.cootek.com/adfs/ls' ,
issuer: 'https://gitlab.corp.cootek.com',
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient',
attribute_statements: {
username: ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn'],
email: ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress'],
name: ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name'],
first_name: ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname'],
last_name: ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname'],
}
}
}
]
gitlab_rails['rack_attack_git_basic_auth'] = {
'enabled' => false,
#'enabled' => true,
'ip_whitelist' => ["101.230.198.109","101.230.198.106","123.59.3.76"],
'maxretry' => 20,
'findtime' => 60,
'bantime' => 600
}
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.partner.outlook.cn"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "gitlab@cootek.cn"
gitlab_rails['smtp_password'] = "CooTek@1023"
gitlab_rails['smtp_domain'] = "partner.outlook.cn"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['gitlab_email_from'] = "gitlab@cootek.cn"
nginx['enable'] = true
nginx['client_max_body_size'] = '1024m'
nginx['redirect_http_to_https'] = true
nginx['redirect_http_to_https_port'] = 80
nginx['ssl_certificate'] = "/etc/gitlab/ssl/corp.cootek.com.pem"
nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/gitlab.corp.cootek.com.key"
nginx['ssl_session_timeout'] = "240m" # default according to http://nginx.org/en/docs/http/ngx_http_ssl_module.html
nginx['log_format'] = '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'
logging['logrotate_frequency'] = "daily" # rotate logs daily
logging['logrotate_size'] = nil # do not rotate by size by default
logging['logrotate_rotate'] = 300 # keep 30 rotated logs
logging['logrotate_compress'] = "compress" # see 'man logrotate'
logging['logrotate_method'] = "copytruncate" # see 'man logrotate'
logging['logrotate_postrotate'] = nil # no postrotate command by default
logging['logrotate_dateformat'] = "-%Y-%m-%d" # use date extensions for rotated files rather than numbers e.g. a value of "-%Y-%m-%d" would give rotated files like production.log-2016-03-09.gz
logrotate['enable'] = true

初始化服务

然后需要开始初始化服务 ,配置低的话可能需要三分钟左右

1
2
3
$ gitlab-ctl reconfigure
- 查看gitlab版本,或者web界面点击帮助即可查看
cat /opt/gitlab/embedded/service/gitlab-rails/VERSION

gitlab 主配置文件

1
2
3
4
5
/var/log/gitlab #日志文件 
/etc/gitlab #配置文件目录
/run/gitlab #运行pid目录
/opt/gitlab #安装目录
/var/opt/gitlab #数据目录 ,数据是比较重要的

web登录

这个时候直接输入ip 就可以访问了 ,账号是root

1
2
3
cat /etc/gitlab/initial_root_password
进去之后先修改密码,密码至少8位数字我设置12345678
现在qq会收到提示,登录失败,因为还没有给管理员权限
  • 设置中文

  • 安装完之后最主要的功能就是,先关闭注册功能,谁有这个账号就可以拷贝开发的代码,后果很严重

  • 创建项目,点击 admin

    1、 创建 Groups 组代表你这个项目,组里面可以创建很多project

    2、创建用户,然后创建项目选择对应的组即可,用户权限根据需求分配

    3、创建项目 在项目URL选择对应的组即可编辑

    4、在另外一台服务器上使用 git clone 测试,使用HTTP克隆然后输入账号密码

    5、上传测试

数据保存方式

SVN 与 CVS: 每次提交的文件都单独保存,即按照文件的提交时间区分不同的版本,保存至不同 的逻辑存储区域,后期恢复的时候直接基于之前版本恢复

Gitlab和SVN区别:

Gitlab 与 SVN 的数据保存方式不同,gitlab会对内部数据进行划分保存,如果数据发生变化他就只会上传发生变化的文件,这样增快了代码提交的速度 (Gitlab 会将之前没变化的代码不会提交,而且还节省了代码提交后的缓存空间,因为每次提交都是会有记录的)

每次提交上传服务器是如何知道的,进入当前项目路径下

1
2
3
4
5
6
7
8
9
10
11
12
13
$ cat .git/config  #指定上传路径
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = http://10.0.0.11/magedu/app1.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main
$ cat .git/logs/HEAD #记录每次上传提交版本的tag本号

常用Git 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
git config --global user.name “name“ #设置全局用户名 
git config --global user.email xxx@xx.com #设置全局邮箱
git config --global --list #列出用户全局设置
git add index.html .#添加指定文件,目录或当前目录下所有数据到暂存区
git commit -m “v1“ #提交文件到工作区
git status #查看工作区的状态
git push #提交代码到服务器
git pull #获取代码到本地
git log #查看操作日志,每次提交都行,可以用于后期代码回滚
vim .gitignore #定义忽略文件上传至 gitlab,需要web先创建这个文件
git reset --hard HEAD^ # 立即回滚到上一个版本,用于代码提交错误 ,回滚以后还需要 git push 重新提交远程仓库才会撤销
git reset --hard HEAD^^ #git 版本回滚, HEAD 为当前版本,加一个^为上一个,^^为上上一个版本

--------以kog ID b版本回滚
git reflog # #获取每次提交的 ID,可以使用--hard 根据提交的 ID 进行版本回退
git reset --hard 5ae4b06 #回退到指定 id 的版本
"git branch #查看当前所处的分支
"git checkout -b develop #强制创建并切换到一个新分支
"git checkout develop #切换分支

忘记root密码找回

  1. 在root用户下执行,获得用户数据,修改用户密码 官网方法
1
2
3
4
5
6
7
8
9
10
11
~]# gitlab-rails console production                     // 打开gitlab控制台
Loading production environment (Rails 4.2.5.2)
irb(main):001:0> user = User.where(id: 1).first // 查看id为1的用户名
=> #<User id: 1, email: "admin@example.com", ...
irb(main):002:0> user.password='12345678' // 更改root用户的密码为12345678
=> 12345678
irb(main):003:0> user.password_confirmation='12345678' // 更改root用户的密码为12345678
=> 12345678
irb(main):004:0> user.save! // 保存更改
=> true
irb(main):005:0> quit // 退出

注意:密码没有使用引号,奇怪的是使用单引号或双引号,密码就无效,估计是包含了这个字符,不包含,就没有问题。

  1. 浏览器重新访问,使用12345678密码登陆验证

git 提交概念

git 缓存区与工作区等概念:

工作区:(git clone):把代码clone到当前目录下。

暂存区:(git add .) :存储在工作区对代码修改过保存的地方。

本地仓库(git commit “” ):用于提交代码修改过的地方。

远程仓库 (git push):开发多个共同提交到代码仓库。

分支管理:

分支和tag区别:

分支可以进行代码提交

tag:用于稳定的代码备份,代码后期不需要在改动,tag不可以提交代码(是只读的,不允许提交)

tag:是可以clone的 克隆方式一样 git clone -b develop http://10.0.0.71/yht/app1.git

数据备份恢复

查看需要恢复的文件:

/var/opt/gitlab/backups/ # Gitlab数据备份目录,需要使用命令备份

/var/opt/gitlab/nginx/conf # Nginx配置文件

/etc/gitlab/gitlab.rb # Gitlab 配置文件

/etc/gitlab/gitlab-secerts.json # Key 文件

停止数据写入

1
2
3
4
5
6
7
8
9
10
11
12
13
`主要备份开发提交的数据和配置文件,类似于MySQL dump主要备份的文件,也可以整个文件打包拷贝  /var/opt/gitlab/
1 备份需要停止写入数据服务,这样备份的过程中就无法在gitlab上面提交数据
$ gitlab-ctl stop unicorn
$ gitlab-ctl stop sidekiq
2 开始备份,自动读取配置生成目录放在指定位置,备份好之后最好放在别的服务器,防止损坏每天备份
$ gitlab-rake gitlab:backup:create
$ ll /var/opt/gitlab/backups/#默认备份路径,只会显示日期,开头是unix时间拖,具体时间可以百度 unix时间戳查看具体时间转换
$ ll /var/opt/gitlab/backups/*`date +%Y_%m_%d`*.tar #备份好以后可以拷贝至其他服务器
3 开始恢复数据,如果是恢复到其他服务器也需要停止数据写入,后缀可以不写,需要手动输入yes
$ gitlab-rake gitlab:backup:restore BACKUP=1628319889_2021_08_07_14.0.7
4 最后启动服务,直接start全部启动也可以
$ gitlab-ctl start sidekiq
$ gitlab-ctl start unicorn

Gitlab 汉化在 12.3.5 版本以后官方就自带了汉化,这里就不在介绍

备份脚本

1
2
3
4
5
6
7
8
9
#数据恢复的脚本
vim gitlab-backup.sh
#!/bin/bash
gitlab-ctl stop unicorn sidekiq
gitlab-rake gitlab:backup:create
FILE_NAME=`ls -l -rt /var/opt/gitlab/backups/*_14.0.7_gitlab_backup.tar | tail -n1 |awk '{print $NF}'`
scp $FILE_NAME root@10.0.0.12:/data/gitlab-bak#基于key验证
rm -rf $FILE_NAME
gitlab-ctl start unicorn sidekiq

代码部署方式

蓝绿部署

1
2
3
4
5
6
7
8
9
10
11
怎样实现gitlab结合jenkins实现代码部署

#蓝绿部署
成本较高 ,大公司才会用,一般用于大环境,假设一套80个虚拟机,两套就是160个,需要两套环境,而且同时只有一套环境在线,另一套是离线的,离线的是用来升级的,一般升级只升级几个服务,所以离线的服务可以任意升级,对用户几乎是无影响。如果没问题就直接切换在离线环境,这个时候才转换,另一套就作为离线环境。如果有问题就回滚到离线服务。
- 部署过程
1 当前版本业务正常访问
2 另一套环境部署 v2 ,代码可能是增加功能修复bug
3 测试通过,就将用户的请求切换到新版本
4 观察一段儿时间,如果有异常就切换到旧的版本
5 下次升级,将旧版本升级到新的版本
升级可能对数据库要求较高,可能表的格式不兼容,需要对数据做备份,一般没事

金丝雀发布

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#金丝雀(灰度)发布介绍
互联网公司经常使用的方式,是我们最常用的一种部署方式,或者叫灰度部署,灰度, 是指定黑于白之间能够平滑过渡的一种方式。结合我们的监控和日志收集, 将代码构建后copyweb服务器,并实现让用户访问的目的。

原理:在现有的环境当中升级一小部分 让一小部分用户访问,然后确定没问题之后在升级全部,如果有问题就从负载均衡器把升级的服务器去掉,没问题就把剩下的服务器升级
"金丝雀发布、灰度步骤组成
1、准备好部署各个阶段的工件(包,配置文件),包括:构建工件,测试脚本,配置文件和部署清单文件。
2、从负载均衡列表中移除掉“金丝雀”服务器。
3、升级“金丝雀”应用(排掉原有流量并进行部署)。
4、对应用进行自动化测试。
5、将“金丝雀”服务器重新添加到负载均衡列表中(连通性和健康检查)。
6、如果“金丝雀”在线使用测试成功,升级剩余的其他服务器。(否则就回滚) 灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。

#滚动升级发布
不测试,v1直接升级v2 ,第二个也以此类推,可能会对用户的请求直接报错,简单,但是一般不会使用

A/B 测试

1
2
3
同时运行两个APP环境,和蓝绿部署是两码事,A/B测试是用来测试功能的表现方法,例如可用性以及受欢迎度(A/B测试有一定的竞争关系)
蓝绿部署是为了安全稳定的发布新版本应用,在必要的时候回滚
- 及蓝绿部署是一套环境在线,A/B 测试是两套环境在线

灰度部署 web环境

环境规划:

首先三台web 服务器安装tomcat,安装命令一样,我这边使用的二进制脚本一键部署 tomcat安装包

生产环境安全起见最好不要使用root

1
2
3
4
5
6
7
8
9
10
11
12
$ cat web.sh
#!/bin/bash
groupadd -g 2020 magedu && useradd -m -g magedu -u 2020 -s /bin/bash magedu
mkdir /data/tomcat/{tomcat_appdir,tomcat_webdir,tomcat_webapps} -p
# appdir保存解压目录,webdir 保存解压目录,webapps 加载app目录 在server.xml中的`appBase这儿`定义,myapp


mkdir /data/tomcat/tomcat_webdir/myapp #假如这个页面是解压过来的,然后在创建一个页面
echo "10.0.0.12 web1" > myapp/index.jsp #根据IP部署三个web
# 每个服务器开始做软连接
ln -sv /data/tomcat/tomcat_webdir/myapp /data/tomcat/tomcat_webapps/myapp
systemctl restart tomcat

部署haproxy

建议两台服务器结合keepalived做高可用,另外haproxy一定要开多进程以及CPU绑定,否则可能会造成网站访问慢的情况,默认是绑定在一颗CPU上面

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
# keepalived配置
$ apt install keepalived haproxy
$ find / -name keepalived.conf*
$ cp /usr/share/doc/keepalived/samples/keepalived.conf.vrrp /etc/keepalived/keepalived.conf
按照以下配置
$ cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
notification_email {
acassen
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}

vrrp_instance VI_1 {
state MASTER
interface eth0
garp_master_delay 10
smtp_alert
virtual_router_id 55
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.22 dev eth0 label eth0:1
10.0.0.23 dev eth0 label eth0:2
10.0.0.24 dev eth0 label eth0:3
}
}
$ systemctl restart keepalived
1
2
3
4
5
6
7
8
9
# haproxy配置,在最后一行添加
$ echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf
$ vim /etc/haproxy/haproxy.cfg
listen yanghongtao-m44-80
bind 10.0.0.22:80
mode http
server 10.0.0.12 10.0.0.12:8080 check inter 3s fall 3 rise 3
server 10.0.0.13 10.0.0.13:8080 check inter 3s fall 3 rise 3
server 10.0.0.14 10.0.0.14:8080 check inter 3s fall 3 rise 3
  • 部署好以后进程web测试,每次刷新都会在三台服务器进行调度