使用serverless构建jenkins

首先为什么要使用serverless呢,因为原来我们的jenkins使用过的本地的服务器,才构建任务比较多的时候,经常会消耗很多服务器的资源,在平时不用的时候,资源又浪费了。

官方已经有最佳实践
https://help.aliyun.com/document_detail/106865.html?spm=a2c4g.11186623.6.927.32b2711cW9zbjf

这里根据最佳实践进行操作并补充说明。

1.第一步先创建一个serverless集群

 ~/  kubectl get node
NAME              STATUS   ROLES   AGE   VERSION
virtual-kubelet   Ready    agent   43h   v1.11.2

serverless 与 普通的k8s集群有以下区别

  1. serverless集群的节点是虚拟的,关联到节点的资源将不可用,比如daemonset、NodePort等;jenkins也无法利用宿主机的docker.sock进行构建;
  2. 默认不支持k8s的服务发现,需要开启PrivateZone,才能支持服务发现

2.创建jenkins集群

最佳实践中已经说明如何创建。有以下几点问题需要注意。

  1. 存储使用NAS实现,之前的K8s使用的是Flexvolume插件,以storageclass的方式创建。但是遇到一个问题,Flexvolume插件默认的是以ds的方式进行部署,后来尝试了一下发现不需要手动安装Flexvolume也可以实现,但是利用nas-controller动态创建PV的时候,就是挂载nas提示权限问题,可能是操作的问题,为了先完成任务,直接手动创建PV+PVC的方式将jenkins_home挂载出来,jenkins就runing起来了。

3.配置jenkins

配置中增加云的配置,最佳实践中没有说明如何创建如何

待续...

问题:

1.docker打包方式

之前采用直接利用宿主机docker的方式进行打包,但是使用serverless以后就无法使用宿主机了。

hostPathVolume(hostPath: '/var/run/docker.sock', mountPath: '/var/run/docker.sock'),

这里使用另外一种方案 https://github.com/GoogleContainerTools/kaniko
使用如下命令进行docker容器的build和push

/kaniko/executor -c `pwd` --dockerfile=./Dockerfile --destination=$IMAGE_NAME

2.本地镜像缓存问题

原本镜像可以缓存在宿主机,每次拉取镜像可以很快,上了serverless无法缓存,但是阿里云还是提供了一种方式imagecache。
https://help.aliyun.com/document_detail/141241.html?spm=a2c4g.11186623.6.592.440d2e14PLj1jV
可以在5秒钟以后将jenkins job需要的镜像拉取完毕

以下是一个完整的pipeline

def registry = 'xxx'
def library = 'example'
def name = 'xxx'

podTemplate(label: 'java',containers: [
    containerTemplate(
            name: 'jnlp',
            image: 'registry-vpc.cn-hangzhou.aliyuncs.com/thundersdata-public/jnlp-slave:3.35-5',
            resourceRequestCpu: '0.25',
            resourceRequestMemory: '500Mi',
            ttyEnabled: true),
    containerTemplate(
            name: 'maven',
            alwaysPullImage: true,
            image: 'registry-vpc.cn-hangzhou.aliyuncs.com/thundersdata/maven-docker-serverless:apm',
            resourceRequestCpu: '1',
            resourceRequestMemory: '1000Mi',
            ttyEnabled: true,
            command: 'cat'),
    containerTemplate(
            name: 'docker',
            image: 'registry-vpc.cn-hangzhou.aliyuncs.com/thundersdata-public/kaniko',
            resourceRequestCpu: '0.25',
            resourceRequestMemory: '500Mi',
            envVars: [
            ## 修改docker默认的认证文件路径, 测试发现默认/home/jenkins/会覆盖,所有换了个目录
            envVar(key: 'DOCKER_CONFIG', value: '/kaniko/.docker'),],
            ttyEnabled: true,
            command: 'sh'
            )
  ],
serviceAccount: 'pods',
slaveConnectTimeout: 60,
volumes: [
    persistentVolumeClaim(mountPath: '/root/.m2', claimName: 'maven-package-hostdisk', readOnly:false),
    secretVolume(secretName: 'registry', mountPath: '/kaniko/.docker')],
    imagePullSecrets: [ 'regsecret' ]
)

{
node ('java') {
    echo 'ready go'
    def path = pwd()
    def branch_ = ''
    def author = ''
    def version = ''
    def image

    branch_='dev'
    stage("clone code"){
        git credentialsId: 'xxx', branch: branch_, url: 'xxx'
        sh 'git log --no-merges --pretty=format:"%an" -1 > author.txt'
        sh 'git log --no-merges --pretty=format:"%h" --abbrev=8 -1 > version.txt'
        sh 'url=`cat .git/config|grep git`&&url=${url##*/}&&echo ${url%.*} > name.txt'
        author = readFile("author.txt")
        version = readFile("version.txt")
        image = "${registry}/${library}/${name}"
    }

    container('maven'){
        stage('copy dockerfile'){
            sh "cp -u /docker/* ."
        }

        stage("maven package"){
            if (moduleName!=''){
                sh "mvn -s settings.xml package -pl ${moduleName} -DskipTests -U"
                sh "cp -r ${childName}/target ."
                sh "if [ -e ${childName}/Dockerfile ]; then  cp ${childName}/Dockerfile ./; fi"
            } else {
                sh 'mvn -s settings.xml package -DskipTests -U'
            }
        }
    }
    container('docker') {
        stage('build and push docker image') {
            sh "/kaniko/executor -c `pwd` --dockerfile=./Dockerfile --destination=${image}:${version}"
        }
    }
}
}

最后顺利构建成功


image.png

最后

关于收费标准,一开始以为只根据request值收费,但是我想多了,有固定的几个参数,会自动根据你配置request的值选择特定的值,所以不要手抖多输了一个0。建议设置一下limitRange和resourceQutao。如果不设置reques值,会默认采用2G1C的配额。
https://help.aliyun.com/document_detail/114662.html?spm=a2c4g.11186623.6.582.55bbee6dZ1DPw4

20191213170746.jpg

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343