Win10下使用Docker搭建Gitlab CI自動(dòng)構(gòu)建平臺(tái)

有幸這幾年待過的公司devops都做的比較完善,每天享受著一鍵編譯打包發(fā)布的快感。最近閑著無事,嘗試著在Win10筆記本電腦上搭建一套自動(dòng)構(gòu)建平臺(tái)玩一玩,在這里記錄下過程。

目標(biāo)和基本環(huán)境

  • 目前公司使用的是gitlab,功能豐富,對(duì)于一般的公司足夠使用。所以使用gitlab作為代碼倉庫,用gitlab ci組件組建持續(xù)編譯工具。
  • 公司配的是Win10電腦,所以整體工具系統(tǒng)的搭建環(huán)境就是:win10 + docker + gitlab + gitlab runner。雖然本文使用的是win10 docker環(huán)境,但相信在maclinux環(huán)境下也是一樣的。
  • 這次只實(shí)現(xiàn)代碼提交到gitlab后的自動(dòng)編譯打包,部署等到下次有機(jī)會(huì)再研究。

整體架構(gòu)

image.png
  • 這個(gè)簡(jiǎn)易的CI系統(tǒng)整體需要搭建兩個(gè)服務(wù),gitlabgitlab runner。
  • 開發(fā)人員除了代碼本身,還需要在項(xiàng)目中編寫一個(gè)gitlab-ci.yml文件,告訴ci系統(tǒng)如何編譯這個(gè)項(xiàng)目,具體包含幾個(gè)ci task。
  • 在成功git push代碼之后,gitlab-runner會(huì)從gitlab上拉取需要執(zhí)行ci任務(wù)的項(xiàng)目,根據(jù)gitlab-ci.yml中的定義執(zhí)行具體的編譯任務(wù),并產(chǎn)出交付物,提供下載或執(zhí)行后續(xù)的部署任務(wù)。

前置準(zhǔn)備

Win10 Docker安裝

  • 在旗艦版Win10上開啟Hyper-V特性,安裝好docker運(yùn)行環(huán)境,應(yīng)該是各位Windows User的基本功,這里就不贅述了。

Docker Compose安裝

使用Docker搭建Gitlab

編寫docker-compose.yml

  • 首先我們需要一個(gè)gitlab,在這我使用sameersbn/gitlab鏡像,組織的docker-compose進(jìn)行gitlab部署。
  • 直接貼出編寫好的yml:
version: '2'

