前言
多年前张小龙在阐述微信对于开放平台的一些理念和方向,提到:再小的个体也有自己的品牌;这个理念使得微信公众号在很长一段时间内保持了创作繁荣、内容繁荣、阅读繁荣;如今我在深度体验了Cloud Studio之后,不禁也发出这样的感慨:再小的个体也可以有自己的生产级流水线。使用Cloud Studio深度结合Coding,就算我们没有大厂的财力、物力、人力依然可以搭建出只有大厂才有的工作流体验的流水线,极大的提高了CI和CD的效率,同时也极大的提高了开发者的幸福度,将宝贵的精力放在创造和业务逻辑的开发上。下文假设我是一家小微企业或者开发个体户的技术选型的全过程。
一、场景模拟
- 人设:我曾经是一名大厂的开发工程师;现在在创业阶段。
- 境况:如今我不再单纯的负责码代码;不仅要负责写代码,还要负责基础设施维护,还要负责到处跑见客户。(总之:很苦逼)
- 特点:我的时间比较碎片化,同时我的精力有限,我想偷懒也想提效。
- 希望:我可以有大厂一样的基础设施,我希望我的大部分时间花在可以直接创造价值的事情上。
二、方案选型
按照以往经验,我们可能首选的方案是:买一台CVM机器,配置一下基础环境;然后再在本地装一个vscode或者其他的编码IDE;便开始愉快的编码了;接着编码完成以后rz到CVM,然后编译,然后部署,最后验证。这种方案看起来是最高效的,也是最直接的。但是我也不禁反思,这种方案是否符合我的要求。
首先,因为我在创业我的时间比较宝贵,我不想把时间花在重复的事情上;
其次,我没有固定的办公地点,甚至没有固定的办公电脑,我要随时随地修改代码以快速的响应客户的要求;
最后,我比较注重安全,我希望我的代码保存的平台是一个让人放心的。
最重要的是:我现在还在创业初期,我希望花最少的钱,满足我上面所有的要求;一句话总结:又穷但是要求又高。
基于我的要求,我又重新回顾了一下这个方案,我是否可以接受?答案是否定的。我的编写代码的热情会被重复的:rz、编译、部署,一点点磨灭掉,最后导致:客户的需求我不想写,停止思考陷入内耗。因为写完代码以后后面还有一堆的事情等着我干,想想都累更何况要做呢。我碎片化的时间也不可能被利用起来,因为一旦做某个东西,我都需要一块完整的时间走完所有的流程。我也不能随时随地的写上两行代码,因为我如果要写代码必须在我自己已经配置好基础环境的机器上。
所以,如果我选用这种方案的话,可能会有“出师未捷身先死”的遗憾。于是我想我在大厂的工作流是否能搬出来为我所用,于是Cloud Studio Coding的开发模式,出现在我的眼前。不得不说云的出现,确实将“赋能”这个词诠释到了极致,而且毫无保留甚至更好的体验。
以下就是我尝试介绍使用Cloud Studio Coding的开发模式,用最小的成本,搭建后台Go应用的工作流的详细过程。
三、如何搭建私有化仓库
我们都很清楚,单打独斗很难成大事,必须协作才能成就大事;所以我们第一步需要考虑的不是选择IDE编辑器,而是先把协同这件大事搞定,那么摆在我们面前的选择有很多,例如:Github、码云、Gitee等等,但是因为我们希望有大厂一样的体验,所以我们选择了大厂出品的Coding。相信这款产品可以持续维护。
3.1、开通Coding DevOps服务
这一步比较简单,打开腾讯云Coding产品介绍页;然后点击立即使用按钮(这是免费的哦,符合我们“穷”人设的要求),如下图所示:
3.2、创建代码仓库
这一步也比较简单,只需要按照页面指引创建代码仓库即可。
至此,如果我们没有开源需求的话,私有仓库已经开通完成。接下来,就是我们的如何结合Cloud Studio开始我们的编码过程了。
四、如何结合Cloud Studio
第三部分,解决了我对协作以及代码安全的需求;接下来我需要解决随时随地写代码不受物理环境限制的需求。
4.1、将Git仓库与我们的Cloud Stuio打通
这一步也比较简单,只需要简单的配置一下即可完成;
第一步:在Coding中选中Cloud Stuio导航并打开,如下图所示:
第二步:选择新建工作空间并与Coding的Git仓库打通
按照上述指引新建完Cloud Stuio的工作空间之后,Cloud Studio会在我们的Git仓库上创建SSH密钥,我们所有的操作都是基于此做的,无需我们额外在做什么。不得不说,真的很方便。
4.2、 如何与Git进行交互
接下来还会有更关键的一步,我们写好的代码如何提交到Git仓库呢,这里的体验与我们在本地开发是一致的,如下图所示。
直接在终端的命令行输入一下命令就可以实现代码提交了
代码语言:javascript复制git add README.md
git commit -m "first commit"
git push -u origin master
拉取代码也是一样的操作。
五、如何使用Coding搭建流水线
至此,我们已经解决了代码安全与协作,以及充分利用碎片时间随时随地编写代码的需求。接下来可能就是我们的重头戏了,如何把我从繁琐重复的工作中解放出来。
5.1、什么是流水线
我们日常说的流水线是指的持续集成的过程;因为其执行过程就像工厂里的流水线一样,因此而得名,只不过这个流水线上的工人是我们实现制定好的脚本。这条流水线没有剥削、也没有旷工,只有兢兢业业的按照既定脚本完成任务。
5.2、一步一步搭建流水线
第一步:创建构建计划,如下图所示:
第二步:基础信息,选择好我们在Coding上的代码仓库,并使用静态配置的Jenkinsfile,如下图所示:
第三步:流程配置,这里我选择了图形化编辑器,这样即简单又直观。
1-1、我的流水线上第一步就是从代码仓库里面检出代码,这里比较简单
1-2、将代码检出以后,就要编译,这里有几个知识点:
1.构建环境的选择,因为我的后台代码是Go写的,所以我在选择构建环境的时候,选择的是golang 1.18的环境。如下图所示
2.做Go开发的同学都知道我们的依赖管理是靠go mod的,go mod对于私有仓库的拉取是有一定门槛的,所以我们需要简单几行代码。
代码语言:javascript复制git config --global url."https://${GO_GET_USER}:${GO_GET_PASSWORD}@e.coding.net/meshisland/go_module/".insteadOf "https://e.coding.net/meshisland/go_module/"
go env -w GOPRIVATE=e.coding.net
3.我们看到这里面有几个变量${GO_GET_USER}和${GO_GET_PASSWORD},这个就是我们的环境变量,可以在流水线的“变量与缓存”中设置。这个环境变量在一定程度上保证了我们配置的安全。
其中${GO_GET_USER}是我们私有仓库的用户名,${GO_GET_PASSWORD}是我们私有仓库的密码。
1-3、将编译好的文件推送到CVM,这个是我们下一个章节重点介绍的。
六、在没有TKE集群的情况下如何将编译包投放到轻量服务器
至此,我基本上解决了所有的诉求,但是最关键的一个问题我还没有解决,创业初期我很穷,对于所有的花费都要额外关注,目前我只有一台轻量服务器,我没有多余的机器可以搭建TKE集群。但是我又想在流水线上实现,自动把我的代码部署到这个机器上。应该怎么办?
6.1、使用SCP将代码推送到CVM上
这个应该是所有程序员想到的最简单直接的方式,废话不多说,直接贴上我的shell脚本。
代码语言:javascript复制apt-get -y install sshpass
touch cmd_stuff
echo `date ' %s'` > cmd_stuff
sshpass -p "${CVM_PASSWORD}" scp cmd_stuff ${CVM_USER}@${CVM_IP}:${CVM_REALEASE_DIR}
sleep 5
sshpass -p "${CVM_PASSWORD}" scp -r stuff/conf/ ${CVM_USER}@${CVM_IP}:${CVM_REALEASE_DIR}
sshpass -p "${CVM_PASSWORD}" scp stuff/main/back_end_stuff ${CVM_USER}@${CVM_IP}:${CVM_REALEASE_DIR}
其中${CVM_PASSWORD} 是我们CVM机器的密码,安全起见这里务必配置到流水线的环境变量上;{CVM_USER}是指的CVM的机器的用户名,${CVM_IP}指的是我们CVM的IP,{CVM_REALEASE_DIR}是指的我们的工程部署在机器上的目录。以上环境变量都是在流水线的“变量与缓存”模块配置的。
6.2、通过CVM的脚本实现自动更新服务
经过6.1的工作,我们已经将编译好的文件推送到我们的机器上了,接下来我不想每次发布都登录到机器上重启我的进程。这样也挺烦的,我就像一键按下去,就等着看效果就好了。于是我想了一个办法,也就是6.1中的一个创建的一个文件,并把当前时间写到这个文件,并推送到CVM。即:这个命令:
代码语言:javascript复制touch cmd_stuff
echo `date ' %s'` > cmd_stuff
同时我机器上也有另外一个常驻进程,在持续检测cmd_stuff这个文件是否有更新,如果有更新的话,则杀死指定的进程,并重启一个进程,以实现服务的自动重启。
常驻进程的shell脚本如下:
代码语言:javascript复制function whether_changed(){
local file_path=${1}
local check_time=${2}
while [[ true ]]; do
file_old_stat="`stat ${file_path}|grep Change`"
sleep ${check_time}
file_new_stat="`stat ${file_path}|grep Change`"
if [[ `echo ${file_old_stat}` == `echo ${file_new_stat}` ]]; then
continue
else
echo "#### Start Restart Server ####"
pkill -9 back_end_stuff
sleep 10
nohup ./back_end_stuff -d > output 2>&1 &
fi
done
}
whether_changed $1 $2
七、总结与附件
最终,我只买了一个轻量级服务器,成本每个月50块钱,便实现了有大厂才有的工作流程,并且满足了我对创业幸福感所有的要求。Cloud Studio Coding的工作流,真的把大厂的工作流赋能给了一个小个体,再小的个体也可以有自己的生产级流水线。最后附上我流水线完整的Jenkinsfile文件。
代码语言:javascript复制pipeline {
agent any
stages {
stage('检出') {
steps {
checkout([
$class: 'GitSCM',
branches: [[name: GIT_BUILD_REF]],
userRemoteConfigs: [[
url: GIT_REPO_URL,
credentialsId: CREDENTIALS_ID
]]])
}
}
stage('自定义构建过程') {
agent {
docker {
reuseNode 'true'
registryUrl 'https://coding-public-docker.pkg.coding.net'
image 'public/docker/golang:1.18-2022'
args ''
}
}
steps {
sh '''git config --global url."https://${GO_GET_USER}:${GO_GET_PASSWORD}@e.coding.net/meshisland/go_module/".insteadOf "https://e.coding.net/meshisland/go_module/"
go env -w GOPRIVATE=e.coding.net
go mod tidy
cd stuff/main
go build -o back_end_stuff main.go
cd ../../
'''
}
}
stage('推送CVM') {
steps {
sh '''apt-get -y install sshpass
touch cmd_stuff
echo `date ' %s'` > cmd_stuff
sshpass -p "${CVM_PASSWORD}" scp cmd_stuff ${CVM_USER}@${CVM_IP}:${CVM_REALEASE_DIR}
sleep 5
sshpass -p "${CVM_PASSWORD}" scp -r stuff/conf/ ${CVM_USER}@${CVM_IP}:${CVM_REALEASE_DIR}
sshpass -p "${CVM_PASSWORD}" scp stuff/main/back_end_stuff ${CVM_USER}@${CVM_IP}:${CVM_REALEASE_DIR}
'''
}
}
}
}