• 私有化轻量级持续集成部署方案--05-持续部署服务-Drone(上)


    提示:本系列笔记全部存在于 Github, 可以直接在 Github 查看全部笔记

    持续部署概述#

    持续部署是能以自动化方式,频繁而且持续性的,将软件部署到生产环境。使软件产品能够快速迭代。

    在之前部署 web 项目时,都是手动进行部署

    拉取代码 ---> 编译项目 ---> 打包镜像 ---> 推送镜像仓库 ---> 服务器拉取新镜像 ---> 停止和移除旧容器 ---> 启动新容器

    这一整套部署步骤枯燥又费时。

    持续部署就是使用工具自动处理整套步骤。代码在提交之后自动执行整套流程将项目部署到生产环境,省去繁琐的人工操作。

    持续部署整套流程本质上是一个极其简单的东西。可以拆解为两个阶段

    1. 打包阶段: 拉取代码 ---> 编译项目 ---> 镜像打包 ---> 推送镜像仓库
    2. 部署阶段: SSH 连接服务器 ---> 拉取新镜像 ---> 停止和移除旧容器 ---> 启动新容器

    未使用自动化部署工具时,整套套也可以使用 .sh 脚本实现半自动化。甚至可以编写一个小程序,自动连接服务器实现全自动化。

    而所谓的持续部署工具本质上做的也是这么一件事,只是提供了更强大更丰富的功能。

    Drone#

    持续部署工具一开始打算使用 GitlabGitlab 中直接集成代码仓库和持续部署工具,用起来会方便很多,但部署完 Gitlab 发现小服务器真心扛不住。

    后也考虑过大名鼎鼎的jenkins,查询资料发现 Jenkins 资源占用也挺大,最后选择了一个轻量级的工具 Drone

    Drone 也是一个优秀、开源的持续部署工具,具有很高的关注度。https://github.com/harness/drone

    不过稍微遗憾的是 Drone 社区不太完善。尤其国内,资料很少。折腾部署时利用 Google 搜索也耗费了不少时间。

    Drone 简介#

    Drone 应用由 Server(服务器)Runner(执行器) 两种服务构成。

    Server(服务器) 主要负责管理和展示, Runner(执行器) 主要负责执行操作。

    Server#

    Server(服务器) 负责的工作主要有

    1. 连接集成代码仓库
    2. 提供 web 管理页面
    3. 管理 Runner

    代码仓库#

    Drone 可以无缝集成多种主流代码仓库,官方给出了具体的使用文档。

    提供 Web 页面#

    Server 负责提供 web 管理页面显示执行情况。

    管理 Runner#

    Server 服务可以与一个或多个 Runner 连接通信进行管理。

    Runner#

    Runner(执行器) 是真正执行持续部署操作服务。Runner 执行时会轮询 Server 来确定执行的操作。

    Drone 官方提供了多种类型的 Runner(执行器),用于适配不同的运行环境。

    SSH Runner 类型 Runner 可以使用容器化管理,所以可以使用 Docker Runner 代替。

    Drone 提供了 管道(Pipeline) 机制,管道(Pipeline) 机制下一篇介绍

    Drone 部署#

    Database#

    Drone 数据存储默认使用 sqlite 数据库。并且提供支持 postgresmysql

    官方文档中强烈建议使用 postgres 而非 mysql。 某些操作在 mysql 未得到优化。 https://docs.drone.io/server/storage/database/

    PS: 支持 postgres9.6 及更高版本 、 mysql:5.6 及更高版本

    Gitea 配置#

    在此直接集成之前部署的 Gitea 仓库, 至于其它仓库,有兴趣的可以查询文档:https://docs.drone.io/server/overview/

    部署 Drone 之前需要先在 Gitea 中添加一个 OAuth 登录密钥, Drone 使用的 OAuth 方式登录。

    登录成功后重定向 URL 地址为 Drone 登录页。 /login 路由。

    PS:注意,此地址必须设置公网可访问地址。

    客户端 ID客户端密钥 保存。 客户端 ID客户端密钥 需要在 Drone 配置中使用

    Dockerfile#

    version: '3.9'
    # 创建自定义网络
    networks:
      drone:
        name: drone
        driver: bridge
    services:
      # 数据库服务
      db:
        image: postgres:latest
        container_name: drone_db
        restart: always
        networks:
          - drone # 加入到drone网络
        ports:
          - '7931:5432'
        environment:
          - POSTGRES_USER=drone # PGSQL默认用户
          - POSTGRES_PASSWORD=drone # PGSQL默认密码
          - POSTGRES_DB=drone # PGSQL默认数据库
        volumes:
          - /volumes/drone/db:/var/lib/postgresql/data
      # Drone Server 服务
      server:
        image: drone/drone:2.8.0 # 目前drone最新版本为 2.8.0
        container_name: drone_server
        restart: always
        networks:
          - drone # 加入到drone网络
        ports:
          - '7929:80'
        environment:
          - DRONE_SERVER_PROTO=http # 访问协议,创建webHooks和重定向
          - DRONE_SERVER_HOST=82.157.55.94:7929 # 主机名称,创建webHooks和重定向
          - DRONE_RPC_SECRET=e1ad8a7f3dbc68ca9c21bcc949335009 # 与 drone runner 通讯的密钥
          - DRONE_USER_CREATE=username:yxs970707,admin:true # 管理员账户
          - DRONE_DATABASE_DRIVER=postgres # 数据库类型
          - DRONE_DATABASE_DATASOURCE=postgres://drone:drone@db/drone?sslmode=disable # 数据库连接
          - DRONE_GIT_ALWAYS_AUTH=true # 使用 oauth 身份验证信息拉取代码
          - DRONE_GITEA_SERVER=https://gitea.mwjz.live # gitea服务器地址
          - DRONE_GITEA_CLIENT_ID=2c921d85-e40e-41f8-90e0-c77c383786b5 # gitea 客户端 id
          - DRONE_GITEA_CLIENT_SECRET=ZVZoRWK6jR5mqgAIm6sB5VX6C2LPK1sYKv4hQWyTdULu # gitea 客户端 密钥
          - DRONE_GITEA_SKIP_VERIFY=false # 禁用 gitea 链接时 tls 验证
    
        volumes:
          - /volumes/drone/server:/data
          - /var/run/docker.sock:/var/run/docker.sock
        depends_on:
          - db
      # Drone Docker Runner
      runner:
        image: drone/drone-runner-docker:1.8.0 # 目前drone-runner-docker最新版本为 1.8.0
        container_name: drone_runner
        restart: always
        networks:
          - drone # 加入到drone网络
        ports:
          - '7930:3000'
        environment:
          - DRONE_RUNNER_NAME=docker-runner
          - DRONE_RUNNER_CAPACITY=10 # 限制runner可执行的并发管道数量
          - DRONE_RPC_PROTO=http # 访问drone server 协议
          - DRONE_RPC_HOST=server # 访问drone server 服务器地址
          - DRONE_RPC_SECRET=e1ad8a7f3dbc68ca9c21bcc949335009 # 与 drone server 通讯的密钥
          - DRONE_UI_USERNAME=yxs970707 # Drone Runner 的 UI 用户账号
          - DRONE_UI_PASSWORD=yxs970707 # Drone Runner 的 UI 用户密码
        volumes:
          - '/var/run/docker.sock:/var/run/docker.sock'
        depends_on:
          - server
    

    Dockerfile 中部署了三个服务:

    • 数据库(postgres)
    • Server(drone/drone:2.8.0)
    • Runner(drone/drone-runner-docker:1.8.0)

    数据库使用的是 postgres。三个服务之间通信使用的是自定义 network

    PS: 多个应用服务可以共享同一个数据库服务,也可以创建独立的数据库服务。在当前服务器中,Gitea 应用和 Drone 应用创建了各自独立的数据库服务,这种方式会浪费一些服务器资源。但是维护起来比较方便。
    具体采用哪种方案可以根据不同场景选择

    部署 Droneenvironment 属性有些麻烦,在此简单介绍下某些属性。

    Server#

    DRONE_SERVER_PROTO 、 DRONE_SERVER_HOST#

    这两个属性是设置 Webhook 重定向 URL 的访问协议和主机名称。 Webhook 在下面会介绍到。

    DRONE_RPC_SECRET#

    此属性是设置 Server(服务器)Runner(执行器) 之间通讯的密钥,Server(服务器)Runner(执行器) 必须设置相同的密钥值才允许通信。

    可以在 服务器(Linux) 中使用 openssl 生成密钥

    openssl rand -hex 16

    DRONE_USER_CREATE#

    此属性是设置 Drone 管理员。

    注意:username 必须设置为 OAuth 用户(Gitea 的用户名),否则不具有管理员权限。

    非管理员会少部分功能,例如不许设置 Trusted 属性

    DRONE_DATABASE_DRIVER 、 DRONE_DATABASE_DATASOURCE#

    这两个属性是设置数据库类型和数据库连接。

    具体连接配置可以参考官方文档

    DRONE_GIT_ALWAYS_AUTH#

    此属性是设置 OAuth 登录用户进行拉取代码

    默认情况下 OAuth 只作用于登录操作。但存储库设置为私有时,需要登录用户才允许拉取代码,此时需要将此属性设置为 true

    可以参考 https://discourse.drone.io/t/fatal-could-not-read-username-for/6198

    默认值为 false

    DRONE_GITEA_SERVER 、 DRONE_GITEA_CLIENT_ID 、DRONE_GITEA_CLIENT_SECRET#

    这几个属性是设置 Gitea 地址和 OAuth ID、密钥。

    DRONE_GITEA_SKIP_VERIFY#

    此属性是设置禁用 GiteaTLS 验证,

    此属性为 false 时,当 Gitea 使用 HTTPS 协议但证书有问题,会出现授权验证失败,报 x509 错误。

    下图是将 网关(Nginx)Gitea 证书特意处理无效后进行的授权验证测试。 有兴趣的朋友可以自行测试。

    当存储库使用 HTTPS 协议但没有证书情况下,此属性设置设置为 true 跳过 TLS 验证。

    默认值为 false

    Runner#

    DRONE_RUNNER_CAPACITY#

    此属性是设置 Runner(执行器) 并发管道数量

    默认值为 2

    DRONE_RPC_PROTO 、DRONE_RPC_HOST#

    这两个属性设置通信 Server(服务器) 的协议和主机名。 主机名使用 server-name

    DRONE_UI_USERNAME、DRONE_UI_PASSWORD#

    Runner(执行器) 也具有 UI 展示页面,可以查看当前执行器的执行信息。这两个属性是设置 UI 展示页面的用户名称和密码

    执行部署#

    使用 Dockerfile 进行部署,大概率不会出现问题,我进行了多次测试,

    但部署 Drone 难免会碰到问题,每个人碰到的问题还不尽相同。所以需要善用 Google 查询

    部署成功后访问,会跳转到欢迎页面,点击按钮就会进行 Gitea 登录

    登录成功后会跳转到主页面,主页面上只有一项,就是 Gitea 中目前的存储库(web),这个存储库当前为未激活状态。

    未激活情况下进入当前项目会跳转到 settings 页面,当前页面具有一个激活按钮,点击就可以激活此存储库

    激活后会向 Gitea 注入一个 Webhook

    这个 Webhook 会监听仓库的变更情况,当代码仓库发生变化时, Webhook会向 Drone 推送消息。

    Drone 接收到消息之后便可以执行,这也就是持续部署的第一步。

    Drone 设置#

    激活完毕之后 settings 页面就会出现很多设置

    Protected#

    此属性是设置 是否要验证 配置文件(.drone.yml) 中的签名,开启后签名验证错误则不允许构建

    Trusted#

    此属性设置是否允许使用挂载权限,挂载在之后会介绍。

    不开通此权限,volumes 挂 host path 时报 Linter: untrusted repositories cannot mount host volumes 错误

    注意:非管理员用户不具有此属性。

    Auto cancel pushes、Auto cancel running#

    这两个属性是优化操作的属性。

    开启这两个属性,当执行构建任务时,会自动取消之前未执行完毕的构建任务。

    当合并多个 commit 时,这个属性具有很好的效果。

    Timeout、Configuration#

    timeout 是设置构建任务执行的超时时间。

    Configuration 是设置配置文件文件,默认为 .drone.yml。 这个一般不需要改动。

    PS: 注意:配置文件必须设置根目录

    Secrets#

    secrets 是用来设置敏感属性的。

    编写配置时,有些敏感数据需要隐藏,如账号密码,这些属性可以配置 Secrets 使用

    测试执行#

    现在对 Giteaweb 项目提交就可以触发 Webhook 发送消息,

    也可以在 Gitea 中主动触发 Webhook测试

    但当前推送会返回一个 context deadline exceeded (Client.Timeout exceeded while awaiting headers) 错误。

    这个错误是因为根目录中没有找到 配置文件(.drone.yml)

    https://discourse.gitea.io/t/client-timeout-exceeded-while-awaiting-headers/4148/4

    在根目录创建 .drone.yml 文件并添加了一个测试配置,配置文件中内容下一篇介绍

    kind: pipeline # 定义一个管道
    type: docker # 当前管道的类型
    name: test # 当前管道的名称
    steps: # 定义管道的执行步骤
      - name: test # 步骤名称
        image: node:latest # 当前步骤使用的镜像
        commands: # 当前步骤执行的命令
          - echo 测试drone执行
    

    提交代码,Webhook 会主动推送到 DroneDrone 会成功构建任务。

    PS:有可能还是会推送失败或者构建失败,可能会发生各种各样的问题。

    在页面中, 具有两个 steps,这是因为默认第一个会拉取仓库代码,当然这个操作也可以禁用。

    网关配置#

    
    server {
        #SSL 访问端口号为 443
        listen 443 ssl http2;
        #填写绑定证书的域名
        server_name drone.mwjz.live;
        #日志
        error_log /var/log/nginx/drone/error.log;
        access_log /var/log/nginx/drone/access.log;
        #证书文件
        ssl_certificate /etc/nginx/conf.d/ssl/drone/drone.mwjz.live_bundle.crt;
        #证书密钥文件
        ssl_certificate_key /etc/nginx/conf.d/ssl/drone/drone.mwjz.live.key;
    
        ssl_ciphers SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!3DES:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        location / {
            proxy_pass http://10.0.24.12:7929;
        }
    }
    

    Drone 方面,我没有找到怎么修改配置,所以直接使用了暴力方式,重新部署。

    部署的时候不需要清理 volume, 不清理重新部署还会保留之前的记录,当然也可以清理后重新部署。

    如果没有删除 volume的话,需要在 Gitea 中手动修改一下 Webhook 的推送地址

    server:
      image: drone/drone:2.8.0 # 目前drone最新版本为 2.8.0
      container_name: drone_server
      restart: always
      networks:
        - drone # 加入到drone网络
      ports:
        - '7929:80'
      environment:
        - DRONE_SERVER_PROTO=https # 访问协议,创建webHooks和重定向
        - DRONE_SERVER_HOST=drone.mwjz.live # 主机名称,创建webHooks和重定向
    

    无证书 HTTPS 触发 Webhook#

    在部署时碰到这样一种情况,当 Drone 使用 HTTPS 但是没有证书情况下,Webhook 推送也会出现 X509 错误。

    解决这个问题需要设置 Gitea 的配置, 在 /data/gitea/conf/app.ini 配置文件中设置跳过验证

    [webhook]
    SKIP_TLS_VERIFY = true
    

    也可以在部署 Gitea时直接添加在 Dockerfileenvironment 属性

    #gitea服务
    server:
      image: gitea/gitea:latest
      container_name: gitea_server
      restart: always
      environment:
        - GITEA__webhook__SKIP_TLS_VERIFY=true # webhook 跳过 tls 验证
        - GITEA__webhook__DELIVER_TIMEOUT=10 # webhook 超时时间
    
  • 相关阅读:
    git 快速构造10个文件
    SI522国产13.56MHz读卡NFC芯片QFN32兼容替代RC522
    Vue3 企业级优雅实战 - 组件库框架 - 4 组件库的 CSS 架构
    zabbix5 使用自动发现对端口进行监控
    实至名归!优维科技荣膺NIISA联盟2022年度双项技术创新奖
    JS面向对象---原型链继承
    云服务器ECS安装Mysql、JDK、RocketMQ
    Integer包装类常用方法和属性
    PyCharm运行python测试,报错“没有发现测试”/“空套件”
    机械工程基础知识点汇总
  • 原文地址:https://www.cnblogs.com/yan7/p/15881087.html