services:
  redis:
    restart: always
    image: sameersbn/redis:4.0.9-2
    command:
    - --loglevel warning
    volumes:
    - redis-data:/var/lib/redis:Z

  postgresql:
    restart: always
    image: sameersbn/postgresql:10-2
    volumes:
    - postgresql-data:/var/lib/postgresql:Z
    environment:
    - DB_USER=gitlab
    - DB_PASS=password
    - DB_NAME=gitlabhq_production
    - DB_EXTENSION=pg_trgm

  gitlab:
    restart: always
    image: sameersbn/gitlab:12.3.5
    depends_on:
    - redis
    - postgresql
    ports:  #gitlab docker與宿主電腦的端口映射
    - "10080:80"  #宿主電腦的10080端口映射到docker的80端口
    - "10022:22"  #同上
    volumes:
    - gitlab-data:/home/git/data:Z
    environment:
    - DEBUG=false

    - DB_ADAPTER=postgresql
    - DB_HOST=postgresql
    - DB_PORT=5432
    - DB_USER=gitlab
    - DB_PASS=password
    - DB_NAME=gitlabhq_production

    - REDIS_HOST=redis
    - REDIS_PORT=6379

    - TZ=Asia/Kolkata
    - GITLAB_TIMEZONE=Kolkata

    - GITLAB_HTTPS=false
    - SSL_SELF_SIGNED=false

    - GITLAB_HOST=10.130.72.51
    - GITLAB_PORT=10080
    - GITLAB_SSH_PORT=10022
    - GITLAB_RELATIVE_URL_ROOT=
    - GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alphanumeric-string
    - GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alphanumeric-string
    - GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alphanumeric-string

    - GITLAB_ROOT_PASSWORD=
    - GITLAB_ROOT_EMAIL=

    - GITLAB_NOTIFY_ON_BROKEN_BUILDS=true
    - GITLAB_NOTIFY_PUSHER=false

    - GITLAB_EMAIL=notifications@example.com
    - GITLAB_EMAIL_REPLY_TO=noreply@example.com
    - GITLAB_INCOMING_EMAIL_ADDRESS=reply@example.com

    - GITLAB_BACKUP_SCHEDULE=daily
    - GITLAB_BACKUP_TIME=01:00

    - SMTP_ENABLED=false
    - SMTP_DOMAIN=www.example.com
    - SMTP_HOST=smtp.gmail.com
    - SMTP_PORT=587
    - SMTP_USER=mailer@example.com
    - SMTP_PASS=password
    - SMTP_STARTTLS=true
    - SMTP_AUTHENTICATION=login

    - IMAP_ENABLED=false
    - IMAP_HOST=imap.gmail.com
    - IMAP_PORT=993
    - IMAP_USER=mailer@example.com
    - IMAP_PASS=password
    - IMAP_SSL=true
    - IMAP_STARTTLS=false

    - OAUTH_ENABLED=false
    - OAUTH_AUTO_SIGN_IN_WITH_PROVIDER=
    - OAUTH_ALLOW_SSO=
    - OAUTH_BLOCK_AUTO_CREATED_USERS=true
    - OAUTH_AUTO_LINK_LDAP_USER=false
    - OAUTH_AUTO_LINK_SAML_USER=false
    - OAUTH_EXTERNAL_PROVIDERS=

    - OAUTH_CAS3_LABEL=cas3
    - OAUTH_CAS3_SERVER=
    - OAUTH_CAS3_DISABLE_SSL_VERIFICATION=false
    - OAUTH_CAS3_LOGIN_URL=/cas/login
    - OAUTH_CAS3_VALIDATE_URL=/cas/p3/serviceValidate
    - OAUTH_CAS3_LOGOUT_URL=/cas/logout

    - OAUTH_GOOGLE_API_KEY=
    - OAUTH_GOOGLE_APP_SECRET=
    - OAUTH_GOOGLE_RESTRICT_DOMAIN=

    - OAUTH_FACEBOOK_API_KEY=
    - OAUTH_FACEBOOK_APP_SECRET=

    - OAUTH_TWITTER_API_KEY=
    - OAUTH_TWITTER_APP_SECRET=

    - OAUTH_GITHUB_API_KEY=
    - OAUTH_GITHUB_APP_SECRET=
    - OAUTH_GITHUB_URL=
    - OAUTH_GITHUB_VERIFY_SSL=

    - OAUTH_GITLAB_API_KEY=
    - OAUTH_GITLAB_APP_SECRET=

    - OAUTH_BITBUCKET_API_KEY=
    - OAUTH_BITBUCKET_APP_SECRET=

    - OAUTH_SAML_ASSERTION_CONSUMER_SERVICE_URL=
    - OAUTH_SAML_IDP_CERT_FINGERPRINT=
    - OAUTH_SAML_IDP_SSO_TARGET_URL=
    - OAUTH_SAML_ISSUER=
    - OAUTH_SAML_LABEL="Our SAML Provider"
    - OAUTH_SAML_NAME_IDENTIFIER_FORMAT=urn:oasis:names:tc:SAML:2.0:nameid-format:transient
    - OAUTH_SAML_GROUPS_ATTRIBUTE=
    - OAUTH_SAML_EXTERNAL_GROUPS=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_EMAIL=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_NAME=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_USERNAME=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_FIRST_NAME=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_LAST_NAME=

    - OAUTH_CROWD_SERVER_URL=
    - OAUTH_CROWD_APP_NAME=
    - OAUTH_CROWD_APP_PASSWORD=

    - OAUTH_AUTH0_CLIENT_ID=
    - OAUTH_AUTH0_CLIENT_SECRET=
    - OAUTH_AUTH0_DOMAIN=
    - OAUTH_AUTH0_SCOPE=

    - OAUTH_AZURE_API_KEY=
    - OAUTH_AZURE_API_SECRET=
    - OAUTH_AZURE_TENANT_ID=

volumes:
  redis-data:
  postgresql-data:
  gitlab-data:
  • 關(guān)鍵點(diǎn):
    • sameersbngitlab部署,需要用到redis, postgresqlgitlab,所以docker-compose.yml中包含了這三個(gè)組件。
    • 每個(gè)組件都設(shè)置了volumes,表示將容器內(nèi)的存儲(chǔ)地址映射到本地硬盤路徑,這樣容器就可以保存運(yùn)行時(shí)的數(shù)據(jù)狀態(tài)。
    • gitlab中配置了端口映射,訪問本機(jī)10080端口將會(huì)打開gitlab主頁。
    • gitlab.environment中主要把GITLAB_HOST配置成測(cè)試用的域名,或者本機(jī)的ip地址,因?yàn)楹罄m(xù)gitlab runner需要通過這個(gè)地址與gitlab通訊。其他配置可以看需要修改。

啟動(dòng)gitlab

  • 將寫好的docker-compose.yml保存至一個(gè)文件夾中,如:D:\docker\gitlab\docker-compose.yml,在命令行中進(jìn)入D:\docker\gitlab\路徑,執(zhí)行docker-compose up

    image.png

  • 運(yùn)行完成后,通過ip訪問本機(jī)10080端口,便可看到gitlab主頁:

    image.png

  • 使用root帳號(hào)即可登錄。

