惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
V2EX - 技术
V2EX - 技术
P
Privacy & Cybersecurity Law Blog
T
The Exploit Database - CXSecurity.com
美团技术团队
WordPress大学
WordPress大学
博客园 - 司徒正美
S
Securelist
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - Franky
Attack and Defense Labs
Attack and Defense Labs
Security Latest
Security Latest
L
LINUX DO - 最新话题
NISL@THU
NISL@THU
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
腾讯CDC
Y
Y Combinator Blog
The Hacker News
The Hacker News
Security Archives - TechRepublic
Security Archives - TechRepublic
IT之家
IT之家
T
Threatpost
Hugging Face - Blog
Hugging Face - Blog
Scott Helme
Scott Helme
S
SegmentFault 最新的问题
Cyberwarzone
Cyberwarzone
C
Cisco Blogs
阮一峰的网络日志
阮一峰的网络日志
U
Unit 42
B
Blog
Microsoft Azure Blog
Microsoft Azure Blog
P
Proofpoint News Feed
小众软件
小众软件
V
Vulnerabilities – Threatpost
J
Java Code Geeks
V
Visual Studio Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
A
Arctic Wolf
博客园 - 【当耐特】
Microsoft Security Blog
Microsoft Security Blog
S
Security @ Cisco Blogs
雷峰网
雷峰网
Help Net Security
Help Net Security
The Last Watchdog
The Last Watchdog
Recent Announcements
Recent Announcements
G
Google Developers Blog
C
CERT Recently Published Vulnerability Notes
T
Troy Hunt's Blog
MyScale Blog
MyScale Blog

Sehnsucht

记一次博客换图床的过程 观《花束般的恋爱》 读《活过》 东京 旅行篇 亲人逝去 我为什么想养鱼 防止AI爬取你的博客 「monthly 」博客重构 游戏全成就 好看的小说 人生的每一步都不会是浪费-2024年终 「weekly」星期五综合征 「weekly」听播客 杂谈 读《美丽新世界》 「weekly」社交媒体 恶性事件 新世界 「weekly」认知觉醒 美丽新世界 follow 「weekly」独立博客9问题 双十一买书 读《惊呆了!原来这就是社会学》 一次聊天与自我建设 2024-09月记 补番《relife》 树状数组简单理解 lvm简单使用 博客自动发布方案 某公众号废案 fail2ban基本使用 Podman 环境使用 Nginx Proxy Manager 最佳实践 2024-07同学聚会 vps使用podman部署freshrss 装备升级:新的PC gitlab局域网搭建流程 FastMail迁移至GMail+Cloudflare Email Routing 读《黑客与画家》 leetcode 第 391 场周赛 Astro添加过渡后DarkModeToggle按钮失效 nuxt3使用echarts5渲染中国地图 人生刻度 又到凤凰花朵开放的时候 2023-05-10 实习结束 2023-04-26 广州博物馆游记 YOASOBI「たぶん」官方音乐视频 风灵玉秀-发如雪 带我的老哥离职了 从p10k转向Starship lunarvim国内安装踩坑记录 什么是对称加密非对称加密、密钥交换、数字签名、证书 强调体验的一种思考时间的方式 ArchLinux使用vscode编写latex报错The font "FontAwesome" cannot be found ArchLinux安装(移动硬盘)流程 yay一个或多个文件没有通过有效性检查! 2022年终 hugo建站伊始 clash设置relay前置代理(校园网破解改进记录) 群青 · YOASOBI · Ayase 华为 matepad pro 11使用体验 Nginx使用acme.sh免费安装ssl证书 永远属于你的安娜 在线 童年趣事 童心,是比野心更难得的梦想 2021年终总结 基于jeeSite的软件测试课程作业 流程记录 Linux不同用户安装不同版本jdk Wifi4更换Wifi6路由器的使用体验 Flask 上传图片并灰度显示 玩客云刷机debain个人记录 jython 简单入门 Jenkins 个人搭建流程记录 集成邮件系统(qq邮箱),gitlab服务器,freestyle风格 在Web项目中配置Log4j --指南-- Codeforces Round 753 (Div. 3) ABCDE 浅谈fork函数 JavaWeb servlet 使用Cookie记录用户访问次数 Codeforces Round Educational Codeforces Round 114 (Rated for Div. 2) ABC 2021牛客多校7 I xay loves or 2021牛客多校9 H Happy Number 2021牛客多校8 D OR 2021牛客多校5 B Boxes 2021牛客多校5 H Holding Two 2021牛客多校2 D Er Ba Game 2021牛客多校1 F Find 3-friendly Integers 2021牛客多校1 B Ball Dropping 记人生第一次投简历和笔试 原型模式 2021-2-20 雨时随记 关于一维差分数组的例子 halo个人建站 关于手机ping电脑和电脑ping手机 泛型类简单理解 CodeForces - 849C From Y to Y 2020牛客国庆集训派对day3 Leftbest 约瑟夫环问题---2020牛客国庆集训派对day2 AKU NEGARAKU mysql 5.7 忘记密码如何更改 CF 1099B Squares and Segments CF 998A Balloons CF 998B Cutting 链表应用之多项式相加 CF 1150A Stock Arbitraging CF 1199A City Day CF 1199B Water Lily CF 982A Row CF 934A A Compatible Pair CF 629B Far Relative’s Problem 651A Joysticks 651B Beautiful Paintings
Gitlab CICD 实践,思考与记录
2024-07-02 · via Sehnsucht

