什么是CI/CD

持续集成(Continous Intergration,CI)是一种软件开发实践,即团队开发成员经常集成它们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都需要通过自动化的编译、发布、自动化回归测试来验证,从而尽快地发现集成错误。而这些自动化的操作则由CI软件进行执行。

持续部署(Continous Delivery,CD)在持续集成的基础上,将集成后的代码部署到真实运行环境中(本文指部署到kubernetes集群)。交付团队 ->版本控制 ->构建和单元测试 ->自动验收测试 -> 发布

什么是Drone

Drone 是一个基于Docker容器技术的可扩展的持续集成引擎,用于自动化测试、构建、发布。每个构建都在一个临时的Docker容器中执行,使开发人员能够完全控制其构建环境并保证隔离。开发者只需在项目中包含 .drone.yml文件,将代码推送到 git 仓库,Drone就能够自动化的进行编译、测试、发布。

使用drone实现CD/CD

首先来看下丑陋的图

简单梳理流程:

1、开发人员向git(gitlab/github/gogs)提交代码,代码中必须包含Dockerfile和.drone.yml文件。

2、将代码commit到远程仓库;发布应用时需要填写服务类型、服务名称、资源数量、实例个数等信息

3、gogs触发drone自动构建

4、Drone的CI流水线中包括了自定义脚本,根据准备好的kubernetes的YAML模板,将其中的变量替换成用户输入的选项

生成应用的kubernetes YAML配置文件

5、Drone的CI流水线自动编译代码并打包成docker镜像推送到Harbor镜像仓库

6、更新DNS,插入一条DNS记录,IP地址是ingress节点的IP地址。

7、Drone的CI流水线中自定义脚本调用kubernetes的API,部署应用;更新Ingress的配置,根据新部署的应用的名称,在ingress的配置文件中增加一条路由信息

接下来,开始实战

部署代码仓库gogs

本文使用gogs,当然你可以选择gitlab,github等代码仓库

1、创建gogs.yaml

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: gogs
labels:
app: gogs
spec:
serviceName: gogs
replicas: 1
selector:
matchLabels:
app: gogs
template:
metadata:
labels:
app: gogs
spec:
terminationGracePeriodSeconds: 180
containers:
- name: gogs
image: gogs/gogs
imagePullPolicy: Always
ports:
- containerPort: 3000
name: port
- containerPort: 22
name: ssh-port
volumeMounts:
- name: volume
mountPath: /data
volumes:
- name: volume
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: gogs
labels:
app: gogs
spec:
type: NodePort
ports:
- port: 3000
targetPort: 3000
selector:
app: gogs

2、执行部署并查看结果

[root@k8s-node001 gogs]# kubectl  apply -f gogs.yaml
statefulset.apps/gogs created
service/gogs created [root@k8s-node001 gogs]# kubectl get po,svc -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/gogs-0 1/1 Running 0 2m2s 100.68.150.197 k8s-node001 <none> <none> NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/gogs NodePort 10.106.102.74 <none> 3000:30526/TCP 2m3s app=gogs

3、浏览器打开,并配置gogs,然后就可以登录gogs了

4、登录gogs



至此,gogs配置完毕。

Tips:本文的gogs,是测试环境,使用卷类型为:emptyDir,生产环境最好单独部署或者使用StorageClass保证数据持久可用性

接下来部署drone

部署CI工具Drone

1、编写drone.yaml文件

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: drone
labels:
app: drone
spec:
serviceName: drone
replicas: 1
selector:
matchLabels:
app: drone
template:
metadata:
labels:
app: drone
spec:
terminationGracePeriodSeconds: 180
containers:
- name: drone
image: drone/drone:1
imagePullPolicy: Always
env:
- name: DRONE_AGENTS_ENABLED
value: "true"
- name: DRONE_GOGS_SERVER
value: http://192.168.100.181:30526/ # 注意这里填的是gogs的地址
- name: DRONE_RPC_SECRET
value: qawsedrftg
- name: DRONE_SERVER_HOST
value: drone.company.com
- name: DRONE_SERVER_PROTO
value: http
ports:
- containerPort: 80
name: port
- containerPort: 443
name: ssl-port
volumeMounts:
- name: volume
mountPath: /data
volumes:
- name: volume
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: drone
labels:
app: drone
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
selector:
app: drone

2、执行部署并查看结果

[root@k8s-node001 drone]# kubectl  apply -f drone.yaml

[root@k8s-node001 drone]# kubectl get po,svc  -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/drone-0 1/1 Running 0 4m40s 100.68.150.198 k8s-node001 <none> <none> NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/drone NodePort 10.100.77.138 <none> 80:31681/TCP 4m40s app=drone

