乐趣区

关于程序员:DevOps自动化简单完整模板案例

案例阐明

  • 模仿场景:模仿 common、user、大数据代码扫描
  • 根本流程:下载代码 -> 执行扫描命令
  • 指标:用最简略的形式演示残缺模板性能

实现思路

分三步:

  1. 编写 project.yaml:形容我的项目、运行环境、编排模板、环境配置等信息
  2. 定义模块:定义扫描代码的执行脚本
  3. 执行:结构申请参数和执行

利用模板的所有配置文件如下图:

编写 project.yaml

蕴含内容如图

project.yaml内容(编排模板另建文件编写,外围且较简单):

kind: Project
apiVersion: api/v1
metadata:
  name: sonar # 项目名称
spec:
  engine:
    sonar: |  # 定义编排模板(个别较简单且外围,因而另建文件治理)%{readText "_projects/sonar.engine.yaml" | indent 6}%
  default:  # 设置全局的默认属性
    env:
      info:
        sonar:  # 设置所有环境的默认 sonar 地址和 token
          url: http://xxx:9090
          token: xxx
  envs:
    prod:
      code:
        branch: master # 按环境设置默认分支
      mvn:
        profile: prod  # maven 治理代码 设置 profile 为 prod

编排模板 (_projects/sonar.engine.yaml) 内容:

first: &first # 扫描的第一局部代码
  sonar:
  - name: common

second: &second # 扫描的第二局部代码
  sonar:
    - name: user

metadata:
  annotations:
    notify-types: "group,personal"
    template: 'sonar:latest'
spec:
  global:
    workflow: # 定义工作流信息
      parallelism: 256  # 并发工作数
      ttlStrategy:
        secondsAfterCompletion: 86400 # 完结工作流保留 1 天工夫
        secondsAfterSuccess: 86400  # 完结工作流保留 1 天工夫
        secondsAfterFailure: 172800 # 失败工作流保留 2 天工夫
    kube: # 定义 k8s 的运行环境信息
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: app
                    operator: In
                    values:
                      - ops
      tolerations:
        - key: cattle.io/os
          operator: Equal
          value: linux
          effect: "NoSchedule"
        - key: app
          operator: Equal
          value: ops
          effect: "NoSchedule"
  @{- $part := $.params.annotations.part}@
  stages:
    - name: "sonar"
      desc: "代码品质扫描"
      modules:
        @{- if eq $part "first"}@
        <<: *first  # 当代码仓库数量很多,而资源又无限时离开扫描
        @{- else if eq $part "second"}@
        <<: *second # 当代码仓库数量很多,而资源又无限时离开扫描
        @{- else if eq $part "bigdata"}@ # 分类扫描:为大数据独立构建工作流
        sonar:
          - name: bigdata
        @{- end}@

定义模块

蕴含内容如图:

模板内容如下(执行脚本 较简单,也另建文件治理):

sonar:
  __global__: # 模块层的全局配置
    execTmpl: |
      %{readText "code/sca.yaml" | indent 34}%
    default:  # 模块级的默认配置
      type: git # 类型都为 git
      config: ""  # 示意不须要生成配置文件
  common:
    labels:
      package: true # 示意公共库
    settings:
      repo: http://xxx/common.git
      mvn:
        api: # 只上传 jar 包 不打包和构建镜像
          dir: ""
      sonar:
        exclusions: 'src/main/java/xxx/protobuf/**'  # sonar 扫描排除 pb 代码
  user:
    labels:
      role: user  # 属于用户核心;默认(和不填)为公共模块,服务于所有部门;反对多个归属
    settings:
      repo: http://xxx/user.git
      mvn:
        api:
          dir: user-api
        service:
          dir: user-service
  bigdata:
    labels:
      role: bigdata  # 属于大数据中心;默认(和不填)为公共模块,服务于所有部门;反对多个归属
    settings:
      repo: http://xxx/bigdata.git
      branch: dev
      mvn:
        api:
          dir: flink-stream
      sonar:
        exclusions: 'src/main/**/proto/**'

执行脚本模板(code/sca.yaml)如下:

# 分两步:# 1. 下载代码
# 2. 扫描代码
@{- $env := .env -}@
@{- $repoName := repoName .settings.repo}@
@{- $parent := .}@

