openshift 通过configmap快速自定义 jenkins slave pod

我们在使用openshift的时候,经常会出现每个项目一个jenkins,在项目初始化过程我们需要对slave pod做一些配置,需要在部署jenkins后通过页面修改,现在我们可以通过configmap方式快速自动的更新。

比如: 配置maven pod的存储,将maven缓存文件保存在持久化存储上,以加快下次编译速度。
比如: 配置maven nodejs的时区,使输出日志时间准确。
比如: 配置slave pod的资源限额,避免编译过程出现OOM,因为有的应用编译过程是比较吃内存的。
比如: 配置多个slave pod,要支持jdk7,8,10,nodejs 6,8,10,12 等情况。。。

Kubernetes Plug-in

Kubernetes Plug-in 是一个动态生成 slave pod 的插件,用于运行jenkins job,job完成后销毁pod。

此插件已经集成在openshift jenkins中,相关默认配置在jenkins初始化过程会自动处理。

slave pod 默认内置了maven 和 nodejs

jenkins-slave-pod-template.png

如果只是变更maven和nodejs的镜像,我们在openshift project下修改jenkins的template,在env 部分新加两个环境变量 MAVEN_SLAVE_IMAGE NODEJS_SLAVE_IMAGE

TZ 时区变量是为了日志时间准确

          - name: JENKINS_SERVICE_NAME
            value: ${JENKINS_SERVICE_NAME}
          - name: JNLP_SERVICE_NAME
            value: ${JNLP_SERVICE_NAME}
          - name: ENABLE_FATAL_ERROR_LOG_FILE
            value: ${ENABLE_FATAL_ERROR_LOG_FILE}
          - name: MAVEN_SLAVE_IMAGE
            value: harbor.test.bocloud.com/openshift/openshift3/jenkins-slave-maven-rhel7:v3.11.141-settings-oraclejdk678-skope
          - name: NODEJS_SLAVE_IMAGE
            value: harbor.test.bocloud.com/openshift/openshift3/jenkins-agent-nodejs-6-8-10-12-rhel7:v3.11.141
          - name: TZ
            value: Asia/Shanghai


OpenShift Sync plug-in

如果要快速便捷自定义 slave pod,openshift 提供了 OpenShift Sync plug-in 插件,此插件默认已安装。

这个插件会在jenkins 启动时候查找project下的具备以下特性的imagestream或者configmap

  • imagestream 具备label role=jenkins-slave
  • imagestream tags 具备 annotation role=jenkins-slave
  • configmap 具备label role=jenkins-slave

具备相关label 的imagestream 或者具备相关annotation 的imagestream tag,会自动更新到kubernetes plugin 配置中,可以和自带的maven与nodejs slave pod一样,直接被jenkins job调用

configmap 方式提供了与kubernetes plugin配置一致的XML格式文件,通过这种方式可以配置kubernetes plugin 支持的所有格式。

kubernetes plugin 支持的参数见插件官方
https://github.com/jenkinsci/kubernetes-plugin

以下为我们在工作中使用到的configmap,配置了资源限额、环境变量、pvc持久化卷
https://raw.githubusercontent.com/cai11745/k8s-ocp-yaml/master/yaml-file/jenkins-agent-pod-template.yaml

kind: ConfigMap
apiVersion: v1
metadata:
  name: jenkins-agent-pod-template
  labels:
    role: jenkins-slave
