WHY GITLAB-CI
WHY GITLAB-CI
vs Jenkins
ABOUT JENKINS
The powerful CI system
Framework
- 延展性 (成堆的Plugin)
- 所有配置都可以在 Jenkins 上做完
- 自由度爆表 (sheeeellscript!)
- 報表
WHY GITLAB-CI
其實只是想偷懶
(簡單一點世界和平)
- 懶人包整合 gitlab
- 所有動作都可以寫 yml 完成 (不負責發言)
- 維護上相對簡單
.gitlab-ci.yml
Configuration of your jobs
起手式 → stages
stages:
- prepare
- lint
- test
- build
- package
- deploy
stages 中會有哪些 job
stages:
- prepare
- lint
- test
- build
- package
- deploy
app:installing_dependencies:
image: $NODE_IMAGE
stage: prepare
script:
- cd app/
- npm install
retry: 2
artifacts:
paths:
- app/node_modules
crawler:installing_dependencies:
image: $NODE_IMAGE
stage: prepare
script:
- cd crawler/
- npm install
retry: 2
artifacts:
paths:
- crawler/node_modules
share:installing_dependencies:
image: $NODE_IMAGE
stage: prepare
script:
- cd share/
- npm install
retry: 2
artifacts:
paths:
- share/node_modules
variables:
NODE_IMAGE: node:10.13.0
Okay, it looks good
BUT...
app:installing_dependencies:
image: $NODE_IMAGE
stage: prepare
script:
- cd app/
- npm install
retry: 2
artifacts:
paths:
- app/node_modules
crawler:installing_dependencies:
image: $NODE_IMAGE
stage: prepare
script:
- cd crawler/
- npm install
retry: 2
artifacts:
paths:
- crawler/node_modules
share:installing_dependencies:
image: $NODE_IMAGE
stage: prepare
script:
- cd share/
- npm install
retry: 2
artifacts:
paths:
- share/node_modules
artifacts 實際上...?
app:ensure_the_code_quality:
image: $NODE_IMAGE
stage: lint
dependencies:
- app:installing_dependencies
script:
- cd app/
- npm run lint
allow_failure: true
Everything goes right
UNTIL...
Build the docker image
app:docker-build:
stage: package
dependencies:
- build_static_assets
script:
- echo $VERSION > app/version
- docker build -f app/Dockerfile -t $APP_GCR:$VERSION .
- docker push $APP_GCR:$VERSION
only:
- tags
variables:
NODE_ENV: production
VERSION: $CI_COMMIT_TAG
Yeah! You're good to go, kid!
WAIT
gitlab-runner 是 base on docker...
那在 docker 內跑 docker...
Docker in Docker
HOW?
Docker in Docker
Yeah! Hold on......WAAAAT!?
Docker in Docker
Docker in Docker
總的來說,還得補一些東西上去 - 1
[[runners]]
url = "https://gitlab.com/"
token = TOKEN
executor = "docker"
[runners.docker]
tls_verify = false
image = "docker:stable"
privileged = true
disable_cache = false
volumes = ["/cache"]
[runners.cache]
Insecure = false
首先得在 gitlab runner 加上 privileged flag
Docker in Docker
總的來說,還得補一些東西上去 - 2A
app:docker-build:
image: docker:stable
stage: package
dependencies:
- build_static_assets
services:
- docker:dind
script:
- echo $VERSION > app/version
- docker build -f app/Dockerfile -t $APP_GCR:$VERSION .
- docker push $APP_GCR:$VERSION
only:
- tags
variables:
NODE_ENV: production
VERSION: $CI_COMMIT_TAG
DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2
然後在你的 gitlab-ci.yml 加上需要的 variable
以及引用服務 dind
Docker in Docker
總的來說,還得補一些東西上去 - 2A+
variables:
# When using dind service we need to instruct docker, to talk with the
# daemon started inside of the service. The daemon is available with
# a network connection instead of the default /var/run/docker.sock socket.
#
# The 'docker' hostname is the alias of the service container as described at
# https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services
#
# Note that if you're using Kubernetes executor, the variable should be set to
# tcp://localhost:2375 because of how Kubernetes executor connects services
# to the job container
DOCKER_HOST: tcp://docker:2375/
# When using dind, it's wise to use the overlayfs driver for
# improved performance.
DOCKER_DRIVER: overlay2
DOCKER_HOST 用來讓 docker 知道 service deamon 在哪裡
DOCKER_DRIVER 則是用來改善效能
Docker in Docker
總的來說,還得補一些東西上去 - 2B
[[runners]]
url = "https://gitlab.com/"
token = REGISTRATION_TOKEN
executor = "docker"
[runners.docker]
tls_verify = false
image = "docker:stable"
privileged = false
disable_cache = false
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
[runners.cache]
Insecure = false
或是另一個方式,掛上自己,但是會有造成所有 container 都會是 runner 的兄弟,而不是 runner 的子節點
在官方文件上有提到這種方式只適用於極少情況
Docker in Docker
app:docker-build:
image: docker:stable
stage: package
dependencies:
- build_static_assets
services:
- docker:dind
script:
- echo $VERSION > app/version
- docker build -f app/Dockerfile -t $APP_GCR:$VERSION .
- docker push $APP_GCR:$VERSION
only:
- tags
variables:
NODE_ENV: production
VERSION: $CI_COMMIT_TAG
DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2
HOW?
CREDENTIAL??
I need google cloud sdk...
I don't wanna create any credential files...
And support docker in docker...
Text
app:docker-build:
image: mtpeak/google-cloud-sdk-with-kubectl:docker
stage: package
dependencies:
- build_static_assets
services:
- docker:dind
before_script:
- gcloud auth configure-docker -q
script:
- echo $VERSION > app/version
- gsutil cp -r app/.nuxt/dist gs://$ASSETS_GCS_BUCKET_NAME/$VERSION
- docker build -f app/Dockerfile -t $APP_GCR:$VERSION .
- docker push $APP_GCR:$VERSION
only:
- tags
variables:
NODE_ENV: production
VERSION: $CI_COMMIT_TAG
DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2
Yeah! You're good to go, kid!
- docker build 可維護性
- runner executor with docker-machine => scalable + 不用想 credential 該怎麼丟 (
等等,我好像沒講到 executor 設定相關) - gitlab-ci.yml 易讀好學外加很多參數可以用,不需要寫 script 拿值
- 無痛整合 gitlab
Wrap it up
- 準備個 slack bot 做 production deploy confirm (build 完後在 slack 確認才做 k8s update)
- 整理 cache 讓流程可以跑快一點
- 搬家到 DRONE
The next...
Introduce the gitlab-CI
By Calvin Huang
Introduce the gitlab-CI
- 1,653