• Jenkins节点配置-K8S云节点


    一、部署jenkins

    pv/pvc

    touch pv_jenkins.yaml

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: jenkins
    spec:
      capacity:
        storage: 20Gi
      accessModes:
        - ReadWriteOnce
      persistentVolumeReclaimPolicy: Recycle
      storageClassName: nfs-jenkins
      nfs:
        path: /data/jenkins/
        server: 10.61.150.21
    
    ---
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: pvc-jenkins
      namespace: servers
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 20Gi
      storageClassName: nfs-jenkins
    

    创建jenkins的serviceaccount

    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      namespace: jenkins
      name: service-reader
    rules:
      - apiGroups: [""] # "" indicates the core API group
        resources: ["services"]
        verbs: ["get", "watch", "list"]
      - apiGroups: [""]
        resources: ["pods"]
        verbs: ["create","delete","get","list","patch","update","watch"]
      - apiGroups: [""]
        resources: ["pods/exec"]
        verbs: ["create","delete","get","list","patch","update","watch"]
      - apiGroups: [""]
        resources: ["pods/log"]
        verbs: ["get","list","watch"]
      - apiGroups: [""]
        resources: ["secrets"]
        verbs: ["get"]
    
    #在jenkins命名空间下创建一个服务账号jenkins
    #kubectl create serviceaccount jenkins -n jenkins -o yaml
    kubectl create serviceaccount jenkins -n servers
    
    #创建一个名为“service-reader-pod”的集群角色绑定,它的“clusterrole”是“service-reader”,它的名字是“default:default”,其中第一个“default”是名空间(namespace),第二个“default”是服务账户名字
    
    kubectl create clusterrolebinding service-reader-pod --clusterrole=service-reader  --serviceaccount=servers:jenkins
    

    修改jenkins镜像

    注意:

    • 创建dockerfile,使用root权限,否则会报错无权限
    • 最新的jenkins版本是jenkins/jenkins 别用错
    FROM hub.ict.ac.cn/jenkins/jenkins:latest
    USER root
    

    svr

    apiVersion: v1
    kind: Service
    metadata:
      name: k8sdemo-jenkins-service
      namespace: servers
      labels:
        app: k8sdemo-jenkins
    spec:
      type: NodePort
      selector:
        app: k8sdemo-jenkins
      ports:
        - port: 8080
          name: http
          protocol : TCP
          nodePort: 30080
          targetPort: 8080
        - port: 50000
          name: agent
          protocol: TCP
          targetPort: 50000
    

    访问

    可以用“http://IP:30080/” 访问Jenkins。

    配置插件安装代理

    方案1.配置插件代理

    升级站点的地址改为:
    这个 URL 改成
    http://mirror.xmission.com/jenkins/updates/update-center.json
    https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

    方案2.使用反向代理连接网络:https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
    方案3.下载插件后离线安装:http://updates.jenkins-ci.org/download/plugins/

    需要下载插件列表:

    插件名 功能
    docker docker
    Localization: Chinese 汉化
    thinbackup 备份
    Kubernetes K8S插件
    Blue Ocean 新款UI

    二、配置Kubernetes Plugin

    1. name使用默认的'Kubernetes'就可以,配置Pipelines时会用到。

    2. Kubernetes URL,是要K8S集群的地址,我们的jenkins在K8S集群里部署的,所以直接用 “https://kubernetes.default” 就可以了。设置之后点击“Test Connection”,见到“
      Connected to Kubernetes 1.16”就成功了。

    3. Jenkins URL就是Jenkins的访问地址,用http://jenkins.default就可以了。可能是没在jenkins上设置的缘故,这个地址集群没有解析成功,导致在测试节点的时候JNLP一直ERROR。我修改成jenkins的访问地址就可以了(就是打开jenkins界面的地址别想多了,有反向代理的就填VIP)

    1. Jenkins tunnel”,这个参数是Jenkins Master和Jenkins Slave之间通信必须配置的。很多文章都没有说要配这个,但是很明确的告诉你,不配置不行(我把这个写上,绝对良心帖)地址也很简单,使用你jenkins的service的集群地址+50000就可以了。

    三、测试

    有几个需要说明的地方:

    1. pipeline有两种语法大家都是知道的,所以呢在K8S插件使用上也支持两种语法的设置。具体的格式参照K8S插件的官方
    2. 新版的K8S插件不需要设置label,jenkins会自动生成一个,节点使用POD_LABEL环境变量引用就可以了。
    3. 在pipeline中先定义podTemplate,在podTemplate中定义containerTemplate,分别有很多可设置的参数,也参照官方设定(用于脚本式)。以下例子中由于我的集群大部分服务器是离线的,为了下载镜像方便使用nodeSelector把节点固定调度到一个可连网的K8S-NODE上。

    测试master

    podTemplate(nodeSelector: 'kubernetes.io/hostname=ict-94',cloud: "kubernetes"){
    	node(POD_LABEL){
    		stage('Run shell'){
    			sh 'echo hello world'
    		}
    	}
    }
    

    测试节点

    这个测试节点的自动创建、销毁、伸缩、分组。是我们最主要的目标

    脚本式pipeline编写

    
    #maven-jlnp:latest是我自己制作的镜像,下一节会说怎么制作。
    podTemplate(nodeSelector: 'kubernetes.io/hostname=ict-94',cloud: 'kubernetes',containers: [
        containerTemplate(
            name: 'jnlp', 
            image: 'hub.ict.ac.cn/jenkins/maven-jlnp:latest', 
            alwaysPullImage: false, 
            args: '${computer.jnlpmac} ${computer.name}'),
      ]) {
    
        node(POD_LABEL) {
            stage('stage1') {
                stage('Show Maven version') {
                    sh 'mvn -version'
                    sh 'sleep 60s'
                }
            }
        }
    }
    

    声明式pipeline编写

    
    #yaml对POD的定义和K8S的一样,例如imagePullPolicy
    #在使用自定义镜像的时候,name只能使用jnlp。这个有待考证
    
    pipeline {
      agent {
        kubernetes {
          yaml """
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        agent: test
    spec:
      containers:
      - name: jnlp
        image: hub.ict.ac.cn/jenkins/maven-jlnp:latest
        imagePullPolicy: IfNotPresent
        tty: true
    """
        }
      }
      stages {
        stage('Run maven') {
          steps {
            container('jnlp') {
              sh 'mvn -version'
            }
          }
        }
      }
    }
    

    测试群组

    • 查看pod可以发现同时运行了包括jnlp在内的3个pod
    • 也就是说一个任务如果需要分别编译前端的代码和后端的代码的时候,就可以分别使用两个容器编译
    podTemplate(nodeSelector: 'kubernetes.io/hostname=ict-94',containers: [
        containerTemplate(name: 'maven', image: 'maven:3.3.9-jdk-8-alpine', ttyEnabled: true, command: 'cat'),
        containerTemplate(name: 'golang', image: 'golang:1.8.0', ttyEnabled: true, command: 'cat')
      ]) {
    
        node(POD_LABEL) {
            stage('Get a Maven project') {
                git 'https://github.com/jenkinsci/kubernetes-plugin.git'
                container('maven') {
                    stage('Build a Maven project') {
                        sh 'mvn -B clean install'
                    }
                }
            }
    
            stage('Get a Golang project') {
                git url: 'https://github.com/hashicorp/terraform.git'
                container('golang') {
                    stage('Build a Go project') {
                        sh """
                        mkdir -p /go/src/github.com/hashicorp
                        ln -s `pwd` /go/src/github.com/hashicorp/terraform
                        cd /go/src/github.com/hashicorp/terraform && make core-dev
                        """
                    }
                }
            }
    
        }
    }
    
    pipeline {
      agent {
        kubernetes {
          yaml """
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        some-label: some-label-value
    spec:
      containers:
      - name: maven
        image: maven:alpine
        command:
        - cat
        tty: true
      - name: busybox
        image: busybox
        command:
        - cat
        tty: true
    """
        }
      }
      stages {
        stage('Run maven') {
          steps {
            container('maven') {
              sh 'mvn -version'
            }
            container('busybox') {
              sh '/bin/busybox'
            }
          }
        }
      }
    }
    

    在jenkins中配置podTemplate

    如果我们使用非Pipeline的方式运行任务, 比如自由风格的,就需要在K8S插件下继续配置POD模板。

    • Labels 配置pod的标签,在新建任务的时候会调用
    • Name 指定运行pod的名称,要注意的是,如果 Name 配置为 jnlp,那么 Kubernetes 会用下边指定的 Docker Image 代替默认的 jenkinsci/jnlp-slave 镜像,否则,Kubernetes plugin 还是会用默认的 jenkinsci/jnlp-sla ve 镜像与 Jenkins Server 建立连接,即使我们指定其他 Docker Image。这里我随便配置为 jnlp-slave,意思就是使用默认的 jenkinsci/jnlp-slave 镜像来运行,因为我们暂时还没制作可以替代默认镜像的镜像。
      “系统管理” —> “系统设置” —> “云” —> “Kubernetes” —> “Add Pod Template”

    新建一个自由风格的任务
    指定label,需要和上述配置pod模板的label一致,和k8S的节点没有关系。我这里的label值就是一个k8s节点的label,测试和K8S节点无关,需要和上述的label一致。

    构建

    输出

    四、制作自己的slave节点

    通过 kubernetest plugin 默认提供的镜像 jenkinsci/jnlp-slave 可以完成一些基本的操作,它是基于 openjdk:8-jdk 镜像来扩展的,但是对于我们来说这个镜像功能过于简单,比如我们想执行 Maven 编译或者其他命令时,就有问题了,那么可以通过制作自己的镜像来预安装一些软件,既能实现 jenkins-slave 功能,又可以完成自己个性化需求,那就比较不错了。如果我们从头开始制作镜像的话,会稍微麻烦些,不过可以参考 jenkinsci/jnlp-slave 和 jenkinsci/docker-slave 这两个官方镜像来做,注意:jenkinsci/jnlp-slave 镜像是基于 jenkinsci/docker-slave 来做的。这里我简单演示下,基于 jenkinsci/jnlp-slave:latest 镜像,在其基础上做扩展,安装 Maven 到镜像内,然后运行验证是否可行吧。

    maven

    #制作镜像
    FROM jenkins/jnlp-slave:latest
    MAINTAINER huwanyang168@163.com
    LABEL Description="This is a extend image base from jenkins/jnlp-slave which install maven in it."
    # 切换到 root 账户进行操作
    USER root
    # 安装 maven-3.3.9
    RUN wget http://mirrors.sonic.net/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz && 
        tar -zxf apache-maven-3.3.9-bin.tar.gz && 
        mv apache-maven-3.3.9 /usr/local && 
        rm -f apache-maven-3.3.9-bin.tar.gz && 
        ln -s /usr/local/apache-maven-3.3.9/bin/mvn /usr/bin/mvn && 
        ln -s /usr/local/apache-maven-3.3.9 /usr/local/apache-maven
    USER jenkins
    ~~~
    `docker build -t maven-jlnp:latest .`
    

    kubectl create secret docker-registry secret-harbor --namespace=my-docs
    --docker-server=http://harbor.shanhy.com:81 --docker-username=admin
    --docker-password=harbor123456789

    测试

    def label = "mypod-${UUID.randomUUID().toString()}"
    podTemplate(label: label, cloud: 'kubernetes',containers: [
        containerTemplate(
            name: 'jnlp', 
            image: 'hub.ict.ac.cn/jenkins/maven-jlnp:latest', 
            alwaysPullImage: false, 
            args: '${computer.jnlpmac} ${computer.name}'),
      ]) {
        node(label) {
            stage('stage1') {
                stage('Show Maven version') {
                    sh 'mvn -version'
                    sh 'sleep 60s'
                }
            }
        }
    }
    

    npm

    #dockerfile
    FROM jenkins/jnlp-slave:latest
    USER root
    RUN wget https://nodejs.org/dist/v12.18.4/node-v12.18.4-linux-x64.tar.gz && 
        tar -zxvf node-v12.18.4-linux-x64.tar.gz && 
        mv node-v12.18.4-linux-x64 nodejs && 
        rm -f apache-maven-3.3.9-bin.tar.gz && 
        ln -s /home/jenkins/nodejs/bin/npm /usr/bin/npm && 
        ln -s /home/jenkins/nodejs/bin/node /usr/bin/node
    
    USER jenkins
    
    #pipeline
    pipeline {
      agent {
        kubernetes {
          yaml """
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        agent: jlnp_npm
    spec:
      containers:
      - name: jnlp
        image: hub.ict.ac.cn/jenkins/jlnp-nmp:v1
        imagePullPolicy: IfNotPresent
        imagePullSecrets:
        - name: harbor31
        tty: true
    """
        }
      }
      stages {
        stage('Run npm') {
          steps {
            container('jnlp') {
              sh 'npm -v'
            }
          }
        }
      }
    }
    

    参考文章:
    https://blog.csdn.net/aixiaoyang168/article/details/79767649
    https://plugins.jenkins.io/kubernetes/
    https://www.cnblogs.com/shawhe/p/11313633.html
    https://blog.csdn.net/weixin_38748858/article/details/102898043
    http://updates.jenkins-ci.org/download/plugins/

  • 相关阅读:
    Baidu aip创建TTS、ASR应用许可并申请免费试用
    网页设计与制作(基本步骤)
    2021新的一年要努力变强变好
    CentOS7查看和关闭防火墙
    CentOS7安装RabbitMQ
    uwsgi启动flask项目(venv虚拟环境)
    centos7 配置python虚拟环境以及使用-virtualenv
    uwsgi下载安装配置(四)http、http-socket和socket配置项详解
    Ubuntu 16.04安装Nginx
    uwsgi下载安装配置(三)uwsgi配置参数讲解
  • 原文地址:https://www.cnblogs.com/zhaobowen/p/13731624.html
Copyright © 2020-2023  润新知