Gitlab CI/CD 实践八:同步文件到其他 Git 仓库

2022-10-04 17:16:56 浏览数 (1)

背景

项目里存放了部署到测试环境的k8s资源定义文件,这部分文件需要提交到一个资源定义文件集中仓库,给运维部署到生产环境用。但这部分文件可能会改动,例如存放的项目配置文件就是以configmap的形式在k8s中使用,如果更改项目配置,就需要同步提交到集中仓库。

最开始,这部分工作是人工手动完成的,但是一份文件保存在多个地方,就可能出现不同步的问题,导致每次部署新环境,经常出现因资源定义文件不是最新版而出现应用异常。

这种重复性工作完全可以通过程序来实现自动化操作,这里通过 Gitlab CI 流水线来解决。

公共仓库脚本

公共脚本仓库具体看Gitlab CI/CD 实践七:公共脚本仓库,实际使用请看Gitlab CI/CD 实践四:Golang 项目 CI/CD 流水线配置

common/sync-deploy-file-to-template/.gitlab-ci.yml

代码语言:javascript复制
.sync_deploy_file_to_template: &sync_deploy_file_to_template
  echo "-------------------- 同步部署文件到 template 仓库,用于生产环境部署 --------------------";

  echo "-------------------- 配置 git ssh,实现免密提交到 ${TARGET_REPOSITORY} 仓库 --------------------";
  eval $(ssh-agent -s) 
  ssh-add <(echo "$CI_AUTO_SYNC_SSH_PRIVATE_KEY");
  mkdir -p ~/.ssh;
  touch ~/.ssh/config;
  echo "StrictHostKeyChecking no" >> ~/.ssh/config;
  echo "UserKnownHostsFile /dev/null" >> ~/.ssh/config;

  echo "-------------------- 配置 git 用户信息为当前触发流水线的用户 --------------------";
  git config --global user.email "$GITLAB_USER_EMAIL";
  git config --global user.name "$GITLAB_USER_LOGIN";
  echo "-------------------- git clone ${TARGET_REPOSITORY} 仓库,只拉取指定分支的最后一次 commit --------------------";
  cd /tmp;
  git clone --depth 1 --branch $TARGET_BRANCH $TARGET_REPOSITORY_ADDR;

  echo "-------------------- 找出全部部署文件 --------------------";
  cd $CI_PROJECT_DIR;
  FILES=$(find ${SOURCE_DIR} -name "*.yaml") && echo $FILES;

  echo "-------------------- 拷贝 test 环境的部署文件到 ${TARGET_REPOSITORY} 仓库--------------------";
  for FILE in $FILES; do
    DIR=$(dirname "$FILE");
    cd $DIR;
    ENV=${DIR##*/};
    if [ "$ENV" = "test" ]; then
      SUB_MODULE=${DIR%/*};
      SUB_MODULE=${SUB_MODULE##*/};
      CURR_FILE=${FILE##*/};
      sed -i "s/IMAGE_VERSION/latest/g" $CURR_FILE;
      sed -i "s/NAME_SPACE/${NAME_SPACE}/g" $CURR_FILE;
      sed -i "s/IMAGE_NAME/${MODULE_PREFIX}-${SUB_MODULE}/g" $CURR_FILE;
      sed -i "s/DOCKER_REGISTRY_ADDR/${DOCKER_REGISTRY_ADDR}/g" $CURR_FILE;
      sed -i "s/IMAGE_GROUP/${IMAGE_GROUP}/g" $CURR_FILE;
      TARGET_FILE_NAME=${MODULE_PREFIX}-${SUB_MODULE}-$CURR_FILE;
      echo "TARGET_FILE_NAME $TARGET_FILE_NAME";
      cp -r $CURR_FILE /tmp/${TARGET_REPOSITORY}/${TARGET_DIR}/${TARGET_FILE_NAME};
    fi;
    cd - > /dev/null;
  done;

  echo "-------------------- 提交到 ${TARGET_REPOSITORY} 仓库 --------------------";
  cd /tmp/$TARGET_REPOSITORY;
  git add .;
  git commit -m "sync: 通过 ${CI_PROJECT_PATH} gitlab ci 自动同步部署文件" || true;
  git pull;
  git push;
  echo "-------------------- 同步成功 --------------------";

.sync_deploy_file_to_template_base:
  stage: sync
  image:
    name: 172.1.1.1/common/ubuntu:20.04
  tags:
    - 172.1.1.2-runner
  interruptible: true
  variables:
    MODULE_PREFIX: default
    IMAGE_GROUP: default
    NAME_SPACE: default
    # 同步目标仓库信息
    TARGET_REPOSITORY: template
    # 待同步的deployment文件夹
    SOURCE_DIR: ./deploy
    # 必须是ssh地址,因为需要使用ssh免密登录
    TARGET_REPOSITORY_ADDR: git@git.google.com:ads/template.git
    TARGET_BRANCH: main
    TARGET_DIR: default
  script:
    - *sync_deploy_file_to_template

项目里如何使用

增加 sync 阶段

代码语言:javascript复制
stages:
 - sync

引入此yml

代码语言:javascript复制
include:
 - project: 'devops/gitlab-cicd-template'
   ref: main
   file: '/common/sync-deploy-file-to-template/.gitlab-ci.yml'

配置全局变量,每个项目只配置一个variables

代码语言:javascript复制
variables: &global-variables
 # 用于拼接镜像名
 MODULE_PREFIX: google-ads
 # 镜像私仓里的项目
 IMAGE_GROUP: ads
 # 拷贝部署文件到template仓库的目录
 TARGET_DIR: ads 

新增一个job

代码语言:javascript复制
sync_deploy_file_to_template:
 extends:
   - .sync_deploy_file_to_template_base
 variables:
   <<: *global-variables
   NAME_SPACE: ads
  • 这里的NAME_SPACE用于替换部署文件里的NAME_SPACE变量

参考资料

  1. Linux shell 之 提取文件名和目录名的一些方法

Post Views: 19

0 人点赞