本文更多的是对之前gitlab部署的补充,单机环境不会涉及k8s滚动部署之流

环境

测试环境:局域网测试服务器(1台)

生产环境:阿里云生产服务器(1台)

在局域网的服务器中用gitlab存储代码,以及运行了gitlab runner用来执行ci脚本

持续交付

版本控制

局域网中部署gitlab,在上面提交代码

分支策略

主分支策略:仓库只保留主干,其他非核心开发者只能分出新分支,当新功能完成后,上传代码请提出合并请求(PR)

多分支策略:在主分支策略的基础上开几个新的分支,可能是专门用于测试环境的分支(测试完成后合并到master),可能是release分支(大版本更新的分支),可能是对一些大型功能进行重构的分支,可能是专门用来解决bug的分支…

代码提交规范

参考: 语义化版本约定式提交

可以使用 Checkstyle,ESLint 等规范代码风格

用 Husky 等工具使用 git hook

如果是规范 git commit 信息,可以直接在 .git/hooks/commit-msg中写入

#!/bin/sh

# 提交信息格式正则表达式
commit_regex='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9_-]+\))?: .{1,50}$'

# 读取提交信息
commit_message=$(cat "$1")

# 检查提交信息是否符合正则表达式
if ! echo "$commit_message" | grep -Eq "$commit_regex"; then
  echo "Error: Invalid commit message format."
  echo "Proper commit message format is required for automated changelog generation."
  echo "Examples: "
  echo "  feat(module): add a new feature"
  echo "  fix(module): fix a bug"
  exit 1
fi

这样,如果 git commit 信息不符合规范就会无法提交

部署自动化

根据gitlab ci脚本可以选择不同的策略:

  • 指定master/main分支,有新提交就自动执行ci脚本
  • 指定分支,当新提交有指定tag(例如test-0.2.1,prod-0.2.2)时执行ci脚本
  • 当有新的PR也可以执行ci脚本

单机部署方式探讨

单服务器,以何种方式进行部署更合适?

  • 线上一套环境(当项目出现bug时需要停机回滚)
  • 线上两套环境相互切换,即蓝绿部署(用nginx切换两套环境,当更新后出问题了就切换回原环境)
  • 其他…

蓝绿部署还有一种,是直接切软链接,但我觉得不太靠谱(强制停机软链接可能会丢失,但其他的问题我就不清楚了)

复杂的项目限制,我在实践中选择了蓝绿部署

  • 缺点:占空间,需要维护两套环境
  • 优点:回滚方便,回滚的速度也快

其他的滚动部署,金丝雀部署等方式不适用单机环境

.gitlab-ci.yml的不同场景

16.11 gitlab-ci

# Executors用docker还是ssh

docker的开启和关闭是需要时间的,缓存的上传和下载也是需要时间的,这时候为了减少时间可以专门开一个构建用的docker,把环境弄好,构建的时候用ssh执行器直接连接,这样依赖无需下载也无需docker开启关闭的时间

我之前写的就是ci太慢了,部署springboot项目,maven构建好了,那么又把构件移到rsync的docker里发往远程服务器,这不是浪费了相当多时间吗

