
# 在CCE Autopilot集群中部署Jenkins Master
在CCE Autopilot集群中安装部署Jenkins Master（无状态工作负载），负责管理任务。
![](https://support.huaweicloud.com/bestpractice-cce-autopilot/public_sys-resources/note_3.0-zh-cn.png)
本示例中使用的Jenkins版本为2.440.2，Jenkins界面中的词条可能因版本不同而存在一些差异，截图仅供参考。
#### 准备工作
- 购买一个CCE Autopilot集群，具体操作请参见[购买CCE Autopilot集群](https://support.huaweicloud.com/usermanual-cce-autopilot/cce_11_0028.html)。
- 购买一台Linux系统的ECS虚拟机，该ECS与集群处于同一VPC，并绑定弹性公网IP，具体操作请参见[快速购买和使用Linux ECS](https://support.huaweicloud.com/qs-ecs/ecs_01_0103.html)。此外，该ECS还需配备kubectl命令并[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce-autopilot/cce_11_0107.html)。
- 创建一个状态可用的高性能弹性文件服务（SFS Turbo），且该SFS Turbo与集群处于同一VPC，具体操作请参见[创建文件系统](https://support.huaweicloud.com/usermanual-sfsturbo/sfsturbo_01_0359.html)。
- 在SWR中创建一个组织，并且该组织与集群处于同一区域，具体操作请参见[创建组织](https://support.huaweicloud.com/usermanual-swr/swr_01_0014.html#section1)。
 
#### 在CCE Autopilot集群中部署Jenkins Master
1. 登录ECS虚拟机，具体操作请参见[通过CloudShell登录Linux ECS](https://support.huaweicloud.com/usermanual-ecs/ecs_03_0185.html)。
2. 创建SFS Turbo类型的持久化存储卷（PV）和持久化存储卷声明（PVC），供Jenkins Master存储持久化数据。
   
   1. 执行以下命令，创建一个名为pv-jenkins-master.yaml的YAML文件，用于创建PV，文件名称可自定义。
      ![](https://support.huaweicloud.com/bestpractice-cce-autopilot/public_sys-resources/note_3.0-zh-cn.png)
      Linux文件命名支持字母、数字、下划线和连字符，但不能包含斜杠（/）和空字符（\\0）。文件名区分大小写，建议避免使用特殊字符，如空格、问号（?）和星号（\*）等，以提高兼容性。
      ```
      vim pv-jenkins-master.yaml
      ```
      文件内容如下，本示例仅涉及必要参数，更多参数信息请参见[通过静态存储卷使用已有SFS Turbo](https://support.huaweicloud.com/usermanual-cce-autopilot/cce_11_0625.html#section3)。
      ```
      apiVersion: v1
      kind: PersistentVolume
      metadata:
        annotations:
          pv.kubernetes.io/provisioned-by: everest-csi-provisioner  # 指定存储驱动，固定为everest-csi-provisioner
        name: pv-jenkins-master    # PV的名称，可自定义
      spec:
        accessModes:
        - ReadWriteMany      # 访问模式，SFS Turbo必须为ReadWriteMany
        capacity:
          storage: 500Gi     # PV申请容量大小
        csi:
          driver: sfsturbo.csi.everest.io    # 挂载依赖的存储驱动，固定为sfsturbo.csi.everest.io
          fsType: nfs        # 指定存储类型，固定为nfs
          volumeHandle: ea8a59b6-485c-xxx    # SFS Turbo的ID
          volumeAttributes:
            everest.io/share-export-location: ea8a59b6-485c-xxx.sfsturbo.internal:/    # SFS Turbo的共享路径
        persistentVolumeReclaimPolicy: Retain    # 回收策略
        storageClassName: csi-sfsturbo           # SFS Turbo存储类名称
      ```
      输入完成后，按**Esc键** 退出编辑，输入**:wq**保存。
      表1关键参数说明 
      | **参数**                           | **示例**                                         | **描述**                                                                                                                                                                                                                                                                                                                                                                                                                 |
      |:---|:---|:---|
      | name                             | pv-jenkins-master                              | 表示PV的名称，可自定义。 PV名称长度范围为1-64个字符，支持使用小写字母、数字和中划线(-)，且中划线不可位于开头或结尾。                                                                                                                                                                                                                                                                                                               |
      | accessModes                      | ReadWriteMany                                  | 表示访问模式，SFS Turbo固定为ReadWriteMany。                                                                                                                                                                                                                                                                                                                                                                                      |
      | storage                          | **500Gi**                                      | 表示PV申请容量，单位为Gi。                                                                                                                                                                                                                                                                                                                                                                                                        |
      | volumeHandle                     | **ea8a59b6-485c-xxx**                          | 表示SFS Turbo的ID。 **获取方法：** 在[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)，单击左上角![](https://support.huaweicloud.com/bestpractice-cce-autopilot/zh-cn_image_0000002104201721.png)，单击"存储 \> 弹性文件服务 SFS"，左侧导航栏单击"SFS Turbo \> 文件系统列表"。在列表中单击对应的SFS Turbo文件存储名称，在"基本信息"页签中复制"ID"后的内容即可。                                          |
      | everest.io/share-export-location | **ea8a59b6-485c-xxx** **.sfsturbo.internal:/** | 表示SFS Turbo的共享路径，是用于共享存储的目录。多个Pod可以通过网络访问该路径，从而共享同一存储资源。 **获取方法：** 在[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)，单击左上角![](https://support.huaweicloud.com/bestpractice-cce-autopilot/zh-cn_image_0000002072045706.png)，单击"存储 \> 弹性文件服务 SFS"，左侧导航栏单击"SFS Turbo \> 文件系统列表"。在列表中单击对应的SFS Turbo文件存储名称，在"基本信息"页签中复制"共享路径"后的内容即可。 |
      | persistentVolumeReclaimPolicy    | **Retain**                                     | 表示PV的回收策略，仅支持Retain回收策略。 Retain：删除PVC，PV资源与底层存储资源均不会被删除，需要手动删除回收。PVC删除后PV资源状态为"已释放（Released）"，不能直接再次被PVC绑定使用。                                                                                                                                                                                                                                       |
      | storageClassName                 | **csi-sfsturbo**                               | 表示SFS Turbo的存储类名称。 本示例中使用系统内置存储类，名称固定为csi-sfsturbo。                                                                                                                                                                                                                                                                                                |
         
      
   
   2. 执行以下命令，创建PV。
      ```
      kubectl create -f pv-jenkins-master.yaml
      ```
      回显如下，表示名为pv-jenkins-master的PV已创建。
      ```
      persistentvolume/pv-jenkins-master created
      ```
      
   
   3. 执行以下命令，创建一个名为pvc-jenkins-master.yaml的YAML文件，用于创建PVC，文件名称可自定义。
      ```
      vim pvc-jenkins-master.yaml
      ```
      文件内容如下，本示例仅涉及必要参数，更多参数信息请参见[通过静态存储卷使用已有SFS Turbo](https://support.huaweicloud.com/usermanual-cce-autopilot/cce_11_0625.html#section3)。
      ```
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: pvc-jenkins-master    # PVC的名称，可自定义
        namespace: default    # 指定命名空间，需要与工作负载处于同一命名空间
        annotations:
          volume.beta.kubernetes.io/storage-provisioner: everest-csi-provisioner  # 指定存储驱动，固定为everest-csi-provisioner
      spec:
        accessModes:
        - ReadWriteMany                  # 访问模式，SFS Turbo必须为ReadWriteMany
        resources:
          requests:
            storage: 500Gi                  # PVC申请容量大小，与PV的容量保持一致
        storageClassName: csi-sfsturbo      # SFS Turbo存储类名称，必须与PV的存储类一致
        volumeName: pv-jenkins-master       # 关联的PV的名称
      ```
      输入完成后，按**Esc键** 退出编辑，输入**:wq**保存。
      表2关键参数说明 
      | **参数**           | **示例**                | **描述**                                                                                                                                         |
      |:---|:---|:---|
      | name             | pvc-jenkins-master    | 表示PVC的名称，可自定义。 PVC名称长度范围为1-64个字符，支持使用小写字母、数字和中划线(-)，且中划线不可位于开头或结尾。                                     |
      | namespace        | default               | 表示命名空间，需要与工作负载处于同一命名空间。                                                                                                                        |
      | accessModes      | ReadWriteMany         | 表示访问模式，SFS Turbo固定为ReadWriteMany。                                                                                                              |
      | storage          | **500Gi**             | 表示PVC申请容量，单位为Gi。 必须与[1]中PV申请容量一致。 |
      | storageClassName | **csi-sfsturbo**      | 表示存储类名称。 必须与[1]中PV的存储类一致。                                         |
      | volumeName       | **pv-jenkins-master** | 表示关联的PV名称。 必须与[1]中PV名称一致。                                       |
         
      
   
   4. 执行以下命令，创建PVC。
      ```
      kubectl create -f pvc-jenkins-master.yaml
      ```
      回显如下，表示名为pvc-jenkins-master的PVC已创建。
      ```
      persistentvolumeclaim/pvc-jenkins-master created
      ```
      
   
   5. PV和PVC创建完成后会自动绑定，本步骤用于检查PV和PVC是否绑定成功，绑定成功后才能在Pod中挂载PVC。当PV和PVC都为绑定状态时，可以认为二者绑定成功。
      首先，利用以下命令检查PV状态。
      ```
      kubectl get pv
      ```
      回显结果如下，STATUS为Bound，说明PV为绑定状态。
      ```
      NAME                CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                        STORAGECLASS   REASON   AGE
      pv-jenkins-master   500Gi      RWX            Retain           Bound    default/pvc-jenkins-master   csi-sfsturbo            88s
      ```
      其次，利用以下命令检查PVC状态。
      ```
      kubectl get pvc
      ```
      回显结果如下，STATUS为Bound，说明PVC为绑定状态。
      ```
      NAME                 STATUS   VOLUME              CAPACITY   ACCESS MODES   STORAGECLASS   AGE
      pvc-jenkins-master   Bound    pv-jenkins-master   500Gi      RWX            csi-sfsturbo   61s
      ```
      该步骤创建的PV和PVC都为绑定状态，可以认为二者绑定成功。
      
   
   
   
   
3. 利用jenkins/jenkins:lts镜像创建无状态工作负载jenkins-master，并挂载[2.d]中创建的PVC。
   
   ![](https://support.huaweicloud.com/bestpractice-cce-autopilot/public_sys-resources/note_3.0-zh-cn.png)
   本示例使用jenkins/jenkins:lts镜像，jenkins/jenkins:lts表示Jenkins LTS版本的Docker镜像。LTS版本是Jenkins官方提供的长期支持的版本镜像，相对稳定，并且会在更长时间内接受安全更新和bug修复，通常适用于需要稳定环境的生产系统，更多信息请参见[LTS Release Line](https://www.jenkins.io/download/lts/)。
   本示例将Jenkins Master部署为无状态工作负载。Jenkins Master核心功能在于管理和调度任务，不依赖于持久化数据，因此将其设置为无状态工作负载能够提高系统的灵活性和可伸缩性。
   您可以根据需要选择不同的镜像和工作负载类型。
   1. 执行以下命令，创建名为jenkins-master的YAML文件，用于创建jenkins-master工作负载，文件名称可自定义。
      ```
      vim jenkins-master.yaml
      ```
      文件内容如下，本示例仅涉及必要参数，更多参数信息请参见[创建无状态负载（Deployment）](https://support.huaweicloud.com/usermanual-cce-autopilot/cce_11_0047.html)。
      ```
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: jenkins-master    # 无状态工作负载的名称
        namespace: default      # 指定命名空间，与PVC命名空间保持一致
      spec:
        replicas: 1       # Pod实例的个数
        selector:
          matchLabels:    # 工作负载的标签选择器，用于匹配所选择的Pod，确保创建的Deployment可以正确地选择和管理所需的Pod
            app: jenkins-master
        template:
          metadata:
            labels:       # 指定Pod实例的标签，需要与工作负载的matchLabels一致，确保创建的Pod实例受Deployment的统一管理
              app: jenkins-master
          spec:
            containers:
              - name: container-1
                image: jenkins/jenkins:lts    # 使用jenkins/jenkins:lts镜像
                resources:       # 用于配置容器的资源限制和请求
                  limits:        # 表示容器可使用的最大资源量
                    cpu: '4'
                    memory: 4Gi
                  requests:      # 表示容器启动时所需的资源量
                    cpu: '4'
                    memory: 4Gi
                volumeMounts:    # 指定容器挂载的卷
                  - name: pvc-jenkins-master
                    mountPath: /var/jenkins_home   # 挂载路径，一般设置为“/var/jenkins_home”
            volumes:    # 用于定义Pod使用的存储卷，对应一个已创建的PVC
              - name: pvc-jenkins-master    # 定义卷的名称，可自定义
                persistentVolumeClaim:
                  claimName: pvc-jenkins-master    # 指定要使用的PVC
            imagePullSecrets:    
              - name: default-secret
      ```
      输入完成后，按**Esc键** 退出编辑，输入**:wq**保存。
      
   
   2. 执行以下命令，创建无状态工作负载jenkins-master。
      ```
      kubectl create -f jenkins-master.yaml
      ```
      回显如下：
      ```
      deployment/jenkins-master created
      ```
      
   
   3. 检查无状态工作负载jenkins-master是否创建成功，即检查该工作负载创建的Pod的STATUS是否为Running。
      ```
      kubectl get pod
      ```
      回显结果如下，Name为jenkins-master-xxx的Pod的STATUS皆为Running，说明无状态工作负载jenkins-master创建成功。
      ```
      NAME                              READY   STATUS    RESTARTS   AGE
      jenkins-master-6f65c7b8f7-255gn   1/1     Running   0          72s
      ```
      
   
   
   
   
4. 创建服务（Service），用来访问Jenkins Master。
   
   Jenkins容器镜像有两个端口：8080和50000，需要分别配置。其中8080端口供Web登录使用，50000端口供Jenkins Master和Jenkins Agent连接使用。本示例需要创建两个Service，相关信息请参见[表3]。
   ![](https://support.huaweicloud.com/bestpractice-cce-autopilot/public_sys-resources/note_3.0-zh-cn.png)
   本示例中，后续步骤创建的Jenkins Agent均与Jenkins Master处于同一集群，因此Jenkins Agent使用ClusterIP类型的Service。
   当Jenkins的Web界面需要与Jenkins Agent通信时，Jenkins Agent连接的地址还需要开放8080端口。在本示例中，ClusterIP类型的Service同时开放8080和50000端口。
   如果Jenkins Agent需要跨集群或使用公网连接Jenkins Master，请自行选择合适的Service类型。
    表3Service 
   | Service类型          | 作用                              | 基本参数                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
   |:---|:---|:---|
   | 负载均衡（LoadBalancer） | 用于提供Web的外部访问（公网访问）              | - Service名称：jenkins-web（可自定义）  - 容器端口：8080  - 访问端口：8080                                                                                                                                                                                               |
   | 集群内访问（ClusterIP）   | 用于Jenkins Agent连接Jenkins Master | - Service名称：jenkins-agent（可自定义）  - 容器端口1：8080  - 访问端口1：8080  - 容器端口2：50000  - 访问端口2：50000   |
      
   1. 执行以下命令，创建名为jenkins-web的YAML文件，用于创建负载均衡类型的Service，文件名称可自定义。
      本示例基于自动创建的弹性负载均衡器（ELB）创建Service，如果您想使用已有的ELB创建Service，请参见[通过kubectl命令行创建-使用已有ELB](https://support.huaweicloud.com/usermanual-cce-autopilot/cce_11_0681.html#section3)。
      ```
      vim jenkins-web.yaml
      ```
      文件内容如下，本示例仅涉及必要参数，更多参数信息请参见[通过kubectl命令行创建-自动创建ELB](https://support.huaweicloud.com/usermanual-cce-autopilot/cce_11_0681.html#section4)。
      ```
      apiVersion: v1
      kind: Service
      metadata:
        name: jenkins-web    # Service名称，可自定义
        namespace: default   # 指定命名空间
        labels:
          app: jenkins-web   # 指定Service的标签
        annotations:    # 自动创建ELB
          kubernetes.io/elb.class: performance    # 指定ELB类型，仅支持独享型负载均衡，即performance
          kubernetes.io/elb.autocreate: '{
            "type": "public",
            "bandwidth_name": "cce-bandwidth-xxx",
            "bandwidth_chargemode": "traffic",
            "bandwidth_size": 5,
            "bandwidth_sharetype": "PER",
            "eip_type": "5_bgp",
            "available_zone": ["cn-east-3a"
            ],
            "l4_flavor_name": "L4_flavor.elb.s1.small"
          }'
      spec:
        selector:    # 用于选择需要绑定的Pod实例
          app: jenkins-master
        ports:       # 定义Service的端口信息
        - name: cce-service-0
          targetPort: 8080   # Service访问目标Pod的端口，与Pod中运行的应用密切相关
          port: 8080 # 外部访问Service的端口，也是负载均衡上的监听端口
          protocol: TCP
        type: LoadBalancer   # Service的类型，LoadBalancer表示负载均衡类型的服务Service
      ```
      输入完成后，按**Esc键** 退出编辑，输入**:wq**保存。
      表4kubernetes.io/elb.autocreate字段关键参数说明 
      | **参数**               | **示例**                     | **描述**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
      |:---|:---|:---|
      | type                 | **public**                 | 表示ELB的网络类型，公网或者私网。 - public：公网型ELB，需要绑定弹性公网IP，允许公网和私网访问。  - inner：私网型ELB，不需要绑定弹性公网IP，只允许私网访问。   由于该Service用于提供Web的外部访问（公网访问），因此需要设置为public。                                                                                                                                               |
      | bandwidth_name       | **cce-bandwidth-xxx**      | 表示带宽的名称，默认值为：cce-bandwidth-xxx，"xxx"可自定义。 取值范围：只能由中文、英文字母、数字、下划线、中划线和点组成，且长度范围为1-64个字符。                                                                                                                                                                                                                                                                                                                                                                                                                  |
      | bandwidth_chargemode | **traffic**                | 表示带宽付费模式。 - bandwidth：按固定的带宽计费。  - traffic：按实际消耗的流量计费。                                                                                                                                                                                                                                         |
      | bandwidth_size       | **5**                      | 表示带宽大小，默认1Mbit/s\~2000Mbit/s，请根据区域带宽支持范围设置。 调整带宽时的最小单位会根据带宽范围不同存在差异，只能选择最小单位的整数倍设置带宽。 - 小于等于300Mbit/s：默认最小单位为1Mbit/s。  - 300Mbit/s\~1000Mbit/s：默认最小单位为50Mbit/s。  - 大于1000Mbit/s：默认最小单位为500Mbit/s。   |
      | bandwidth_sharetype  | **PER**                    | 表示带宽共享方式，仅支持PER，即为独享带宽。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
      | eip_type             | **5_bgp**                  | 表示弹性公网IP类型。 - 5_bgp：全动态BGP。  - 5_sbgp：静态BGP。                                                                                                                                                                                                                                                    |
      | available_zone       | ***cn-east-3a***           | 表示负载均衡所在可用区，独享型负载均衡器独有字段。 可以通过[查询可用区列表](https://support.huaweicloud.com/api-elb/ListAvailabilityZones.html)获取所有支持的可用区。                                                                                                                                                                                                                                                                                                                                                                                    |
      | l4_flavor_name       | **L4_flavor.elb.s1.small** | 表示四层负载均衡实例规格名称，独享型负载均衡器独有字段。 可以通过[查询规格列表](https://support.huaweicloud.com/api-elb/ListFlavors.html#section5)获取所有支持的类型。                                                                                                                                                                                                                                                                                                                                                                                   |
         
      
   
   2. 执行以下命令，创建负载均衡类型的Service，用于提供Web的外部访问。
      ```
      kubectl create -f jenkins-web.yaml
      ```
      回显如下：
      ```
      service/jenkins-web created
      ```
      
   
   3. 创建名为jenkins-agent的YAML文件，用于创建集群内访问类型的Service，文件名称可自定义。
      ```
      vim jenkins-agent.yaml
      ```
      文件内容如下，本示例仅涉及必要参数，更多参数信息请参见[集群内访问（ClusterIP）](https://support.huaweicloud.com/usermanual-cce-autopilot/cce_11_0011.html)。
      ```
      apiVersion: v1
      kind: Service
      metadata:
        name: jenkins-agent      # Service名称，可自定义 
        namespace: default       # 指定命名空间
        labels:
          app: jenkins-agent
      spec:
        ports:    # 定义Service的端口信息
        - name: service0          # 端口1：用于保证Web的外部访问地址和Agent访问地址一致
          port: 8080              # 内部访问Service的端口
          protocol: TCP           # 访问Service的协议，支持TCP和UDP
          targetPort: 8080        # Service访问目标容器的端口，此端口与容器中运行的应用强相关
        - name: service1          # 端口2：用于Master和Agent连接使用
          port: 50000             
          protocol: TCP           
          targetPort: 50000       
        selector:                 # 标签选择器，Service通过标签选择Pod，将访问Service的流量转发给Pod
          app: jenkins-master
        type: ClusterIP           # Service的类型，ClusterIP表示在集群内访问类型的Service
      ```
      输入完成后，按**Esc键** 退出编辑，输入**:wq**保存。
      
   
   4. 执行以下命令，创建集群内访问类型的Service，用于Agent连接Master。
      ```
      kubectl create -f jenkins-agent.yaml
      ```
      回显如下：
      ```
      service/jenkins-agent created
      ```
      
   
   5. 检查上述服务是否创建成功。
      ```
      kubectl get svc
      ```
      回显如下，可以通过"负载均衡公网IP：8080"登录Jenkins，即"xx.xx.xx.xx:8080"。
      ```
      NAME            TYPE           CLUSTER-IP      EXTERNAL-IP                   PORT(S)              AGE
      jenkins-agent   ClusterIP      10.247.22.139   <none>                        8080/TCP,50000/TCP   34s
      jenkins-web     LoadBalancer   10.247.76.78    xx.xx.xx.xx,192.168.0.239     8080:31694/TCP       15m
      kubernetes      ClusterIP      10.247.0.1      <none>                        443/TCP              3h3m
      ```
      
    
   
   
5. 登录并初始化Jenkins。 
   1. 在浏览器中输入"负载均衡公网IP：8080"，打开jenkins配置界面。
   
   2. 初次访问时界面会提示获取初始管理员密码，该密码可在jenkins的Pod中获取，具体步骤如下。
      1. 返回ECS，输入以下命令查找Pod名称。
         ```
         kubectl get pod|grep jenkins-master
         ```
         回显如下，其中"jenkins-master-6f65c7b8f7-255gn"即为Pod名称。
         ```
         jenkins-master-6f65c7b8f7-255gn   1/1     Running   0          144m
         ```
         
      
      2. 输入以下命令进入"jenkins-master-6f65c7b8f7-255gn"内部。
         ```
         kubectl exec -it jenkins-master-6f65c7b8f7-255gn -- /bin/sh
         ```
         
      
      3. 输入以下命令获取初始管理员密码。
         ```
         cat /var/jenkins_home/secrets/initialAdminPassword
         ```
         
       
   
   3. 首次登录时选择安装推荐的插件即可，并根据界面提示创建一个管理员。完成初始配置后，即可进入Jenkins界面。
      图1首次登录页面   
      ![](https://support.huaweicloud.com/bestpractice-cce-autopilot/zh-cn_image_0000002124848209.png "点击放大")
      图2Jenkins界面   
      ![](https://support.huaweicloud.com/bestpractice-cce-autopilot/zh-cn_image_0000002107845557.png "点击放大") 
   
   
   
   
 
