优秀的编程知识分享平台

网站首页 > 技术文章 正文

用简单的例子唠叨一下云效的流水线

nanyue 2024-10-28 16:41:31 技术文章 3 ℃

需求&目标

开发语言:SpringCloud

CICD工具:云效-流水线

目标运行环境:k8s(阿里云内部)

效率方面:尽可能减少开发人员手工操作

过程节点:拉取代码 -> Maven单元测试 -> 代码扫描(审核,安全扫描)-> 构建(Java代码构建、Dockerfile生成、镜像上传)-> 在k8s中发布

代码包特点:

1.整个代码目录只有本模块代码;

2.根代码目录下存在多个子模块,并按子模块进行发布

效果图

云效内置变量

# 系统提供参数,从流水线上下文获取
PIPELINE_ID=$PIPELINE_ID       # 流水线ID
PIPELINE_NAME=$PIPELINE_NAME   # 流水线名称
BUILD_NUMBER=$BUILD_NUMBER     # 流水线运行实例编号
EMPLOYEE_ID=$EMPLOYEE_ID       # 触发流水线用户ID
WORK_SPACE=$WORK_SPACE         # /root/workspace容器中目录
PROJECT_DIR=$PROJECT_DIR       # 代码库根路径,默认为/root/workspace/code
PLUGIN_DIR=$PLUGIN_DIR         # 插件路径,默认为/root/workspace/plugins
BUILD_JOB_ID=$BUILD_JOB_ID     # build-service 任务ID

步骤分解讲解

1.流水线名字制定

将流水线名字作为关键字,用于后面各步骤的需求处理

2.代码拉取

代码仓库设置,各取所需

如果公司已存在内部代码仓库,建议使用内部仓库,通过增加云效访问白名单,从而让云效进行代码拉取。

3.Maven单元测试

JDK版本

Maven单元测试->添加步骤->选择jdk版本

内部maven仓库设置

代码根目录放置自定义的settings.xml

maven单元测试控制

方案一

通过mvn命令指定约定test目录

mvn test -Dtest=xxxTest,yyyTest 
mvn test -Dtest=*Test

方案二(建议选择该方案)

