0%

Gitea+Drone+Rancher CI/CD持续集成解决方案Gitea 关于Gitea Gitea 是一个自己托管 - 掘金

Excerpt

Gitea 关于Gitea Gitea 是一个自己托管的Git服务程序。他和GitHub, Bitbucket or Gitlab等比较类似。他是从 Gogs 发展而来,Gitea 是一个开源社区驱动


关于Gitea

Gitea 是一个自己托管的Git服务程序。他和GitHub, Bitbucket or Gitlab等比较类似。他是从 Gogs 发展而来,Gitea 是一个开源社区驱动的轻量级代码托管解决方案,采用 MIT 许可证。极易安装,运行非常快速,安装和使用体验良好的自建 Git 服务。并且他还支持跨平台,支持 Linux, macOS 和 Windows 以及各种架构,除了x86,amd64,还包括 ARM 和 PowerPC。

系统要求

  • 最低的系统硬件要求为一个廉价的树莓派
  • 如果用于团队项目,建议使用 2 核 CPU 及 1GB 内存

功能特性

  • 支持活动时间线
  • 支持 SSH 以及 HTTP/HTTPS 协议
  • 支持 SMTP、LDAP 和反向代理的用户认证
  • 支持反向代理子路径
  • 支持用户、组织和仓库管理系统
  • 支持添加和删除仓库协作者
  • 支持仓库和组织级别 Web 钩子(包括 Slack 集成)
  • 支持仓库 Git 钩子和部署密钥
  • 支持仓库工单(Issue)、合并请求(Pull Request)以及 Wiki
  • 支持迁移和镜像仓库以及它的 Wiki
  • 支持在线编辑仓库文件和 Wiki
  • 支持自定义源的 Gravatar 和 Federated Avatar
  • 支持邮件服务
  • 支持后台管理面板
  • 支持 MySQL、PostgreSQL、SQLite3、MSSQL 和 TiDB(MySQL) 数据库
  • 支持多语言本地化(21 种语言)
  • 支持软件包注册中心(Composer/Conan/Container/Generic/Helm/Maven/NPM/Nuget/PyPI/RubyGems)

安装

安装环境依赖

gitea 依赖于docker和docker-compose

安装docker

安装所需的安装包yum-utils:

1
yum install -y yum-utils

添加yum源

1
yum -y update #设置镜像仓库地址 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #更新yum软件包索引 yum makecache fase

查看可用版本

1
yum list docker-ce --showduplicates | sort -r

安装docker社区版和社区办对应的cli工具已经依赖

1
yum install -y docker-ce docker-ce-cli containerd.io

启动 Docker 并设置开机自启

1
systemctl start docker systemctl enable docker

添加镜像源地址

1
tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://uyah70su.mirror.aliyuncs.com"] } EOF

重新启动 Docker 服务

1
<span data-line-num="1">systemctl daemon-reload &amp;&amp; sudo systemctl restart docker</span>

验证配置是否生效

1
docker info | grep Mirrors -A1

安装docker-compose

安装epel源

1
yum install -y epel-release

安装docker-compose

1
<span data-line-num="1">yum install -y docker-compose</span>

安装gitea

安装参考链接:使用 Docker 安装 - Docs

最简单的设置只是创建一个卷和一个网络,然后将 gitea/gitea:latest 镜像作为服务启动。由于没有可用的数据库,因此可以使用 SQLite3 初始化数据库。创建一个类似 gitea 的目录,并将以下内容粘贴到名为 docker-compose.yml 的文件中。

1
version: "3" networks: gitea: external: false services: server: image: gitea/gitea:1.16.7 container_name: gitea environment: - USER_UID=1000 - USER_GID=1000 restart: always networks: - gitea volumes: - /home/data:/data # /home/data可以替换成你想要的挂载目录 - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro ports: - "3030:3000" # 3030可以替换成你想要的端口 - "322:22" # 322可以替换成22

在后台启动

1
<span data-line-num="1">docker-compose up -d</span>

配置gitea

访问 访问:http://server-ip:3030

设置域名访问地址等信息 Snipaste_2022-08-07_13-45-57.png 设置管理员账号密码 Snipaste_2022-08-07_13-49-05.png 点击安装后,系统安装完毕会自动登录

创建测试仓库

创建组织 Snipaste_2022-08-07_14-00-45.png 创建仓库 Snipaste_2022-08-07_13-49-05.png Snipaste_2022-08-07_14-04-35.png 创建一个SpringBoot项目 Snipaste_2022-08-07_14-15-20.png HelloController.java

1
@Slf4j @RestController @RequestMapping("/v1") public class HelloController { @GetMapping("hello") public String SayHello() { log.info("SayHello: hello world!"); return "hello world!"; } }

Dockerfile