3、现在就可以用浏览器访问http://192.168.100.181:31681 ,使用gogs的账号就可以登录drone了



4、登录后可以看到,现在并没有任何项目,后续再gogs新建项目,就能看到了

部署Drone Runner

Runner的作用是询问Drone Server,然后执行pipeline,更多信息请查看官网

1、编写drone-runner.yaml

---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: drone
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: drone
namespace: default
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: Role
name: drone
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: drone-runner
labels:
app.kubernetes.io/name: drone-runner
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: drone-runner
template:
metadata:
labels:
app.kubernetes.io/name: drone-runner
spec:
containers:
- name: drone-runner
image: drone/drone-runner-kube:latest
ports:
- containerPort: 3000
env:
- name: DRONE_RPC_HOST
value: 192.168.100.181:31681 # Drone Server地址
- name: DRONE_RPC_PROTO
value: http
- name: DRONE_RPC_SECRET
value: qawsedrftg # Drone Server部署时候填写的secret

2、执行部署并查看结果

[root@k8s-node001 drone]# kubectl  apply -f drone-runner.yaml

[root@k8s-node001 drone]# kubectl  get po
NAME READY STATUS RESTARTS AGE
drone-runner-7c64bffb45-dh2dn 1/1 Running 0 11m

至此,实现CI/CD的环境都准备好了,现在来跑一个demo

CI/CD示例

1、gogs新建项目demo



2、drone上点sync,就可以看到demo项目



3、激活demo项目,保存



4、在gogs的demo项目中,添加.drone.yml文件,添加一个pipeline



5、提交代码,但是不触发CI,Commit的时候填写[CI SKIP]就可以跳过触发CI



如果这里直接Commit提交代码,就直接触发CI功能,Drone就开始执行这个pipeline了

[CI SKIP]的作用就是如果需要修改多个文件,这时候会很有用;

当然在实际开发过程中,都是把项目clone到本地,编辑好所有文件,再push到代码仓库,这样就不需要[CI SKIP]了

6、我们这里随便修改 README,然后知己commit,不是用[CI SKIP]看下效果



7、执行结果,这里失败了,后面再解决



8、如果您commit以后并没有触发Drone,需要在gogs查看webhooks时候正常,如下图



9、这里我们来解决pipeline执行失败的问题

我们通过drone界面可以看到项目pipeline报错如下,显示runner clone代码失败了

Initialized empty Git repository in /drone/src/.git/
+ git fetch origin +refs/heads/master:
fatal: unable to access 'http://192.168.100.181:3000/scofield/demo.git/': Failed to connect to 192.168.100.181 port 3000: Connection refused

首先看下这个pipeline,很简单,使用镜像alpine执行两条输出语句

kind: pipeline
type: kubernetes
name: default steps:
- name: greeting
image: alpine
commands:
- echo hello
- echo world

但是默认情况下,Drone执行pipeline之前会克隆项目,url就是gogs的http地址,这里是http://192.168.100.181:3000/scofield/demo.git 因为我这里测试环境使用NodePort暴露的服务,Drone需要使用http://192.168.100.181:30526/scofield/demo.git 这个地址才能克隆到项目,如果使用ingress暴露gogs服务,这个url就是域名而不是IP,就不会出现这个问题。

那现在需要解决这个问题,我们就自定义clone,修改默认的克隆地址,修改如下,修改完直接commit代码,触发CI



通过drone页面查看结果,可以看到clone成功



而且执行的echo命令也成功执行



至此本文实战结束

总结

本文是“基于Docker及Kubernetes构建的容器云平台”系列第十篇,也是最后一篇,如果您看完了整个系列文章,在此感谢。

通过这十篇文章,您应该可以构建出一个测试环境的容器平台。关于容器云平台更多内容,后续会继续分享,尽请持续关注。

PS:后续文章会同步到dev.kubeops.net

