记一次gitlab仓库迁移阿里云云效以及相关的流水线改造全过程

最近接到一个繁琐的任务,从来没尝试过,要把现有的代码仓库以及发包流程整合起来,迁移到阿里云云效,然后利用云效的代码管理、CICD持续集成、代码扫描、代码评审...

image.png

脑瓜子嗡嗡的,我想现在不挺好的吗,gitlab管理代码,Jenkins发布。可能看上去不是那么现代化,那能咋办,硬扛,老板就是天。

接着开始找资料学习,弄懂大概是咋个回事。。。。。。。

一、前置知识 Docker、k8s

image.png Docker灵感来源于集装箱,最简单并且带有一定错误的认知就是 “Docker 是一种性能非常好的虚拟机”,使用 Linux 内核和内核功能(例如 Cgroups 和 namespaces)来分隔进程,以便各进程相互独立运行。就好似一个个独立的集装箱

Docker 中有三个核心概念:Image、Container、Repository。

  • Image: 有领“好人卡”倾向的广大程序猿一定对 镜像 的概念不会陌生。但和 windows 的那种 iso 镜像相比,Docker 中的镜像是分层的,可复用的,而非简单的一堆文件迭在一起(类似于一个压缩包的源码和一个 git 仓库的区别)。
  • Container: 容器的存在离不开镜像的支持,他是镜像运行时的一个载体(类似于实例和类的关系)。依托 Docker 的虚拟化技术,给容器创建了独立的端口、进程、文件等“空间”,Container 就是一个与宿机隔离 “容器”。容器可宿主机之间可以进行 port、volumes、network 等的通信。
  • Repository: Docker 的仓库和 git 的仓库比较相似,拥有仓库名、tag。在本地构建完镜像之后,即可通过仓库进行镜像的分发。常用的 Docker hub 有 hub.docker.com/cr.console.aliyun.com/ 等。

用通俗语言描述就是:1、Docker启动构建时会读取项目根目录下的DockerFile文件,它就好比是一个生产说明书,根据说明书生产出产品(Image镜像)2、Docker隔离出一个单独的容器环境并把生产的产品(Image镜像)放到容器中 3、Docker启动容器中的镜像并暴露一个端口给宿主机

Kubernetes(k8s)是跨主机集群的自动部署、扩展以及运行应用程序容器的开源平台,这些操作包括部署,调度和节点集群间扩展。简单说就是控制编排docker容器

了解更多

二、前端静态包是怎么跑起来的

Nginx 是一个高性能的HTTP和反向代理web服务器

前端大致的一个工作流程:项目搭建 -> 编码 -> 构建 -> 部署

我们主要讨论部署,这里以vue为例。在讨论这个问题之前先了解 publicPath

环境准备
  • 本地安装nginx
  • 通过vue-cli创建一个项目
publicPath

这个publicPathvue-cliwebpack都存在这个api,目的都是为了给构建出来的静态包提供一个自定义公共路径的功能,默认情况都是/。如果你是用vuecli搭建的项目,在vue.config.js自定义publicPath就OK,不要在output里配置。

模拟部署测试

1、启动vue项目、构建出dist

2、把dist包提取到nginx静态文件夹下

publicPath: '/'
复制代码

注:Mac系统nginx默认安装路径/usr/local/bin,配置文件路径/usr/local/etc/nginx,静态文件夹/usr/local/var/www

修改nginx.conf配置

...
location / {
    root /usr/local/var/www/dist;
    index index.html index.htm;
    try_files $uri $uri/ /index.html;
}
...
复制代码

3、启动服务 在安装路径下/usr/local/bin 执行

nginx
复制代码

4、浏览器调试

image.png 截屏2021-10-26 下午6.02.33.png image.png

看上图,所有构建的静态资源都放在跟路径,也可以正常访问了,到这里就完成部署了,好像没什么问题。如果是这样的话那就没必要写这篇文章了,且听下文分享

多个静态包部署在同一个域名

在实际开发部署中,不太可能会是一个包有一个单独的域名,而是一个域名下会部署多个包,这种场景再套用上面的配置那就会出问题了,怎么办?

此时就需要派上publicPath了,通过在域名后拼接一个标识来区分

比如我想在a.b.com域名下部署projectA、projectB、projectC

http://a.b.com/projectA/

http://a.b.com/projectB/

http://a.b.com/projectC/

现在方案有了,接下来就是编码配置了

vue.config.js

...
publicPath: '/projectA/'
...
复制代码

这个publicPath是作用于资源引用路径上,我们还需要在vue项目访问页面的路径上有所体现,类似http://a.b.com/projectA/,那就要在router里配置一个公共路径

const router = createRouter({
  history: createWebHistory('/projectA/'),
  routes: routes
})
复制代码

如果是vue2.x的配套路由的话要在baseUrl里配

image.png

可以看到配置的publicPath在模板index.html文件引用资源时体现了

image.png

image.png

点开sourses,可以看到图片文件夹不见了,页面空白,可以判断是没有映射到资源

万能的百度发挥作用了,一通检索,做了如下nginx配置

