终于到了最激动人心的时刻了,自动化部署!
K8S的自动化部署在任何CICD平台实际上都非常的简单,基本没什么要说的,这里简单介绍一下,主要是说一下drone部署k8s会遇到的坑。
编写deploy.yaml
既然要部署到k8s,那么k8s的资源文件是必不可少的,该文件我放在了源码的根目录下,和.drone.yml一起,这里不详细讲怎么编写了,如果想要学习,可以参考我的k8s系列文章,注意image的tag是一个占位符,详见下文。
apiVersion: apps/v1
kind: Deployment
metadata:
name: ui-whatsfordinner
namespace: default
labels:
app: ui-wfd
spec:
replicas: 1
selector:
matchLabels:
app: ui-wfd
template:
metadata:
labels:
app: ui-wfd
spec:
containers:
- name: ui-whatsfordinner
image: registry-vpc.cn-shanghai.aliyuncs.com/hulu0811/whatsfordinner:{{.image_tag}}
ports:
- containerPort: 80
protocol: TCP
imagePullPolicy: Always
restartPolicy: Always
编写.drone.yml
接着我们前文中CI的后面写,把CD的步骤也加上去,这里提供完整的yml,仍然是vue3项目:
kind: pipeline
type: kubernetes
name: hulu-project
steps:
- name: docker
image: plugins/docker
settings:
mirror: https://jnyis2wm.mirror.aliyuncs.com
username:
from_secret: username
password:
from_secret: password
repo: registry-vpc.cn-shanghai.aliyuncs.com/hulu0811/whatsfordinner
registry: registry-vpc.cn-shanghai.aliyuncs.com
tags:
- latest
- ${DRONE_COMMIT}
- name: dron8s
image: bh90210/dron8s:latest
settings:
yaml: ./deploy.yaml
# variables. Must be lowercase, Usage: {{.service_name}}
image_tag: ${DRONE_COMMIT}
kubeconfig:
from_secret: kubeconfig
---
kind: secret
name: username
get:
path: docker-secret
name: DOCKER_USERNAME
---
kind: secret
name: password
get:
path: docker-secret
name: DOCKER_PASSWORD
---
kind: secret
name: kubeconfig
get:
path: kubeconfig
name: KUBECONFIG
这里只注意name为dron8s的步骤,该步骤使用的插件就叫dron8s,顾名思义,drone的k8s插件,该插件主要功能就是部署k8s项目,setting里的配置简单易懂,setting实际上就是每个插件运行容器的环境变量:
- yaml:k8s的yaml资源文件,该文件我放在了项目的根目录内,和.drone.yml处于同文件夹,所以context就是[./]。
- image_tag:这里实际上是一个自定义变量,你要在yaml内指定k8s部署资源时用的image的tag,这里的CI步骤使用的是全局变量:DRONE_COMMIT作为镜像的tag,所以我们的yaml文件内应该也使用这个变量作为tag,方式是在yaml文件内的image指定tag为{{.image_tag}},如果你的自定义变量不叫image_tag,那这里也应该保持一致。
- kubeconfig:这里应该使用你的集群配置文件的内容,该文件如何获得请参照这篇文章,这个文件的内容是非常机密的,所以我们要填入到仓库机密或k8s secret中,这里使用了后者的方式,可以看到文件末尾定义了kubeconfig的secret。
以上配置都填完后,CD步骤就完成了,怎么样是不是很简单,那么接下来提交代码或者手动触发工作流试试看,没有问题的话会显示如下:

现在可以去你的k8s集群中检查项目是否已经成功部署起来了,没有问题的话,恭喜你已经拥有了自己的k8s droneCICD了!
可能发生的错误
当你执行CD步骤时,会报一个异常,大概是告诉你container冲突,这里实际上是因为dron8s插件用了个k8s较为新颖的特性,该特性允许不同的用户以yaml中的key为单位去管理一个资源,比如一个deployment资源中包含多个container,那么可以配置用户A去管理Acontainer,用户B去管理Bcontainer,然后k8s怕用户A把Bcontainer给改了,这里设置了一个权限:只有该key的创建者可以对其进行修改。
如果你cicd的这个项目已经部署在了你的K8S集群内,那么dron8s可能没有权限去替换该key,所以会报错提示replace key的时候与现有的key产生冲突,好在解决办法也很简单,把你之前手动部署的资源文件直接从k8s删除就可以了,这样dron8s会自己新建这个资源,就不会有权限冲突了。
使用DockerLayerCache优化构建速度
现在你已经拥有了自己的cicd,但如果你经常使用docker build的话,聪明的你一定发现了一个非常吊诡的事情——每次构建竟然都没有use cache!
没错,drone作为一个docker in docker(dind)的CI平台,你的docker build命令实际上是在容器内执行的,而该容器在完成任务后会带着你的构建缓存就地销毁,导致你下一次构建的时候全部都要重来一次,每次项目重建依赖包的时候都会耗费你几分到十几分的人生!
这个问题我当时绕了很大的弯子,用了好几天去查资料做实验,甚至还把公司的测试服务器搞坏掉了,最后发现解决办法异常简单,这里容我卖个关子,我后续的文章会详细讲述如何解决docker layer cache无法在dind环境生效的问题。