• Post author:
  • Post category:运维
  • Post comments:0评论
  • Reading time:3 mins read

终于到了最激动人心的时刻了,自动化部署!

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环境生效的问题。

葫芦

葫芦,诞生于1992年8月11日,游戏宅,胶佬,爱好摸鱼,一个干过超市收银,工地里搬过砖,当过广告印刷狗,做过电焊铁艺的现役.Net程序员。

发表回复