Gogs + Drone搭建

devops工作流与基础实现

1. Devops工作流

没啥用的前戏介绍

DevOps是一组过程、方法与系统的统称,用于促进开发、技术运营和质量保障(QA)部门之间的沟通、协作与整合。
	---- 维基百科

一般来说项目软件从零到最终交付, 大概分为以下几个阶段: 规划、编码、构建、测试、发布、部署和维护。

瀑布模型

img

对应步骤及其工种

img

这三个阶段,即开发,测试,布署. 是早期所采用的软件交付模型,称之为“瀑布(Waterfall)模型”。

但需求是会不断变化的, 产品也会不断提出问题的, 瀑布式开发难以满足. 于是软件开发团队引入了新概念: “敏捷开发”.

敏捷开发

敏捷开发其实简单来说,就是把大项目变成小项目,把大时间点变成小时间点. 拆分功能, 将每个需求变为小项目, 不断的进行"开发-测试",美名其曰 "持续".

preview

敏捷开发大幅提高了开发团队的工作效率,让版本的更新速度变得更快。可以帮助更快地发现问题, 风险会更小.

但是问题点依旧, 虽然提升了软件开发的效率和版本更新的速度, 但仅限于开发环节, 部署运维依旧未改变.

DevOps

简介

从目标来看,DevOps就是让开发人员和运维人员更好地沟通合作,通过自动化流程来使得软件交付整体过程更加快捷和可靠。

img

DevOps 其实包含了三个部分:开发、测试和运维。换句话 DevOps 希望做到的是软件产品交付过程中IT工具链的打通,使得各个团队减少时间损耗,更加高效地协同工作。

preview

这几年云计算技术突飞猛进, 虚拟化、容器、微服务等等, 都为DevOps提供了很好的前提条件. 
开发环境和部署环境都可以更好地隔离了,减小了相互之间的影响。

微服务:
	就是将原来黑盒化的一个整体产品进行拆分(解耦),从一个提供多种服务的整体,拆成各自提供不同服务的多个个体.
	
虚拟化:
	它从硬件上,将一个系统“划分”为多个系统,系统之间相互隔离,为微服务提供便利。
	
容器:
	在操作系统上划分为不同的“运行环境”(Container),占用资源更少,部署速度更快。

CICD

这种开发模式下带来的新问题是, 如何确保运维上线的即时, 那就是CI和CD。

  • CI(持续集成):
    • 是指多名开发者在开发不同功能代码的过程当中,可以频繁的将代码行合并到一起并切相互不影响工作。
  • CD(持续交付与持续部署):
    • 基于某种工具或平台实现代码自动化的构建、测试和部署到线上环境以实现交付高质量的产品
    • 持续部署在某种程度上代表了一个开发团队的更新迭代速率。
开发只需要关注代码, 业务逻辑, 测试脚本, 然后提交到代码仓库.
后续测试, 发布, 部署都由自动化脚本完成, 减少运维工作量, 避免人为失误.
DevOps平台

而DevOps平台的搭建可通过如下工具进行实现

项目管理(PM):Jira

代码管理:GitLab

持续集成(CI):GitLab CI

镜像仓库:VMware Harbor 私服nexus

容器:Docker

容器平台: Rancher

镜像扫描:Clairctl

编排:Kubernetes

服务注册与发现:etcd

脚本语言:python

日志管理:EFK

系统监控:prometheus

Web服务器:Nginx

数据库:MySQL redis

负载均衡:Nginx。

产品和UI图:蓝湖

公司内部文档:Confluence。

报警:推送到工作群 企业微信 钉钉

技术选型

初期采取: gogs + drone + docker-compose
后期可采用: gitlab + Jenkins

2. Gogs + Drone 搭建

Gogs

Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自助 Git 服务。使用 Go 语言开发使得 Gogs 能够通过独立的二进制分发,并且支持 Go 语言支持的 所有平台,包括 Linux、Mac OS X、Windows 以及 ARM 平台。(引之官网)

官网: https://gogs.io/

上下文
公司项目目前放在 githup 上, 有些奇怪
想往gitlab 上迁移, 奈何公司没有测试服务器, 个人服务器1核2G又不给力,权衡之下, 选择轻量级的 Gogs.
以下为自行搭建的过程, 后续可迁移至公司服务器中, 或升级使用 gitlab, 可当做经验
优缺点
语言:
	gogs 国人开发基于go
	gitlab 基于ruby

