持续集成(Continous Intergration,CI)是一种软件开发实践,即团队开发成员常常集成它们的工做,一般每一个成员天天至少集成一次,也就意味着天天可能会发生屡次集成。每次集成都须要经过自动化的编译、发布、自动化回归测试来验证,从而尽快地发现集成错误。而这些自动化的操做则由CI软件进行执行。node
持续部署(Continous Delivery,CD)在持续集成的基础上,将集成后的代码部署到真实运行环境中(本文指部署到kubernetes集群)。交付团队 ->版本控制 ->构建和单元测试 ->自动验收测试 -> 发布git
Drone 是一个基于Docker容器技术的可扩展的持续集成引擎,用于自动化测试、构建、发布。每一个构建都在一个临时的Docker容器中执行,使开发人员可以彻底控制其构建环境并保证隔离。开发者只需在项目中包含 .drone.yml文件,将代码推送到 git 仓库,Drone就可以自动化的进行编译、测试、发布。github
首先来看下丑陋的图web
一、开发人员向git(gitlab/github/gogs)提交代码,代码中必须包含Dockerfile和.drone.yml文件。
二、将代码commit到远程仓库;发布应用时须要填写服务类型、服务名称、资源数量、实例个数等信息
三、gogs触发drone自动构建
四、Drone的CI流水线中包括了自定义脚本,根据准备好的kubernetes的YAML模板,将其中的变量替换成用户输入的选项
生成应用的kubernetes YAML配置文件
五、Drone的CI流水线自动编译代码并打包成docker镜像推送到Harbor镜像仓库
六、更新DNS,插入一条DNS记录,IP地址是ingress节点的IP地址。
七、Drone的CI流水线中自定义脚本调用kubernetes的API,部署应用;更新Ingress的配置,根据新部署的应用的名称,在ingress的配置文件中增长一条路由信息
接下来,开始实战docker
本文使用gogs,固然你能够选择gitlab,github等代码仓库
一、建立gogs.yamlapi
--- 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
二、执行部署并查看结果浏览器
[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
三、浏览器打开,并配置gogs,而后就能够登陆gogs了bash
四、登陆gogs
至此,gogs配置完毕。
Tips:本文的gogs,是测试环境,使用卷类型为:emptyDir,生产环境最好单独部署或者使用StorageClass保证数据持久可用性
接下来部署droneapp
一、编写drone.yaml文件ssh
--- 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
二、执行部署并查看结果
[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
三、如今就能够用浏览器访问http://192.168.100.181:31681 ,使用gogs的帐号就能够登陆drone了
四、登陆后能够看到,如今并无任何项目,后续再gogs新建项目,就能看到了
Runner的做用是询问Drone Server,而后执行pipeline,更多信息请查看官网
一、编写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
二、执行部署并查看结果
[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
一、gogs新建项目demo
二、drone上点sync,就能够看到demo项目
三、激活demo项目,保存
四、在gogs的demo项目中,添加.drone.yml文件,添加一个pipeline
五、提交代码,可是不触发CI,Commit的时候填写[CI SKIP]就能够跳过触发CI
若是这里直接Commit提交代码,就直接触发CI功能,Drone就开始执行这个pipeline了
[CI SKIP]的做用就是若是须要修改多个文件,这时候会颇有用;
固然在实际开发过程当中,都是把项目clone到本地,编辑好全部文件,再push到代码仓库,这样就不须要[CI SKIP]了
六、咱们这里随便修改 README,而后知己commit,不是用[CI SKIP]看下效果
七、执行结果,这里失败了,后面再解决
八、若是您commit之后并无触发Drone,须要在gogs查看webhooks时候正常,以下图
九、这里咱们来解决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