介绍

今天介绍一个可以自建的开源 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,镜像仓库用哪写哪就可以,我这里是阿里云。 Job Executors

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

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

Job

通过这个页面可以一步步配置 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 任务。 在 build 中可以看到日志

在流水线中可以看到当前执行的是哪一个

生成的制品

CD

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

Roll Back

总结

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