持續集成(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