data:
  template1: |-
    <org.csanchez.jenkins.plugins.kubernetes.PodTemplate>
      <inheritFrom></inheritFrom>
      <name>maven</name>
      <namespace></namespace>
      <privileged>false</privileged>
      <capOnlyOnAlivePods>false</capOnlyOnAlivePods>
      <alwaysPullImage>false</alwaysPullImage>
      <instanceCap>2147483647</instanceCap>
      <slaveConnectTimeout>100</slaveConnectTimeout>
      <idleMinutes>0</idleMinutes>
      <activeDeadlineSeconds>0</activeDeadlineSeconds>
      <label>maven</label>
      <serviceAccount>jenkins</serviceAccount>
      <nodeSelector></nodeSelector>
      <nodeUsageMode>NORMAL</nodeUsageMode>
      <customWorkspaceVolumeEnabled>false</customWorkspaceVolumeEnabled>
      <workspaceVolume class="org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.EmptyDirWorkspaceVolume">
        <memory>false</memory>
      </workspaceVolume>
      <volumes>
        <org.csanchez.jenkins.plugins.kubernetes.volumes.PersistentVolumeClaim>
          <mountPath>/home/jenkins/.m2/repository/</mountPath>
          <claimName>maven-m2</claimName>
          <readOnly>false</readOnly>
        </org.csanchez.jenkins.plugins.kubernetes.volumes.PersistentVolumeClaim>
      </volumes>
      <containers>
        <org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate>
          <name>jnlp</name>
          <image>harbor.test.geely.com/openshift/openshift3/jenkins-slave-maven-rhel7:v3.11.141-settings-oraclejdk678-skope</image>
          <privileged>false</privileged>
          <alwaysPullImage>true</alwaysPullImage>
          <workingDir>/tmp</workingDir>
          <command></command>
          <args>${computer.jnlpmac} ${computer.name}</args>
          <ttyEnabled>false</ttyEnabled>
          <resourceRequestCpu>1</resourceRequestCpu>
          <resourceRequestMemory>2G</resourceRequestMemory>
          <resourceLimitCpu>1</resourceLimitCpu>
          <resourceLimitMemory>2G</resourceLimitMemory>
          <envVars>
            <org.csanchez.jenkins.plugins.kubernetes.model.KeyValueEnvVar>
              <key>TZ</key>
              <value>Asia/Shanghai</value>
            </org.csanchez.jenkins.plugins.kubernetes.model.KeyValueEnvVar>
            <org.csanchez.jenkins.plugins.kubernetes.model.KeyValueEnvVar>
              <key>LC_ALL</key>
              <value>en_US.UTF-8</value>
            </org.csanchez.jenkins.plugins.kubernetes.model.KeyValueEnvVar>
          </envVars>
          <ports/>
          <livenessProbe>
            <execArgs></execArgs>
            <timeoutSeconds>0</timeoutSeconds>
            <initialDelaySeconds>0</initialDelaySeconds>
            <failureThreshold>0</failureThreshold>
            <periodSeconds>0</periodSeconds>
            <successThreshold>0</successThreshold>
          </livenessProbe>
        </org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate>
      </containers>
      <envVars/>
      <annotations/>
      <imagePullSecrets/>
      <nodeProperties/>
      <yaml></yaml>
      <podRetention class="org.csanchez.jenkins.plugins.kubernetes.pod.retention.Default"/>
    </org.csanchez.jenkins.plugins.kubernetes.PodTemplate>
  template2: |-
    <org.csanchez.jenkins.plugins.kubernetes.PodTemplate>
      <inheritFrom></inheritFrom>
      <name>nodejs</name>
      <namespace></namespace>
      <privileged>false</privileged>
      <capOnlyOnAlivePods>false</capOnlyOnAlivePods>
      <alwaysPullImage>false</alwaysPullImage>
      <instanceCap>2147483647</instanceCap>
      <slaveConnectTimeout>100</slaveConnectTimeout>
      <idleMinutes>0</idleMinutes>
      <activeDeadlineSeconds>0</activeDeadlineSeconds>
      <label>nodejs</label>
      <serviceAccount>jenkins</serviceAccount>
      <nodeSelector></nodeSelector>
      <nodeUsageMode>NORMAL</nodeUsageMode>
      <customWorkspaceVolumeEnabled>false</customWorkspaceVolumeEnabled>
      <workspaceVolume class="org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.EmptyDirWorkspaceVolume">
        <memory>false</memory>
      </workspaceVolume>
      <volumes>
        <org.csanchez.jenkins.plugins.kubernetes.volumes.PersistentVolumeClaim>
          <mountPath>/home/jenkins/npm-cache</mountPath>
          <claimName>npm-cache</claimName>
          <readOnly>false</readOnly>
        </org.csanchez.jenkins.plugins.kubernetes.volumes.PersistentVolumeClaim>
      </volumes>
      <containers>
        <org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate>
          <name>jnlp</name>
          <image>harbor.test.geely.com/openshift/openshift3/jenkins-agent-nodejs-6-8-10-12-rhel7:v3.11.141-geely</image>
          <privileged>false</privileged>
          <alwaysPullImage>true</alwaysPullImage>
          <workingDir>/tmp</workingDir>
          <command></command>
          <args>${computer.jnlpmac} ${computer.name}</args>
          <ttyEnabled>false</ttyEnabled>
          <resourceRequestCpu>1</resourceRequestCpu>
          <resourceRequestMemory>3G</resourceRequestMemory>
          <resourceLimitCpu>1</resourceLimitCpu>
          <resourceLimitMemory>3G</resourceLimitMemory>
          <envVars>
            <org.csanchez.jenkins.plugins.kubernetes.model.KeyValueEnvVar>
              <key>TZ</key>
              <value>Asia/Shanghai</value>
            </org.csanchez.jenkins.plugins.kubernetes.model.KeyValueEnvVar>
          </envVars>
          <ports/>
          <livenessProbe>
            <execArgs></execArgs>
            <timeoutSeconds>0</timeoutSeconds>
            <initialDelaySeconds>0</initialDelaySeconds>
            <failureThreshold>0</failureThreshold>
            <periodSeconds>0</periodSeconds>
            <successThreshold>0</successThreshold>
          </livenessProbe>
        </org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate>
      </containers>
      <envVars/>
      <annotations/>
      <imagePullSecrets/>
      <nodeProperties/>
      <yaml></yaml>
      <podRetention class="org.csanchez.jenkins.plugins.kubernetes.pod.retention.Default"/>
    </org.csanchez.jenkins.plugins.kubernetes.PodTemplate>

如果不知道XML参数怎么写,可以找一个jenkins,通过页面配置好slave pod的参数,然后进入jenkins容器,配置的参数保存在这里 /var/lib/jenkins/config.xml

导入configmap,sync 插件会把configmap内容自动同步到jenkins pod template,不需要重启jenkins

jenkins-pod-template-auto-update.png

需要注意几点:

  1. 原来的maven nodejs配置会被覆盖,因为configmap中使用了相同的name
  2. 删除configmap,会将jenkins中的两个slave pod 同步删除
  3. 不要直接在 jenkins 页面中修改 slave pod的参数,因为一重启就会被configmap重置
  4. 如果后面不想被configmap同步,但是想保留配置,在jenkins页面把pod template 名称改掉,就是第一个maven 或者nodejs参数
    ,然后把configmap 删了
jenkins-pod-template-changename.png

更多分享见github
https://github.com/cai11745/k8s-ocp-yaml

参考文档:
openshift 官方手册
https://docs.openshift.com/container-platform/3.11/using_images/other_images/jenkins.html

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

推荐阅读更多精彩内容