17

DevOps之Gitlab-CICD实践篇

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzUzOTc2MjcwOQ%3D%3D&%3Bmid=2247484978&%3Bidx=1&%3Bsn=ae5582ca7dc2effe7d1d6f4b32b1ac99
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

yIFzie6.jpg!web

YnURBjF.jpg!web

lyonger

18年加入网易,先后负责过多个游戏产品的运维工作,多年运维生涯。负责小游戏CI/CD、事件处理平台开发、游戏Nomad运维模式探索、gitlab平台维护等工作。主要关注Linux性能优化、DevOps、云原生领域。探索和分享是一趟美好的旅程。

背景

  • 随着公司项目使用 gitlab 越来越多,业务发布的次数越来越频繁,对于发布效率提出了更高的要求。从2012开始,Gitlab官方开始集成了 Continuous Integration (CI) & Continuous Delivery (CD) 功能。本文主要针对该功能的实践做一个分享。

基础介绍

  • GitLab CI/CD 可以做很多事情,下图展现了 GitLab CI/CD 工作流程中整个的服务能力,而无需使用外部工具来交付软件。

f6fMreR.jpg!web

  • 在介绍实践方案之前,我们先简单的了解一下和 Continuous Integration (CI) & Continuous Delivery (CD) 功能有关的相关知识。

术语介绍

RJ7VbaN.png!web