特点:
	gogs:
		安装简单, 功能简要够用, 对于小团队而言挺合适.
		git 版本库, 问题管理, wiki
		头像不能自定义(dog)
	gitlab:
		集成较强的 CICD 功能
		功能全面, 适合大团队开发, 相对耗费资源(4G内存)
安装方式
- 源码安装, 需要安装 go 语言
- 使用 Gogs 的二进制包安装, 不需要安装go环境
- 使用 docker 安装

Drone

官网: https://docs.drone.io/server/overview/

简介

Drone 是一个基于Docker容器技术的可扩展的持续集成引擎,用于自动化测试、构建、发布。每个构建都在一个临时的Docker容器中执行,使开发人员能够完全控制其构建环境并保证隔离。开发者只需在项目中包含 .drone.yml文件,将代码推送到 git 仓库,Drone就能够自动化的进行编译、测试、发布。

可以与docker完美集成, 相对于Jenkins来说更加轻量, 可以配合 Gogs 来实现持续集成

- Drone 引入了Pipeline 的概念, 管道可以帮助我们自动化软件交付过程中的步骤, 例如启动代码构建, 运行自动化测试以及部署到测试或生产环境
- 通过 .drone.yml 文件放在 git 信息库的根目录来配置管道.
- Drone 通过多个 step 来完成一系列的指令.
步骤梳理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7gUXSMDj-1626946901190)(https://images1.tqwba.com/20200926/gpafwuflo4b.png)]

1. 开发人员向 git 仓库提交代码, 代码中必须包含 DockerFile 与 .drone.yml 文件

2. 分支进行代码更新时, Gogs会通过钩子同步通知 Drone 

3. Drone 通过git 插件 clone 分支代码到容器-测试-编译-构建可执行文件-打包镜像-发布到registry仓库-部署至生产环境-发送邮件通知等, 这里可以使用很多插件,比如harbor,notify, 微信钉钉等

4. 构建的pipeline脚本是通过 .drone.yml 编排的

安装步骤
  • 安装 drone

  • 安装 Drone-runner

    drone-runner是执行pipeline的服务, 对应编写.drone.ymltype.

    • 安装启动drone-runner-ssh
    • 安装启动drone-runner-docker

所以安装时最后统一安装管理, 这里使用 docker-compose进行编排部署

可以使用 openssl rand -hex 16 生成秘钥

几个关键配置

DRONE_GOGS_SERVER
	使用gogs 作为仓库存储, 不同的仓库需要设置不同的变量
DRONE_RPC_SECRET
	与 agent 之间通信的秘钥, 一定要配置
DRONE_SERVER_HOST
	设置 drone server 使用的host名称, 可以是ip+port
DRONE_SERVER_PROTO
	使用的协议 http/https
DRONE_LOGS_TRACE
	启动日志
DRONE_USER_CREATE
	设置初始管理员
DRONE_OPEN
	开启注册,此配置允许任何人自注册和登录系统

几个关键配置

DRONE_RPC_HOST
	上面启动server时配置的host
DRONE_RPC_SECRET
	通信秘钥, 跟server配置的要保持一致
DRONE_RUNNER_CAPACITY
	可以同时执行的任务数
DRONE_RUNNER_NAME
	一般设置为主机名

安装集成

二进制文件安装太麻烦了, 我这边直接使用docker安装的方式.

确保服务器中已安装 docker + docker-compose

创建配置文件夹

mkdir -p /etc/opt/cicd_data/drone
mkdir -p /etc/opt/cicd_data/gogs
cd /data/cicd
docker-compose.yml

编写docker-compose.yml文件

version: "3.6"
services:

  # gogs 服务镜像
  gogs:
    image: gogs/gogs
    container_name: gogs
    restart: always
    ports:
      - "10022:22"	# ssh 端口
      - "9999:3000" # gogs仓库
    volumes:
      - /data/docker_test/gogs:/data	# gogs 挂载卷
  
  # drone server 端
  drone:
    image: drone/drone:latest
    container_name: drone-server
    ports:
      - "10080:80"	# drone 服务:HTTP
      - "10443:443"	# drone 服务:HTTPS
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock	# 本地docker
      - /data/docker_test/drone:/var/lib/drone/	# 挂载卷
    restart: always
    environment:
      - TZ=Asia/Shanghai
      - DRONE_OPEN=true
      - DRONE_GOGS_SERVER=http://服务器host:9999/	# 不同的代码仓库对应不同的key, v: 服务器仓库地址
      - DRONE_SERVER_HOST=服务器host:10080 # drone 的server端地址
      - DRONE_SERVER_PROTO=http
      - DRONE_LOGS_TRACE=true
      - DRONE_LOGS_DEBUG=true
      - DRONE_GOGS=true
      - DRONE_PROVIDER=gogs	# 代码仓库
      - DRONE_RPC_SECRET=2cbdaab90813f3743dc700816a322c62  # 秘钥与runner一致
      - DRONE_USER_CREATE=username:管理员账户,admin:true	# 设置管理员账户, 与gogs一致, 否则无法使用缓存
  
  # drone runner 端, 用于执行pipeline
  drone-runner:
    image: drone/drone-runner-docker:1
    container_name: drone-docker-runner	# docker 与 ssh 有不同的runner
    restart: always
    ports:
      - 10082:3000	# 端口映射
    depends_on:
      - drone	# server端先构建启动
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock	# 本机docker
    environment:
      - TZ=Asia/Shanghai
      - DRONE_DEBUG=true
      - DRONE_RPC_SECRET=2cbdaab90813f3743dc700816a322c62	# 秘钥与server端一致
      - DRONE_RPC_HOST=服务器host:10080	# server端
      - DRONE_RPC_PROTO=http
      - DRONE_RUNNER_CAPACITY=2
      - DRONE_RUNNER_NAME=drone-runner

配置mysql服务或容器

使用自家的mysql, 或者新建容器(我直接新建容器测试的)

mkdir -p /etc/opt/cicd_data/mysql/conf
mkdir -p /etc/opt/cicd_data/mysql/logs
mkdir -p /etc/opt/cicd_data/mysql/data
      
docker run --restart=always \
    -p 3308:3306 --name gogs_mysql	\
    -v /etc/opt/cicd_data/mysql/conf:/etc/mysql  \
    -v /etc/opt/cicd_data/mysql/logs:/var/log/mysql	\
    -v /etc/opt/cicd_data/mysql/data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=admin	\
    -e MYSQL_DATABASE=gogs	\
    -e MYSQL_USER=gogs	\
    -e MYSQL_PASSWORD=123456	\
    -e TZ="Asia/Shanghai"	\
    -d mysql:5.7
构建
docker-compose up -d

# 输入 DRONE_SERVER_HOST 配置的地址, 就可以进入系统进行使用了

gogs设置

访问 gogs web页面, 进行数据库及基础设置

数据库类型:
	mysql
	
数据库主机用户密码库等信息:
	上面配置的mysql服务或容器地址 ip:3308
	
运行系统用户:
	root

域名:
	你的域名或ip
	
ssh端口:
	1022

HTTP 端口:
	9999

应用 url:
	http://ip:9999/

配置管理员账户:
	test_admin : test_admin
	# 限制不能使用 admin 为管理员账号名
	

用户设置, 添加ssh秘钥

查看本机秘钥
	cd  ~/.ssh
	cat id_rsa.pub

创建仓库并提交代码

drone 设置
- 访问drone web页面
	服务器host:10080
- 使用 gogs 管理员账户登录

- 配置 settings - Webhooks 
	可以看到 gogs 仓库中项目已同步

- 进入gogs: 代码仓库 - 仓库设置 - 管理web钩子
	可以测试推送结果及请求
	
- 配置 settings - Webhooks - trusted
	使用挂载功能
	设置 secrets (如有)
编写 .drone.yml 文件

对于 Drone 来说, 最核心的就是 .drone.yml文件, 里面定义了所有的流程 step

下面以部署go项目为例

部署Go项目触发CI

 使用以下文件需要提前定义 `drone secret`
 
    DDTOKEN: 钉钉机器人token
    REGISTRY_HUB_USER: dockerhub 用户名
    REGISTRY_HUB_PWD: dockerhub 密码
    SSH_HOST: 服务器地址
    SSH_NAME: 服务器用户名
    SSH_PWD: 服务器密码
.drone.yml
kind: pipeline
type: docker # 使用docker
name: demo-go # 指定项目名称


steps:
  # 编译测试
  - name: build
    image: golang:alpine  # 本项目是golang项目, 所以使用go镜像
    pull: if-not-exists
    environment:
      GOPROXY: "https://goproxy.cn,direct"
      CGO_ENABLED: "0"    # 指定不使用cgo
     volumes:	# 临时卷
      - name: gopath
          path: /go
    commands:
      - go build    # 执行编译命令
      - go test

  # 构建镜像
  - name: publish
    image: plugins/docker  # 构建docker镜像专用镜像
    pull: if-not-exists # 默认always,指定if-not-exists或never可以大幅度提高速度,pull在中国很费时
    settings: # plugins/docker用到的相关配置
      dockerfile: ./Dockerfile	# dockerfile 所在地址
      username:
        from_secret: REGISTRY_HUB_USER   # 指定的docker hub的用户名(前面配置)
      password:
        from_secret: REGISTRY_HUB_PWD   # 指定的docker hub的密码(前面配置)
      repo: 镜像仓库/test   # 要推送构建的镜像名字
      # registry: https://harbor.kikakika.com # 如果使用自建的镜像仓库,例如 Harbor,这里可以通过 registry 指定
      tags: latest  # docker的tag值版本号 latest

  # 部署容器
  - name: deploy
    image: appleboy/drone-ssh # 需要登录ssh服务器, 进行镜像拉取部署
    pull: if-not-exists
    settings:
      host:
        from_secret: SSH_HOST # from_secret 敏感信息请使用 drone secret
      port: 22
      username:
        from_secret: SSH_NAME
      password:
        from_secret: SSH_PWD
      script:
        - image=镜像仓库/go_vmp:latest
        - docker pull $image
        - docker rm -f go_vmp_server || true
        - docker image prune -f
        - docker run -d -p 8080:8080 -v /data/docker_test/go_vmp/log:/app/log --name go_vmp_server $image

  # 钉钉通知
  - name: dingtalk
    image: guoxudongdocker/drone-dingtalk    # 钉钉通知专用镜像
    settings:
      token:
        from_secret: DDTOKEN     # 钉钉的token(前面配置)
      type: markdown
      message_color: true
      message_pic: true
      sha_link: true
    when:
      status: [failure, success]   # 不管成功与否都发通知

volumes:
  - name: deps
    temp: {}
  - name: dockersock
    host:
      path: /var/run/docker.sock
      
trigger:
  branch:
    - master   # master分支收到推送就触发
    

以上 yml 文件定义了4个step, 并在master分支上触发

build:
	执行 test 与 build 

publish:
	构建镜像, 并发布至docker_bub 镜像仓库(后期可自建)

deploy:	
	拉取镜像仓库中的镜像, 删除旧容器, 运行新镜像.

dingtalk:
	钉钉群通知, 无论成功还是失败.
	

踩坑点

配置文件重启
修改了 api.ini 文件后, 我们需要进行应用的重启来加载文件

但是重启后会有异常报错

原因: 
	应用使用的是docker进行启动
	而api.ini文件在我们 web install 界面已经进行了修改, 把端口映射成了我们的容器的指定值(9000:3000). 
	但此时重启, 应用暴露的端口理应是3000, 可文件中是修改之后的9000, 所以出现异常
	所以, 进入容器后, 修改 vi /data/gogs/conf/app.ini 文件
        将 HTTP_PORT 改成 3000
        然后再重启
ssh仓库clone
由于配置了域名, 导致clone出现问题, 配置要主要, 不要遗漏

由于宿主机的端口20被sshd占用, 所以我们gogs只能使用其他端口映射 gogs 容器的20端口. 
因此, ssh仓库clone代码时会有 域名:端口 出现, 如果想要去除域名, 官网我没找到方法, 可以借鉴以下的方式:

	https://discuss.gogs.io/t/ssh-git-clone-fatal-xxx-vscode-git-does-not-appear-to-be-a-git-repository/2594
	https://www.jianshu.com/p/831d29b5d598
你的 SSH 根本不是直连 Docker 容器的,所以你不可能连得上,只能使用 HTTP/HTTPS 进行访问。除非运行 Gogs 的 Docker 容器 expose 端口 22,但是这样你宿主的 SSHD 就凉凉了。如果你尝试 expose 宿主的其它端口到 Docker 容器的端口 22 的话,应该还是可以通过 SSH 访问的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值