专门的docker构建环境

可能需要安装的:

  • rsync
  • git
  • maven
  • node
  • java jdk/jre(如果是构建jar包就需要jdk,不然jre就行)

可以考虑用nvmmise这种版本切换工具来切换不同环境,且这种工具一般是无需root权限的,是用户级别的命令

大部分此类工具在非交互式shell里和一般的操作是不一样的,例如非交互式shell里直接使用nvm是不行的,需要先source ~/.bashrc一下

当然,也可以自行编写dockerfile

ssh 执行器取消git clone操作

单个作业脚本中添加:

  variables:
    GIT_STRATEGY: none

指定分支/标签

  only:
    refs:
      - /^prod-.*$/
    variables:
      - $CI_COMMIT_REF_NAME == "master"

Git回滚时指定SHA

  stage: build
  variables: {} # 可以用来跳过单个作业中的全局变量
  script:
    - |
      git checkout $COMMIT_SHA
      echo "COMMIT_SHA: $COMMIT_SHA"

点入作业,可以手动修改变量(覆盖变量)后提交

rsync传输文件

  script:
    rsync -av ~/A/ devops@$PROD_SERVER:/home/devops/cache/

rsync

  • 排除文件夹 : rsync -av --chmod=755 --exclude '.git' ~/A/ devops@$PROD_SERVER:/home/devops/cache/
  • 修改文件权限 : rsync -av --chmod=755 ~/A/ devops@$PROD_SERVER:/home/devops/cache/
  • 默认会把...的权限也同步,所以需要加上 --no-implied-dirs : rsync -av --no-implied-dirs ~/A/ devops@$PROD_SERVER:/home/devops/cache/

减少依赖安装次数

可以考虑,当依赖文件发生变化才安装依赖

可以使用 git diff 查询本次提交和上次的提交有什么区别,如果以下文件不一样就构建

  • ‘pom.xml’
  • ‘package.json’
  • ‘package-lock.json’
  • ‘yarn.lock’

并行策略

有时可以考虑并行执行任务

build_source m-source m &
build_source n-source n &
wait

跨pipelines缓存

node依赖,maven依赖等

  cache:
    key: "XXX_CACHE"
    paths:
      - node_modules

普通不加key的缓存不能跨pipelines

部分执行器是不支持缓存的,例如ssh执行器(但是ssh执行器本身就不需要缓存)

dockerhub访问问题

可以考虑用docker_image_pusher转成国内的镜像

单独开一个构建专用的容器的利弊

单独开一个容器进行:

  • 构建(maven的打包,npm的build等)
  • 推送(rsync等)

优点:

  • 省时间(好处是构建的依赖不会丢失,比每次用缓存上传下载依赖省时间,且无需找到rsync或者node,maven容器再启动)
  • 环境一致
  • 与主机环境隔离

缺点:

  • 需要单独创建一个容器,并在里面安装好对应的依赖
  • 容器管理麻烦(需要将容器的22端口映射到外部,使用ssh执行器连接)
  • 需要占用一定资源

其实在测试环境开一个新用户,在里面直接安装需要的工具并构建,也是可行的,但就是没有与主机隔离就是了

无需root启动容器

可以使用docker的替代品podman代替docker操作,命令几乎完全一样

docker反复构建镜像造成空间不够

解决办法:

  • 在构建完成后直接删除多余的容器
  • 直接用脚本定期清理多余的构建容器

重复构建相同名称相同标签相同的容器,会造成悬空镜像(可以用时间戳随机生成来打标签,防止生成悬空镜像)

修改dockerfile时旧的镜像层次可能会变成悬空镜像

手动清理空间步骤:

查看命令:

# 查看docker网络
docker network ls
# 查看容器卷
docker volume ls
# 查看容器镜像
docker image ls
## 或者
docker images
# 查看悬空镜像
docker image ls -f dangling=true
# 查看所有悬空卷:
docker volume ls -f dangling=true
# 查看未使用镜像
docker image prune -a --filter "until=24h"

删除命令:

# 删除镜像
docker rmi mh-go
# 删除所有悬空镜像
docker image prune
# 删除所有悬空卷
docker volume prune
# 删除所有未使用的 Docker 对象(包括停止的容器,未使用的网络,悬空镜像和未使用的镜像,构建缓存,不包括悬空卷)
docker system prune -a