gitlab-pipeline介绍

  • 一次 pipeline 其实相当于一次任务构建,里面可以包含多个流程,如安装依赖、运行测试、编译代码、部署测试服务器、部署生产服务器等。任何提交或者 Merge Request 的合并都可以触发 pipeline ,触发pipeline创建的方式主要有如下。如需详细了解,请查阅官网

    (https://about.gitlab.com/blog/2019/07/12/guide-to-ci-cd-pipelines/)。

YfuURjb.png!web

gitlab-stage介绍

  • Stage 表示一个构建阶段,我们可以在一个 Pipeline 中定义多个 Stage ,这些 Stage 会有以下特点:

    • 所有 Stage 会按照 Stages 参数里定义的顺序串行执行,即当一个 Stage 完成后,才会执行下一个 Stage

    • 默认情况下只有当所有 Stage 成功后,最终的 pipeline 构建任务才会成功。

    • 默认情况下任何一个 Stage 失败,那么后面的 Stage 不会执行,该构建任务最终会失败。

  • pipelinestage 的关系简单理解为下图。

baqE3ii.png!web

gitlab-job介绍

  • job 表示构建工作,即某个 Stage 里面执行的工作内容。我们可以在同一个 Stage 里面定义多个 Job ,这些 Jobs 会有以下特点:

    • 相同 Stage 中的 Job 会并行执行。

    • 相同 Stage 中的 Job 都执行成功时,该 Stage 才会成功。

    • 如果任何一个 Job 失败,那么该 Stage 失败,即该构建任务失败。

  • stagejobs 的关系简单理解为下图。

UniYjeU.png!web

  • 我们以某个 pipeline 为例解释 pipelinestagejob 的含义,具体请看下图。

z67FBnN.jpg!web

gitlab-ci-yaml介绍

  • pipeline 执行的内容使用 ymal 语言进行描述,默认文件名为 .gitlab-ci.yml ,该文件默认放在仓库的根目录下即可生效。关于 ymal 语言的使用可点击这里。

    (https://www.ruanyifeng.com/blog/2016/07/yaml.html)

    下表对 gitlab 11.11.4 版本中 .gitlab-ci.yml 文件里常用的关键字参数进行简单说明。如需深入了解可查阅官方文档

    (https://docs.gitlab.com/ee/ci/yaml/)。

BB7b2qI.jpg!web

U3MZber.jpg!web

zA3iMrq.jpg!web

gitlab-runner介绍

  • .gitlab-ci.yml 文件里的内容由谁来执行呢,答案就是 gitlab-runnter ,一般 gitlab-runner 会和 gitlab 所在服务器进行隔离,因为一个任务的构建,往往会执行编译、测试、发布的过程,这个过程会大量消耗系统资源。 gitlab-runner 几乎可以安装在任何机器上。下面介绍 gitlab-runner 的官方仓库源安装方式。关于 gitlab-runner 的其他安装方式请查阅官方文档

    (https://docs.gitlab.com/runner/install/)。

  • 添加仓库源

# For Debian/Ubuntu/Mint
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash

# For RHEL/CentOS/Fedora
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
  • 安装指定的gitlab-runner版本,比如这里安装11.11.4版本。

# for DEB based systems
sudo apt-get install gitlab-runner=11.11.4

# for RPM based systems
sudo yum install gitlab-runner-11.11.4
  • 点击左侧栏 Settings->CI/CD->Runners->Collapse 获取runner的token,如下图。

ZNNzuaR.png!web

  • 注册gitlab-runner到gitlab实例。

JFrqMnR.jpg!web

实践方案

  • 该实践方案主要介绍微服务项目使用 gitlab 自带的 GitLab Continuous Integration (CI) & Continuous Delivery (CD) 功能,在 gitlab 提供的 runner 里面进行打包、测试、发布。

持续集成CI

  • 持续集成主要是代码编译和打包的过程,一般最终会集成一个适合业务场景的系统层docker镜像。

容器镜像集成

  • 下面为集成系统层docker镜像 Dockerfile 的主要内容:

FROM debian:stretch

# 准备软件包文件
ADD soft/ /data/soft/

# 安装基本软件
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y vim htop wget dnsutils dmidecode ipmitool pciutils perl \
    rsync screen less sysstat at stress tcpdump lsof curl telnet ntp rsyslog sudo locales logrotate cron supervisor \
    numactl openssh-server-x509 openssh-client iptables gawk filebeat mongodb3.4.16 graphviz \
       && apt-get clean

# 安装开发环境
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
    && apt-get install -y python python-pip gcc g++ build-essential python-dev python-setuptools python-smbus \
    build-essential libncursesw5-dev libgdbm-dev libc6-dev zlib1g-dev libsqlite3-dev tk-dev libssl-dev openssl \
    libffi-dev cmake automake python-setuptools libtcmalloc-minimal4 sockstat strace gdb graphviz \
    && apt-get clean

# 安装python3.7
RUN cd /data/soft/ && tar xf /data/soft/Python-3.7.0.tgz && cd Python-3.7.0 && ./configure --enable-optimizations --with-ssl-default-suites=openssl --enable-shared \
    && make && make install && cp libpython3.7m.so.1.0 /lib64/  && ldconfig && rm -rf /data/soft

# 业务启动脚本
COPY entrypoint.sh /sbin/entrypoint.sh
ENTRYPOINT ["/bin/bash", "-x", "/sbin/entrypoint.sh"]
  • 那么怎么把docker镜像推送到docker仓库呢?可在 .gitlab-ci.yml 文件中进行描述,把 build 好的镜像推送到 gitlab 内置的 registry 中。关于gitlab内置的 registry 部署可参考官网说明

    (https://docs.gitlab.com/ce/user/packages/container_registry/index.html)。

    下面为打包并上传容器镜像stage的主要内容。

build_push:
  only:
    refs:
      - tags
    variables:
      - $CI_COMMIT_REF_NAME =~ /^rel_[0-9].*$/  # 规定必须通过打tag且名字为rel_xxx的格式才触发pipeline。
  tags:
    - docker
  stage: ex_build
  script:
    # build docker image
    - docker login $DOCKER_REGISTRY
    - echo "$ docker pull $BUILD_IMAGE"
    - docker pull $BUILD_IMAGE  # 防止$BUILD_IMAGE更新后,runner会缓存,故在build之前先pull一次。
    - echo "$ docker build -t $image"
    - docker build --no-cache -t $image .  
    - echo "$ docker tag  $image $latest"
    - docker tag  $image $latest

    # push  docker image
    - echo "$ docker push $image"
    - docker push $image
    - echo "$ docker push $latest"
    - docker push $latest
    - docker logout $DOCKER_REGISTRY
  when: manual  # 手工确认
  allow_failure: false
  environment:
    name: build
  • gitlab-runner中对应job的部分日志截图如下:

ruyAFrJ.jpg!web

持续交付CD

  • 持续交付或者持续发布的方式其实有很多种,理论上只要服务方提供了发布接口,你就可以封装在 .gitlab-ci.yml 文件里使用 gitlab-runner 调用 api 进行自动发布。下面主要介绍容器的发布方式。

发布容器

  • 发布容器时主要调用自建容器服务的发布接口,其中主要的stage内容如下:

deployment_production:
  only:
    refs:
      - tags
    variables:
      - $CI_COMMIT_REF_NAME =~ /^exrel_[0-9].*$/
  tags:
    - docker
  stage: ex_deployment_production
  script:
    # 更新当前环境下指定渠道
    - deploy_service ${CI_ENVIRONMENT_NAME} "$image"  #image为持续集成build后push到registry的docker镜像。deploy_service是封装容器发布过程的函数。该函数主要是根据传入的image,请求k8s的kube接口进行微服务发布。
  when: manual
  environment:
    name: production
  • gitlab-runner中发布game微服务的job日志截图如下。

rEVzIjv.jpg!web

发布流程

  • 微服务的发布流程主要分2种类型:常规发布和热更发布。常规发布需要重建容器,热更发布无需重建容器。

常规发布

  • 下面为常规发布场景下整体的发布流程。

UrM3ier.png!web

热更发布

  • 核心思路是把需要热更的内容put到etcd集群,服务端集群自动获取内容进行热更,下面为热更发布场景下整体的发布流程。

YrMbuyA.jpg!web

效果展示

常规发布下的pipeline

y2mqQn3.jpg!web

热更发布下的pipeline

3aI7reI.jpg!web

资料参考

  • https://about.gitlab.com/product/continuous-integration

  • https://docs.gitlab.com/ce/ci/introduction/index.html


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK