当前位置: 首页 > news >正文

开源CICD工具-Drone

目录

一.简介

二.组件介绍

Drone Server(调度与管理中心)

Drone Runner(任务执行者)

三.配置部署

3.1 配置Gitee

设置仓库Webhooks

设置Gitee第三方应用

仓库中添加配置文件

3.2 部署Drone Server和Drone Runner

Drone Server

Drone Runner

3.3 初始化Drone Web UI

 3.4 测试


一.简介

        在现代软件开发流程中,持续集成(CI)与持续部署(CD)已成为团队快速交付与稳定迭代的关键环节。
        Drone作为一个轻量级、云原生的 CI/CD 系统,以其容器化、易扩展、高度自动化的特性,被越来越多团队用于替代传统的Jenkins、GitLab CI等工具。

        本文将介绍一个基于Drone + GitLab + Harbor + Kubernetes的完整自动化构建与部署架构,帮助开发者实现从代码提交到应用上线的全自动流水线。

        整个CI&CD流程如上面数据访问流所示:

        1.当开发者向代码仓库推送代码或合并分支时,代码仓库通过Webhook通知Drone Server;
        2.Drone Server分配任务给Drone Runner执行代码拉取、编译构建、生成容器镜像、推送到容器仓库、部署到Kubernetes或者服务器上、自定义的测试验证脚本等;
        整个过程完全自动化,构建日志和执行状态可通过Drone Web UI实时查看。

二.组件介绍

Drone Server(调度与管理中心)

        Drone Server是整个流水线的核心调度控制器,主要功能包括:

  • 接收来自GitLab等代码仓库的Webhook请求;

  • 校验签名与权限;

  • 解析项目根目录下的 .drone.yml配置文件;

  • 调度Drone Runner执行任务;

  • 提供Web UI用于实时查看:

    • 仓库与分支列表;

    • 构建历史与执行日志;

    • 每个步骤的状态(成功 / 失败 / 执行中)。

        Server与Runner之间通过gRPC / HTTP API通信,并使用DRONE_RPC_SECRET进行身份认证。

Drone Runner(任务执行者)

        Drone Runner是一个常驻的执行代理,负责从Drone Server拉取构建任务并启动实际的执行环境。它本身并不直接执行构建步骤,而是根据 .drone.yml文件的内容,动态创建临时容器(或 Kubernetes Pod) 来完成各个步骤的操作。

        整个过程如下:

  1. 拉取任务:Drone Runner从Drone Server轮询新的构建请求;

  2. 准备环境:为本次构建创建一个隔离的执行环境(Docker容器或 K8s Pod);

  3. 执行步骤:按照 .drone.yml中定义的每个step,依次启动临时容器执行任务;

  4. 上报结果:任务执行完毕后,Runner收集所有步骤的日志与状态,通过gRPC / HTTP回传给Drone Server;

  5. 清理环境:临时容器或Pod自动销毁,确保环境干净、可复用。

        Drone Runner 支持多实例并行运行,不同Runner可通过标签(Label)区分职责,这样既保证了任务隔离,又能提升整个CI&CD集群的执行效率。

三.配置部署

        我们以Kubernetes和Gitee代码库为例来演示整个Drone环境的搭建并测试CI&CD流程。

        首先规划一个可供访问的域名,来代理Drone Server的Webhook,例如https://drone.fzwtest.xyz,虽然是个人测试环境,但为了保证安全性,我们只允许来自Gitee的出口IP地址段访问Drone的443端口。

3.1 配置Gitee

        创建一个用来测试的代码仓库,然后做如下配置

设置仓库Webhooks

 

设置Gitee第三方应用

        注意这是全局设置,不是代码仓库的设置,用来允许Drone Server回调Gitee API

仓库中添加配置文件

        如下图所示,.drone.yml中定义CI&CD要执行的命令,Dockerfile和Kubernetes-cd.yaml是本次示例的.drone.yml用到的两个文件(根据实际情况添加)

        .drone.yml文件内容如下,其中git clone阶段选择自定义执行命令,没有用它的集成组件:

