中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

基于drone如何構建CI-CD系統

發布時間:2022-01-12 10:18:48 來源:億速云 閱讀:213 作者:iii 欄目:云計算

本篇內容主要講解“基于drone如何構建CI-CD系統”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“基于drone如何構建CI-CD系統”吧!

kubernetes集群三步安裝

CI 概述

用一個可描述的配置定義整個工作流

程序員是很懶的動物,所以想各種辦法解決重復勞動的問題,如果你的工作流中還在重復一些事,那么可能就得想想如何優化了

持續集成就是可以幫助我們解決重復的代碼構建,自動化測試,發布等重復勞動,通過簡單一個提交代碼的動作,解決接下來要做的很多事。

容器技術使這一切變得更完美。

<!--more-->

典型的一個場景:

我們寫一個前端的工程,假設是基于vue.js的框架開發的,提交代碼之后希望跑一跑測試用例,然后build壓縮一個到dist目錄里,再把這個目錄的靜態文件用nginx代理一下。 最后打成docker鏡像放到鏡像倉庫。 甚至還可以增加一個在線上運行起來的流程。

現在告訴你,只需要一個git push動作,接下來所有的事CI工具會幫你解決!這樣的系統如果你還沒用上的話,那請問還在等什么。接下來會系統的向大家介紹這一切。

代碼倉庫管理

首先SVN這種渣渣軟件就該盡早淘汰,沒啥好說的,有git真的沒有SVN存在的必要了我覺得。

所以我們選一個git倉庫,git倉庫比較多,我這里選用gogs,gitea gitlab都行,根據需求自行選擇

docker run -d --name gogs-time -v /etc/localtime:/etc/localtime -e TZ=Asia/Shanghai --publish 8022:22 \
           --publish 3000:3000 --volume /data/gogs:/data gogs:latest

訪問3000端口,然后就沒有然后了 gogs功能沒有那么強大,不過占用資源少,速度快,我們穩定運行了幾年了。缺點就是API不夠全。

CI 工具

當你用過drone之后。。。

裝:

version: '2'

services:
  drone-server:
    image: drone/drone:0.7
    ports:
      - 80:8000
    volumes:
      - /var/lib/drone:/var/lib/drone/
    restart: always
    environment:
      - DRONE_OPEN=true
      - DOCKER_API_VERSION=1.24
      - DRONE_HOST=10.1.86.206
      - DRONE_GOGS=true
      - DRONE_GOGS_URL=http://10.1.86.207:3000/   # 代碼倉庫地址
      - DRONE_SECRET=ok

  drone-agent:
    image: drone/drone:0.7
    command: agent
    restart: always
    depends_on:
      - drone-server
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DOCKER_API_VERSION=1.24
      - DRONE_SERVER=ws://drone-server:8000/ws/broker
      - DRONE_SECRET=ok

docker-compose up -d 然后你懂的,也沒有然后了

用gogs賬戶登錄drone即可

每個步驟就是個容器,每個插件也是個容器,各種組合,簡直就是活字印刷術

怎么使用這種初級膚淺的內容我就不贅述了,但是有很多坑的地方:

  • 裝drone的機器能用aufs盡量用,device mapper有些插件是跑不了的,如一些docker in docker的插件,這不算是drone的毛病,只能說docker對 docker in docker支持不夠好

  • centos對aufs支持不夠好,如果想用centos支持aufs,那你可得折騰折騰了,社區方案在此:https://github.com/sealyun/kernel-ml-aufs

  • 最推薦的是drone的機器內核升級到4.9以上,然后docker使用overlay2存儲驅動,高版本內核跑容器筆者也實踐過比較長的時間了,比低內核穩定很多

安裝方式2,在k8s上安裝:

helm install stable/drone

使用篇

首先在你的代碼倉庫主目錄下新建三個文件:

  • .drone.yml : 描述構建與部署的流程(狹義),流程配置文件(廣義)CI/CD無本質區別

  • Dockerfile : 告訴你的應用如何打包成鏡像,當然如果不是容器化交付可以不需要

  • k8s yaml配置文件 or docker-compose文件 or chart包 :告訴你的應用如何部署

  • 其他 :如kube-config等

用gogs賬戶密碼登錄到drone頁面上之后同步下項目就可以看到項目列表,打開開關就可以關聯到git倉庫,比較簡單,自行探索 基于drone如何構建CI-CD系統

官方事例

pipeline:
  backend:    # 一個步驟的名稱,可以隨便全名
    image: golang  # 每個步驟的本質都是基于這個鏡像去啟動一個容器
    commands:      # 在這個容器中執行一些命令
      - go get
      - go build
      - go test

  frontend:
    image: node:6
    commands:
      - npm install
      - npm test

  publish:
    image: plugins/docker
    repo: octocat/hello-world
    tags: [ 1, 1.1, latest ]
    registry: index.docker.io

  notify:
    image: plugins/slack
    channel: developers
    username: drone