1
FROM openjdk:8u332-jdk ENV SERVICE_PORTS=8080 RUN mkdir -p /app/ WORKDIR /app COPY ./start.sh /app/ COPY ./.dockerignore /app/ COPY ./claydemo-0.0.1.jar /app/ RUN chmod 755 -R /app/ ENTRYPOINT ["/app/start.sh"]

start.sh

1
#!/bin/sh java -Xms128m -Xmx128m -jar /app/claydemo*.jar --spring.profiles.active=dev if [ $? != 0 ]; then echo Failed to start java >&2 exit 1 fi

application-dev.properties

1
server.port=8080

Drone

关于Drone

Dron是一个现代化的持续集成平台,它使用强大的云原生pipeline引擎自动化构建、测试和发布工作流。Drone 与多个源代码管理系统无缝集成,包括 GitHub、GitHubEnterprise、Bitbucket、GitLab和Gitea;它的每个构建都在一个隔离的 Docker 容器中运行;另外它也支持插件,可以使用你熟知的语言轻松的扩展它们。

安装

依赖安装

需要安装docker和docker-compose,参照上方安装方式即可

安装Drone

安装参考: Gitea | Drone

此处同样采用docker-compose.yml的方式安装

1
version: '3' services: drone-server: restart: always image: drone/drone:2 ports: - "映射宿主机端口:80" volumes: - 宿主机挂载目录:/var/lib/drone/ - 宿主机挂载目录:/data/ environment: - DRONE_GITEA_SERVER=http://gitea服务器地址 # 支持http, https - DRONE_GITEA_CLIENT_ID=gitea生成的OAuth2客户端ID - DRONE_GITEA_CLIENT_SECRET=gitea生成的OAuth2客户端密钥 - DRONE_SERVER_HOST=drone服务器地址 - DRONE_SERVER_PROTO=http # 支持http, https - DRONE_RPC_SECRET=自定义的Drone与runner通信密钥 - DRONE_GIT_ALWAYS_AUTH=true - DRONE_GIT_USERNAME=部署账户的用户名 - DRONE_GIT_PASSWORD=部署账户的密码 - DRONE_USER_CREATE=username:你的管理员账户名,admin:true # 开启管理员账户 drone-runner-docker: restart: always image: drone/drone-runner-docker:1 ports: - "3000:3000" volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - DRONE_RPC_PROTO=http # 支持http, https - DRONE_RPC_HOST=drone-server - DRONE_RPC_SECRET=自定义的Drone与runner通信密钥 - DRONE_RUNNER_NAME=drone-runner-docker - DRONE_RUNNER_CAPACITY=2

其中需要将gitea的授权信息填写到上方yml文件中

Gitea个人中心的应用设置创建Gitea OAuth application Snipaste_2022-08-07_14-26-05.png 点击创建后将秘钥妥善保管并替换到上面的docker-compose.yml

1
- DRONE_GITEA_CLIENT_ID=gitea生成的OAuth2客户端ID - DRONE_GITEA_CLIENT_SECRET=gitea生成的OAuth2客户端密钥 - DRONE_GIT_USERNAME=令牌名称 - DRONE_GIT_PASSWORD=令牌秘钥

生成Drone与runner通信密钥,并替换上面docker-compose.yml对应的字段

1
openssl rand -hex 16 93b722f581830b9abf11345536b9ecfb

启动drone

1
<span data-line-num="1">docker-compose up -d</span>

访问drone

访问:http://drone-server-domain Snipaste_2022-08-07_14-40-12.png 授权 Snipaste_2022-08-07_15-46-05.png 填写登录信息 7e22dd46559947ada73cb5605487610e.png 登录之后就可以看到刚刚我们gitea中的项目 Snipaste_2022-08-07_15-46-05.png 在设置中激活 1659858792624.png 激活保存 1659858832731.png

使用pipeline

在gitea项目增加.drone.yml文件,内容如下 1659859004218.png drone立马就收到提交事件,并及时构建 1659859026243.png 1659859080002.png

编写一个完整的## pipeline

.drone.yml

