zoukankan      html  css  js  c++  java
  • 基于kubernetes构建动态Jenkins-slave

    基于kubernetes构建动态Jenkins-slave

    安装配置 Master

    1. 创建pvc- 基于NFS的存储类

      ---
      
      kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: jenkins-rbd-pvc
      spec:
        accessModes:
          - ReadWriteOnce
        volumeMode: Filesystem
        resources:
          requests:
            storage: 10Gi
        storageClassName: managed-nfs-storage
      
    2. 创建RBAC

      需要先创建namespace,这里不写在yaml里,怕误操作。 kubectl create ns devops

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: jenkins
        namespace: devops
      
      ---
      
      kind: ClusterRole
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
        name: jenkins
      rules:
        - apiGroups: ["extensions", "apps"]
          resources: ["deployments"]
          verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
        - apiGroups: [""]
          resources: ["services"]
          verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
        - 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","list","watch"]
      
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: jenkins
        namespace: devops
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: jenkins
      subjects:
        - kind: ServiceAccount
          name: jenkins
          namespace: devops
      
    3. 创建Jenkins master的 jenkins-statefulset.yaml

      这里我采用的是deployment,因为我本地没有存储集群,所以我这里使用的是hostpath,也添加nodeSelector,只能调度到此节点,避免数据丢失。

      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: jenkins
        namespace: devops
        labels:
          app: jenkins
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: jenkins
        template:
          metadata:
            name: jenkins
            labels:
              app: jenkins
          spec:
            terminationGracePeriodSeconds: 10
            serviceAccountName: jenkins
            nodeSelector:
              jenkins: home
            containers:
            - name: jenkins
              image: jenkins/jenkins:lts
              imagePullPolicy: IfNotPresent
              ports:
              - containerPort: 8080
                name: web
                protocol: TCP
              - containerPort: 50000
                name: agent
                protocol: TCP
              resources:
                limits:
                  cpu: 2000m
                  memory: 4Gi
                requests:
                  cpu: 500m
                  memory: 512Mi
              volumeMounts:
              - name: jenkinshome
                subPath: jenkins
                mountPath: /var/jenkins_home
              env:
              - name: LIMITS_MEMORY
                valueFrom:
                  resourceFieldRef:
                    resource: limits.memory
                    divisor: 1Mi
              - name: JAVA_OPTS
                value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 -Duser.timezone=Asia/Shanghai
            securityContext:
              fsGroup: 1000
            volumes:
            - name: jenkinshome
              hostPath:
                path: /jenkins_home
      
      ---
      
      kind: Service
      apiVersion: v1
      metadata:
        labels:
          app: jenkins
        name: jenkins
        namespace: devops
      spec:
        type: NodePort
        ports:
          - name: web
            port: 8080
            targetPort: 8080
            nodePort: 30086
          - name: agent
            port: 50000
            targetPort: 50000
            nodePort: 30087
        selector:
          app: jenkins
      

      如果使用了存储类,可以参考如下配置文件。

      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: jenkins
        namespace: devops
        labels:
          app: jenkins
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: jenkins
        template:
          metadata:
            name: jenkins
            labels:
              app: jenkins
          spec:
            terminationGracePeriodSeconds: 10
            serviceAccountName: jenkins
            containers:
            - name: jenkins
              image: jenkins/jenkins:lts
              imagePullPolicy: IfNotPresent
              ports:
              - containerPort: 8080
                name: web
                protocol: TCP
              - containerPort: 50000
                name: agent
                protocol: TCP
              resources:
                limits:
                  cpu: 2000m
                  memory: 4Gi
                requests:
                  cpu: 500m
                  memory: 512Mi
              volumeMounts:
              - name: jenkinshome
                subPath: jenkins
                mountPath: /var/jenkins_home
              env:
              - name: LIMITS_MEMORY
                valueFrom:
                  resourceFieldRef:
                    resource: limits.memory
                    divisor: 1Mi
              - name: JAVA_OPTS
                value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 -Duser.timezone=Asia/Shanghai
            securityContext:
              fsGroup: 1000
            volumes:
            - name: jenkinshome
              persistentVolumeClaim:
                claimName: jenkins-rbd-pvc
      
      ---
      
      kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: jenkins-rbd-pvc
        namespace: devops
      spec:
        accessModes:
          - ReadWriteOnce
        volumeMode: Filesystem
        resources:
          requests:
            storage: 10Gi
        storageClassName: managed-nfs-storage
      ---
      
      kind: Service
      apiVersion: v1
      metadata:
        labels:
          app: jenkins
        name: jenkins
        namespace: devops
      spec:
        type: NodePort
        ports:
          - name: web
            port: 8080
            targetPort: 8080
            nodePort: 30086
          - name: agent
            port: 50000
            targetPort: 50000
            nodePort: 30087
        selector:
          app: jenkins
      
    4. 此时可以访问k8s节点的nodePort端口,进行配置和验证。

    配置Jenkins cloud

    需要安装kubernetes相关插件。以及docker和pipeline相关的插件,可自行搜索。

    在新版本的Jenkins当中,增加了Manage Nodes and Clouds,在此处配置我们的k8s集群。配置如下图所示:

    images下的k8s-slave

    添加Pod Labels

    imagespod-labels

    Jenkins在kubernetes集群内部的话,是不需要进行证书配置的。

    编写测试的流水线

    def label = "slave-${UUID.randomUUID().toString()}"
    
    podTemplate(label: label, serviceAccount: 'jenkins', containers: [
      containerTemplate(name: 'maven', image: 'maven:3.6-alpine', command: 'cat', ttyEnabled: true),
      containerTemplate(name: 'docker', image: 'docker', command: 'cat', ttyEnabled: true),
      containerTemplate(name: 'kubectl', image: 'cnych/kubectl', command: 'cat', ttyEnabled: true),
      containerTemplate(name: 'helm', image: 'cnych/helm', command: 'cat', ttyEnabled: true)
    ], volumes: [
      hostPathVolume(mountPath: '/root/.m2', hostPath: '/var/run/m2'),
      hostPathVolume(mountPath: '/home/jenkins/.kube', hostPath: '/root/.kube'),
      hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock')
    ]) {
      node(label) {
    
    
        stage('单元测试') {
          echo "测试阶段"
        }
        stage('代码编译打包') {
          container('maven') {
            echo "打码编译打包阶段"
          }
        }
        stage('构建 Docker 镜像') {
          container('docker') {
            echo "构建 Docker 镜像阶段"
          }
        }
        stage('运行 Kubectl') {
          container('kubectl') {
            echo "查看 K8S 集群 Pod 列表"
            sh "whoami"
            sh "echo $HOME"
            sh "ls -l $HOME/.kube/config"
            sh "sed -i 's/apiserver.k8s.local:8443/192.168.50.101:6443/g' $HOME/.kube/config"
            sh "cat $HOME/.kube/config"
            sh "ls -l $HOME/.kube/"
            sh "kubectl get pods"
          }
        }
        stage('运行 Helm') {
          container('helm') {
            echo "查看 Helm Release 列表"
            sh "helm list"
          }
        }
      }
    }
    

    PS: 这里挂载宿主机的kubeconfig配置文件,可能需要所有的node节点 进行相关配置,因为slave会动态的创建在随机节点中。如果自行命令报错。也可检查Jenkins RBAC授权的权限是否足够。

  • 相关阅读:
    PAT (Advanced Level) 1010. Radix (25)
    PAT (Advanced Level) 1009. Product of Polynomials (25)
    PAT (Advanced Level) 1008. Elevator (20)
    PAT (Advanced Level) 1007. Maximum Subsequence Sum (25)
    PAT (Advanced Level) 1006. Sign In and Sign Out (25)
    PAT (Advanced Level) 1005. Spell It Right (20)
    PAT (Advanced Level) 1004. Counting Leaves (30)
    PAT (Advanced Level) 1001. A+B Format (20)
    PAT (Advanced Level) 1002. A+B for Polynomials (25)
    PAT (Advanced Level) 1003. Emergency (25)
  • 原文地址:https://www.cnblogs.com/skymyyang/p/13895248.html
Copyright © 2011-2022 走看看