各步驟啟動的容器共享workdir這個卷, 這樣build步驟的結果產物就可以在publish這個容器中使用

結合Dockerfile看:

# docker build --rm -t drone/drone .

FROM drone/ca-certs
EXPOSE 8000 9000 80 443

ENV DATABASE_DRIVER=sqlite3
ENV DATABASE_CONFIG=/var/lib/drone/drone.sqlite
ENV GODEBUG=netdns=go
ENV XDG_CACHE_HOME /var/lib/drone

ADD release/drone-server /bin/   #  因為工作目錄共享,所以就可以在publish時使用到 build時的產物,這樣構建和發布就可以分離

ENTRYPOINT ["/bin/drone-server"]

上面說到構建與發布分離,很有用,如構建golang代碼時我們需要go環境,但是線上或者運行時其實只需要一個可執行文件即可,

所以Dockerfile里就可以不用FROM一個golang的基礎鏡像,讓你的鏡像更小。又比如java構建時需要maven,而線上運行時不需要,

所以也是可以分離。

用drone時要發揮想象,千萬不要用死了,上面每句話都需要仔細讀一遍,細細理解。再總結一下關鍵點:

drone自身是不管每個步驟是什么功能的,只傻瓜式幫你起容器,跑完正常就執行下個步驟,失敗就終止。

編譯,提交到鏡像倉庫,部署,通知等功能都是由鏡像的功能,容器的功能決定的 drone里叫插件,插件本質就是鏡像,有一丟丟小區別后面說

這意味著你想干啥就弄啥鏡像,如編譯時需要maven,那去做個maven鏡像,部署時需要對接k8s,那么搞個有kubectl客戶端的鏡像;要物理機部署那么搞個 ansible的鏡像,等等,發揮想象,靈活使用。

drone環境變量

有時我們希望CI出來的docker鏡像tag與git的tag一致,這樣的好處就是知道運行的是哪個版本的代碼,升級等等都很方便,不過每次都去修改pipeline 文件顯然很煩,那么drone就可以有很多環境變量來幫助我們解決這個問題:

pipeline:
    build:
        image: golang:1.9.2 
        commands:
            - go build -o test --ldflags '-linkmode external -extldflags "-static"'
        when:
            event: [push, tag, deployment]
    publish:
        image: plugins/docker
        repo: fanux/test
        tags: ${DRONE_TAG=latest}
        dockerfile: Dockerfile
        insecure: true
        when:
            event: [push, tag, deployment]

這個例子${DRONE_TAG=latest} 如果git tag事件觸發了pipeline那就把git tag當鏡像tag,否則就用latest,這樣我們自己研發過程中就 可以一直用latest迭代,覺得版本差不多了,打個tag,生成一個可以給測試人員測試的鏡像,非常優雅,不需要改什么東西,不容易出錯

同理還有很多其它的環境變量可以用,如git的commitID 分支信息等等, 這里可以查

對接k8s實踐

首先得有個k8s集群,那么首選:kubernetes集群三步安裝 廣告,無視就好。。。

有了上面的鋪墊,對接k8s就相當簡單了:搞個kubectl的鏡像嵌入流程中即可:

把項目的k8s yaml文件放到代碼中,然后pipelie里直接apply

  publish:
    image: plugins/docker   # 鏡像倉庫,執行Dockerfile插件
    tags:
      - ${DRONE_TAG=latest}
    insecure: true  # 照抄
  
  deploy:
     image: kubectl:test  # 這個鏡像自己去打即可
     commands:
          - cat test.yaml
          - ls   
          - rm -rf /root/.kube && cp -r .kube /root # k8s 的kubeconfig文件,可以有多個,部署到哪個集群就拷貝哪個kubeconfig文件
          - kubectl delete -f test.yaml || true
          - kubectl apply -f test.yaml

不過最佳實踐還有幾個細節:

  • k8s 的kubeconfig文件同樣放在了代碼目錄(這個不太安全,不過倉庫私有還好,還可以利用drone的secret,不細展開)

  • k8s 部署的yaml文件里的鏡像怎么配置? 每次都修改test.yaml多不爽

  • 如果多個集群yaml配置有區別怎么辦?寫多個yaml?造成混亂,非常不優雅

所以我們引入chart, 用helm進行部署:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: test
  namespace: {{ .Values.namespace }}
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    metadata:
      labels:
        name: test
    spec:
      serviceAccountName: test
      containers:
      - name: test
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"  # deployment的yaml文件是模板,創建時再傳參進來渲染
        imagePullPolicy: {{ .Values.image.pullPolicy }} 
....