kind: pipeline
type: kubernetes
name: cidemo
metadata:namespace: drone
service_account_name: drone-ci
clone:disable: truesteps:- name: ci-Gitcloneimage: alpine/gitenvironment:SSH_PRIVATE_KEY:from_secret: ssh_private_keycommands:- echo "beginclone"- mkdir -p ~/.ssh- echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa- chmod 600 ~/.ssh/id_rsa- ssh-keyscan -H gitee.com >> ~/.ssh/known_hosts- git clone git@gitee.com:fan-zhiwei1211/fund-distribution.git;cd fund-distribution && git checkout dev- cp -r . ../- echo "endclone"- echo `date +"%Y-%m-%d_%H-%M-%S"`","`git rev-parse HEAD | cut -c 1-7` > /drone/src/.tags- cat /drone/src/.tags- name: ci-ImagePushimage: docker:20.10-dindprivileged: trueenvironment:DOCKER_USERNAME:from_secret: DOCKER_USERNAMEDOCKER_PASSWORD:from_secret: DOCKER_PASSWORDvolumes:- name: dockersockhost:path: /var/runcommands:- dockerd-entrypoint.sh &  # 启动 docker daemon- sleep 10- docker version- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin crpi-d7xhghcft4dbtjor.cn-beijing.personal.cr.aliyuncs.com- TAG=$(cut -d ',' -f 1 /drone/src/.tags)- echo "Using tag:$TAG"- docker build -t crpi-d7xhghcft4dbtjor.cn-beijing.personal.cr.aliyuncs.com/dronefzw/fund-distribution:$TAG .- docker push crpi-d7xhghcft4dbtjor.cn-beijing.personal.cr.aliyuncs.com/dronefzw/fund-distribution:$TAG- name: cd-DeployToK8simage: bitnami/kubectlworking_dir: /drone/srcprivileged: trueenvironment:myuser:from_secret: DOCKER_USERNAMEmypass:from_secret: DOCKER_PASSWORDcommands:- pwd && ls /drone/src/- sed -i "s|IMAGE_TAG|`cat /drone/src/.tags |cut -d "," -f 1`|g" /drone/src/kubernetes-cd.yaml- kubectl apply -f /drone/src/kubernetes-cd.yaml- kubectl rollout status deployment/fund-distribution -n dev --timeout=10s- kubectl get pod -l app=fund-distribution -n dev -o wide- name: cd-test-api-with-curlimage: curlimages/curl:latestcommands:- |echo "开始测试API..."sleep 10RESPONSE_CODE=$(curl -o /dev/null -s -w "%{http_code}" http://fund-distribution.dev.svc.cluster.local:8124/)echo "获取到状态码: $RESPONSE_CODE" if [ "$RESPONSE_CODE" != "200" ]; thenecho "测试失败,状态码: $RESPONSE_CODE (期望200)" >&2exit 1  # 明确返回非0状态码elseecho "测试通过"fitrigger:event:- pushbranches:- dev

        Dockerfile内容如下:

# 使用轻量级基础镜像
#FROM docker.m.daocloud.io/library/python:3.11-slim
FROM crpi-d7xhghcft4dbtjor.cn-beijing.personal.cr.aliyuncs.com/dronefzw/fund-distribution:basic
WORKDIR /app
# 复制所有文件到容器中
COPY . /app# 安装依赖(如果你有 requirements.txt)
#RUN pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
# 暴露 80 端口
EXPOSE 8888# 启动 nginx
CMD ["python3", "run.py"]

        kubernetes-cd.yaml内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:name: fund-distributionnamespace: dev
spec:replicas: 1selector:matchLabels:app: fund-distributiontemplate:metadata:labels:app: fund-distributionspec:imagePullSecrets:- name: acr-plaintext-secretcontainers:- name: fund-distributionimage: crpi-d7xhghcft4dbtjor.cn-beijing.personal.cr.aliyuncs.com/dronefzw/fund-distribution:IMAGE_TAGports:- containerPort: 8888---
apiVersion: v1
kind: Service
metadata:name: fund-distributionnamespace: dev
spec:selector:app: fund-distributionports:- protocol: TCPport: 8124targetPort: 8888nodePort: 32669type: NodePort