...
location / {
    root /usr/local/var/www/dist;
    index index.html index.htm;
    try_files $uri $uri/ /index.html;
}
location /projectA {
    alias /usr/local/var/www/dist;
    index index.html index.htm;
    try_files $uri $uri/ /projectA/index.html;
}
...
复制代码

image.png

vue项目的路由模式,不管是history还是hash模式,配置方式都一样的,不过有一点要注意,如果要发静态包到github pages,history模式好像不行,要用hash模式的路由

此时,也就把开始抛出的疑问解决了。不知道大家有没有别的疑问?rootalias 有啥区别?

rootalias 的区别

使用alias,实际的路径就是:alias值。

例如,
有一张图片,URL是:www.awaimai.com/static/a.jp…

它在服务器的路径是:/var/www/app/static/a.jpg

那么用root的配置是:

location /static/ {
    root /var/www/app/;
}
复制代码

用alias的配置就是:

location /static/ {
    alias /var/www/app/static/;
}
复制代码

对于alias,location值可以随便取,例如:

location /hello/ {
    alias /var/www/app/static/;
}
复制代码

这样,我们访问图片的地址就是:www.awaimai.com/hello/a.jpg

注意:
很多文章说:alias 后面必须要用 “/” 结束,是错误的,亲测加不加/效果是一样的。
alias在使用正则匹配时,必须捕捉要匹配的内容,并在指定的内容处使用。
alias只能位于location块中,root可以不放在location中。

域名 + /index.html

接着往下,有个这样的链接 http://a.b.com/group/test/index.html

项目结构也是一个vue的项目,原来由于是手动上传到CDN,套了几层目录,现在迁移到云服务用流水线发布。考虑到怕改变了链接有影响,怎样在访问链接不变动的情况顺利的迁移。

1、改造构建产物套几层目录

修改输出目录

vue.config.js

...
outputDir: 'dist/group/test',
...
复制代码

image.png

2、正常的发布到nginx静态文件目录下

3、配置nginx

location /group/test/index.html {
    root /usr/local/var/www/dist;
    index index.html index.htm;
    try_files $uri $uri/ /group/test/index.html;
}
复制代码

根据root和alias的区别,