注意,有了模板之后,我們部署v1版本和v2版本時就不需要改動yaml文件,這樣降低出錯風險,pipeline執行時把環境變量傳進來,完美解決

這樣git tag 鏡像tag與yaml里鏡像配置實現了完全的統一:

    deploy_dev:   # 部署到開發環境
        image: helm:v2.8.1
        commands:
            - mkdir -p /root/.kube && cp -r .kube/config-test101.194 /root/.kube 
            - helm delete test --purge || true
            - helm install --name test --set image.tag=${DRONE_TAG=latest}  Chart
        when:
            event: deployment
            environment: deploy_dev

    deploy_test:  # 部署到測試環境
        image: helm:v2.8.1
        commands:
            - mkdir -p /root/.kube && cp -r .kube/config-test101.84 /root/.kube  # 兩個環境使用不同的kubeconfig
            - helm delete test --purge || true
            - helm install --name test --set image.tag=${DRONE_TAG=latest}  Chart # 把git tag傳給helm,這樣運行的鏡像就是publish時構建的鏡像,tag一致
        when:
            event: deployment
            environment: deploy_test

以上,優雅的解決了上面問題

細節:event可以是git的事件也可以是手動處罰的事件,類型是deployment時就是手動觸發的,drone支持命令行觸發

我們進行了二次開發,讓drone可以在頁面上觸發對應的事件

原理篇

drone上開通一個倉庫時,會給倉庫設置一個webhook,在項目設置里可以看到,這樣git的事件就可以通知到drone,drone根據事件去拉取代碼走流程

pipeline基本原理

理解原理對使用這個系統非常重要,否則就會把一個東西用死。

pipeline就負責起容器而已,容器干啥的系統不關心,用戶決定 這句話本文不止強調過一次,非常重要多讀幾遍

插件原理

鏡像即插件,也就是可能現有很多鏡像都能直接當作插件嵌入到drone流程中。

有個小區別是,你會發現drone有些插件還帶一些參數,這就是比普通的鏡像多做了一丟丟事,如publish時打docker的鏡像:

  publish:
    image: plugins/docker
    repo: octocat/hello-world
    tags: [ 1, 1.1, latest ]
    registry: index.docker.io

你會發現它有 repo tags什么的參數,其實drone處理時非常簡單,就是把這些參數轉化成環境變量傳給容器了, 然后容器去處理這些參數。 本質就是做了這個事情:

docker run --rm \
  -e PLUGIN_TAG=latest \
  -e PLUGIN_REPO=octocat/hello-world \
  -e DRONE_COMMIT_SHA=d8dbe4d94f15fe89232e0402c6e8a0ddf21af3ab \
  -v $(pwd):$(pwd) \
  -w $(pwd) \
  --privileged \
  plugins/docker --dry-run

那我們自定義一個插件就簡單了,只要寫個腳本能處理特定環境變量即可,如一個curl的插件:

pipeline:
  webhook:
    image: foo/webhook
    url: http://foo.com
    method: post
    body: |
      hello world

寫個腳本

#!/bin/sh

curl \
  -X ${PLUGIN_METHOD} \  # 處理一個幾個環境變量
  -d ${PLUGIN_BODY} \
  ${PLUGIN_URL}
FROM alpine
ADD script.sh /bin/
RUN chmod +x /bin/script.sh
RUN apk -Uuv add curl ca-certificates
ENTRYPOINT /bin/script.sh
docker build -t foo/webhook .
docker push foo/webhook

打成docker鏡像,大功告成

所以大部分情況我們會很懶的什么也不寫,直接在容器里執行命令就是了,同樣是一個curl的需求,不寫插件的話

pipeline:
  webhook:
    image: busybox  # 直接用busybox
    command: 
    - curl -X POST -d 123 http://foo.com  完事,插件都懶得開發了

值得注意的是一些復雜功能還是需要開發插件的,如publish鏡像時用的插件。關于該插件我想補充一句 它是docker里面起了一個docker engine,用docker內的docker engine進行打鏡像的 所以devicemapper存儲驅動是支持不了的。請升級內核用overlay2,或者ubuntu用aufs

到此,相信大家對“基于drone如何構建CI-CD系統”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

乌鲁木齐市| 逊克县| 宣武区| 栖霞市| 固安县| 内江市| 调兵山市| 咸宁市| 旬阳县| 安宁市| 杨浦区| 兴文县| 修武县| 丘北县| 锡林郭勒盟| 那坡县| 连州市| 巴中市| 永福县| 会昌县| 德安县| 六安市| 鹤峰县| 乌兰察布市| 株洲市| 吕梁市| 聊城市| 深泽县| 扎兰屯市| 崇仁县| 恩施市| 仙桃市| 乌鲁木齐县| 义马市| 台东县| 石楼县| 岳阳市| 宜川县| 鱼台县| 武义县| 赤壁市|