基于GitLab+Jenkins集群+K8S+Docker CICD方案实践

前言

上一篇文章介绍了公司基于docker的CICD架构,具体内容参考文章

​​​​​​GitLab+Jenkins集群+docker CICD集成

本文将分享 GitLab+Jenkins+K8S+Docker CICD方案实践

k8s简介

k8s是一个完备的分布式系统支持平台,k8s具有完备的集群管理能力,包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制、内建智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级能力和在线扩容能力、可扩展的资源自我调度机制,以及粒度度的资源配额管理能力。同时k8s提供了完善的管理工具。这些工具包含开发,部署测试,运维监控在内的各个环节,因此,k8s是一个全新的基于容器技术的分布式架构解决方案,并且是一个一站式完备的分布式系统开发和支撑平台。

CICD架构设计

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc3lzdGVtdXBfdjE=,size_20,color_FFFFFF,t_70,g_se,x_16

上篇文章的CICD架构其实存在一些问题​​​​​​ GitLab+Jenkins集群+docker CICD集成

  1. 所有资源无法集中管理,无法根据实际运行资源进行划分
  2. 无法实现动态扩容,缩容
  3. 对回滚不友好

引入K8S后这些问题能够得到有效解决。引入K8S后只需稍微改造下发布jenkinsfile即可实现集成。CICD流程如下

  1. 开发人员提交代码
  2. 开发人申请merge request
  3. repo owner 合并代码
  4. 开发人员trigger build
  5. checkout 代码
  6. mvn 编译
  7. 构建docker 镜像
  8. 推送镜像到docker hub
  9. 将K8S 资源文件发送到K8S主节点
  10. 在主节点运行K8S命令启动pod 

Deployment资源清单

deployment作为K8S资源组件支持资源限制及滚动更新因此项目中采用此种方式发布pod

由于是微服务项目因此只需要提供deployment.yaml模版,在jenkins build时进行动态替换实际为服名称,命名空间等信息

apiVersion: apps/v1
kind: Deployment
metadata:
  name: #appName
  namespace: #env
spec:
  replicas: 1
  revisionHistoryLimit: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
  selector:
    matchLabels:
      app: #appName
  template:
    metadata:
      labels:
        app: #appName
    spec:
      imagePullSecrets:
        - name: #secret
      containers:
        - name: #appName
          image: #img
          ports:
            - name:
              containerPort: #port
              protocol: TCP
          env:
            - name: "NACOS_SERVER"
              value: #nacos

svc资源清单

由于使用k8s管理所有应用部署因此网络连通至关重要,k8s中service组件可配置不同网络模式。

由于项目中前端未改造成容器部署,因此需要在K8S集群提供外部访问K8S node 节点网络。在service.yaml文件中使用nodeport进行端口暴露实现外部访问

apiVersion: v1
kind: Service
metadata:
  name: #appName
  namespace: #env
spec:
  selector:
    app: #appName
  type: NodePort # service类型
  ports:
    - port: #port
      nodePort: #port
      targetPort: #port

jenkinsfile改造

由于引入deployment与service两个资源文件因此在jenkinsfile中需要将两个资源文件模版进行替换后部署

node {
   stage('prepare') {
        checkout([$class: 'GitSCM', branches: [[name: 'origin/****']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '***********', url: 'http://******']]])  
   }
   stage('build') {
        sh "mvn clean install -pl ${project_name} -am -amd -Dmaven.test.skip=true -P ${build_env}"
        pom_path = sh (script: 'echo ${project_name}/pom.xml', returnStdout: true).trim()
        pom = readMavenPom file: pom_path
        app_name = "${pom.artifactId}"
        source_file= "${pom.artifactId}/target/*.jar"
        jar_file="${pom.artifactId}.jar"
        commit_id = sh (script: 'git rev-parse --short HEAD', returnStdout: true).trim()
        echo "commit id: $commit_id"
        docker_img_name = "${dockerHub}:****/${app_name}"
        echo "docker-img-name: ${docker_img_name}"
        sh "docker build --build-arg APP_NAME=${app_name} --build-arg SOURCE_FILE=${source_file} --build-arg JAR_FILE=${jar_file} -t ${docker_img_name}:${commit_id} ."
        sh "docker login -u **** -p **** ${dockerHub}:****"
        sh "docker push ${docker_img_name}:${commit_id}"
        echo "delete images"
        sh "docker rmi `docker images | grep  '${app_name}' | awk '{print \$3}'`"
        
        sh "sed -e 's/#appName/${app_name}/' -e 's/#env/${build_env}/' -e 's/#image/${image_name}/' -e 's/#port/${port}/' -e 's/#NACOS_SERVER/${nacosServer}/' k8s-template.yaml > ${app_name}-${build_env}.yaml"
        sh "sed -e 's/#appName/${app_name}/' -e 's/#port/${port}/' -e 's/#env/${build_env}/' service-template.yaml > ${app_name}-${build_env}-svc.yaml"
        yaml=app_name+'-'+build_env+'.yaml'
        svcYaml=app_name+'-'+build_env+'-svc.yaml'


   }
   stage('deploy'){
       
           def remote = [:]
           remote.name = ip
           remote.host = ip
           remote.user = ****
           remote.password = ****
           remote.allowAnyHosts = true
           sshPut remote: remote, from: yaml, into: '/**'
           sshPut remote: remote, from: svcYaml, into: '/**'
           sshCommand remote: remote, command: "kubectl apply -f /**/${app_name}-${build_env}-svc.yaml"
           sshCommand remote: remote, command: "kubectl apply -f /**/${app_name}-${build_env}.yaml"
          
         
      }

}

项目改造

工程项目中增加两个模版文件,具体内容根据实际情况自定义

  1. k8s-template.yaml
  2. service-template.yaml

 至此所有CICD改造均已完成。

总结

本文使用K8S部署方式比较简单,随着对k8s的了解逐渐深入将会持续对cicd进行升级。同时也会分享更多K8S 原理相关文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值