容器云平台No.10~通过gogs+drone+kubernetes实现CI/CD的更多相关文章

  1. 容器云平台No.1~基于Docker及Kubernetes构建的容器云平台

    开篇 最近整理笔记,不知不觉发现关于kubernetes相关的笔记已经达99篇了,索性一起总结了.算是对这两年做容器云平台的一个总结,本文是开篇,先介绍下所有用到的组件.首先来看下架构图(实在画的太丑 ...

  2. 【原创】基于Docker的CaaS容器云平台架构设计及市场分析

    基于Docker的CaaS容器云平台架构设计及市场分析 ---转载请注明出处,多谢!--- 1 项目背景---概述: “在移动互联网时代,企业需要寻找新的软件交付流程和IT架构,从而实现架构平台化,交 ...

  3. Kubernetes容器云平台建设实践

    [51CTO.com原创稿件]Kubernetes是Google开源的一个容器编排引擎,它支持自动化部署.大规模可伸缩.应用容器化管理.伴随着云原生技术的迅速崛起,如今Kubernetes 事实上已经 ...

  4. 容器云平台使用体验:DaoCloud

    容器技术风起云涌,在国内也涌现出了很多容器技术创业公司,本文介绍容器厂商DaoCloud提供的容器云平台,通过使用容器云平台,可以让大家更加了解容器,并可以学习不同容器云平台的优势. 1.       ...

  5. 容器云平台No.4~kubernetes 服务暴露之Ingress

    这是容器云平台第四篇,接上一篇继续, 首先kubernetes服务暴露有如下几种方式: NodePort Loadbalance ClusterIP Ingress 本文紧贴第一篇架构图,只介绍Ing ...

  6. 容器云平台No.2~kubeadm创建高可用集群v1.19.1

    通过kubernetes构建容器云平台第二篇,最近刚好官方发布了V1.19.0,本文就以最新版来介绍通过kubeadm安装高可用的kubernetes集群. 市面上安装k8s的工具很多,但是用于学习的 ...

  7. 微服务与K8S容器云平台架构

    微服务与K8S容器云平台架构 微服务与12要素 网络 日志收集 服务网关 服务注册 服务治理- java agent 监控 今天先到这儿,希望对技术领导力, 企业管理,系统架构设计与评估,团队管理, ...

  8. 026.[转] 基于Docker及Kubernetes技术构建容器云平台 (PaaS)

    [编者的话] 目前很多的容器云平台通过Docker及Kubernetes等技术提供应用运行平台,从而实现运维自动化,快速部署应用.弹性伸缩和动态调整应用环境资源,提高研发运营效率. 本文简要介绍了与容 ...

  9. 轻量化安装 TKEStack:让已有 K8s 集群拥有企业级容器云平台的能力

    关于我们 更多关于云原生的案例和知识,可关注同名[腾讯云原生]公众号~ 福利: ①公众号后台回复[手册],可获得<腾讯云原生路线图手册>&<腾讯云原生最佳实践>~ ②公 ...

随机推荐

  1. 算法-图(4)用边表示活动的网络(AOE网络)Activity On Edge Network

    有向边表示活动,权值表示活动的持续时间,顶点表示事件. 只有一个开始点和完成点,称为源点.汇点,完成工程时间取决于从源点到汇点的最长路径长度,即在这条路径(关键路径)上所有活动的持续时间之和.关键路径 ...

  2. jieba分词-强大的Python 中文分词库

    1. jieba的江湖地位 NLP(自然语言)领域现在可谓是群雄纷争,各种开源组件层出不穷,其中一支不可忽视的力量便是jieba分词,号称要做最好的 Python 中文分词组件. 很多人学习pytho ...

  3. Excel-Countif函数对重复值的处理之删除、统计和标记

    问题场景 删除重复值: 统计重复项出现的次数: 对比两列,找出重复项. 场景一 某列员工编号user_id相当于身份证,可以唯一代表这个人,需要删除重复项. 目标 将user_id重复的人员所在行都删 ...

  4. Selenium执行js脚本

    如何使用Selenium来执行Javascript脚本呢 Selenium中提供了一个方法:execute_script 来执行js脚本 return 可以返回js的返回结果 execute_scri ...

  5. Laravel5的验证码功能

    第三方扩展包 mews/captcha 作为基础来实现 Laravel 中的验证码功能 安装 注册 配置验证码文件 前端引用 后端验证 安装前准备(我这边没执行这个,安装成功,但是搜到的文件有写,不清 ...

  6. python学习第八天

    解析库之bs4的基本使用方法 ''' pip install beautifulsoup4#安装bs4 pip install lxml#安装lxml ''' html_doc = "&qu ...

  7. 深入了解Kafka【四】消费者的Offset管理

    1.Offset Topic Consumer通过提交Offset来记录当前消费的最后位置,以便于消费者发生崩溃或者有新的消费者加入消费者组,而引发的分区再均衡操作,每个消费者可能会分到不同的分区.我 ...

  8. My Github Repository

    最近在Github上整了个Repository来保存打过的比赛的代码,包括Codeforces,Google Code Jam和Google Kick Start等,之后应该也会搞一点刷题的代码. 之 ...

  9. HTTP协议中的提交方式和解释POST、GET、HEAD、PUT等

    最基本的方法有4种,分别是GET,POST,PUT,DELETE HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作 GET一般用于获取/查询资源信息,而PO ...

  10. SpringBoot整合Quartz及log4j实例

    SpringBoot整合Quartz及log4j实例 因为之前项目中经常会做一些定时Job的东西,所以在此记录一下,目前项目中已经使用elastic-job,这个能相对比Quartz更加简单方便一些, ...