gitlab-runner实现CICD
先简单介绍一下gitlab-runner
GitLab Runner 是一个与 GitLab CI/CD 一起使用以在管道中运行作业的应用程序。
您可以选择在您拥有或管理的基础设施上安装GitLab Runner 应用程序。如果这样做,出于安全和性能原因,您应该将 GitLab Runner 安装在与托管 GitLab 实例的机器不同的机器上。当您使用不同的机器时,您可以在每台机器上拥有不同的操作系统和工具,例如 Kubernetes 或 Docker。
GitLab Runner 是开源的,用Go编写。它可以作为单个二进制文件运行;不需要特定语言的要求。
您可以在几个不同的受支持操作系统上安装 GitLab Runner。其他操作系统也可以工作,只要您可以在它们上编译 Go 二进制文件。
GitLab Runner 也可以在 Docker 容器内运行或部署到 Kubernetes 集群中
这里可以docker安装也可以裸机部署,为了方便,我这里选择docker部署
第一步,安装gitlab,这里有三种方式可以安装,我这里选择docker engine
docker run --detach --hostname localhost --publish 443:443 --publish 80:80 --publish 222:22 --name gitlab --restart always --volume /giblab/config:/etc/gitlab --volume /giblab/logs:/var/log/gitlab --volume /giblab/data:/var/opt/gitlab --shm-size 256m gitlab/gitlab-ee:latest
确保gitlab正常启动
查看gitlab默认密码
[root@node1 config]# docker exec -it gitlab 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: 7NMXACjqBTUQBJtFuVHnrGDeddAQJ9hbC5zUAbIcSjY= # NOTE: This file will be automatically deleted in the first reconfigure run after 24 hours.
登录浏览器登录gitlab
默认用户名:root
第二步,新建gitlab项目
第三步,查看注册gitlab-runner的token,看你是想注册项目的runner,组的runner还是共享的runner,如果是项目runner或者是组的runner,那么权限有限,只能按照项目或者组去运行,如果share共享类型的runnner,那么可以执行任何项目,我这里注册一个share类型的runner
第四步,安装gitlab-runner,这里安装gitlab-runner也可以裸机安装,也可以docker安装,为了更好实现cicd,我使用的是裸机安装,点击下面的按钮可以查看如何裸机安装gitlab-runner
一通操作之后查看gitlab-runner是否正常启动
第五步,注册runner
[root@node1 ~]# gitlab-runner register --url http://localhost/ --registration-token ivvoCJfBTZ56BFuiMMtC Runtime platform arch=amd64 os=linux pid=14276 revision=c6bb62f6 version=14.10.0 Running in system-mode. Enter the GitLab instance URL (for example, https://gitlab.com/): [http://localhost/]: Enter the registration token: [ivvoCJfBTZ56BFuiMMtC]: Enter a description for the runner: [node1]: share-runner Enter tags for the runner (comma-separated): tag Enter optional maintenance note for the runner: shell Registering runner... succeeded runner=ivvoCJfB Enter an executor: custom, ssh, docker+machine, docker-ssh+machine, kubernetes, docker, docker-ssh, parallels, shell, virtualbox: shell Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
查看gitlab,是否有注册成功的runner,可以看到,已经有runner了,并且是share类型的
把下面这个勾上,否则执行不了
第六步,编写.gitlab-ci.yml文件,这个是默认的文件名字,不要修改文件名
内容格式如下:
stages: # List of stages for jobs, and their order of execution - build - test - deploy build-job: # This job runs in the build stage, which runs first. stage: build script: - echo "Compiling the code..." - echo "Compile complete." unit-test-job: # This job runs in the test stage. stage: test # It only starts when the job in the build stage completes successfully. script: - echo "Running unit tests... This will take about 60 seconds." - sleep 60 - echo "Code coverage is 90%" lint-test-job: # This job also runs in the test stage. stage: test # It can run at the same time as unit-test-job (in parallel). script: - echo "Linting code... This will take about 10 seconds." - sleep 10 - echo "No lint issues found." deploy-job: # This job runs in the deploy stage. stage: deploy # It only runs when *both* jobs in the test stage complete successfully. script: - echo "Deploying application..." - echo "Application successfully deployed."
执行后结果如下:
gitlab-runner in k8s版本
1.添加仓库
helm repo add gitlab https://charts.gitlab.io
2.helm拉取仓库
helm pull gitlab/gitlab-runner
3.修改values.yml文件,修改完成之后的内容如下:
这里需要注意的是,因为pod需要有权限去创建pod,要调用apiserver,因此需要rbac权限,并且需要docker命令,因此需要挂载宿主机的docker进程!
image: registry: registry.gitlab.com image: gitlab-org/gitlab-runner imagePullPolicy: IfNotPresent gitlabUrl: http://192.168.28.149/ runnerRegistrationToken: "GR1348941JguWkEEiDTUWdyVzd2DW" terminationGracePeriodSeconds: 3600 concurrent: 10 checkInterval: 30 sessionServer: enabled: false rbac: create: true resources: ["*"] verbs: ["*"] rules: [] clusterWideAccess: false podSecurityPolicy: enabled: false resourceNames: - gitlab-runner metrics: enabled: false portName: metrics port: 9252 serviceMonitor: enabled: false service: enabled: false type: ClusterIP runners: config: | [[runners]] executor = "kubernetes" [runners.kubernetes] image = "docker:20.10.18" privileged = true helper_image = "registry.gitlab.com/gitlab-org/ci-cd/gitlab-runner-ubi-images/gitlab-runner-helper-ocp:x86_64-v13.11.0" [[runners.kubernetes.volumes.host_path]] name = "docker-sock" read_only = true mount_path = "/var/run/docker.sock" host_path = "/var/run/docker.sock" [[runners.kubernetes.services]] name = "docker:19.03.12-dind" alias = "docker" executor: kubernetes image: centos:7 imagePullPolicy: "if-not-present" locked: false tags: "k8s-runner" runUntagged: false protected: false privileged: true namespace: gitlab cache: {} builds: {} services: cpuLimit: 200m memoryLimit: 256Mi cpuRequests: 100m memoryRequests: 128Mi helpers: cpuLimit: 200m memoryLimit: 256Mi cpuRequests: 100m memoryRequests: 128Mi image: "registry.gitlab.com/gitlab-org/ci-cd/gitlab-runner-ubi-images/gitlab-runner-helper-ocp:x86_64-v13.11.0" pod_security_context: run_as_non_root: true run_as_user: 100 run_as_group: 100 fs_group: 65533 supplemental_groups: [101, 102] securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: false runAsNonRoot: true privileged: false capabilities: drop: ["ALL"] podSecurityContext: runAsUser: 0 fsGroup: 65533 resources: limits: memory: 256Mi cpu: 200m requests: memory: 128Mi cpu: 100m affinity: {} nodeSelector: {} tolerations: [] hostAliases: - ip: "127.0.0.1" hostnames: - "minikube-k8s" podAnnotations: {} podLabels: {} priorityClassName: "" secrets: [] configMaps: {} volumeMounts: [] volumes: []
4.安装部署gitlab-runner
helm install k8s-runner -f ./values.yaml gitlab/gitlab-runner -n gitlab
5.查看gitlab是否有注册商runner
6.测试,添加.gitlab-ci.yaml文件,内容如下
需要注意,如果用pod来去做docker build这种操作,就需要配置service.docker为dind版本(docker in docker)
image: docker:20.10.18 services: - docker:20.10.16-dind stages: # List of stages for jobs, and their order of execution - deploy deploy-job: # This job runs in the deploy stage. stage: deploy # It only runs when *both* jobs in the test stage complete successfully. environment: production script: - echo "Deploying application..." - echo "Application successfully deployed." - docker build -t test:v1 ./
7.把项目git push到仓库中看是否执行成功
查看镜像是否制作成功
ok!!!
案例
.gitlab-ci.yml内容如下
## # 注意variables需要字符串型值,yaml的 1 和 "1"不通 # DDING_ROBOT_TOKEN 钉钉机器人的token # CHANDAO_PROJECT_ID 禅道的project id # CHANDAO_PRODUCT_ID 禅道的product id ## variables: GIT_SUBMODULE_STRATEGY: recursive DDING_ROBOT_TOKEN: xxxx CHANDAO_PROJECT_ID: "1" CHANDAO_PRODUCT_ID: "5" stages: - unittest - package - deploy2test - sendqa - deploy before_script: - source gitlab-ci/activate.sh - export PROJECT_NAME=`pwd | awk -F '/' '{print $NF}'` - mkdir bin - cp config.yml.sample config.yml - gitlab-ci/ci_helper.py config.version ${BUILD_VERSION} - mv version.json bin/ - export DEV_IMAGE=registry.cn-beijing.aliyuncs.com/xxxdev/${PROJECT_NAME}:${BUILD_VERSION} - export TEST_IMAGE=registry.cn-beijing.aliyuncs.com/xxxtest/${PROJECT_NAME}:${BUILD_VERSION} - export ONLINE_IMAGE=registry.cn-beijing.aliyuncs.com/xxx/${PROJECT_NAME}:${BUILD_VERSION} - export TEST_DEPLOY_TO=$PROJECT_NAME - if [[ $GIT_BRANCH == *"/dev_"* ]]; then export TEST_DEPLOY_TO=`echo $GIT_BRANCH | awk -F '/dev_' '{print $2}'`; fi - echo "test will deploy to:"$TEST_DEPLOY_TO unittest: stage: unittest script: - echo "no unittest" package it: stage: package only: - /^v[0-9]+[\.0-9]+\/dev.*$/ except: - tags script: - if [ "$GIT_BRANCH" != "master" ] && [ $(git diff origin/master|wc -l) == "0" ]; then echo "new branch created, nothing to do"; exit 0; fi - echo "-----------Build image for branch $GIT_BRANCH" - proxy4 go mod download - proxy4 go build ./cmd/appcourse - proxy4 go build ./cmd/admin - proxy4 go build ./cmd/console - mv ./appcourse bin/ - mv ./admin bin/ - mv ./console bin/ - gitlab-ci/ci_helper.py dockerfile.go_ffmpeg ${AUTHOR_NAME} ${AUTHOR_EMAIL} ${PROJECT_NAME} - docker build --no-cache -t ${DEV_IMAGE} . - docker push ${DEV_IMAGE} - docker rmi ${DEV_IMAGE} - gitlab-ci/ci_helper.py notification.dingding "测试打包成功:" "${PROJECT_NAME}" "${DEV_IMAGE}" "user=${AUTHOR_NAME}" "email=${AUTHOR_EMAIL}" package failed : stage: package when: on_failure only: - /^v[0-9]+[\.0-9]+\/dev.*$/ except: - tags script: - if [ "$GIT_BRANCH" != "master" ] && [ $(git diff origin/master|wc -l) == "0" ]; then echo "new branch created, nothing to do"; exit 0; fi - gitlab-ci/ci_helper.py notification.dingding "测试打包失败:" "${PROJECT_NAME}:${BUILD_VERSION}" "user=${AUTHOR_NAME}" "email=${AUTHOR_EMAIL}" deploy2test: stage: deploy2test only: - /^v[0-9]+[\.0-9]+\/dev.*$/ except: - tags script: - if [ "$GIT_BRANCH" != "master" ] && [ $(git diff origin/master|wc -l) == "0" ]; then echo "new branch created, nothing to do"; exit 0; fi - git clone git@git.365jiating.com:server/test-docker.git - cd test-docker && bash ./builddeploy.sh -p ${TEST_DEPLOY_TO} -v ${BUILD_VERSION} && cd .. - cd ${PROJECT_PATH} - gitlab-ci/ci_helper.py notification.dingding "测试环境部署成功:" "${PROJECT_NAME}" ">>> deploy to:${TEST_DEPLOY_TO}" "${TEST_IMAGE}" "who?=${AUTHOR_EMAIL}" - echo "push email to qa done" to qa: stage: sendqa when: manual only: - /^v[0-9]+[\.0-9]+\/dev.*$/ except: - tags script: - if [ "$GIT_BRANCH" != "master" ] && [ $(git diff origin/master|wc -l) == "0" ]; then echo "new branch created, nothing to do"; exit 0; fi - gitlab-ci/ci_helper.py notification.dingding "项目提测:" "${PROJECT_NAME}" "${BUILD_VERSION}" "who?=${AUTHOR_EMAIL}" - gitlab-ci/ci_helper.py notification.to_test deploy: stage: deploy only: - tags script: - if [ $(git diff origin/master|wc -l) != "0" ]; then gitlab-ci/ci_helper.py notification.dingding "project=${PROJECT_NAME}" "user=${AUTHOR_NAME}" "请将代码合并入master后再打tag"; exit 0; fi - proxy4 go mod download - proxy4 go build ./cmd/appcourse/ - proxy4 go build ./cmd/admin - proxy4 go build ./cmd/console - gitlab-ci/online-config.sh ${PROJECT_NAME} - mv ./appcourse bin/ - mv ./admin bin/ - mv ./console bin/ - gitlab-ci/ci_helper.py dockerfile.go_ffmpeg ${AUTHOR_NAME} ${AUTHOR_EMAIL} ${PROJECT_NAME} - docker build -t ${ONLINE_IMAGE} . - docker push ${ONLINE_IMAGE} - docker rmi ${ONLINE_IMAGE} - gitlab-ci/ci_helper.py notification.dingding "线上包打包成功:" "${PROJECT_NAME}" "${ONLINE_IMAGE}" "user=${AUTHOR_NAME}" "email=${AUTHOR_EMAIL}" delopy failed: stage: deploy only: - tags script: - if [ $(git diff origin/master|wc -l) != "0" ]; then echo "请将代码合并入master后再打tag"; exit 0; fi - gitlab-ci/ci_helper.py notification.dingding "线上包打包失败:" "${PROJECT_NAME}:${CI_COMMIT_TAG}" "user=${AUTHOR_NAME}" "email=${AUTHOR_EMAIL}" when: on_failure