前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >jenkins-5:参数化构建结合jenkinsfile对go服务进行容器化部署

jenkins-5:参数化构建结合jenkinsfile对go服务进行容器化部署

作者头像
千里行走
发布2022-08-31 10:41:33
7100
发布2022-08-31 10:41:33
举报
文章被收录于专栏:千里行走千里行走

需求:

因为不同的服务需要的资源不一样,如cpu,内存等,需要做一个通用模版,对这些差异化资源通过参数来进行定制。

目录:

(1).准备工作

1.jenkins安装时间戳插件

2.测试用的golang-demo

3.其他准备

(2).参数化构建

1.创建pipeline并定制参数

2.定义流水线

3.执行构建

(3).语法注意事项

(4).使用jenkinsfile的方式进行参数化构建

(5).参考资料

(1).准备工作

1.jenkins安装时间戳插件

image的tag使用时间戳,需要安装jenkins插件:build timestamp。

还需要在jenkins的系统配置中修改timestamp的格式(默认是utc格式,不符合image名称语法):

时间戳改为数字形式,精确到秒。

2.测试用的golang-demo

https://gitee.com/future-cicd/jenkins-kubernetes-golang-demo

3.其他准备

jenkins-3:使用jenkinsfile在kubernetes中创建jnlp完成一个简单构建

jenkins-2:使用pipeline在kubernetes创建jnlp完成第一个最简task构建并剖析

jenkins-1:kubernetes中部署的jenkins配置k8s集群连接

harbor-1:创建用户与项目并推送第一个本地镜像到harbor

(2).参数化构建

1.创建pipeline并定制参数

创建pipeline后进行参数化配置:

repo_url:https://gitee.com/future-cicd/jenkins-kubernetes-golang-demo.git

demo的仓库地址。

credentialsId:xxxxxx

这个其实不需要,因为demo是public的,如果是private的,你需要在jenkins里创建credentialsId,输入你的用户名密码。

branch_name:master

要拉取的分支。

k8s_namespace:demo

要部署在k8s中的namespace。

harbor_url:harbor-core.qianlixinzou.com:31600

image要推送到的镜像仓库私服地址。

harbor_group:devops

image存放在harbor的group。

k8s_requests_memory,k8s_requests_cpu,k8s_limits_memory,k8s_limits_cpu:对应k8s的requests, limit。

2.定义流水线

流水线内容:

备份在:

https://gitee.com/future-cicd/jenkins-kubernetes-golang-demo/blob/master/jenkinsfile-with-params-build

代码语言:javascript
复制
def image_tag = "${BUILD_TIMESTAMP}"
def image_name = "${env.JOB_NAME}"
def app_name = "${env.JOB_NAME}"


def harbor_url = "${params.harbor_url}"




def k8s_yaml = """


---
apiVersion: v1
kind: Namespace
metadata:
  name: ${params.k8s_namespace}


---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ${app_name}
  namespace: ${params.k8s_namespace}
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ${app_name}
  template:
    metadata:
      name: ${app_name}
      labels:
        app: ${app_name}
    spec:
      volumes:
      - name: ${app_name}-logs
        hostPath:
          path: /app/logs/${app_name}
          type: DirectoryOrCreate
      containers:
      - name: ${app_name}
        env:
          - name: APP_NAME
            value: ${app_name}
          - name: TZ                       # 添加
            value: Asia/Shanghai      # 添加
        image: ${params.harbor_url}/${params.harbor_group}/${app_name}:${image_tag}
        imagePullPolicy: IfNotPresent
        volumeMounts:
          - name: ${app_name}-logs
            mountPath: /app/logs
        resources:
          requests:
            memory: "${params.k8s_requests_memory}"
            cpu: ${params.k8s_requests_cpu}
          limits:
            memory: "${params.k8s_limits_memory}"
            cpu: ${params.k8s_limits_cpu}
          limits:
        ports:
        - name: web
          containerPort: 8080
        startupProbe:
          httpGet:
            path: /helloworld
            port: 8080
          failureThreshold: 30
          periodSeconds: 60
        livenessProbe:
          failureThreshold: 6
          httpGet:
            path: /helloworld
            port: 8080
          initialDelaySeconds: 50
          periodSeconds: 5
          timeoutSeconds: 5
        readinessProbe:
          failureThreshold: 10
          httpGet:
            path: /helloworld
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 5
          timeoutSeconds: 5


---
apiVersion: v1
kind: Service
metadata:
  name: ${app_name}-web
  namespace: ${params.k8s_namespace}
spec:
  selector:
    app: ${app_name}
  type: ClusterIP
  ports:
  - name: tcp
    port: 80
    targetPort: 8080
    
"""


