介绍
今天介绍一个可以自建的开源 Git 服务 OneDev, 功能强大,资源占用少,国人 Java 开发。
- 开箱即用的符号跳转、符号搜索
- 全功能的 CI/CD,支持 GUI
- 强大易用的 Commit/Issue/Build/Pull Request 查询语言
- 代码标注和讨论
- 更多功能特性看官网说明
目前不足是全英文,文档简洁,还不知道什么时候支持中文,也不算什么大事。另外小 Bug 多,不过作者修复神速。
部署安装
运行环境 k8s v1.21.5,容器运行时 containerd。
安装方式直接参考官方文档 helm 装就完事,除了在 k8s 运行也可以直接 docker run 和裸机跑。
helm 安装完成会创建一个 onedev 的 service type 是 LoadBalancer,由于我使用 apisix ingress 所以直接改成 ClusterIP 然后外面再套负载均衡走流量。细节不展开了可以参考实践 Apache APISIX Ingress。
符号跳转、搜索
支持 Java, JavaScript, C, C++, CSharp, Go, PHP, Python, CSS, SCSS, LESS and R 语言,IDE 级别的功能。 据作者说使用 ANTLR 分析主流语言的语法,并提取符号定义进行增量存储,速度快,占用空间小。

CI/CD
直接来体验下 CI/CD,测试项目依然是我的 wx-msg-push。
先创建一个 yaml 配置文件,在 k8s 中 apply,这个是 onedev 在 k8s 中部署应用使用。
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: gitops-onedev
rules:
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "create"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "patch", "create"]
然后在 Administration -> Job Executors 中创建一个 Build 执行方式。类型可以选远程docker、远程shell、k8s。我这里还是选k8s,也可以指定运行节点,Cluster Role 写上刚才创建的 gitops-onedev,镜像仓库用哪写哪就可以,我这里是阿里云。

在项目配置中加上镜像仓库的账号信息。这里 ali-repo-auth 通过 echo -n "username:passwd" | base64 生成。

然后在项目中点击 .onedev-buildspec.yml 进入 build 配置页面。


通过这个页面可以一步步配置 CI/CD。 可以设置触发参数、触发逻辑比如push branch或者push tag,可以设置从属关系、重试、超时、缓存等。
我这里 CI 阶段由 push tag 触发,具体分为四个 Step
- checkout 代码检出
- make 编译可执行文件
- build & push 构建镜像推送
- publish artifact 发布制品,各平台的可执行文件包
通过 View Source 可以看到实际生成的配置文件。
分享下我现在的配置文件,Job Executor 就是刚才创建的 Build 执行方式。
version: 16
jobs:
- name: ci
jobExecutor: k8s
steps:
- !CheckoutStep
name: checkout
cloneCredential: !DefaultCredential {}
withLfs: false
withSubmodules: true
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
- !CommandStep
name: make
runInContainer: true
image: zyh94946/golang:v1.18.3
interpreter: !ShellInterpreter
shell: sh
commands:
- make release
useTTY: false
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
- !CommandStep
name: build & push
runInContainer: true
image: zyh94946/kaniko:v1.8.1-debug
interpreter: !ShellInterpreter
shell: /busybox/sh
commands:
- echo "{\"auths\":{\"@secret:ali-repo-url@\":{\"auth\":\"@secret:ali-repo-auth@\"}}}"
> /kaniko/.docker/config.json
- /kaniko/executor --context "/onedev-build/workspace" --dockerfile "/onedev-build/workspace/Dockerfile"
--destination "@secret:ali-repo-url@/zyh94946/nico:wx-msg-push-@tag@"
useTTY: false
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
- !PublishArtifactStep
name: publish artifact
artifacts: '*.zip'
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
triggers:
- !TagCreateTrigger
tags: v*
retryCondition: never
maxRetries: 3
retryDelay: 30
cpuRequirement: 250
memoryRequirement: 256
timeout: 3600
- name: cd
jobExecutor: k8s
steps:
- !CheckoutStep
name: checkout
cloneCredential: !DefaultCredential {}
withLfs: false
withSubmodules: true
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
- !CommandStep
name: deploy
runInContainer: true
image: zyh94946/kubectl:v1.21.5
interpreter: !DefaultInterpreter
commands:
- 'echo "tag: @tag@"'
- 'if [ "@tag@" != "" ]; then '
- "\tsed -i \"s/#tag#/@tag@/g\" k8s.deployment.yaml"
- "\tkubectl apply -f k8s.deployment.yaml"
- fi;
useTTY: false
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
jobDependencies:
- jobName: ci
requireSuccessful: true
artifacts: '**'
retryCondition: never
maxRetries: 3
retryDelay: 30
cpuRequirement: 250
memoryRequirement: 256
timeout: 3600
由于 k8s 集群容器运行时采用 containerd 所以无法通过 docker 正常构建和推送。这里我通过 google 开源的容器工具 kaniko 构建和推送镜像。
该工具镜像地址为 gcr.io/kaniko-project/executor:debug,建议用 debug 版可以进入 shell,由于原镜像地址太慢自行下载后传到了 dockerhub 上 zyh94946/kaniko:v1.8.1-debug。使用方式也很简单,一条命令就完成构建和推送了,具体看上面的配置。
CD 部分只有两个 Step,代码检出和应用部署,部署中的镜像就是 CI 中创建的。CD 附属于 CI,当 CI 执行成功后手动触发 CD,当然也可以在 CI 完成后自动开始 CD 任务。




关于版本回退,可以从 k8s 中执行 Roll Back,或者在 onedev 中单独执行一个指定 tag 的 CD 重新部署。

总结
以上就是在 onedev 中的 CI/CD 应用,通过编译可执行文件,构建镜像推送,最后用 kubectl 在 k8s 中部署。
其中通过 kubectl 部署应用,赋予了 onedev 对 k8s 的操作权限。另外还有一种方式采用 Argo CD 拉取配置来更新,onedev 只做 CI 的事,这样即使采用在 k8s 集群外的 git 服务也能有较好的安全性。