在傳統軟件的開發中,代碼的集成工做一般是在全部人都將工做完成後在項目即將結束進行時,而這每每會花費大量的時間和精力。而持續集成是一種將集成階段放在軟件開發階段的作法,以便更加有規律地構建,測試和集成代碼。html
「持續集成並不能消除 Bug,而是讓它們很是容易發現和改正。」java
持續集成能夠在開發人員提交了新代碼後,馬上進行構建、單元測試。從而咱們能夠根據測試結果以肯定新的代碼或者環境配置與原來的以及其餘開發人員的代碼或者環境配置可否正確地集成在一塊兒。linux
持續交付(Continuous Delivery):頻繁地將軟件的新版本,交付給質量團隊或者用戶,以供評審。若是評審經過,代碼就進入生產階段。nginx
持續部署(Continuous Deployment):是持續交付的下一步,指的是代碼評審之後,自動部署到生產環境。git
從 GitLab 8.0 開始,GitLab CI 就已經集成在 GitLab 中,咱們只須要在項目中添加一個 .gitlab-ci.yml
文件,而後添加一個 Runner
,便可進行持續集成。並且隨着 GitLab 的升級,GitLab 也變得愈來愈強大。github
.gtilab-ci.yml
文件存放與項目於倉庫的根目錄,用以來定義 GitLab CI/CD 中的 Pipeline
。其實無非是一個配置文件,理解起來挺簡單的,咱們主要是須要了解 Pipeline
的概念以及如何配置一個 .gitlab-ci.yml
web
一個 Pipeline 大概相對於一個構建任務,裏面能夠包含多個流程,如安裝依賴、運行測試、編譯、部署測試服務器、部署生產服務器等流程,Git 提交時會觸發 Pipeline。而一個 Pipeline 中又能夠包含一至多個 Stage
,即用來定義安裝依賴、運行測試之類的流程的。而後,一個 Stage 中又包含了一至多個 Job
,Jobs 表示一個 Stage 中具體的構建工做,即某個 Stage 裏面執行的工做。咱們能夠在 Stages 裏面定義這些 Job,它們之間的關係以下圖所示:spring
注意:docker
.gitlab-ci.yml
中配置的順序執行,當前面的 Stage 執行完畢後纔會繼續執行後面的 Stage,若是一個 Stage 失敗,那麼後面的 Stage 不會執行,該構建任務失敗。stages: - build - test - deploy build: stage: build script: - "execute-script-for-build" - "do something..."" only: - master tags: - ruby - postage test: stage: test script: ......
上面配置將一次 pipeline 分紅了三個階段:build、test、deploy。下面介紹配置文件中的節點:shell
當咱們理解完上面的概念後,咱們還沒了解最重要的東西——上面的任務由誰來構建呢?答案就是 Gitlab-runner 了!
爲何不用 GitLab CI 來運行這些構建任務呢?
通常來講,構建任務任務都會佔用不少的系統資源(譬如編譯代碼),而 GitLab CI 又是 GitLab 的一部分,若是由 GitLab CI 來運行構建任務的話,在執行構建任務的時候, GitLab 的性能會大幅降低。
GitLab CI 最大的做用是管理各個項目的構建狀態,所以,運行構建任務這種浪費資源的事情就交給 GitLab Runner 來作啦!
由於 GitLab Runner 能夠安裝到不一樣的機器上,因此在構建任務運行期間並不會影響到 GitLab 的性能。
接下來介紹 GitLab 對 Spring Boot 程序的持續集成,固然 GitLab 不止支持 Java 應用服務,確定也支持其餘編譯語言,這裏主要只是像演示一下過程,過程基本上是相通的。
這不是本次的重點,因此就簡要介紹下咯。
利用 Docker 和 Docker Compose 快速搭建 GitLab 服務,docker-compose.yml 文件以下:
version: '3' services: web: image: 'twang2218/gitlab-ce-zh:10.5' restart: always hostname: '192.168.253.139' environment: TZ: 'Asia/Shanghai' GITLAB_OMNIBUS_CONFIG: | external_url 'http://192.168.253.139:8080' gitlab_rails['gitlab_shell_ssh_port'] = 2222 unicorn['port'] = 8888 nginx['listen_port'] = 8080 ports: - '8080:8080' - '8443:443' - '2222:22' volumes: - /usr/local/docker/gitlab/config:/etc/gitlab - /usr/local/docker/gitlab/data:/var/opt/gitlab - /usr/local/docker/gitlab/logs:/var/log/gitlab
啓動完畢後,訪問 http://ip:8080,初始化安裝完成後效果以下:
設置初始化密碼後刷新,就能夠看見登陸界面了,登陸!
ssh-keygen -t rsa -P 'youname'
複製用戶目錄下的 .ssh 文件夾下的公鑰,將其複製到 GitLab 的
/usr/lcoal/docker/runner
/usr/local/docker/runner/enviroment
jdk-8u152-linux-x64.tar.gz
並複製到 /usr/local/docker/runner/environment
在 usr/lcoal/docker/runner/environment
目錄下建立 Dockerfile
FROM gitlab/gitlab-runner:v11.0.2 RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse' > /etc/apt/sources.list && \ echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse' >> /etc/apt/sources.list && \ echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse' >> /etc/apt/sources.list && \ echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse' >> /etc/apt/sources.list && \ apt-get update -y && \ apt-get clean RUN apt-get -y install apt-transport-https ca-certificates curl software-properties-common && \ curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | apt-key add - && \ add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" && \ apt-get update -y && \ apt-get install -y docker-ce COPY daemon.json /etc/docker/daemon.json WORKDIR /usr/local/bin RUN wget https://raw.githubusercontent.com/topsale/resources/master/docker/docker-compose RUN chmod +x docker-compose RUN mkdir -p /usr/local/java WORKDIR /usr/local/java COPY jdk-8u152-linux-x64.tar.gz /usr/local/java RUN tar -zxvf jdk-8u152-linux-x64.tar.gz && \ rm -fr jdk-8u152-linux-x64.tar.gz RUN mkdir -p /usr/local/maven WORKDIR /usr/local/maven RUN wget https://raw.githubusercontent.com/topsale/resources/master/maven/apache-maven-3.5.3-bin.tar.gz RUN tar -zxvf apache-maven-3.5.3-bin.tar.gz && \ rm -fr apache-maven-3.5.3-bin.tar.gz ENV JAVA_HOME /usr/local/java/jdk1.8.0_152 ENV MAVEN_HOME /usr/local/maven/apache-maven-3.5.3 ENV PATH $PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin WORKDIR /
在 /usr/local/docker/runner/environment
目錄下建立 daemon.json
,用於配置加速器和倉庫地址
{ "registry-mirrors": [ "https://registry.docker-cn.com" ], "insecure-registries": [ "ip:port" ] }
新建一個 Git 項目,將其克隆到本地
docker exec -it gitlab-runner gitlab-runner register # 輸入 GitLab 地址 Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/): http://192.168.75.146:8080/ # 輸入 GitLab Token Please enter the gitlab-ci token for this runner: 1Lxq_f1NRfCfeNbE5WRh # 輸入 Runner 的說明 Please enter the gitlab-ci description for this runner: 能夠爲空 # 設置 Tag,能夠用於指定在構建規定的 tag 時觸發 ci Please enter the gitlab-ci tags for this runner (comma separated): 能夠爲空 # 選擇 runner 執行器,這裏咱們選擇的是 shell Please enter the executor: virtualbox, docker+machine, parallels, shell, ssh, docker-ssh+machine, kubernetes, docker, docker-ssh: shell
以上交互中,GitLab 地址和 Token 令牌能夠在 GitLab 的項目的設置中找到:
當上述步驟完成後,刷新當前頁面,能夠看見當前頁面下多出來一個 runner:
在這裏我只簡單地作了個小 dome,大概這麼簡單:
項目中用到的 .gitlab-ci.yml
、Dockerfile
、docker-compose.yml
以下:
.gitlab-ci.yml
stages: - build - run - clean build: stage: build script: - /usr/local/maven/apache-maven-3.5.3/bin/mvn clean package - cp target/ci-test-project-1.0.0-SNAPSHOT.jar docker - cd docker - docker build -t ci-test-project . run: stage: run script: - cd docker - docker-compose down - docker-compose up -d clean: stage: clean script: - docker rmi $(docker images -q -f dangling=true)
Dockerfile
FROM openjdk:8-jre RUN mkdir /app COPY ci-test-project-1.0.0-SNAPSHOT.jar /app/app.jar ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app/app.jar"] EXPOSE 8080
docker-compose.yml
version: '3.1' services: itoken-config: restart: always image: ci-test-project ports: - 8080:8080
完成 demo 的以後就將項目提交到 GitLab 上,push 完成以後,點擊項目的 CI/CD 能夠看見一下頁面
再點擊進入就能夠看見具體的做業了,自行體會
當項目出現全部 jobs 所有經過時,也就是持續集成初步完善了,這時咱們能夠打開瀏覽器訪問 ip:8080
能夠看見瀏覽器上顯示
Hello GitLab
此時咱們能夠嘗試修改項目中的代碼再提交,好比簡單地將 retuen "Hello GitLab"
改爲 return "Hello World"
再提交一遍代碼,等 jobs 經過後,再刷新瀏覽器,咱們能夠看見
Hello World
至此,這個小 Demo 也就完成了。