podTemplate(cloud: 'kubernetes',nodeSelector: 'jenkins-jnlp=yes',
    containers: [
        containerTemplate(
            name: 'container-go', 
            //设置go代理,否则有些依赖包无法下载。
            envVars: [
                envVar(key: 'GO111MODULE', value: 'on'), 
                envVar(key: 'GOPROXY', value: 'https://mirrors.aliyun.com/goproxy/'),
                envVar(key: 'CGO_ENABLED', value: 'p0'),
                envVar(key: 'GOOS', value: 'linux')
            ],
            image: harbor_url+'/devops/jenkins-jnlp-golang:1.18', 
            ttyEnabled: true,
            command: 'cat'
        ),
        containerTemplate(
            name: 'container-docker',
            ttyEnabled: true,
            image: harbor_url+'/devops/jenkins-jnlp-docker:19.03'
        ),
    ],
    //需要将docker和kubectl挂在到pod中这样才可以在pod中与k8s进行联通操作。
    volumes: [
        hostPathVolume(hostPath: '/run/docker.sock', mountPath: '/run/docker.sock'),
        hostPathVolume(hostPath: '/etc/docker', mountPath: '/etc/docker'),
        hostPathVolume(hostPath: '/root/.kube', mountPath: '/root/.kube'),
        hostPathVolume(hostPath: '/usr/bin/kubectl', mountPath: '/usr/bin/kubectl')
    ]
 )
 {
    node(POD_LABEL) {
        stage('stage-1.Clone') {
            // 从git仓库拉取代码
            checkout([
                $class: 'GitSCM', 
                branches: [
                    [name: "${params.branch_name}"]
                ],
                browser: [$class: 'GitLab', repoUrl: "${params.repo_url}"], 
                doGenerateSubmoduleConfigurations: false, 
                extensions: [], 
                submoduleCfg: [], 
                userRemoteConfigs: [
                    [url: "${params.repo_url}", credentialsId: "${params.credentialsId}"]
                ]
            ])
        }
        stage('stage-2.Test') {
        }
        stage('stage-3.Build') {
            container('container-go') {
                // 将go应用构建名为app的可执行二进制文件
                sh "go mod tidy"
                //必须加CGO_ENABLED=0,因为alpine缺少很多go程序依赖的lib库,不加会提示你app not found,你需要ldd app才能看到需要依赖的lib库。
                sh "CGO_ENABLED=0 go build -o app "
                
            }
            container('container-docker') {
                sh """
                    echo "FROM ${params.harbor_url}/devops/alpine-golang-common:0.1" > ./Dockerfile
                    echo "ADD ./app /app/3rd/" >> ./Dockerfile
                    cat ./Dockerfile
                    """
                sh "docker build ./ -t ${params.harbor_url}/${params.harbor_group}/${image_name}:${image_tag}"
            }
        }
        stage('stage-4.Push') {
           container('container-docker') {
               sh "docker push ${params.harbor_url}/${params.harbor_group}/${image_name}:${image_tag}"
           }
        }
        stage('stage-5.Deploy') {
            container('container-docker') {
                writeFile(file: "k8s_yaml.yaml", text: "${k8s_yaml}")
                sh "cat k8s_yaml.yaml"
                sh "kubectl apply -f k8s_yaml.yaml"
            }
        }
    }
}

3.执行构建

(3).语法注意事项

主要是流水线定义中的语法注意:

获取jenkins时间戳插件中的时间戳:

def image_tag = "${BUILD_TIMESTAMP}"

获取jenkins任务的隐藏变量的写法,如JOB_NAME:

def image_name = "${env.JOB_NAME}"

def app_name = "${env.JOB_NAME}"

获取参数化构建中定义的参数:

def harbor_url = "${params.harbor_url}"

将变量值写入磁盘文件:

writeFile(file: "k8s_yaml.yaml", text: "${k8s_yaml}")

(4).使用jenkinsfile的方式进行参数化构建

创建流水线job,从前边那个复制即可。

流水线定义选择:Pipeline script from SCM

配置完成后,执行构建。由于job_name起的名字太长,容器化时会报错:

这个不重要,可以自行修改,这里只是验证jenkinsfile中也是可以取到各种变量。

(5).参考资料

1.JenkinsPipeline语法概要

https://www.ssgeek.com/post/jenkinspipeline-yu-fa-gai-yao/#421-%E6%96%87%E4%BB%B6%E7%9B%AE%E5%BD%95%E7%9B%B8%E5%85%B3%E6%AD%A5%E9%AA%A4

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 千里行走 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档