CI/CD工具介紹
2022/10/13
名詞解釋
-
CI
-
Continuous Integration
-
持續整合
-
是一種軟體工程流程,在測試驅動開發(TDD)的作法中,通常還會搭配自動單元測試。
-
持續整合的提出主要是為解決軟體進行系統整合時面臨的各項問題。
-
-
CD
-
Continuous Deployment/Delivery
-
持續部署/交付
-
持續部署是將開發的產品或系統以系統導向方式持續地將系統部署到指定階段環境
-
如開發的環境(development environment)
-
如上線環境(production environment)
-
-
持續部署是將開發的產品或是系統功能持續的改進與交付給需求方
-
CI工具分類
-
由雲端主機供應商推出
-
私人公司推出的CI/CD工具產品或服務
-
自架版本
-
雲端服務版本
-
由雲端主機供應商推出
-
AWS
-
AWS CodePipeline
-
-
Azure
-
Azure DevOps
-
-
Google Cloud Platform
- Cloud Build、Cloud Deploy 以及 Cloud Run
私人公司推出的CI/CD工具產品或服務
-
Jenkins
-
GitLab CI/CD
自架版本(self-hosted)
私人公司推出的CI/CD工具產品或服務
-
Travis CI
-
GitLab.com上的GitLab CI/CD
- CircleCI
- GitHub Workflows
雲端服務版本(cloud)
Jenkins安裝(自架需要先安裝)
peter@devops-demo:~$ sudo apt-get install openjdk-11-jdk-headless
peter@devops-demo:~$ wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
[sudo] password for peter:
OK
peter@devops-demo:~$ sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
peter@devops-demo:~$
peter@devops-demo:~$ sudo apt-get update
Hit:2 http://mirrors.digitalocean.com/ubuntu focal InRelease
Hit:3 https://repos-droplet.digitalocean.com/apt/droplet-agent main InRelease
Hit:4 http://mirrors.digitalocean.com/ubuntu focal-updates InRelease
Hit:5 http://mirrors.digitalocean.com/ubuntu focal-backports InRelease
Ign:1 https://pkg.jenkins.io/debian-stable binary/ InRelease
Get:6 https://pkg.jenkins.io/debian-stable binary/ Release [2044 B]
Get:7 https://pkg.jenkins.io/debian-stable binary/ Release.gpg [833 B]
Hit:8 http://security.ubuntu.com/ubuntu focal-security InRelease
Get:9 https://pkg.jenkins.io/debian-stable binary/ Packages [23.2 kB]
Fetched 26.1 kB in 1s (42.5 kB/s)
Reading package lists... Done
peter@devops-demo:~$ sudo apt-get install jenkins
......
peter@devops-demo:~$ systemctl status jenkins.service
● jenkins.service - Jenkins Continuous Integration Server
Loaded: loaded (/lib/systemd/system/jenkins.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2022-10-13 17:04:11 UTC; 20s ago
Main PID: 13531 (java)
Tasks: 51 (limit: 9508)
Memory: 2.2G
CGroup: /system.slice/jenkins.service
└─13531 /usr/bin/java -Djava.awt.headless=true -jar /usr/share/java/jenkins.war --webroot=/var>
peter@devops-demo:~$
Jenkins設定並選擇安裝推薦的外掛
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915812/pasted-from-clipboard.png)
Jenkins設定並選擇安裝推薦的外掛
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915821/pasted-from-clipboard.png)
Jenkins建立第一個管理員使用者
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915833/pasted-from-clipboard.png)
Jenkins執行instance設定
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915839/pasted-from-clipboard.png)
開始使用Jenkins
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915842/pasted-from-clipboard.png)
開始使用Jenkins
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915846/pasted-from-clipboard.png)
在Jenkins上建立新的作業
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915848/pasted-from-clipboard.png)
在Jenkins上建立新的作業-Hello Pipelines
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915852/pasted-from-clipboard.png)
在Jenkins上建立新的作業-執行Hello Pipelines
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915860/pasted-from-clipboard.png)
在Jenkins上建立新的作業-執行Hello Pipelines
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915871/pasted-from-clipboard.png)
安裝Pipeline As YAML外掛
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915875/pasted-from-clipboard.png)
安裝Pipeline As YAML外掛
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915880/pasted-from-clipboard.png)
安裝Pipeline As YAML外掛
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915884/pasted-from-clipboard.png)
使用Pipeline As YAML外掛
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915982/pasted-from-clipboard.png)
執行使用Pipeline As YAML外掛的pipelines
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9915973/pasted-from-clipboard.png)
GitLab CI/CD-安裝GitLab CE版本
root@devops-demo:/tmp# apt-get update
root@devops-demo:/tmp# apt-get install ca-certificates curl openssh-server postfix
root@devops-demo:~# cd /tmp/
root@devops-demo:/tmp# curl -LO https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 6865 100 6865 0 0 30923 0 --:--:-- --:--:-- --:--:-- 30923
root@devops-demo:/tmp# bash script.deb.sh
......
The repository is setup! You can now install packages.
root@devops-demo:/tmp# apt-get install gitlab-ce
.......
Thank you for installing GitLab!
GitLab was unable to detect a valid hostname for your instance.
Please configure a URL for your GitLab instance by setting `external_url`
configuration in /etc/gitlab/gitlab.rb file.
Then, you can start your GitLab instance by running the following command:
sudo gitlab-ctl reconfigure
For a comprehensive list of configuration options please see the Omnibus GitLab readme
https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md
Help us improve the installation experience, let us know how we did with a 1 minute survey:
https://gitlab.fra1.qualtrics.com/jfe/form/SV_6kVqZANThUQ1bZb?installation=omnibus&release=15-4
root@devops-demo:/tmp#
GitLab CI/CD-安裝GitLab CE版本(設定GitLab)
root@devops-demo:/tmp# vim /etc/gitlab/gitlab.rb
root@devops-demo:/tmp# cat /etc/gitlab/gitlab.rb | grep '^external_url'
external_url 'https://gitlab.peterli.website'
root@devops-demo:/tmp# cat /etc/gitlab/gitlab.rb | grep '^letsencrypt'
letsencrypt['contact_emails'] = ['peter279k@gmail.com'] # This should be an array of email addresses to add as contacts
root@devops-demo:/tmp# gitlab-ctl reconfigure
......
Running handlers:
[2022-10-13T18:18:24+00:00] INFO: Running report handlers
Running handlers complete
[2022-10-13T18:18:24+00:00] INFO: Report handlers complete
Infra Phase complete, 650/1720 resources updated in 05 minutes 14 seconds
Notes:
Default admin account has been configured with following details:
Username: root
Password: You didn't opt-in to print initial root password to STDOUT.
Password stored to /etc/gitlab/initial_root_password. This file will be cleaned up in first reconfigure run after 24 hours.
NOTE: Because these credentials might be present in your log files in plain text, it is highly recommended to reset the password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password.
gitlab Reconfigured!
root@devops-demo:/tmp# cat /etc/gitlab/initial_root_password
# WARNING: This value is valid only in the following conditions
# 1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`, it was provided before database was seeded for the first time (usually, the first reconfigure run).
# 2. Password hasn't been changed manually, either via UI or via command line.
#
# If the password shown here doesn't work, you must reset the admin password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password.
Password: l+ReQBz71nutZq7BPZ4nqD9eKpW472iWLk+30oHsfUI=
# NOTE: This file will be automatically deleted in the first reconfigure run after 24 hours.
root@devops-demo:/tmp#
GitLab CI/CD-瀏覽GitLab網址(https://gitlab.peterli.website)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9916159/pasted-from-clipboard.png)
GitLab CI/CD-瀏覽GitLab網址(建立專案)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9916173/pasted-from-clipboard.png)
GitLab CI/CD-瀏覽GitLab網址(建立Git專案)
root@devops-demo:/tmp# cd
root@devops-demo:~# mkdir hello-gitlab-ci
root@devops-demo:~# cd hello-gitlab-ci/
root@devops-demo:~/hello-gitlab-ci# vim .gitlab-ci.yml
root@devops-demo:~/hello-gitlab-ci# cat .gitlab-ci.yml
build-job:
stage: build
script:
- echo "Hello, $GITLAB_USER_LOGIN!"
test-job1:
stage: test
script:
- echo "This job tests something"
test-job2:
stage: test
script:
- echo "This job tests something, but takes more time than test-job1."
- echo "After the echo commands complete, it runs the sleep command for 20 seconds"
- echo "which simulates a test that runs 20 seconds longer than test-job1"
- sleep 20
deploy-prod:
stage: deploy
script:
- echo "This job deploys something from the $CI_COMMIT_BRANCH branch."
environment: production
root@devops-demo:~/hello-gitlab-ci# git init
Initialized empty Git repository in /root/hello-gitlab-ci/.git/
root@devops-demo:~/hello-gitlab-ci#
GitLab CI/CD-瀏覽GitLab網址(建立Git專案)
root@devops-demo:~/hello-gitlab-ci# git remote add origin https://gitlab.peterli.website/gitlab-instance-9f10964a/hello-gitlab-ci
root@devops-demo:~/hello-gitlab-ci# git config --global user.email peter279k@gmail.com
root@devops-demo:~/hello-gitlab-ci# git config --global user.name peter279k
root@devops-demo:~/hello-gitlab-ci# git add .
root@devops-demo:~/hello-gitlab-ci# git config --global core.editor vim
root@devops-demo:~/hello-gitlab-ci# git commit -a
[master (root-commit) fddb677] Initial commit
1 file changed, 23 insertions(+)
create mode 100644 .gitlab-ci.yml
root@devops-demo:~/hello-gitlab-ci# git push origin master
Username for 'https://gitlab.peterli.website': root
Password for 'https://root@gitlab.peterli.website':
warning: redirecting to https://gitlab.peterli.website/gitlab-instance-9f10964a/hello-gitlab-ci.git/
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 496 bytes | 496.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://gitlab.peterli.website/gitlab-instance-9f10964a/hello-gitlab-ci
* [new branch] master -> master
root@devops-demo:~/hello-gitlab-ci#
GitLab CI/CD-瀏覽GitLab網址(運行專案之GitLab CI/CD)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9916200/pasted-from-clipboard.png)
GitLab CI/CD-瀏覽GitLab網址(安裝Docker)
GitLab CI/CD-瀏覽GitLab網址(安裝GitLab Runner)
root@devops-demo:~# curl -LJO "https://gitlab-runner-downloads.s3.amazonaws.com/latest/deb/gitlab-runner_amd64.deb"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
48 414M 48 203M 0 0 10.6M 0 0:00:38 0:00:19 0:00:19 12.1M
root@devops-demo:~# dpkg -i gitlab-runner_amd64.deb
Selecting previously unselected package gitlab-runner.
(Reading database ... 157514 files and directories currently installed.)
Preparing to unpack gitlab-runner_amd64.deb ...
Unpacking gitlab-runner (15.4.0) ...
......
15.4.0
Check and remove all unused containers (both dangling and unreferenced) including volumes.
------------------------------------------------------------------------------------------
Total reclaimed space: 0B
root@devops-demo:~# gitlab-runner status
Runtime platform arch=amd64 os=linux pid=23296 revision=43b2dc3d version=15.4.0
gitlab-runner: Service is running
GitLab CI/CD-瀏覽GitLab網址(安裝GitLab Runner)
root@devops-demo:~/hello-gitlab-ci# gitlab-runner register
Runtime platform arch=amd64 os=linux pid=24415 revision=43b2dc3d version=15.4.0
Running in system-mode.
Enter the GitLab instance URL (for example, https://gitlab.com/):
https://gitlab.peterli.website/
Enter the registration token:
GR1348941Z1qeA8HkLxPvTaji52Zp
Enter a description for the runner:
[devops-demo]: hello-gitlab-ci
Enter tags for the runner (comma-separated):
hello-gitlab-ci
Enter optional maintenance note for the runner:
Registering runner... succeeded runner=GR1348941Z1qeA8Hk
Enter an executor: docker, docker-ssh, shell, docker+machine, docker-ssh+machine, kubernetes, custom, ssh, virtualbox, parallels:
docker
Enter the default Docker image (for example, ruby:2.7):
python:3.7
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
Configuration (with the authentication token) was saved in "/etc/gitlab-runner/config.toml"
root@devops-demo:~/hello-gitlab-ci#
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9916327/pasted-from-clipboard.png)
GitLab CI/CD-瀏覽GitLab網址(安裝GitLab Runner)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9916331/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404993/images/9916333/pasted-from-clipboard.png)
Travis CI(雲端服務版本)
.travis.yml
language: python
python:
- "2.7"
- "3.4"
- "3.5"
- "3.6" # current default Python on Travis CI
- "3.7"
- "3.8"
- "3.9"
- "3.9-dev" # 3.9 development branch
- "nightly" # nightly build
# command to install dependencies
install:
- pip install -r requirements.txt
# command to run tests
script:
- pytest
Circle CI(雲端服務版本)
.circleci/config.yml
version: 2.1
orbs:
python: circleci/python@2.0.3
heroku: circleci/heroku@1.2.6
jobs:
build_and_test: # this can be any name you choose
executor: python/default
steps:
- checkout
- python/install-packages:
pkg-manager: pip
- run:
name: Run tests
command: python -m pytest
- persist_to_workspace:
root: ~/project
paths:
- .
deploy: # this can be any name you choose
executor: python/default
steps:
- attach_workspace:
at: ~/project
- heroku/deploy-via-git:
force: true # force push when pushing to the heroku remote, see: https://devcenter.heroku.com/articles/git
workflows:
test_my_app:
jobs:
- build_and_test
- deploy:
requires:
- build_and_test # only deploy if the build_and_test job has completed
filters:
branches:
only: main # only deploy when on main
GitHub Workflow(雲端服務版本)
.github/workflows/your-ci-name.yml
name: Test Workflow
on: push
jobs:
first-job:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Run Action
# we can give directory path that contains action.yaml or repo address in username/repository_name@version format
# in our case it would be nashmaniac/create-issue-action@v1.0 where v1.0 is the version of action
# for now we will give directory path. The directory must contain action.yaml
uses: ./
# pass user input as arguments
with:
title: Build Failed
token: ${{secrets.GITHUB_TOKEN}} # default token in GitHub Workflow
assignees: ${{github.actor}} # actor who started the workflow
labels: worflow-failed
body: Workflow failed for commit ${{github.sha}}
總結比較
CI/CD工具或服務名稱 | 優點 | 缺點 |
---|---|---|
Travis CI | 快速、方便與好用 | 只有提供雲端服務 |
GitHub Workflow | 與GitHub平台整合佳 | 只有提供雲端服務 |
CircleCI | 方便與好用 | 只有提供雲端服務 |
GitLab CI/CD | 與GitLab平台整合佳 | 安裝自架版本後會附加GitLab的專案託管平台 |
Jenknis | 可自架、維護與管理 | 需要會寫平台自定義Pipelines語言 或是安裝外掛支援YAML檔案編寫CI/CD設定檔 有很多既有的功能是支援Java專案的 其他程式語言專案的測試環境要先自己架好 也可以使用Docker image建置測試環境 |
參考資料
-
https://www.digitalocean.com/community/tutorials/how-to-install-jenkins-on-ubuntu-20-04
-
https://www.jenkins.io/blog/2018/04/25/configuring-jenkins-pipeline-with-yaml-file
-
https://github.com/jenkinsci/pipeline-as-yaml-plugin/blob/master/src/test/resources/job/pipelineTestWithBranches.yml
-
https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-gitlab-on-ubuntu-18-04
-
https://docs.gitlab.com/runner/install/linux-manually.html
-
https://docs.docker.com/engine/install/ubuntu
-
https://docs.gitlab.com/ee/ci/examples
-
https://docs.gitlab.com/ee/ci/quick_start
-
https://docs.travis-ci.com/user/languages/python
-
https://circleci.com/docs/language-python
-
https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
-
https://medium.com/@xthewiz/notify-jenkins-for-push-event-on-gitlab-18e2e4104827
-
https://www.cnblogs.com/panzi/p/10536654.html
CI/CD Tools Survey
By peter279k
CI/CD Tools Survey
CI/CD Tools Survey
- 437