- name: git
  image: busybox
  command: [/bin/sh, -c]
  args:
    - |
      echo 下载代码 @{.settings.repo}@ branch:@{or .settings.tag .settings.branch (render $env.code.branch .) }@

@{- range $type,$val := .settings.mvn}@
- name: mvn-sast-@{$type}@
  depends: [git]
  image: busybox
  command: [/bin/sh, -c]
  args:
    - |
      echo 代码扫描 
      @{- $projName := $repoName}@
      @{- if $val.dir}@
      @{- $projName = concat $projName ":" $val.dir}@
      @{- end}@
      @{- $projName = replace $projName "/" ":" -1}@
      
      echo 'mvn clean package sonar:sonar -DskipTests -U -P @{$env.mvn.profile}@  \
        @{- if (or $parent.settings.sonar.exclusions "") }@
        -Dsonar.exclusions=@{$parent.settings.sonar.exclusions}@ \
        @{- end}@
        -Dsonar.projectKey=SAST:@{$projName}@ \
        -Dsonar.projectName=SAST:@{$projName}@ \
        -Dsonar.host.url=@{$env.info.sonar.url}@ \
        -Dsonar.login=@{$env.info.sonar.token}@'

@{- end}@

执行

分两步:

  1. yaml 定义参数
  2. cli 执行

残缺的执行脚本 (Makefile) 如下:

server=http://localhost:8888

# OPS_USER 需设置环境变量,eg:export OPS_USER=xxx
apply-sonar:
    ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/project.yaml
    ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/definitions/main.yaml
    #扫描 common 代码
    ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/engines/params-common.yaml
    #扫描 user 代码
    ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/engines/params-user.yaml
    #扫描大数据代码
    ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/engines/params-bigdata.yaml

扫描第一局部代码(common)

参数定义:

kind: Engine
apiVersion: api/v1
metadata:
  name: sonar-1      # 编排名称:用于编排工作分类
  cron: "0 20 * * *" # 定时工作:每天晚上 8 点执行一次
  envs:
    - prod           # 指定环境:应用环境定义的属性
  engine: sonar      # 指定我的项目编排的模板:利用 `project.spec.engine.sonar` 编排模板
  annotations:       # 扩大属性:用于编排模板渲染
    part: first
    branch: master

执行

ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/engines/params-common.yaml

扫描第二局部代码(user)

参数定义:

kind: Engine
apiVersion: api/v1
metadata:
  name: sonar-2      # 编排名称:用于编排工作分类
  cron: "0 20 * * *" # 定时工作:每天晚上 8 点执行一次
  envs:
    - prod           # 指定环境:应用环境定义的属性
  engine: sonar      # 指定我的项目编排的模板:利用 `project.spec.engine.sonar` 编排模板
  annotations:       # 扩大属性:用于编排模板渲染
    part: second
    branch: master

执行

ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/engines/params-user.yaml

扫描大数据代码(bigdata)

参数定义:

kind: Engine
apiVersion: api/v1
metadata:
  name: sonar-bigdata # 编排名称:用于编排工作分类
  cron: "0 20 * * *" # 定时工作:每天晚上 8 点执行一次
  envs:
    - prod           # 指定环境:应用环境定义的属性
  engine: sonar      # 指定我的项目编排的模板:利用 `project.spec.engine.sonar` 编排模板
  annotations:       # 扩大属性:用于编排模板渲染
    part: bigdata
    branch: dev

执行

ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/engines/params-bigdata.yaml

成果展现

扫描第一局部代码(common)

工作流工作

工作流日志 1(下载代码):

工作流日志 2(代码扫描):

扫描第二局部代码(user)

工作流工作

工作流日志 1(下载代码):

工作流日志 2(代码扫描):

扫描大数据代码(bigdata)

工作流工作(apiservice两个个代码扫描工作

工作流日志 1(下载代码):

工作流日志 2(扫描代码api):

工作流日志 2(扫描代码service):

结语

只需写 模板文件 配置文件 就能够构建本人的工作流,保障了 <font style=”color:red;font-weight:bold”> 良好的扩展性 </font>。

请 <font style=”color:red;font-weight:bold”> 同学 </font> 关注下😉,我专一云原生 DevOps 落地,将按段公布上述能力的落地计划。

本文由 mdnice 多平台公布

退出移动版