本文介绍如何使用 Drone 持续构建与发布 Golang + node + kubernetes 应用。
Docker 部署 Drone
docker-compose.yaml
示例, 其中配置项如下:
Key | 说明 |
---|---|
GITHUB_USER_NAME | GitHub 的username |
TOKEN | API 或 Cli 连接 Drone 服务用的 token,可以随机生成:openssl rand -hex 16 |
GITHUB_CLIENT_ID | 参考 Drone 文档 GitHub 引导 创建 OAuth Application,配置参考如下:Homepage URL 为http://{SERVER_HOST} ,注意如果不是80 端口需要带端口,如http://drone.hbchen.com:8000 Authorization callback URL 为{Homepage URL}/login ,如http://drone.hbchen.com:8000/login |
GITHUB_CLIENT_SECRET | 同上 |
SERVER_HOST | 绑定的域名,如drone.hbchen.com |
RPC_SECRET | Drone server 和 runner 通信用的 secret,可以随机生成:openssl rand -hex 16 |
RUNNER_DASHBOARD_USERNAME | 可选 ,Runner 可以在3000 端口提供一个 dashboard,如果需要可以配置用户名和密码 |
RUNNER_DASHBOARD_PASSWORD | 同上 |
- 如果外网使用的不是80端口(如此处使用
8000
),在激活一个 Repo 后需要修改 Repo Webhook 的地址,增加端口- 为用户添加 admin 权限,做 cache 挂载 volume 时需要将 Repo 的
Project settings
设置为trusted
,要 admin 才有此权限
version: '3'
services:
drone-server:
image: drone/drone:1.6
restart: always
ports:
- 8000:80
volumes:
- /var/lib/drone:/data
environment:
- DRONE_USER_CREATE=username:{GITHUB_USER_NAME},machine:false,admin:true,token:{TOKEN}
- DRONE_GITHUB_SERVER=https://github.com
- DRONE_GITHUB_CLIENT_ID={GITHUB_CLIENT_ID}
- DRONE_GITHUB_CLIENT_SECRET={GITHUB_CLIENT_SECRET}
- DRONE_GITHUB_SKIP_VERIFY=true
- DRONE_SERVER_HOST={SERVER_HOST}
- DRONE_SERVER_PROTO=http
- DRONE_RPC_SECRET={RPC_SECRET}
drone-runner:
image: drone/drone-runner-docker:1.2
restart: always
ports:
- 3000:3000
depends_on:
- drone-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- DRONE_RPC_HOST=drone-server
- DRONE_RPC_PROTO=http
- DRONE_RPC_SECRET={RPC_SECRET}
- DRONE_RUNNER_NAME=drone-runner
- DRONE_RUNNER_CAPACITY=2
- DRONE_UI_USERNAME={RUNNER_DASHBOARD_USERNAME}
- DRONE_UI_PASSWORD={RUNNER_DASHBOARD_PASSWORD}
Drone Pipeline
Secret 配置
Pipeline 涉及到 Secret 配置与我们的目标相关,以micro-in-cn/starter-kit/.drone.yml为例:
- Docker 镜像发布
- push 镜像需要仓库用户名及密码
- k8s 部署
- kubectl 需要配置
server
、ca
和token
- kubectl 需要配置
k8s 配置获取
1.取一个 Pod 的 Secret 或者单独创建一个 account
kubectl describe po {pod-name} | grep SecretName
2.取Secret的ca和token
kubectl get secret {secret-name} -o yaml | egrep 'ca.crt:|token:'
3.drone secret 配置
k8s_server
cat ~/.kube/config
,适用于minikube
环境
k8s_ca
- ca直接使用
k8s_token
- token做base64解码后使用
kubectl
部署需要对应的account有授权,根据自己的环境情况配置
测试可以将clusterrole=cluster-admin授权给serviceaccount# Error from server (Forbidden): services is forbidden: User "system:serviceaccount:default:default" cannot list resource "services" in API group "" in the namespace "default" kubectl create clusterrolebinding cluster-admin-role-bound --clusterrole=cluster-admin --serviceaccount={namespace}:{service-account}
使用 drone cli 工具连接 drone server
喜欢 web 操作可以选择在控制台配置 secret
export DRONE_SERVER=http://drone.hbchen.com:8000
export DRONE_TOKEN={前面配置的TOKEN}
drone info
drone secret add --repository=micro-in-cn/starter-kit --name=ali_registry_username --data={xxx}
drone secret add --repository=micro-in-cn/starter-kit --name=ali_registry_password --data={xxx}
drone secret add --repository=micro-in-cn/starter-kit --name=k8s_server --data={xxx}
drone secret add --repository=micro-in-cn/starter-kit --name=k8s_ca --data={xxx}
drone secret add --repository=micro-in-cn/starter-kit --name=k8s_token --data={xxx}
编译&缓存
在项目编译时都会有大量的依赖下载,这些对编译速度影响很大,并且容易导致失败,所以需要使用缓存,避免每次都要重新拉取依赖,以micro-in-cn/starter-kit/console/web为例,有 Golang 和 node 的编译,使用 drone 社区drillster/drone-volume-cache
插件对 Golang 和 node 依赖进行缓存。基本过程就是在编译前将cache
加载到相应目录,编译后重新将cache
写回volume
,编译时 Golang 需要指定GOPATH
,node 指定global cache
。
# 挂载 host 缓存目录
volumes:
- name: cache
host:
path: /tmp/drone_cache
steps:
- name: restore-cache
image: drillster/drone-volume-cache
settings:
restore: true
mount:
- ./.npm-cache
- ./console/web/vue/node_modules
- ./_gopath
volumes:
- name: cache
path: /cache
when:
event:
- push
- name: build-vue
image: node:10.16.3-alpine
commands:
- cd console/web/vue
- npm config set cache ./.npm-cache --global
- npm install
- export VUE_APP_BASE_API=
- npm run build:prod
when:
event:
- push
- name: build-golang
image: golang:1.13-alpine
environment:
GOPATH: /drone/src/github.com/micro-in-cn/starter-kit/_gopath
GOOS: linux
GOARCH: amd64
CGO_ENABLED: 0
GOPROXY: https://mirrors.aliyun.com/goproxy/,direct
GOSUMDB: off
commands:
- cd console/web
- go version
- go build -o ./bin/linux_amd64/console-web main.go plugin.go
when:
event:
- push
- name: rebuild-cache
image: drillster/drone-volume-cache
settings:
rebuild: true
mount:
- ./.npm-cache
- ./console/web/vue/node_modules
- ./_gopath
volumes:
- name: cache
path: /cache
when:
event:
- push
发布镜像&部署
- docker username 和 password 通过 secret 获取
- k8s 先用 secret 配置环境变量,使用时再从环境变量去取
- name: publish-xxx
image: plugins/docker
settings:
tags: latest
dockerfile: ./console/api/Dockerfile
context: ./console/web
repo: registry.cn-hangzhou.aliyuncs.com/hb-chen/starter-kit-console-api
registry: registry.cn-hangzhou.aliyuncs.com
username:
from_secret: ali_registry_username
password:
from_secret: ali_registry_password
when:
event:
- push
- name: deploy-xxx
image: dtzar/helm-kubectl:3.1.1
environment:
SERVER:
from_secret: k8s_server
CERTIFICATE_AUTHORITY_DATA:
from_secret: k8s_ca
USER_TOKEN:
from_secret: k8s_token
commands:
- kubectl config set-cluster k8s --server="$${SERVER}"
- kubectl config set clusters.k8s.certificate-authority-data "$${CERTIFICATE_AUTHORITY_DATA}"
- kubectl config set-credentials k8s-admin --token="$${USER_TOKEN}"
- kubectl config set-context default --cluster=k8s --user=k8s-admin
- kubectl config use-context default
- helm template micro ./deploy/k8s/helm/starter-kit/charts/service --namespace starter-kit --set nameOverride=console-api --set micro.command=/console-api --set image.repository=registry.cn-hangzhou.aliyuncs.com/hb-chen/starter-kit-console-api --set image.tag=${DRONE_TAG=latest} --set image.pullPolicy=Always --set serviceAccount.create=true --set serviceAccount.name=micro-services | kubectl apply -f -
when:
event:
- push