美文网首页k8s
K8S - Jenkins在K8S下的持续集成

K8S - Jenkins在K8S下的持续集成

作者: hiningmeng | 来源:发表于2019-11-02 16:53 被阅读0次
    image

    关于搭建Kubernetes环境可以参考我前面的公众号文章:Centos7下使用kubeadm搭建Kubernetes-v1.14.2,本篇文章主要实现Jenkins在k8s集群的安装、slave节点在k8s内自动创建销毁,通过pipeline实现java项目的持续集成发布。

    安装Jenkins服务到K8S集群

    使用Dockerfile制作Jenkins镜像

    下载war包进行的安装,Dockerfile如下,war包下载地址:https://jenkins.io/zh/download

    FROM java:8
    RUN echo 'hello docker, start build image'
    
    RUN mkdir -p /app
    WORKDIR /app
    
    RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    RUN echo "Asia/Shanghai" > /etc/timezone
    
    COPY jenkins.war .
    
    CMD ["java" ,"-Xms1024m","-Xmx1024m", "-jar","/app/jenkins.war"]
    

    制作镜像

    docker build -t registry.cn-hangzhou.aliyuncs.com/hiningmeng/jenkins:2.176.2  .
    
    docker push registry.cn-hangzhou.aliyuncs.com/hiningmeng/jenkins:2.176.2
    
    

    K8S安装Jenkins应用

    在k8s集群内创建Jenkins工作的namespace,我这边统一放在devops这个ns底下;

    kubectl create ns devops
    

    我这里把Jenkins工作目录单独挂载到PVC,需要先创建pv-pvc,挂载点是使用的nfs服务,请先创建好服务,jenkins-pv-pvc.yaml如下:

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: jenkins-home-pv
    spec:
      capacity:
        storage: 100Gi
      accessModes:
        - ReadWriteMany
      nfs:
        server: 192.168.1.100
        path: "/data/jenkins_home"
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: jenkins-home-pvc
      namespace: devops
    spec:
      accessModes: ["ReadWriteMany"]
      resources:
        requests:
          storage: 100Gi
    

    为Jenkins创建单独的ServiceAccount,这里的ClusterRole直接使用的cluster-admin,jenkins-serveraccount.yaml如下;

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      labels:
        app: jenkins
      name: jenkins-admin
      namespace: devops
    ---
    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: ClusterRoleBinding
    metadata:
      name: jenkins-admin
      labels:
        app: jenkins
    subjects:
      - kind: ServiceAccount
        name: jenkins-admin
        namespace: devops
    roleRef:
      kind: ClusterRole
      name: cluster-admin
      apiGroup: rbac.authorization.k8s.io
    

    编写Deployment文件,我使用到了node标签apps.k8s.icjl/devops,打标签的命令如下:

    kubectl label node your-node-name apps.k8s.icjl/devops=
    

    jenkins-deployment.yaml如下:

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: jenkins
      namespace: devops
      labels:
        app: jenkins
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: jenkins
        spec:
          serviceAccountName: jenkins-admin
          imagePullSecrets:
            - name: ram-secret
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: apps.k8s.icjl/devops
                    operator: Exists
          containers:
          - name: jenkins
            image: registry.cn-hangzhou.aliyuncs.com/hiningmeng/jenkins:2.176.2
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - name: jenkins-home
              mountPath: /root/.jenkins
              readOnly: false
            ports:
            - containerPort: 8080
            - containerPort: 50000
          volumes:
          - name: jenkins-home
            persistentVolumeClaim:
              claimName: jenkins-home-pvc
    

    创建service,这边使用了NodePort,jenkins-service.yaml如下;

    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: jenkins
      name: jenkins
      namespace: devops
      annotations:
        prometheus.io/scrape: 'true'
    spec:
      type: NodePort
      ports:
      - name: jenkins-web
        port: 8080
        targetPort: 8080
        nodePort: 31442
      - name: jenkins-agent
        port: 50000
        targetPort: 50000
        nodePort: 30005
      selector:
        app: jenkins
    

    也可以使用ingress暴露的方式,jenkins-ingress.yaml如下:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: jenkins
      labels:
        name: jenkins
      namespace: devops
    spec:
      rules:
      - host: jenkins.hiningmeng.cn
        http:
          paths:
          - path: /
            backend:
              serviceName: jenkins
              servicePort: 8080
    

    执行

     kubectl apply -f jenkins-pv-pvc.yaml
     kubectl apply -f jenkins-serveraccount.yaml
     kubectl apply -f jenkins-deployment.yaml
     kubectl apply -f jenkins-service.yaml
     kubectl apply -f jenkins-ingress.yaml
    
    image-20190806145150888

    Jenkins配置

    系统管理 --> 插件管理 --> available,安装需要的插件,有的插件下载不下来可以去官网下载之后上传安装。

    • Kubernetes
    • pipeline
    • Git Parameter
    配置Kubernetes云信息

    在系统管理 --> 系统设置 ,最后面有个Cloud设置,Add a new cloud


    image

    添加具体的Kubernetes信息,K8S服务器可以是Jenkins本身所在的服务器,也可以是其他集群(需要配置证书),这里以本身所在集群为例。

    • 名称 :用于pipeline调用云名称
    • Kubernetes地址:可以通过kubectl cluster-info命令获取
    • Kubernetes 服务证书 key:本身所在的集群因为我们通过sa所以不需要
    • Kubernetes 命名空间:Jenkins的nodePod节点启动的namespace
    • Jenkins 地址:主节点8080端口通过nodeport暴露出来的,地址:端口
    • Jenkins 通道:主节点50000端口通过nodeport暴露出来的,地址:端口
    image
    创建pipeline任务

    选择新建任务,构建流水线。


    image

    安装了Git Parameter插件之后,可以进行分支的选择,需要进行参数化构建,这个可以在页面设置,也可以放到pipeline里面,这边直接在页面配置参数。


    image

    其中Use repository如果不设置,后面的Pipeline from SCRM的时候,就会取不到分支;

    指定pipeline地址,可以直接在页面写,做好是通过Git的方式管理。


    image

    Git管理Pipeline的Jenkinsfile文件,需要提供证书拉取


    image
    编写Jenkinsfile文件
    #定义参数label,K8S启动的pod名称通过这个来制定
    def label = "JenkinsPOD-${UUID.randomUUID().toString()}"
    #定义jenkins的工作目录
    def jenworkspace="/home/jenkins/workspace/${params.PROJECT}"
    #maven项目缓存,提供编译速度
    def mvnrepo="/tmp/repository"
    #kubectl和docker执行文件,这个可以打到镜像里面,这边直接共享的方式提供
    def sharefile="/tmp/sharefile"
    #deployment等K8S的yaml文件目录
    def k8srepo='/tmp/k8s_repos'
    
    #cloud为我们前面提供的云名称,nodeSelector是K8S运行pod的节点选择
    podTemplate(label: label, cloud: 'kubernetes-hiningmeng',nodeSelector: 'devops.k8s.icjl/jenkins=jnlp',
        containers: [
            containerTemplate(
                name: 'jnlp',
                image: 'registry-vpc.cn-hangzhou.aliyuncs.com/hiningmeng/jnlp:v1',
                ttyEnabled: true,
                alwaysPullImage: false),
            containerTemplate(
                name: 'jnlp-maven',
                image: 'jenkins/jnlp-agent-maven',
                //image:'ungerts/jnlp-agent-maven',
                ttyEnabled: true,
                alwaysPullImage: false,
                command: 'cat')
        ],
        volumes: [
            hostPathVolume(hostPath: '/var/run/docker.sock', mountPath:'/var/run/docker.sock'),
            persistentVolumeClaim(mountPath: "$mvnrepo", claimName: 'maven-repo-pvc', readOnly: false),
            persistentVolumeClaim(mountPath: "$sharefile", claimName: 'sharefile-repo-pvc', readOnly: false),
        ]
    )
    {
    
        node (label) {
            stage('Hello World'){
                container('jnlp'){
                    echo "hello, world"
                    sh "ln -s $sharefile/kubectl  /usr/bin/kubectl"
                    sh "ln -s $sharefile/docker /usr/bin/docker"
    
                }
            }
            stage('Git Pull'){
                dir("$jenworkspace"){
                    git branch: "${params.BRANCH}", changelog: false, credentialsId: 'jenkins-pull-key', poll: false, url: "${params.CODE_URL}"
                }
            }
            stage('Mvn Package'){
                container('jnlp-maven'){
                    dir("$jenworkspace"){
                        sh "mvn clean install -Dmaven.test.skip=true  -U  -s  $sharefile/settings.xml"
                    }
                }
            }
            stage('Docker build'){
                ...
            }
            stage('K8S Deploy'){
                ...
            }
        }
    }
    
    
    

    具体的脚本还是自己摸索一下,不同的项目定制即可,大体的架子如上面的实例

    构建项目
    image

    任务一次都没构建的时候会出现报错,构建一次就没问题了;

    image

    如果一切正常的话,在K8S的devops命名空间会创建出新的POD


    image

    至此,简单的可伸缩的基于K8S的Jenkins就完成了,如有问题欢迎交流。

    相关文章

      网友评论

        本文标题:K8S - Jenkins在K8S下的持续集成

        本文链接:https://www.haomeiwen.com/subject/tchhbctx.html