指向路径:/usr/local/var/www/dist/group/test/index.html

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;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    #gzip  on;
    include /etc/nginx/conf.d/*.conf;
}
复制代码

default.conf

server {
	listen        80 ;
	server_name   localhost;
	root          /usr/share/nginx/html;
	index         index.html;  # 入口文件
	charset        utf-8;   # 编码

	location / {
		try_files $uri $uri/ /index.html;
	}

	#location ^~/gatewayApi {
	#	proxy_set_header X-Real-IP $remote_addr;
	#	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	#	proxy_buffering off;
	#	rewrite ^/gatewayApi/(.*)$ /$1 break;
	#	proxy_pass http://gateway.xxxx.com/;
	#}
}
复制代码
include /etc/nginx/conf.d/*.conf;
复制代码

这句代码的意思是部署的时候把default.conf提到nginx目录里conf.d文件夹去,然后自动引入nginx.conf配置文件中。这个好处就是default.conf可以写在开发项目里,方便做一些nginx的配置

以上就是本地搭建NGINX环境模拟前端静态包部署的全过程

三、代码迁移

1、登录阿里云云效 截屏2021-11-23 下午10.32.21.png

2、新建代码仓库

截屏2021-11-23 下午10.34.55.png

导入方式可以根据原仓库来选择相应的导入方式 截屏2021-11-23 下午10.50.01.png

这个地方要注意,新建代码仓库导入代码库的用途,一般如果是全新的仓库就是用新建,如果是老仓库使用导入会比较友好,因为云效可以同步原仓库所有的提交记录、分支、tag,不存在断档,非常的安全。但是有一个点需要注意,同步的时候会拉取原仓库代码覆盖云效上的代码,具体细节可以看一下官方推荐的仓库迁移策略

仓库同步官方文档

同步完之后,可以进行一些必要的仓库设置:

1、设置保护分支,比如将 master 设置为保护分支,后续开发过程中不能直接向master提交代码,必须通过 合并请求 将改动的代码合到master,还可以做代码审查,降低master代码被污染的风险

截屏2021-11-23 下午11.25.29.png

截屏2021-11-23 下午11.26.14.png

  • 分支:选择受保护的分支
  • 推送规则: 不允许任何人直接推送代码到受保护的分支
  • 合并规则:默认是只有管理员有权限合

四、搭建 Docker 配置文件 DockerFile

DockerFile就是 Docker 构建镜像的说明书,他会根据配置文件产出目标镜像

FROM nginx:1.15   # 意思是拉取那个版本的nginx来制作镜像
ADD ./default.conf /etc/nginx/conf.d/  # 将代码仓库根目录下的 default.conf nginx配置文件添加到镜像 nginx /etc/nginx/conf.d/ 目录下
COPY ./dist/ /usr/share/nginx/html/ # 复制前端构建出来的静态包放到镜像nginx /usr/share/nginx/html/ 目录下
复制代码

这里具体的nginx配置就是第二步讲到前端部署,没明白可以回过头去仔细研读一遍

五、搭建流水线

1、打开导入的代码仓库

截屏2021-11-23 下午11.10.59.png

2、新建流水线

截屏2021-11-23 下午11.07.57.png

3、填写流水线配置项(重点)

截屏2021-11-23 下午11.13.46.png 分别是添加源码、代码扫描、代码构建、代码部署(通常情况下是这四部,当然也可以自定义更多步骤)

添加源码(应用源码、部署代码片段)

截屏2021-11-24 上午11.35.38.png

代码扫描(主要是做一些代码风格语法的检测,其实省略这一步问题也不大)

截屏2021-11-24 上午11.41.57.png

代码构建

截屏2021-11-24 下午1.59.45.png

Nodejs构建

截屏2021-11-24 下午2.06.20.png

执行命令

截屏2021-11-24 下午2.14.06.png

执行命令这个功能非常实用灵活,作用就是将当前目录下的default.conf文件中 'gateway.caibeitv.com' 替换成 GatewayDomain 这个变量,进而可以达到动态的指定后端服务环境,那这个变量在哪设置呢?

截屏2021-11-24 下午2.30.06.png

命令格式1:sed 's/原字符串/新字符串/' 文件

命令格式2:sed 's/原字符串/新字符串/g' 文件

Linux sed -i 替换相关知识讲解

镜像构建并推送至阿里云镜像仓库

截屏2021-11-24 下午2.41.44.png

代码部署
执行命令

截屏2021-11-24 下午2.59.32.png

helm Release

截屏2021-11-24 下午6.25.30.png

上面相关的参数都在这里设置

截屏2021-11-24 下午6.35.38.png

配置完毕!!!

六、运行流水线

点击 运行 弹起弹窗,填写运行设置 截屏2021-11-24 下午6.47.53.png 截屏2021-11-24 下午6.38.21.png

七、域名解析、负载均衡等访问配置

确认部署的包是否成功跑起来了

截屏2021-11-24 下午6.59.16.png --> image.png --> image.png --> 进入相应集群 --> 工作负载/无状态

能看到自己部署上去的节点,说明部署ok,进入详情确认是否成功跑起来了 截屏2021-11-24 下午7.02.40.png

设置域名

截屏2021-11-25 下午2.39.20.png

在功能面板搜索关键词 域名 进入

一般来情况,公司运维都会指定一级域名,我们只需找到对应的一级域名,进入添加二级域名,例如 baidu.com

截屏2021-11-25 下午2.44.26.png

添加记录,也就是设置二级域名, 例如 haha.baidu.com haha就是二级域名标识

添加好就是这样的,注意,添加时要指定一个记录值,可以是IP也是是域名,但必须和记录类型对应 截屏2021-11-25 下午2.52.35.png

这个就是记录类型列表

截屏2021-11-25 下午2.56.14.png

我这里是设置的 A 类型,指向的是一台负载均衡机器的ip

设置负载均衡

在功能面板搜索关键词 负载均衡 进入

截屏2021-11-25 下午3.09.44.png

负载均衡实例列表就这样的,上一步设置的域名指向的就是负载均衡实例的IP

到这里,你可能还是不行白,设置的域名怎么就能访问到我们部署的项目呢?继续往下看

截屏2021-11-25 下午3.16.30.png

我们以这台测试环境的负载均衡为例,点击 添加后端服务器 进入配置

截屏2021-11-25 下午3.20.19.png

进入后首先是创建虚拟服务器组,这里我们就要回过头来捋一下,当时部署的时候选的是测试集群还是生产集群,如果是部署的测试集群,那我们就要搜索测试集群的节点添加进来,选好,进入下一步,这里需要配置一个端口号,也就是我们在设置流水线的部署阶段设置的端口号(就是暴露给宿主机的端口号)

截屏2021-11-25 下午3.24.35.png

截屏2021-11-25 下午3.33.15.png

如果想不起来,看看这张图,瞬间清晰了有没有?

截屏2021-11-25 下午3.39.39.png

添加好后就长这样

截屏2021-11-25 下午3.42.15.png

虚拟机组添加好后,下一步添加监听

截屏2021-11-25 下午3.49.29.png

截屏2021-11-25 下午3.46.59.png

截屏2021-11-25 下午3.46.38.png

配置转发策略

截屏2021-11-25 下午3.44.30.png

就把设置的域名填进去,虚拟机组选择跟上面几步是一样的

到这里基本配置完了,那就体验一下吧

发现还是没有访问不通,完了,心态崩了!!!!!

别慌继续往下看

截屏2021-11-25 下午3.58.08.png

原因:域名解析进入 负载均衡,默认是先访问80端口,所以需要在监听80端口转发策略里加上当前的域名

再访问一遍,成就感爆棚有没有?

写在后面

这里面没有写搭建集群、创建负载均衡的步骤,是因为这一步是运维早就配置好了,需要了解这两部分是怎么是配的可以去网上看看别人写的文章。

Guess you like

Origin juejin.im/post/7034419195639136269