1
kind: pipeline type: docker name: claydemo steps: - name: build-jar # 流水线名称 image: maven:3.8.5-openjdk-8 # 定义创建容器的Docker镜像 volumes: # 将容器内目录挂载到宿主机,仓库需要开启Trusted设置 - name: maven-cache path: /root/.m2 # 将maven下载依赖的目录挂载出来,防止重复下载 - name: maven-build path: /app/build # 将应用打包好的Jar和执行脚本挂载出来 commands: # 定义在Docker容器中执行的shell命令 - mvn clean package -DskipTests=true # 应用打包命 - cp target/claydemo-1.0-SNAPSHOT.jar /app/build/claydemo-0.0.1.jar - cp start.sh /app/build/ - cp Dockerfile /app/build/ - cp .dockerignore /app/build/ - cp docker.sh /app/build/ - name: build-docker image: docker volumes: # 将容器内目录挂载到宿主机,仓库需要开启Trusted设置 - name: maven-build path: /app/build # 将应用打包好的Jar和执行脚本挂载出来 - name: docker path: /var/run/docker.sock # 挂载宿主机的docker settings: dockerfile: /app/build/Dockerfile commands: # 定义在Docker容器中执行的shell命令 - cd /app/build - chmod +x docker.sh - sh docker.sh - docker ps volumes: # 定义流水线挂载目录,用于共享数据 - name: maven-build host: path: /home/data/maven/build # 从宿主机中挂载的目录 - name: maven-cache host: path: /home/data/maven/cache - name: docker host: path: /var/run/docker.sock

docker.sh

1
#!/bin/sh # 定义应用组名 group_name='clay' # 定义应用名称 app_name=${DRONE_REPO_NAME} # 定义应用版本 app_version='latest' echo '----copy jar----' docker stop ${app_name} echo '----stop container----' docker rm ${app_name} echo '----rm container----' docker rmi ${group_name}/${app_name}:${app_version} echo '----rm image----' # 打包编译docker镜像 docker build -t ${group_name}/${app_name}:${app_version} . echo '----build image----' docker run -p 8080:8080 --name ${app_name} \ -e TZ="Asia/Shanghai" \ -v /etc/localtime:/etc/localtime \ -d ${group_name}/${app_name}:${app_version} echo '----start container----'

运行结果 1659860404135.png 1659860484624.png

Rancher

Rancher 是供采用容器的团队使用的完整软件堆栈。它解决了管理多个Kubernetes集群的运营和安全挑战,并为DevOps团队提供用于运行容器化工作负载的集成工具。简单来说是一个k8s的管理软件!

安装

rancher的latest版本是2.6以上,本次安装v2.4.15

1
docker run -d --privileged --restart=unless-stopped -p 80:80 -p 443:443 --privileged rancher/rancher:v2.4.15

访问(注意是https) https://ip-server 输入admin 的密码 1659861472908.png 点击下一步,设置rancher的访问url,如果有域名则填写域名 1659861565669.png 进入管理页面 1659861619139.png

添加集群

点击右上角的添加集群 1659861716608.png 选择自定义 1659861756287.png 配置集训信息 1659861839152.png 点击下一步进入添加节点页面,由于当前集群还没有节点,所以主机选项中的每一个角色都需要选择 1659861949108.png 复制下方的命令到装有docker的主机中运行即可,注意rancher安装的主机和其他节点主机的ip都必须为静态ip,不然主机重启后集群就失效了,原因为主机重启后ip变更,k8s不能够通过ip找到对应的节点 1659862145815.png 集群正在添加节点(等待时间很漫长) 1659862165132.png 添加完成 1659862423973.png 1659862458725.png

完成gitea+drone+rancher ci/cd的全链路打通

在此之前已经实现gitea+drone的部署,现在需要完成drone+rancher的对接

drone+rancher

因为drone的pipeline每一个环节都是基于docker运行的,所以现在需要使用一个包含kubectl的命令行工具的docker进行,可以使用下面的命令拉取

1
docker pull registry.cn-hangzhou.aliyuncs.com/claywang/kubectl

将rancher中的Kubeconfig 文件 复制到drone所在的主机中,后边在运行的时候将改文件挂载到运行的docker容器中

创建命名空间 1659863657133.png 1659863691233.png 1659863714803.png 1659863739334.png 1659863763359.png 1659863782708.png 添加docker镜像的秘钥 1659865181637.png 1659865592171.png 1659865521711.png

修改对应的文件

添加 deployment.yml

1
apiVersion: v1 kind: Service metadata: name: $DRONE_REPO_NAME spec: type: ClusterIP ports: - protocol: TCP port: 8080 targetPort: 8080 selector: app: $DRONE_REPO_NAME --- apiVersion: apps/v1 kind: Deployment metadata: name: $DRONE_REPO_NAME spec: replicas: 1 selector: matchLabels: app: $DRONE_REPO_NAME template: metadata: labels: app: $DRONE_REPO_NAME spec: imagePullSecrets: - name: aliyun-docker-registry containers: - image: $REGISTRY/$REGISTRY_NAMESPACE/$DRONE_REPO_NAME:$DRONE_COMMIT name: $DRONE_REPO_NAME imagePullPolicy: Always env: - name: TIME_ZONE value: Asia/Shanghai - name: REF_NAME value: $DRONE_COMMIT_BRANCH resources: requests: memory: 0.1Gi cpu: 0.1 limits: memory: 2Gi cpu: 2 ports: - containerPort: 8080 name: app-port

更改.drone.yml文件

