gitee+drone 自动构建安装及配置说明
此文章仅作为脚本留存,并没有参数说明及详细介绍,如需要了解更详细的请结合其他文章,或者等作者有时间完善(手动狗头)
gitee+drone 自动构建安装及配置说明
gitee 配置:https://docs.drone.io/server/provider/gitee/
在gitee中创建第三方应用授权
我的-设置-数据管理-第三方应用
需要授予projects,pull_request,notes,hook权限
server 安装
kubernates安装脚本
生成agent与server通信秘钥
# 生成agent与server通信秘钥
openssl rand -hex 16
创建ConfigMap
---
apiVersion: v1
kind: ConfigMap
metadata:
name: drone-env
namespace: drone
data:
DRONE_GITEE_SERVER: https://gitee.com
DRONE_GITEE_CLIENT_ID: <github-client-id>
DRONE_GITEE_CLIENT_SECRET: <github-client-secret>
DRONE_SERVER_HOST: <example.com>
DRONE_SERVER_PROTO: http
DRONE_RPC_SECRET: <rpc-secret>
DRONE_LOGS_TRACE: 'true'
DRONE_USER_CREATE: 'username:yourUserName,admin:true'
创建Deployment
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: drone-server
namespace: drone
spec:
selector:
matchLabels:
app: drone-server
template:
metadata:
labels:
app: drone-server
spec:
containers:
- name: drone-server
image: 'drone/drone:2'
imagePullPolicy: Always
envFrom:
- configMapRef:
name: drone-env
volumeMounts:
- mountPath: /data
name: drone-server-sqlite-db
volumes:
- hostPath:
path: /home/gg/app/drone/data
type: ''
name: drone-server-sqlite-db
创建Service
---
apiVersion: v1
kind: Service
metadata:
name: drone-server
namespace: drone
spec:
selector:
app: drone-server
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 80
docker-compose 安装脚本
version: '3'
services:
drone-server:
image: drone/drone:2
ports:
- 4443:443
- 8080:80
restart: always
environment:
- DRONE_GITEE_SERVER: https://gitee.com
- DRONE_GITEE_CLIENT_ID: <github-client-id>
- DRONE_GITEE_CLIENT_SECRET: <github-client-secret>
- DRONE_SERVER_HOST: <example.com>
- DRONE_SERVER_PROTO: http
- DRONE_RPC_SECRET: <rpc-secret>
- DRONE_LOGS_TRACE: 'true'
- DRONE_USER_CREATE: 'username:yourUserName,admin:true'
volumes:
- /home/gg/app/drone/data:/data:rw
runner安装
runner有种运行镜像,详情参考官方文档:https://docs.drone.io/runner/overview
Kubernetes runner部署脚本
官方文档:https://docs.drone.io/runner/kubernetes/installation/
创建rbac
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: drone
name: kube-runner
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- delete
- apiGroups:
- ""
resources:
- pods
- pods/log
verbs:
- get
- create
- delete
- list
- watch
- update
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kube-runner
namespace: drone
subjects:
- kind: ServiceAccount
name: default
namespace: drone
roleRef:
kind: Role
name: kube-runner
apiGroup: rbac.authorization.k8s.io
创建ConfigMap
---
apiVersion: v1
data:
DRONE_NAMESPACE_DEFAULT: drone
DRONE_RPC_HOST: 'drone-service.drone:8080'
DRONE_RPC_PROTO: http
DRONE_RPC_SECRET: <rpc-secret>
DRONE_RUNNER_CAPACITY: '2'
DRONE_RUNNER_NAME: kube-runner
kind: ConfigMap
metadata:
name: kube-runner-env
namespace: drone
创建Deployment
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: kube-runner
name: kube-runner
namespace: drone
spec:
selector:
matchLabels:
app.kubernetes.io/name: kube-runner
template:
metadata:
labels:
app.kubernetes.io/name: kube-runner
spec:
containers:
- envFrom:
- configMapRef:
name: kube-runner-env
image: 'drone/drone-runner-kube:1.0.0-beta.12'
imagePullPolicy: Always
name: runner
ports:
- containerPort: 3000
protocol: TCP
Docker Runner部署脚本
version: '3'
services:
drone-agent:
image: drone/drone-runner-docker:1
container_name: drone-docker-runner
restart: always
depends_on:
- drone-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- TZ=Asia/Shanghai
- DRONE_RPC_HOST: 'drone-service.drone:8080'
- DRONE_RPC_PROTO: http
- DRONE_RPC_SECRET: <rpc-secret>
- DRONE_RUNNER_CAPACITY: '2'
- DRONE_RUNNER_NAME: drone-docker-runner
自动构建配置
基于portainer部署的项目
创建portainer_restart.sh文件
在drone服务器中创建自动拉取镜像并重启的shell脚本
#!/bin/bash
if [ $# -eq 0 ]
then
echo "USAGE: USERNAME PASSWORD HOST STACKNAME SERVICE_IMAGES"
echo "admin password server:9000 stack-name image:latest"
exit 0
fi
USERNAME=$1
PASSWORD=$2
HOST=$3
STACKNAME=$4
SERVICE_IMAGES=$5
REGISRY_AUTH_TOKEN=$6
echo "params USERNAME: $USERNAME"
echo "params PASSWORD: $PASSWORD"
echo "params HOST: $HOST"
echo "params STACKNAME: $STACKNAME"
echo "params SERVICE_IMAGES: $SERVICE_IMAGES"
echo "params REGISRY_AUTH_TOKEN: $REGISRY_AUTH_TOKEN"
# GENERATE LOGIN TOKEN
LOGIN_TOKEN=$(curl -s -H "Content-Type: application/json" -d "{\"username\":\"$USERNAME\",\"password\":\"$PASSWORD\"}" -X POST $HOST/api/auth | jq -r .jwt)
echo "get token seccess: $LOGIN_TOKEN"
# GET STACK ID OF $NAME
ID=$(curl -s -H "Authorization: Bearer $LOGIN_TOKEN" $HOST/api/stacks | jq -c ".[] | select( .Name==(\"$STACKNAME\"))" | jq -r .Id)
echo "get stack id seccess: $ID"
# GET THE ENV
# ENV=$(curl -s -H "Authorization: Bearer $LOGIN_TOKEN" $HOST/api/stacks/$ID | jq .Env)
# GET THE STACK LIVE FILE
EXTERNAL_STACKFILE=$(curl -s -H "Authorization: Bearer $LOGIN_TOKEN" $HOST/api/stacks/$ID/file | jq .StackFileContent)
echo "get EXTERNAL_STACKFILE seccess"
ENDPOINT_ID=$(curl -s -H "Authorization: Bearer $LOGIN_TOKEN" $HOST/api/stacks/$ID | jq .EndpointId)
# GET LOCAL STACKFILE AND FORMAT NEWLINE TO \n
echo "remote stack file used"
UPDATE="{
\"StackFileContent\": ${EXTERNAL_STACKFILE},
\"Env\": [],
\"Prune\": true
}"
# UPDATE IMAGES
curl -s -H 'Content-Type: text/json; charset=utf-8' \
-H "Authorization: Bearer $LOGIN_TOKEN" \
-H "X-Registry-Auth: $REGISRY_AUTH_TOKEN" \
-X POST $HOST/api/endpoints/$ENDPOINT_ID/docker/images/create?fromImage=$SERVICE_IMAGES
# UPDATE THE STACK > /dev/null beacuse the $ENV contains passwords
curl -s -H 'Content-Type: text/json; charset=utf-8' \
-H "Authorization: Bearer $LOGIN_TOKEN" -X PUT -d "${UPDATE}" \
$HOST/api/stacks/$ID?endpointId=$ENDPOINT_ID
echo "ALL SUCCESS"
项目中创建drone.yml
在项目根目录创建
.drone.yml
文件
java项目
kind: pipeline # 定义对象类型,还有secret和signature两种类型
type: docker #kubernetes / docker # 定义流水线类型,还有kubernetes、exec、ssh等类型1
name: test-drone # 定义流水线名称
steps:
- name: Maven编译
image: maven:3-jdk-8
volumes:
- name: mvnCache
path: /root/.m2 #maven依赖包的本地缓存
commands:
- mvn clean package -DskipTests=true -Dmaven.javadoc.skip=true
#when: #条件,仅某个分支执行,可配置全局的
# branch:
# - dev
- name: 构建并推送镜像 - dev
image: plugins/docker:20
settings:
mirror: https://ovj8fg0z.mirror.aliyuncs.com #加速器
registry: registry.cn-beijing.aliyuncs.com
username:
from_secret: aliyun_registry_username #镜像仓库用户名(秘钥,在drone页面创建)
password:
from_secret: aliyun_registry_password #镜像仓库密码(秘钥,在drone页面创建)
repo: registry.cn-beijing.aliyuncs.com/xxxx/xxxx-xxxx #镜像全地址
tags: 0.0.1 #版本号
- name: 更新并重启portainer服务 - dev
image: appleboy/drone-ssh
environment:
PORTAINER_USERNAME:
from_secret: 121portainer_username #portainer用户名(秘钥,在drone页面创建)
PORTAINER_PASSWORD:
from_secret: 121portainer_password #portainer密码(秘钥,在drone页面创建)
SERVER_IMAGES: "registry.cn-beijing.aliyuncs.com/xxxx/xxxx-xxxx" #要更新的镜像
IMAGES_VERSION: "0.0.1" #要更新的镜像版本号
PORTAINER_HOST: "http://121.36.104.46:9000" #portainer服务地址
STACKNAME: "XXXX" #portainer中要重启的stack名字
#portainer的token,可f12获取
REGISTRY_AUTH_TOKEN: "eyJzZXJ2ZXJhZGRyZXNzIjoicmVnaXN0cnkuY24tYmVpamluZy5hbGl5dW5jcy5jb20ifQ=="
settings:
host:
- 121.36.104.46
username:
from_secret: 121_server_username #服务器用户名(秘钥,在drone创建)
password:
from_secret: 121_server_password #服务器(秘钥,在drone创建)
port: 22
command_timeout: 2m
envs:
- PORTAINER_USERNAME
- PORTAINER_PASSWORD
- PORTAINER_HOST
- STACKNAME
- SERVER_IMAGES
- IMAGES_VERSION
- REGISTRY_AUTH_TOKEN
#调用上面放到服务器中用于重启的shell脚本
script:
- /home/softding/restartsh/portainer_update.sh $PORTAINER_USERNAME $PORTAINER_PASSWORD $PORTAINER_HOST $STACKNAME $SERVER_IMAGES:$IMAGES_VERSION $REGISTRY_AUTH_TOKEN
- name: 钉钉通知
pull: if-not-exists
image: guoxudongdocker/drone-dingtalk:latest
settings:
token: c3f19ed8a8757ef38a415d031ed1a60b9209f0a30e359914075e1e6c263d01a6
type: markdown
message_color: true
message_pic: true
sha_link: true
when:
status: [ failure, success ]
volumes:
- name: mvnCache
host:
path: /home/softding/projectDir/drone/maven
#全局条件,限制特定分支、动作执行
trigger:
branch:
- dev
event:
- push
vue项目
除了打包从maven换成了node,并将镜像地址换掉,其他基本一致
kind: pipeline # 定义对象类型,还有secret和signature两种类型
type: docker #kubernetes / docker # 定义流水线类型,还有kubernetes、exec、ssh等类型1
name: test-drone # 定义流水线名称
steps:
- name: node打包
image: node:14-alpine3.15
volumes:
- name: node_modules
path: /drone/src/node_modules
commands:
- npm config set registry https://registry.npm.taobao.org
- npm install
- npm run build:prod
- name: 构建并推送镜像 - dev
image: plugins/docker:20
settings:
mirror: https://ovj8fg0z.mirror.aliyuncs.com
registry: registry.cn-beijing.aliyuncs.com
username:
from_secret: aliyun_registry_username
password:
from_secret: aliyun_registry_password
repo: registry.cn-beijing.aliyuncs.com/xxxx/xxxx-xxxx
tags: 0.0.1
- name: 更新并重启portainer服务 - dev
image: appleboy/drone-ssh
environment:
PORTAINER_USERNAME:
from_secret: 121portainer_username
PORTAINER_PASSWORD:
from_secret: 121portainer_password
SERVER_IMAGES: "registry.cn-beijing.aliyuncs.com/xxxx/xxxx-xxxx"
IMAGES_VERSION: "0.0.1"
PORTAINER_HOST: "http://121.36.104.46:9000"
STACKNAME: "XXXX"
REGISTRY_AUTH_TOKEN: "eyJzZXJ2ZXJhZGRyZXNzIjoicmVnaXN0cnkuY24tYmVpamluZy5hbGl5dW5jcy5jb20ifQ=="
settings:
host:
- 121.36.104.46
username:
from_secret: 121_server_username
password:
from_secret: 121_server_password
port: 22
command_timeout: 2m
envs:
- PORTAINER_USERNAME
- PORTAINER_PASSWORD
- PORTAINER_HOST
- STACKNAME
- SERVER_IMAGES
- IMAGES_VERSION
- REGISTRY_AUTH_TOKEN
script:
- /home/softding/restartsh/portainer_update.sh $PORTAINER_USERNAME $PORTAINER_PASSWORD $PORTAINER_HOST $STACKNAME $SERVER_IMAGES:$IMAGES_VERSION $REGISTRY_AUTH_TOKEN
- name: 钉钉通知
pull: if-not-exists
image: guoxudongdocker/drone-dingtalk:latest
settings:
token: c3f19ed8a8757ef38a415d031ed1a60b9209f0a30e359914075e1e6c263d01a6
type: markdown
message_color: true
message_pic: true
sha_link: true
when:
status: [ failure, success ]
volumes:
- name: node_modules
host:
path: /home/softding/projectDir/drone/node/dr-ioneworld-vue
trigger:
branch:
- devlop-v1.2
event:
- push
基于K8s部署的项目
在项目中创建deployment.yml
在项目根目录创建
deployment.yml
文件,k8s编排文件
java项目
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: {{ .env.deployment }}
name: {{ .env.deployment }}
namespace: {{ .env.namespace }}
spec:
selector:
matchLabels:
app: {{ .env.deployment }}
template:
metadata:
labels:
app: {{ .env.deployment }}
spec:
containers:
- env:
- name: created_time
value: '{{ .env.build_created }}'
- name: SPRING_PROFILES_ACTIVE
value: dev
- name: REDIS_HOST
value: ''
- name: REDIS_PORT
value: ''
- name: REDIS_PW
value:
- name: DB_URL
value: ''
- name: DB_NAME
value:
- name: DB_USERNAME
value:
- name: DB_PASSWORD
value:
image: {{ .env.repo }}
imagePullPolicy: Always
name: {{ .env.container }}
ports:
- containerPort: 8080
name: web
protocol: TCP
- containerPort: 8081
name: actuator
protocol: TCP
livenessProbe:
httpGet:
path: /actuator/health
port: 8081
scheme: HTTP
initialDelaySeconds: 120
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: image-pull-secret
nodeName: master
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: {{ .env.deployment }}
namespace: {{ .env.namespace }}
spec:
ports:
- name: http
nodePort: 31108 #使用node节点的端口访问系统
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: {{ .env.deployment }}
sessionAffinity: None
type: NodePort
vue项目
# 使用ConfigMap配置nginx的config文件
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .env.deployment }}-nginxconfig
namespace: {{ .env.namespace }}
data:
vue.conf: |
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
location ^~/prod-api/ {
rewrite ^/prod-api/(.*)$ /$1 break;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://dr-bigherdsman.softding:8080;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: {{ .env.deployment }}
name: {{ .env.deployment }}
namespace: {{ .env.namespace }}
spec:
selector:
matchLabels:
app: {{ .env.deployment }}
template:
metadata:
labels:
app: {{ .env.deployment }}
spec:
containers:
- env:
- name: created_time
value: '{{ .env.build_created }}'
image: {{ .env.repo }}
imagePullPolicy: Always
name: {{ .env.container }}
ports:
- containerPort: 80
name: web
protocol: TCP
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d/default.conf
subPath: vue.conf
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: image-pull-secret
restartPolicy: Always
volumes:
- name: nginx-config
configMap:
name: {{ .env.deployment }}-nginxconfig
items:
- key: vue.conf
path: vue.conf
---
apiVersion: v1
kind: Service
metadata:
name: {{ .env.deployment }}
namespace: {{ .env.namespace }}
spec:
ports:
- name: http
nodePort: 31100 #使用node节点的端口访问系统
port: 80
protocol: TCP
targetPort: 80
selector:
app: {{ .env.deployment }}
sessionAffinity: None
type: NodePort
项目中创建drone.yml
在项目根目录创建
.drone.yml
文件
java项目
kind: pipeline # 定义对象类型,还有secret和signature两种类型
type: kubernetes # / docker # 定义流水线类型,还有kubernetes、exec、ssh等类型1
name: test-drone # 定义流水线名称
steps:
- name: Maven编译
image: maven:3-jdk-8
volumes:
- name: mvnCache
path: /root/.m2 #maven依赖包的本地缓存
commands:
- mvn clean package -DskipTests=true -Dmaven.javadoc.skip=true
- name: 构建并推送镜像 - dev
image: plugins/docker:20
settings:
mirror: https://ovj8fg0z.mirror.aliyuncs.com #加速器
registry: registry.cn-beijing.aliyuncs.com
username:
from_secret: aliyun_registry_username #镜像仓库用户名(秘钥,在drone页面创建)
password:
from_secret: aliyun_registry_password #镜像仓库密码(秘钥,在drone页面创建)
repo: registry.cn-beijing.aliyuncs.com/xxxx/xxxx-xxxx #镜像全地址
tags: 0.0.1 #版本号
- name: 更新kubernetes服务
image: zc2638/drone-k8s-plugin
settings:
kubernetes_server: https://kubernetes.default.svc.cluster.local #k8s api服务地址
kubernetes_token:
from_secret: k8s_token #k8s用户token
namespace: softding #服务所在namespace名称
kubernetes_skip_tls: true
templates:
- deployment.yaml #编排文件名称
build_created: ${DRONE_BUILD_CREATED} #编排参数-构建时间
deployment: xxxxxx #编排参数-容器组名称
repo: registry.cn-beijing.aliyuncs.com/xxxx/xxxx-xxxx:0.0.1 #编排参数-镜像地址
container: xxxx #编排参数-容器名称
- name: 钉钉通知
pull: if-not-exists
image: guoxudongdocker/drone-dingtalk:latest
settings:
token: c3f19ed8a8757ef38a415d031ed1a60b9209f0a30e359914075e1e6c263d01a6
type: markdown
message_color: true
message_pic: true
sha_link: true
when:
status: [ failure, success ]
volumes:
- name: mvnCache
host:
path: /home/softding/projectDir/drone/maven
#全局条件,限制特定分支、动作执行
trigger:
branch:
- dev
event:
- push
vue项目
除了打包从maven换成了node,并将镜像地址换掉,其他基本一致
kind: pipeline # 定义对象类型,还有secret和signature两种类型
type: kubernetes #kubernetes / docker # 定义流水线类型,还有kubernetes、exec、ssh等类型1
name: test-drone # 定义流水线名称
steps:
- name: node打包
image: node:14-alpine3.15
volumes:
- name: node_modules
path: /drone/src/node_modules
commands:
- npm config set registry https://registry.npm.taobao.org
- npm install
- npm run build:prod
- name: 构建并推送镜像 - dev
image: plugins/docker:20
settings:
mirror: https://ovj8fg0z.mirror.aliyuncs.com
registry: registry.cn-beijing.aliyuncs.com
username:
from_secret: aliyun_registry_username
password:
from_secret: aliyun_registry_password
repo: registry.cn-beijing.aliyuncs.com/xxxx/xxxx-xxxx
tags: 0.0.1
- name: 更新kubernetes服务
image: zc2638/drone-k8s-plugin
settings:
kubernetes_server: https://kubernetes.default.svc.cluster.local #k8s api服务地址
kubernetes_token:
from_secret: k8s_token #k8s用户token
namespace: softding #服务所在namespace名称
kubernetes_skip_tls: true
templates:
- deployment.yaml #编排文件名称
build_created: ${DRONE_BUILD_CREATED} #编排参数-构建时间
deployment: dr-bigherdsman-vue #编排参数-容器组名称
repo: registry.cn-beijing.aliyuncs.com/xxxx/xxxx-xxxx:0.0.1 #编排参数-镜像地址
container: dr-bigherdsman-vue #编排参数-容器名称
- name: 钉钉通知
pull: if-not-exists
image: guoxudongdocker/drone-dingtalk:latest
settings:
token: c3f19ed8a8757ef38a415d031ed1a60b9209f0a30e359914075e1e6c263d01a6
type: markdown
message_color: true
message_pic: true
sha_link: true
when:
status: [ failure, success ]
volumes:
- name: node_modules
host:
path: /home/softding/projectDir/drone/node/dr-ioneworld-vue
trigger:
branch:
- devlop-v1.2
event:
- push
drone中的配置
激活项目
-
将上面在项目中创建的
.drone.yml
文件并提交。 -
通过gitee授权登录到drone后。
-
找到你要是用的项目,如果没找到可点击同步按钮,并确保你有管理员权限,此时会显示一个激活按钮
ACTIVATE REPOSITORY
,点击激活即可 -
激活后,在设置
Settings
页面的General
中将Trusted
设置为启用状态(必须),也可设置Auto cancel pull requests
、Auto cancel Pushes
、Auto cancel running
为启用(非必须,此为当任务在执行时如果有新的提交则停止当前任务执行新任务),设置完成后点击保存SAVE CHANGES
-
同样在设置
Setting
页面,在Secrets
中创建之前在.drone.yml
中保留的秘钥,名字保持一致即可,已经创建过无需重复
常见错误
构建失败,终止,未出现明显异常
可能是服务器内存资源不够,可点击到任务执行详情中点击Restart
重新尝试
构建成功了,但是服务没重新或代码有异常重启失败,再提交新代码还是不行
这时需要到portainer
中手动更新,无法通过脚本自动拉取最新的镜像重启
激活项目时出现404
这是项目创建时的名字与当前名字不一致,如果可以的话换回去即可
代码提交了,但是没有自动构建的任务
这时可以检查下码云是否正常,可能是码云服务器在维护,过段时间再试吧