3.2 部署Drone Server和Drone Runner

Drone Server

apiVersion: v1
kind: ServiceAccount
metadata:name: drone-cinamespace: drone
automountServiceAccountToken: true
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:name: drone-secrets-managernamespace: drone
rules:
- apiGroups: [""]resources: ["pods", "pods/log", "pods/exec","secrets"]verbs: ["get", "create","update", "delete","list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: drone-secrets-bindingnamespace: drone
subjects:
- kind: ServiceAccountname: drone-cinamespace: drone
roleRef:kind: Rolename: drone-secrets-managerapiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: docker-sock-access
rules:
- apiGroups: [""]resources: ["nodes/proxy"]verbs: ["get", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: drone-docker-access
subjects:
- kind: ServiceAccountname: drone-cinamespace: drone
roleRef:kind: ClusterRolename: docker-sock-accessapiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:name: drone-ci-rolenamespace: dev  # 注意:需要与测试用例部署的namespace一致
rules:
- apiGroups: ["apps", ""]resources: ["deployments", "pods", "services"]verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: drone-ci-rolebindingnamespace: dev # 注意:需要与测试用例部署的namespace一致
subjects:
- kind: ServiceAccountname: drone-cinamespace: drone
roleRef:kind: Rolename: drone-ci-roleapiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ConfigMap
metadata:name: drone-confignamespace: drone
data:DRONE_GITEE_CLIENT_ID: "xxxxxxxxx" #自行修改DRONE_GITEE_CLIENT_SECRET: "xxxxxxxxxx" #自行修改DRONE_GITEE_SECRET:"xxxxxxxxxx"  #自行修改,可选配置DRONE_RPC_SECRET: "sdsgrgty54t4rereer"DRONE_SERVER_HOST: "drone.fzwtest.xyz"DRONE_SERVER_PROTO: "https"DRONE_SERVER_PORT: ":80"DRONE_LOGS_DEBUG: "true"DRONE_USER_CREATE: "username:fan-zhiwei1211_admin,admin:true"
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: drone-ingressnamespace: droneannotations:cert-manager.io/cluster-issuer: "letsencrypt-prod"nginx.ingress.kubernetes.io/backend-protocol: "HTTP"nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:ingressClassName: nginxtls:- hosts:- drone.fzwtest.xyzsecretName: drone-tlssrules:- host: drone.fzwtest.xyzhttp:paths:- path: /pathType: Prefixbackend:service:name: drone-serverport:number: 80
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: drone-pvcnamespace: drone
spec:accessModes:- ReadWriteOnceresources:requests:storage: 5Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:name: drone-servernamespace: drone
spec:replicas: 1selector:matchLabels:app: drone-servertemplate:metadata:labels:app: drone-serverspec:serviceAccountName: drone-cicontainers:- name: drone-serverimage: drone/drone:2.17envFrom:- configMapRef:name: drone-configsecurityContext:runAsUser: 0capabilities:add: ["NET_BIND_SERVICE"]  # 允许绑定特权端口ports:- containerPort: 80volumeMounts:- name: drone-datamountPath: /datavolumes:- name: drone-datapersistentVolumeClaim:claimName: drone-pvc---
apiVersion: v1
kind: Service
metadata:name: drone-servernamespace: drone
spec:ports:- port: 80targetPort: 80name: http- port: 443targetPort: 443name: httpsselector:app: drone-server

Drone Runner

apiVersion: v1
kind: Secret
metadata:name: acr-plaintext-secretnamespace: dev  # 按需修改命名空间
type: kubernetes.io/dockerconfigjson
stringData:  # 注意这里使用 stringData 而非 data.dockerconfigjson: |{"auths": {"crpi-d7xhghcft4dbtjor.cn-beijing.personal.cr.aliyuncs.com": {"username": "xxxx", #容器仓库鉴权,自行修改"password": "xxxxxxx", #容器仓库鉴权,自行修改"auth": "xxxxxxxx" #容器仓库鉴权,自行修改}}}
---
apiVersion: apps/v1
kind: Deployment
metadata:name: drone-runnernamespace: drone
spec:replicas: 1selector:matchLabels:app: drone-runnertemplate:metadata:labels:app: drone-runnerspec:serviceAccountName: drone-cicontainers:- name: drone-runnerimage: drone/drone-runner-kube:latestenv:- name: DRONE_RPC_HOSTvalue: "drone-server.drone.svc.cluster.local"  # K8S 内部 Service 地址- name: DRONE_RPC_SECRETvalueFrom:configMapKeyRef:name: drone-configkey: DRONE_RPC_SECRET- name: DRONE_RUNNER_CAPACITYvalue: "2"- name: DRONE_RUNNER_PRIVILEGED_IMAGESvalue: "plugins/docker,appleboy/drone-docker"

        部署到Kubernetes中,确保服务运行正常:

# kubectl get pod -n drone
NAME                            READY   STATUS    RESTARTS   AGE
drone-runner-f5cd6496b-s7wbl    1/1     Running   0          31s
drone-server-6c6d4d778b-5tzrv   1/1     Running   0          33s

3.3 初始化Drone Web UI

        登录Drone的域名 https://drone.fzwtest.xyz/ 并同意授权,进入操作页面

        可以点击SYNC同步仓库,点击我们的示例仓库,激活CI&CD集成

        可以添加自己需要的Secrets,用来.drone.yml的参数调用。例如我们示例中的DOCKER_USERNAME和DOCKER_PASSWORD以及ssh_private_key

 3.4 测试

        现在提交代码到dev分支,会看到自动触发了CI&CD流程,并且能看到.drone.yml中定义的几个step的执行日志。

        查看我们的测试服务已经成功部署

# kubectl get pod -n dev
NAME                                READY   STATUS    RESTARTS   AGE
fund-distribution-9478b5f84-825h7   1/1     Running   0          28m

http://www.dtcms.com/a/605352.html

相关文章:

  • 给予虚拟成像台尝鲜版十之二,完善支持 HTML 原型模式
  • 原生表格文本过长展示问题,参考layui长文本,点击出现文本域
  • 桂林网站建设培训asp.net网站建设
  • Ubuntu 24.04 MariaDB 完整安装与配置文档
  • [特殊字符] 在 Linux 上设置 SQLite
  • Arbess从初级到进阶(2) - 使用Arbess+GitLab实现Vue.js项目自动化部署
  • 网站开发外文参考文献邯郸小学网站建设
  • C语言编译器最新版 | 提升开发效率,优化性能
  • 手游网站怎么做企业型网站
  • 用Rust实现二进制文件差异工具
  • 代理IP的匿名性测试:如何验证你的真实IP是否已泄露?
  • FreeRTOS 在 AS32系列RISC-V 架构MCU电机驱动中的应用实践与优化
  • 【OpenCV + VS】 图像像素类型转换与归一化
  • 用 Rust 写一个可落地的目录实时监听器:跨平台文件系统事件的可靠表达与工程实践
  • Linux网络--Socket 编程 TCP
  • 【一文了解】C#反射
  • 网站建设seo推广外贸网站建设海外推广
  • 网站ip域名查询安徽省住房城乡建设厅网站电工
  • 202511-Selenium技术深度解析:Web自动化测试的王者之路
  • Android 打开 在线 pdf 文件
  • Python 教程:如何快速在 PDF 中添加水印(文字、图片)
  • 普中51单片机学习笔记-矩阵按键
  • 视觉语言模型新突破!开源项目解读
  • 深圳南山区住房和建设局网站官网天天向上做图网站
  • 微算法科技(NASDAQ MLGO)通过容量证明(PoC)构建全球存储资源池,为Web3应用提供低成本、抗审查的数据存储服务
  • 08-微服务原理篇(Canal-Redis)
  • 填写网站备案信息深圳建设材料价格网站
  • 【Spring Boot 报错已解决】Spring Boot开发避坑指南:Hibernate实体类主键配置详解与异常修复
  • 【CSS】cursor: auto, default, none 有什么区别?
  • 网站备案负责人三网合一营销型全网站