1
kind: pipeline type: docker name: claydemo steps: - name: build-jar image: maven:3.8.5-openjdk-8 # 定义创建容器的Docker镜像,maven:3.8.5-openjdk-8用于对java进行打包使用 volumes: # 将容器内目录挂载到宿主机,仓库需要开启Trusted设置 - name: maven-cache path: /root/.m2 # 将maven下载依赖的目录挂载出来,防止重复下载 - name: maven-build path: /app/build # 将应用打包好的Jar和执行脚本挂载出来 commands: # 定义在Docker容器中执行的shell命令 - mvn clean package -DskipTests=true # 应用打包命 - cp target/claydemo*.jar /app/build/claydemo-0.0.1.jar # 将打包后的内容复制到挂载目录下 - cp start.sh /app/build/ # java包的启动脚本 - cp Dockerfile /app/build/ # docker镜像打包时的文件 - cp deployment.yml /app/build/ # k8s部署文件 - cp .dockerignore /app/build/ # docker镜像打包时过滤文件 - cp docker.sh /app/build/ # docker 镜像打包脚本 - name: build-docker # 制作docker镜像 image: docker # 使用官方docker镜像 volumes: # 将容器内目录挂载到宿主机 - name: maven-build path: /app/build # 将应用打包好的Jar和执行脚本挂载出来 - name: docker path: /var/run/docker.sock # 挂载宿主机的docker environment: # 获取到密文的docker用户名和密码 DOCKER_USERNAME: from_secret: docker_username DOCKER_PASSWORD: from_secret: docker_password REGISTRY: from_secret: registry REGISTRY_NAMESPACE: from_secret: registry_namespace commands: # 定义在Docker容器中执行的shell命令 - cd /app/build - sed -i 's/$REGISTRY/'"$REGISTRY"'/' deployment.yml - sed -i 's/$REGISTRY_NAMESPACE/'"$REGISTRY_NAMESPACE"'/' deployment.yml - echo $DOCKER_PASSWORD | docker login $REGISTRY --username $DOCKER_USERNAME --password-stdin - chmod +x docker.sh - sh docker.sh - docker rmi -f $(docker images | grep $DRONE_REPO_NAME | awk '{print $3}') - name: drone-rancher # rancher运行 image: registry.cn-hangzhou.aliyuncs.com/claywang/kubectl #阿里云的kubectl镜像,里面包含kubectl命令行工具 volumes: # 将容器内目录挂载到宿主机 - name: maven-build path: /app/build # 将应用打包好的Jar和执行脚本挂载出来 - name: config path: /app/config # 将kubectl 配置文件挂载出来 commands: # 定义在Docker容器中执行的shell命令 - cd /app/build - sed -i 's/$DRONE_COMMIT/'"$DRONE_COMMIT"'/' deployment.yml - sed -i 's/$DRONE_REPO_NAME/'"$DRONE_REPO_NAME"'/' deployment.yml - sed -i 's/$DRONE_COMMIT_BRANCH/'"$DRONE_COMMIT_BRANCH"'/' deployment.yml - kubectl apply -f deployment.yml -n demo --kubeconfig=/app/config/rancher的kubectl配置文件 volumes: # 定义流水线挂载目录,用于共享数据 - name: maven-build # maven打包后的文件 host: path: 从宿主机中挂载的目录 - name: config # k8s对接的配置文件 host: path: rancher对接目录 - name: maven-cache # maven的缓存文件 host: path: /home/data/maven/cache - name: docker # 宿主机中的docker host: path: /var/run/docker.sock

修改docker.sh

1
#!/bin/sh # 定义应用组名 group_name='clay' # 定义应用名称 app_name=${DRONE_REPO_NAME} # 定义应用版本 app_version=${DRONE_COMMIT} echo ${app_version} # 打包编译docker镜像 echo '----build image start----' docker build -t ${group_name}/${app_name} . echo '----build image success----' docker tag ${group_name}/${app_name} $REGISTRY/$REGISTRY_NAMESPACE/${app_name}:${app_version} docker push $REGISTRY/$REGISTRY_NAMESPACE/${app_name}:${app_version} echo 'push success'

提交更改 drone流程运行成功 1659864009668.png rancher结果 1659863957040.png 1659864874393.png

总结

drone的ci/cd配置的每一个环节是基于docker镜像运行的,所以可操作性空间非常的大,并且官方也提供了不少的插件可以使用,但本次ci/cd都是基于自定义的docker镜像进行持续集成。

只要你能够写好对应的sh,不管是java还是其他语言的项目,都可以使用这一套配置。

写在最后

drone由于中文文档少,摸索的过程中难免会出现踩坑现象,希望此篇文档对你有所帮助 文中的源码地址

其他开源项目

ebts 代码生成系统

个人博客地址Clay