使用Docker部署Gitlab Runner

gitlab ci配置頁

  • 打開管理中心 > 概覽 > Runner,這里能看到目前配置的gitlab runner
    image.png
  • 我們主要關(guān)注點(diǎn)是配置runner使用的urltoken。

編寫Runner docker-compose并執(zhí)行

version: '3'
services:
    runner:
      image: 'gitlab/gitlab-runner:v11.4.2'
      container_name: gitlab-runner
      restart: always 
      privileged: true
      volumes: 
        - ./config:/etc/gitlab-runner
        - /var/run/docker.sock:/var/run/docker.sock
  • 關(guān)鍵點(diǎn):在volumes需要指定docker.sock,這個(gè)與docker執(zhí)行的上下文環(huán)境有關(guān),這里不作太多說明。
  • 同樣的,把文件保存到一個(gè)單獨(dú)目錄,執(zhí)行docker-compose up
    image.png

注冊(cè)Gitlab Runner

  • 運(yùn)行docker exec -it gitlab-runner gitlab-runner register命令,將docker中的gitlab-runner注冊(cè)到gitlab上:
    image.png
  • 依次輸入gitlab配置頁面上的urltoken,runner的描述,runnertag(多個(gè)可以用逗號(hào)隔開),executor類型使用docker,默認(rèn)的鏡像使用docker。
  • 注冊(cè)完成后,在gitlab管理頁面上就能看到runner:


    image.png

創(chuàng)建SpringBoot項(xiàng)目,對(duì)接gitlab-ci

在Gitalb中創(chuàng)建Project

  • 創(chuàng)建Project并提交Springboot項(xiàng)目代碼,這里不贅述過程。

編寫.gitlab-ci.yml配置文件

  • 在項(xiàng)目源碼根目錄下,創(chuàng)建.gitlab-ci.yml文件,這文件描述了ci過程的各個(gè)任務(wù)和需要的資源。
image: docker:latest  #1
variables:  #2
  MAVEN_OPTS: "-Dmaven.repo.local=.m2"
  DOCKER_DRIVER: overlay2

cache:  #3 緩存maven repository
  key: maven-repository-cache
  paths:
    - .m2

services:  #4 使用docker鏡像執(zhí)行任務(wù)
  - docker:dind
stages:  #5  定義CI過程有幾個(gè)stage
  - package

maven-package:  #6  定義一個(gè)task
  image: maven:3.5-jdk-8-alpine

  tags:  # 此任務(wù)在具有哪個(gè)tag上的runner執(zhí)行
    - maven
  stage: package  # 此task對(duì)應(yīng)哪個(gè)stage
  script:
    - mvn clean package -Dmaven.test.skip=true
  artifacts:  # CI交付物
    paths:
      - target/*.jar
    expire_in: 1 day  # 一天后過期
  • 關(guān)鍵點(diǎn):
    • stage:定義ci過程有幾個(gè)階段,gitlab-ci會(huì)按順序執(zhí)行每個(gè)stage。
    • task定義maven-package
      • stage:指定這個(gè)task屬于哪個(gè)階段。同一個(gè)階段下的所有task并發(fā)執(zhí)行。
      • tag:指定此task要在具有哪個(gè)tag的runner上執(zhí)行,可以實(shí)現(xiàn)需要不同編譯環(huán)境的任務(wù)在特定runner上運(yùn)行,如ios app編譯需要在mac環(huán)境下的runner運(yùn)行。
      • image:此任務(wù)使用哪個(gè)鏡像進(jìn)行ci任務(wù),這里使用帶有maven-jdk的鏡像。
      • scriptci任務(wù)的執(zhí)行腳本,springboot項(xiàng)目使用mvn命令進(jìn)行編譯打包。

提交代碼,觸發(fā)gitlab-ci

  • 編寫好項(xiàng)目代碼和.gitlab-ci.yml,Push至gitlab,就會(huì)觸發(fā)ci過程:
    image.png
  • CI任務(wù)的詳細(xì)過程,可以在這個(gè)頁面中下載到CI交付物:
    image.png

優(yōu)化點(diǎn)和后續(xù)

  • 目前maven編譯使用的是公共maven鏡像,默認(rèn)連接的是中央倉庫,我們可以繼承它做一個(gè)連接到公司私服的maven鏡像,提供給ci任務(wù)進(jìn)行編譯。
  • 這個(gè)示例ci只做了編譯,后續(xù)可以對(duì)接k8s實(shí)現(xiàn)自動(dòng)部署,這樣一整套CI/CD工具就完整了。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容