gitlab-CICD共享runner基本配置
gitlab-CICD共享runner基本配置
- 使用docker部署runner
- 多个项目使用共享runner
- 部署机器与runner不在同一台服务器上(使用ssh部署)
部署runner
- 部署镜像
docker pull gitlab/gitlab-runner:latest
docker run -d --name gitlab-runner-shared \
--restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest
- 注册runner
docker exec -it gitlab-runner-shared gitlab-runner \
register -n \
--tag-list "gitlab-runner-shared" \
--description "描述" \
--url <私有gitlab地址> \
--registration-token <项目/共享token> \
--executor docker \
--docker-privileged \
--docker-image "alpine:latest" \
--docker-pull-policy "if-not-present" \
--docker-volumes "/var/run/docker.sock:/var/run/docker.sock"
SSH相关配置
- 在linux服务器使用ssh-keygen创建一个ssh key
ssh-keygen -t rsa -P "" ~/.ssh/id_rsa
- 推送到部署服务器上
ssh-copy-id -i ~/.ssh/id_rsa.pub <远程服务器ip>
- 测试登录
ssh <远程服务器登录名>@<远程服务器ip>
# 按提示输入密码
- 将私钥复制下来
cat ~/.ssh/id_rsa
-
将私钥设置到Gitlab的变量中(例如:SSH_PRIVATE_KEY)
-
远程部署(编写ci文件)
image_build:
stage: build
image: alpine:latest
before_script:
- sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories # 设置国内镜像源
- 'which ssh-agent || ( apk update && apk add openssh-client )' # 安装ssh
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" > deploy.key # 设置ssh私钥
- chmod 0600 deploy.key # 设置私钥权限
- ssh-add deploy.key # 添加到缓存中
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' # 第一次登录不需要询问
script:
- ssh <用户名>@<服务器ip> "ls && exit" # 远程执行语句
使用docker打包
image-build:
stage: build
image: docker:18.09.7
services:
- docker:18.09.7-dind
script:
- docker build --no-cache -t <镜像>:<镜像tag> . # 生成镜像
- docker login -u <docker用户名> -p <docker密码> <docker库地址> # 登录云端
- docker push <镜像>:<镜像tag> # 镜像推送到云端
after_script:
- docker rmi -f <镜像>:<镜像tag> # 已上传云端,清理本地镜像,减少占用内存
retry:
max: 2
when: always
通知(curl)
build-job-failure:
stage: build-notify
when: on_failure # 失败时通知
image: alpine:latest
before_script:
- sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories # 设置国内镜像源
- apk update && apk add curl # 安装curl
script:
- if [ "$CI_COMMIT_REF_NAME" == "dev" ]; then env_name="dev"; else env_name="prod"; fi
- echo '{"content":"@'$GITLAB_USER_LOGIN' '${CI_COMMIT_TITLE}'\n'$CI_PROJECT_NAME' 构建'$env_name'环境 [ 失败 ]"}' > content.json # 避免提交文字中有空格导致报错,使用json的方式
- curl -X POST -H "Content-Type:application/json" -d @content.json "$NOTIFY_URL"
完整.gitlab-ci.yml
default:
tags:
- gitlab-runner-shared
variables:
NOTIFY_URL: "通知地址"
IMAGE_REPOSITORIES: "docker地址"
IMAGE_NAME: "docker镜像名"
SSH_USERNAME: "SSH用户名"
SSH_IP: "部署服务端IP"
workflow:
rules:
- if: $CI_COMMIT_TITLE =~ /^[skip ci]/
when: never
- when: always
stages:
- build
- deploy
- notify
# 使用docker构建镜像
image-build:
stage: build
image: docker:18.09.7
services:
- docker:18.09.7-dind
script:
- docker build --no-cache -t $IMAGE_NAME:$CI_COMMIT_REF_NAME .
- docker login -u $IMAGE_REPOSITORY_USER -p $IMAGE_REPOSITORY_PASSWORD $IMAGE_REPOSITORIES
- docker push $IMAGE_NAME:$CI_COMMIT_REF_NAME
after_script:
- docker rmi -f $IMAGE_NAME:$CI_COMMIT_REF_NAME
retry:
max: 2
when: always
# 部署镜像
image-deploy:
stage: deploy
image: alpine:latest
rules:
- if: $CI_COMMIT_REF_NAME == "dev"
variables:
PORT: "8180"
- if: $CI_COMMIT_REF_NAME == "master"
variables:
PORT: "8181"
before_script:
- sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
- 'which ssh-agent || ( apk update && apk add openssh-client )'
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" > deploy.key
- chmod 0600 deploy.key
- ssh-add deploy.key
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
script:
- ssh $SSH_USERNAME@$SSH_IP "docker rm -f frontend-$CI_COMMIT_REF_NAME && docker run -itd --restart=always --name frontend-$CI_COMMIT_REF_NAME -p $PORT:80 $IMAGE_NAME:$CI_COMMIT_REF_NAME && exit"
retry:
max: 2
when: always
success:
stage: notify
when: on_success
image: alpine:latest
before_script:
- sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
- apk update && apk add curl
script:
- if [ "$CI_COMMIT_REF_NAME" == "dev" ]; then env_name="dev"; else env_name="prod"; fi
- echo '{"content":"@'$GITLAB_USER_NAME'\n'$CI_PROJECT_NAME' 部署'$env_name'环境 [ 成功 ]\n'${CI_COMMIT_TITLE}'"}' > content.json
- curl -X POST -H "Content-Type:application/json" -d @content.json "$NOTIFY_URL"
retry:
max: 2
when: always
failure:
stage: notify
when: on_failure
image: alpine:latest
before_script:
- sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
- apk update && apk add curl
script:
- if [ "$CI_COMMIT_REF_NAME" == "dev" ]; then env_name="dev"; else env_name="prod"; fi
- echo '{"content":"@'$GITLAB_USER_NAME'\n'$CI_PROJECT_NAME' 部署'$env_name'环境 [ 失败 ]\n'${CI_COMMIT_TITLE}'\n'$CI_PIPELINE_URL'"}' > content.json
- curl -X POST -H "Content-Type:application/json" -d @content.json "$NOTIFY_URL"
retry:
max: 2
when: always