开发同事通过pom.xml指定测试模块

           <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
                <configuration>
                    <includes>
                        <include>**/*Tests.java</include>
                    </includes>
                </configuration>
            </plugin>

代码模板(用于定位具体代码模块)

cd $PROJECT_DIR
#代码片段一:判断是否有子项目
if [[ -e $PIPELINE_NAME ]] ; then
    cd $PIPELINE_NAME
fi
#代码片段二:判断是否有开发自定义的settings文件
settingsConfig=""
[[ -e  $PROJECT_DIR/settings.xml ]] && settingsConfig="-s $PROJECT_DIR/settings.xml"
代码片段三
mvn $settingsConfig -B test -Dmaven.test.failure.ignore=true
mvn $settingsConfig surefire-report:report-only
mvn $settingsConfig site -DgenerateReports=false

4.代码扫描

代码规约扫描

默认方案:代码审查->添加步骤 ->Java代码规约扫描

可选方案:内部的sonar

安全扫描

默认方案:Java安全审查->添加步骤->Java安全扫描

5.构建(ava代码构建、Dockerfile生成、镜像上传需要统一在流程中,否则需要考虑jar包的传递


Java代码构建

JDK选择,Java构建-> JDK版本

# 代码片段,自动定位需要发布的模块
if [[ -e $PIPELINE_NAME ]] ; then
    cd $PIPELINE_NAME
fi
settingsConfig=""
[[ -e  $PROJECT_DIR/settings.xml ]] && settingsConfig="-s $PROJECT_DIR/settings.xml"
mvn  $settingsConfig -B clean package -Dmaven.test.skip=true -Dautoconfig.skip         


Dockerfile制作

#代码片段一:自动填充Dockerfile,从而避免开发同事过多人工操作
cd $PROJECT_DIR
if [ -e target ];then
  mavenPackage=`ls -alt target|grep ".jar"|head -1|awk '{print $NF}'`
  echo "target1:$mavenPackage"
  newPackage=target/$mavenPackage
  sed -i 's%PACKAGE%'$newPackage'%g' Dockerfile
elif [ -e $PIPELINE_NAME/target ];then
    mavenPackage=`ls -alt $PIPELINE_NAME/target|grep ".jar"|head -1|awk '{print $NF}'`
    echo "target2:$mavenPackage"
    newPackage=$PIPELINE_NAME/target/$mavenPackage
    sed -i 's%PACKAGE%'$newPackage'%g' Dockerfile
else
    newPackage=$(find . -name $PIPELINE_NAME*.jar | sed 's#\./##g')
    echo "newPackage:$newPackage"
    sed -i 's%PACKAGE%'$newPackage'%g' Dockerfile
fi


代码目录中放置Dockerfile模板
其中,需要人工接入的是,启动命令中的jvm配置和应用配置文件指定
eg:springboot&springcloud范例:
ENTRYPOINT [""java"",""-Djava.security.egd=file:/dev/./urandom"",""-server"",""-Xms512m"",""-Xmx512m"",""-Xss512k"",""-Djava.awt.headless=true"",""-Djava.net.preferIPv4Stack=true"",""-jar"",""/app.jar"",""--spring.profiles.active=dev""]

Xms Xmx  Xss : 不修改则按默认值
--spring.profiles.active:指定配置文件
/app.jar :不需要修改,统一规范容器代码包名,提高自动化、标准化

更多的个性化视频,怎为在该流程展示"


FROM 镜像仓库地址/alpine-oraclejdk8
VOLUME /tmp
ADD 加载公司公共配置资源
ADD PACKAGE /app.jar
ENV LANG zh_CN.UTF-8
ENV LANGUAGE zh_CN.UTF-8
WORKDIR /
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-server","-Xms512m","-Xmx512m","-Xss512k","-Djava.awt.headless=true","-Djava.net.preferIPv4Stack=true","-jar","/app.jar","--spring.profiles.active=dev"]


镜像上传



发布到K8S中

云效发布组件(以svc发布为例)
A.代码路面存在目录manifests,目录下存在deployment发布文件app-deploy.yaml,入口配置app-svc.yaml
1.deployment自动生成(svc只需要程序初始化的时候建立)
#代码片段:自动生成对应deployment
d $PROJECT_DIR
if [[ -e manifests ]] ; then
    cd manifests
    if [[ -e app-deploy.yaml ]] ; then
      sed -i 's%appname%'$PIPELINE_NAME'%g' app-deploy.yaml
      cat app-deploy.yaml
      if [[ -e app-svc.yaml ]] ; then
         sed -i 's%appname%'$PIPELINE_NAME'%g' app-svc.yaml
      fi
    else
      exit 1
    fi
else
    exit 1
fi
2.kubectl发布(建议不要使用内部授权,会出错,出错后,找客服,客服响应时间巨慢并有可能解决不了问题,可能与产品迭代有关)
复制~/root/.kube证书到集群配置文件(Kubectl 发布-》新建连接)
选择对应的k8s版本


总结:

1.对于没有运维系统或者CICD积累的小团队公司,云效能提高不少效率

2.从过程可知,当团队项目越来越多,管理的人力投入也不少(云效也可以对规则模块设计,进行企业自定义,从而减少每个流水线的人工配置成本)

3.没有运维信息库,项目与相关运维模块不能有效建立关联关系(例如:k8s管理平台、监控平台、日志平台);生命周期中,项目成员要在不同地方达到对应需求和获取对应信息

4.可以对k8s的api进行封装,弱化流水线配置过程中k8s相关信息的配置;从而也很好支持多集群发布。

Tags:

最近发表
标签列表