【Docker】之使用Gitea+Drone实现持续集成(CI/CD)
前言
安装Gitea
安装过程,参考:【Docker】之安装Gitea
安装Drone
- 首先下载Drone的Server和Runner的镜像;
# Drone的Server docker pull drone/drone # Drone的Runner docker pull drone/drone-runner-docker
- 生成GiteaOauth
gitea右上角->设置->应用->创建应用
生成rpc秘钥:客户端id : f4d1e22d-b092-4e86-bedd-dffb362b1c70 客户端秘钥 : EBjiksxi7QBaAtY9cIisGY36Ghr81Y4vtk2uqj8g5qEa
openssl rand -hex 16
这个用于[root@loaclhost build]# openssl rand -hex 16 1bd0710533d6ade9ab943df6822e7e1d
DRONE_RPC_SECRET
,当然也可随便设置值(dronerpc666) - 接下来我们来安装
drone-server
,使用如下命令即可;docker run \ --net docker-mynet --ip 172.172.0.12 \ --volume=/root/.docker/drone/data:/data/docker/drone \ --env=DRONE_AGENTS_ENABLED=true \ --env=DRONE_GIT_ALWAYS_AUTH=true \ --env=DRONE_GITEA_SERVER=http://10.211.55.81:3000 \ --env=DRONE_GITEA_CLIENT_ID=f4d1e22d-b092-4e86-bedd-dffb362b1c70 \ --env=DRONE_GITEA_CLIENT_SECRET=EBjiksxi7QBaAtY9cIisGY36Ghr81Y4vtk2uqj8g5qEa \ --env=DRONE_RPC_SECRET=1bd0710533d6ade9ab943df6822e7e1d \ --env=DRONE_SERVER_HOST=10.211.55.81:3080 \ --env=DRONE_SERVER_PROTO=http \ --env=DRONE_USER_CREATE=username:leeze,admin:true \ --publish=3080:80 \ --publish=10443:443 \ --restart=always \ --detach=true \ --name=drone \ drone/drone:latest
调试阶段建议启动设置# 这里的配置参数比较多,下面统一解释下; DRONE_AGENTS_ENABLED : 是否开启身份验证 DRONE_GITEA_SERVER : Gitea服务器地址((建议填写宿主机地址+端口, 需要`http://`开头)) DRONE_GITEA_CLIENT_ID : 应用的客户端id(gitea上生成的Client ID) DRONE_GITEA_CLIENT_SECRET : 应用的客户端秘钥(gitea上生成的Client Secret) DRONE_RPC_SECRET : Drone的共享秘钥,用于验证连接到server的rpc连接,server和runner需要提供同样的秘钥。(后面安装runner使用相同的秘钥) DRONE_SERVER_HOST : Drone服务地址,外部可访问的域名或IP地址(建议填写宿主机地址+端口, 不需要`http://`开头) DRONE_SERVER_PROTO : Drone提供服务的协议类型(可选为`http`或`https`) DRONE_USER_CREATE : 设置Drone管理员账号(`注意设置的是Gitea平台里的账号`), `Drone`是直接使用`Gogs账号`登录的
detach=false
, 这样可以查看日志输出 - 接下来安装
drone-runner-docker
,当有需要执行的任务时,会启动临时的容器来执行流水线任务;docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ --net docker-mynet --ip 172.172.0.13 \ -e DRONE_RPC_PROTO=http \ -e DRONE_RPC_HOST=10.211.55.81:3080 \ -e DRONE_RPC_SECRET=1bd0710533d6ade9ab943df6822e7e1d \ -e DRONE_RUNNER_CAPACITY=2 \ -e DRONE_RUNNER_NAME=runner-docker \ -e TZ="Asia/Shanghai" \ -p 3010:3000 \ --restart always \ --name runner-docker \ drone/drone-runner-docker:latest
# 这里的配置参数比较多,下面统一解释下。 DRONE_RPC_PROTO : 用于配置连接到Drone server的协议(必须是`http`或`https`) DRONE_RPC_HOST : 用于配置Drone server的访问地址,runner会连接到server获取流水线任务并执行。 DRONE_RPC_SECRET : 用于配置连接到Drone server的共享秘钥。 DRONE_RUNNER_CAPACITY : 限制runner并发执行的流水线任务数量(默认2)。 DRONE_RUNNER_NAME : 自定义runner的名称。
- 开放相关端口:
firewall-cmd --zone=public --add-port=3080/tcp --permanent firewall-cmd --reload
让我们来访问下Drone
使用Drone
的控制台页面,第一次登录需要输入账号密码(在Gitea中注册的账号),访问地址:http://10.211.55.81:3080/
此时我们在Gitea中的项目会现在在列表中,如果没有的话可以点下SYNC
按钮;
接下来我们需要对仓库进行设置,将仓库设置为Trusted
(否则Drone创建的容器无法挂载目录到宿主机),最后点击SAVE
按钮保存;
保存成功后会在Gitea
中自动配置一个Web钩子
,当我们推送代码到Gitea中去时,会触发这个钩子,然后执行在Drone中的流水线任务;
拉到最下面,我们可以发送一个测试推送,推送成功会显示绿色的√;
此时我们在Drone
中发现其实流水线执行失败了,那是因为我们在脚本中引用了Secret
中的ssh_password
;
在仓库的设置中添加一个Secret
即可,Secret是专门用来存储密码的,此密码只能被使用或删除,无法被查看;
在ACTIVITY FEED
中使用RESTART
可以重新执行该流水线,发现已经成功执行。
编写脚本
- 项目结构
- 首先我们来了解下在
.drone.yml
中配置的工作流都有哪些操作,看下流程图就知道了; - 再来一个完整的
.drone.yml
,配上详细的注解,看下就基本懂了!kind: pipeline # 定义对象类型,还有secret和signature两种类型 type: docker # 定义流水线类型,还有kubernetes、exec、ssh等类型 name: mybatisplus-drone # 定义流水线名称 steps: # 定义流水线执行步骤,这些步骤将顺序执行 - name: package # 流水线名称 image: maven:3-jdk-8 # 定义创建容器的Docker镜像 volumes: # 将容器内目录挂载到宿主机,仓库需要开启Trusted设置 - name: maven-cache path: /root/.m2 # 将maven下载依赖的目录挂载出来,防止重复下载 - name: maven-build path: /app/build # 将应用打包好的Jar和执行脚本挂载出来 commands: # 定义在Docker容器中执行的shell命令 - mvn clean package # 应用打包命令 - cp mybatisplus/target/mybatisplus-0.0.1-SNAPSHOT.jar /app/build/mybatisplus.jar - cp Dockerfile /app/build/Dockerfile - cp run.sh /app/build/run.sh - name: build-start image: appleboy/drone-ssh # SSH工具镜像 settings: host: 10.211.55.81 # 远程连接地址 username: root # 远程连接账号 password: from_secret: ssh_password # 从Secret中读取SSH密码 port: 22 # 远程连接端口 command_timeout: 5m # 远程执行命令超时时间 script: - cd /mydata/maven/build # 进入宿主机构建目录 - chmod +x run.sh # 更改为可执行脚本 - ./run.sh # 运行脚本打包应用镜像并运行 volumes: # 定义流水线挂载目录,用于共享数据 - name: maven-build host: path: /mydata/maven/build # 从宿主机中挂载的目录 - name: maven-cache host: path: /mydata/maven/cache
- Dockerfile
# 该镜像需要依赖的基础镜像 FROM clockard/alpine-java:8_jdk LABEL maintainer="mybatisplus" \ version="1.0.0" \ description="This is mybatisplus's test." RUN echo "Asia/Shanghai" > /etc/timezone # 将当前目录下的jar包复制到docker容器的/目录下 ADD mybatisplus.jar /app/mybatisplus.jar # 指定docker容器启动时运行jar包 #在容器启动的时候运行命令,来启动我们的项目 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/mybatisplus.jar","-Xms128m","-Xmx128m","-c"] # 指定维护者的名字 MAINTAINER leeze ``` 5. `run.sh`执行脚本可以实现打包应用和运行容器镜像 ```bash #!/usr/bin/env bash # 定义应用组名 group_name='zancunli' # 定义应用名称 app_name='mybatisplus' # 定义应用版本 app_version='1.0.0' # 定义应用环境 #profile_active='prod' 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 7080:9091 --name ${app_name} --net docker-mynet --ip 172.172.0.88 \ -e TZ="Asia/Shanghai" \ -v /etc/localtime:/etc/localtime \ -v /mydata/app/${app_name}/logs:/var/logs \ -d ${group_name}/${app_name}:${app_version} \ echo '----start container----'
- 运行成功
浏览器:http://10.211.55.81:7080/user/list ,成功取到数据
问题
gitea & drone webhook推送不成功
修改 Gitea 服务器的 Webhook 白名单
出于安全考虑,您通过 Gitea Webhook 触发外部服务器的响应前需要设定webhook.ALLOWED_HOST_LIST
白名单来控制 Webhook 的目的地址。具体信息参考文档 Webhook。
修改配置时,打开conf/app.ini
,添加ALLOWED_HOST_LIST = *
到 [webhook
] 栏目中,并重启 Gitea 服务器。例如:[webhook] ALLOWED_HOST_LIST = *
# 添加 gitea/conf/app.ini [webhook] ALLOWED_HOST_LIST = 192.168.0.0/16
参考资料
官方文档:https://docs.drone.io/
结合Maven使用:https://docs.drone.io/pipeline/kubernetes/examples/language/maven/
结合SSH使用:http://plugins.drone.io/appleboy/drone-ssh/
将容器目录挂载到宿主机:https://docs.drone.io/pipeline/docker/syntax/volumes/host/