百度智能云

All Product Document

          Cloud Container Engine

          CCE Cluster Uses Jenkins to Continuously Release

          Continuous building and publishing is an essential step in our day-to-day work. Currently, most companies use Jenkins clusters to build the CI/CD process that meets the needs, and the continuous publishing process of Jenkins can better interface with Kubernetes clusters, better exert its deployment advantages, this document can specify users to integrate Jenkins publishing process with CCE clusters.

          1. Set Jenkins Storage Directory

          All applications under the Kubenetes environment are Dockerimage, and to keep the data secure in the event of an application restart, the data directory of Jenkins shall be persisted in the storage. Here, one of the much persistent storage provided by CCE to facilitate to maintain consistency of application data for node activiation to escape data under the Kubernetes environment. Of course, you can choose to store locally, but in order to maintain the consistency of the application data, it is required to fix Jenkins to a certain Kubernetes node.

          Refer to the Section Container Engine CCE – Operation Guide – Storage Management https://cloud.baidu.com/doc/CCE/s/mjxppo8qq

          Select any way to deploy and generate PVC and record the PVC name.

          2. Deploy Jenkins Server to Kubernetes

          service-account.yaml

          ---
          apiVersion: v1
          kind: ServiceAccount
          metadata:
            name: jenkins
           
          ---
          kind: Role
          apiVersion: rbac.authorization.k8s.io/v1beta1
          metadata:
            name: jenkins
          rules:
          - 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: ["events"]
            verbs: ["watch"]
          - apiGroups: [""]
            resources: ["secrets"]
            verbs: ["get"]
           
          ---
          apiVersion: rbac.authorization.k8s.io/v1beta1
          kind: RoleBinding
          metadata:
            name: jenkins
          roleRef:
            apiGroup: rbac.authorization.k8s.io
            kind: Role
            name: jenkins
          subjects:
          - kind: ServiceAccount
            name: jenkins

          jenkins.yaml

          # jenkins
           
          ---
          apiVersion: apps/v1
          kind: StatefulSet
          metadata:
            name: jenkins
            labels:
              name: jenkins
          spec:
            selector:
              matchLabels:
                name: jenkins
            serviceName: jenkins
            replicas: 1
            updateStrategy:
              type: RollingUpdate
            template:
              metadata:
                name: jenkins
                labels:
                  name: jenkins
              spec:
                terminationGracePeriodSeconds: 10
                serviceAccountName: jenkins
                containers:
                  - name: jenkins
                    image: hub.baidubce.com/jpaas-public/jenkins-github:v0
                    imagePullPolicy: Always
                    ports:
                      - containerPort: 8080
                      - containerPort: 50000
                    resources:
                      limits:
                        cpu: 1
                        memory: 1Gi
                      requests:
                        cpu: 0.5
                        memory: 500Mi
                    env:
                      - name: LIMITS_MEMORY
                        valueFrom:
                          resourceFieldRef:
                            resource: limits.memory
                            divisor: 1Mi
                      - name: JAVA_OPTS
                        # value: -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85
                        value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85
                    volumeMounts:
                      - name: jenkins-home
                        mountPath: /var/jenkins_home
                    livenessProbe:
                      httpGet:
                        path: /login
                        port: 8080
                      initialDelaySeconds: 60
                      timeoutSeconds: 5
                      failureThreshold: 12 # ~2 minutes
                    readinessProbe:
                      httpGet:
                        path: /login
                        port: 8080
                      initialDelaySeconds: 60
                      timeoutSeconds: 5
                      failureThreshold: 12 # ~2 minutes
                securityContext:
                  fsGroup: 1000
                volumes:
                  - name: jenkins-home
                    persistentVolumeClaim:
                      claimName: myjenkinspvc
           
          ---
          apiVersion: v1
          kind: Service
          metadata:
            name: jenkins
          spec:
            type: NodePort
            selector:
              name: jenkins
            # ensure the client ip is propagated to avoid the invalid crumb issue when using LoadBalancer (k8s >=1.7)
            #externalTrafficPolicy: Local
            ports:
              -
                name: http
                port: 80
                targetPort: 8080
                protocol: TCP
              -
                name: agent
                port: 50000
                protocol: TCP

          Note

          • The field claimName in jenkins.yaml file needs changing to 1. Set the PVC name generated in Jenkins storage directory

          Execute the following commands in CCE Kubernetes clusters

          kubectl create -f service-account.yaml
          kubectl create -f jenkins.yaml

          Generating the following contents in turn represents the success of the creation

          create.png

          3. Initialize the Configuration ofJenkins

          At this point, the Jenkins Master service has been deployed and activated, and the port is exposed to80:30427, 50000:31598, at which point you can access Jenkins page by opening http:// <Node_IP>:30427 through the browser.

          Complete the initialization plug-in installation of Jenkins on the browser, configure the account information of administrator, which is ignored here, and the interface after the initialization is shown as follows:

          Note

          • During the initialization, when you are required to enter the initial passward for /var/jenkins_home/secret/initialAdminPassword, you can read it by mounting to PVC persistent directory directly, or access it inside the container directly.

          kubectl exec -it jenkins-0 cat /var/jenkins_home/secrets/initialAdminPassword

          4. Jenkins Installs the Plug-in Kubernetes Plugin

          The administrator logs in the Jenkins Master page and clicks on "System Management" - "Plug-in Management" - "Optional Plug-ins" - and "Kubernetes" to check the installation.

          Once installed, click "System Management" - "System Setting" - "Add a New Cloud" - select "Kubernetes" and enter the Kubernetes and Jenkins configuration information.

          Instructions

            1. Name defaults tokubernetes, or can be modified to a different name; if you modify it here, you shall specify the parameter cloud of podTemplate() as its corresponding name when executing Job in the following; otherwise, you cannot find it, and cloud defaults to: kubernetes
            1. Enter https://kubernetes.default in Kubernetes URL, and enter the DNS records corresponding to Kubernetes Service, you can resolve the Cluster IP of the Service through the DNS record.

          Note Or, you can enter the complete DNS record of https://kubernetes.default.svc.cluster.local, as it shall meet the name mode of <svc_name>.<namespace_name>.svc.cluster.local, or enter the address https://<ClusterIP>:<Ports> of external Kubernetes directly.

            1. Enter http://jenkins.default at Jenkins URL, which is to use the DNS record corresponding to Jenkins Service as similar to the above, or use the mode of http://<ClusterIP>:<Node_Port> at the same time. For example, we can enter http://x.x.x.x:30427 here, and 30427 here is the NodePort exposed outside.
            1. Once configured, click "Test Connection" button to test if t is possible to connect Kubernetes, and if Connection test successful appears, it indicates that the connection succeeded, without problem in configuration

          5. Non-clustered Jenkins Connects to Kubernetes

          5.1. Enter Kubernetes configuration contents

          Take a kubeconfig file as an example

          apiVersion: v1
          clusters:
          - cluster:
              certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURwRENDQW95Z0F3SUJBZ0lVUldSdmNwRkxNaTVaUFZJUVllL2o2WkxsZlJJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd2FqRUxNQWtHQTFVRUJoTUNRMDR4RURBT0JnTlZCQWdUQjBKbGFVcHBibWN4RURBT0JnTlZCQWNUQjBKbAphVXBwYm1jeEREQUtCZ05WQkFvVEEyczRjekVVTUJJR0ExVUVDeE1MWTJ4dmRXUnVZWFJwZG1VeEV6QVJCZ05WCkJBTVRDbXQxWW1WeWJtVjBaWE13SGhjTk1qQXdOVEU0TURjeE5qQXdXaGNOTWpVd05URTNNRGN4TmpBd1dqQnEKTVFzd0NRWURWUVFHRXdKRFRqRVFNQTRHQTFVRUNCTUhRbVZwU21sdVp6RVFNQTRHQTFVRUJ4TUhRbVZwU21sdQpaekVNTUFvR0ExVUVDaE1EYXpoek1SUXdFZ1lEVlFRTEV3dGpiRzkxWkc1aGRHbDJaVEVUTUJFR0ExVUVBeE1LCmEzVmlaWEp1WlhSbGN6Q0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUtuNmNNMWYKQzlGMTFVVG1jVFlEQmZJMGlBUnJ2N3RtUEhDNU02NHBQNlViRVhIQ2lMNEFIUEVHK29tdVZKWHZ6MExhNVZRagp2SjZUblc0K2h4UjNuT2pGSmhGbldVZDcrWUtBM1Fic05qUVNybFNLTVhqRVlTSTA2M3NGS1YzNFZNUERXR3ByClVvVlZWZjduVmVkY0FhRTdzeFg3cXFOeERDS3Fjc2cxWCtDNFFrK01zaExKaUdyRnNnRC8rOHNUVkRzVzRoTEMKZ01zZ1R5WlVwRDlmM2hBTXQ0dzduV3RiWURsOFlvZnhEcU9tYndpVEx3VlNyaXAvZHlVeW9BZXhxbFFWaUgrMwpTNXY5cXRnTXVRRjhUMVNPUkwzcldsMUNYR0JPU3k0YTVBenA0dUx6TTlnbjJzdzZIU3gySG1aZlpxUlI1SXdICkFnQU9ydStFZ1lXVmNoOENBd0VBQWFOQ01FQXdEZ1lEVlIwUEFRSC9CQVFEQWdFR01BOEdBMVVkRXdFQi93UUYKTUFNQkFmOHdIUVlEVlIwT0JCWUVGSjBNOXlyc2F5SXEzZnVuYkhWWHJiZUZZL3RBTUEwR0NTcUdTSWIzRFFFQgpDd1VBQTRJQkFRQkE0UzBoVkpyOTBmNjNPU0tRMzVrUGNvTE9ObTg0TVNUbkI1OHE3alJHOHBtRHVvc09TUXUwCjZpUE9CZVBMOE92eEpObzhRcHBXOWJCR1N1ZFRKMG5CUnMyTmFjWU1BM0FqeUM0Y09nOFFJNGxHcUJWQllvVEcKa0I0cVlsYjl4dVJ2bnBJenVUWkd0RkVYQkpkZXFGZzZzSno2THRIZzFiUmM2cGJGZThuVUZZYnRSMzRPeGl2Qgp5WUNUKzNSbEpxTmhXcjlJK2djNDhMeXNheTBnL3BmQ1lsSzdXQm8rSWFZTXF1Z2Zmc2RQS2dISkU0Tm0xei9pCmlsNnhYMWV3R1RYMEFsMENKN2tNeitHa3hZalFHcHY1UG5iNzRpOHZZMm5uODVhUnliZVZjeENMZkhTazBTN2kKL0hjTXRkRjdxMVE5bndqMlhiclMxRmRCTEVSWGFGQTkKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
              server: https://1.1.1.1:6443
            name: kubernetes
          contexts:
          - context:
              cluster: kubernetes
              user: kubernetes-admin
            name: kubernetes-admin@kubernetes
          current-context: kubernetes-admin@kubernetes
          kind: Config
          preferences: {}
          users:
          - name: kubernetes-admin
            user:
              client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUsdafZJQ0FURS0tLS0tCUJBZ0lVQlRMK3lWNXdNbjNvamdkdzRKSmFBa0RpNTZrd0RRWUpLb1pJaHZjTkFRRUwKQlFBd2FqRUxNQWtHQTFVRUJoTUNRMDR4RURBT0JnTlZCQWdUQjBKbGFVcHBibWN4RURBT0JnTlZCQWNUQjBKbAphVXBwYm1jeEREQUtCZ05WQkFvVEEyczRjekVVTUJJR0ExVUVDeE1MWTJ4dmRXUnVZWFJwZG1VeEV6QVJCZ05WCkJBTVRDbXQxWW1WeWJtVjBaWE13SGhjTk1qQXdOVEU0TURjeE5qQXdXaGNOTXpBd05URTJNRGN4TmpBd1dqQjcKTVFzd0NRWURWUVFHRXdKRFRqRVFNQTRHQTFVRUNCTUhRbVZwU21sdVp6RVFNQTRHQTFVRUJ4TUhRbVZwU21sdQpaekVYTUJVR0ExVUVDaE1PYzNsemRHVnRPbTFoYzNSbGNuTXhGREFTQmdOVkJBc1RDMk5zYjNWa2JtRjBhWFpsCk1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrYldsdU1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0MKQVE4QU1JSUJDZ0tDQVFFQTErQjh2aXJGU0ZTQVJEQk4yOWxzRHN2WDlxaHJRTU82WnlCK0E5bWNybUtQZG5NOQozdU80T3FGQ1RjNktxTVNDQStDUHVKdlQwZXFJM29UUWZRMHZmWW40UndVNFhIZ21IbWQ2Nk50SXlQZUdzZGtGClRJc1FxaElzVm1VQS9ZNXBEb2h1Yk9OQWlGbDFOaEliUTNqU3JmMy9MYzVLY3RYM2ZOSGhxOE1hblpYYkVmRUsKY1NsdVI5Um4rQkdET1pubGNMZTkzRWRxME9EeFRsaXV6aFNYektUQUhyZnRLbGlIS3hyVXVkRlFZcGpHaFgrTgpLT2pRTFAzdkUwNjYzbklibGxZb2trYkxpZUVnd3lkcDNWUFpHSXI2aE5kZnd5bEdpU2lHMmw0N045bG1lVVhoCmt6MjZoWG5OeDZXRzdvL2d1aXBLdUpWeHZmT1NXS0tHWmJyZmhRSURBUUFCbzRISE1JSEVNQTRHQTFVZER3RUIKL3dRRUF3SUZvREFkQmdOVkhTVUVGakFVQmdnckJnRUZCUWNEQVFZSUt3WUJCUVVIQXdJd0RBWURWUjBUQVFILwpCQUl3QURBZEJnTlZIUTRFRmdRVVZUQm5ESjJYRUtCMkRRTlJZY2c5SFlsL2VCQXdId1lEVlIwakJCZ3dGb0FVCm5RejNLdXhySWlyZCs2ZHNkVmV0dDRWaiswQXdSUVlEVlIwUkJENHdQSWNFckJJQUFZY0VaRURtSUljRVpFYWsKeUljRVpFRG1INGNFWkVha3dZY0VaRURtSG9jRVpFYWt2b2NFWkVEbUlZY0VhZ3hkSm9jRVpFSUFiREFOQmdrcQpoa2lHOXcwQkFRc0ZBQU9DQVFFQUNFc2JBOWh6cHp6YWdwL2RMemQremx2anJVQ0dqNVFBQjNmQlN0OEN4Z2loCnhKNzBLeWV5TDdVVExOZDRNd09Tcjd0VGxhMTFmZTE4VkRvRUNDV0NzY0FabXZEK014eVJ2alFaL1NjY29xMGwKRkc5RFlBU3dOL2RhMURaeTY2L0FJdllaWEV1WmxQbGtSNnlrQ1F4MHJNYjJtdVdSemdJTS9MUTNwSFVYenJ4cQo3cUlreEtJeWlHZC8yUDdvcFBtSzMvemJIU2wyVnNnc1pFL2tJb1ZNQ3BYc1NEaml2aEpHNUlya1lyamNSa2JzCmV2cDI2b0M0K0lKNkNYNjh0TDROTkFxNzFoRmh1QTJ1TGhVLzFhc3NOY0w4RFpFNnFvTlFpWUZXQjVheE81NEsKZXlxRkM3dDBTbEVNYTFRVnNlbklwTVlTRmRlYTZselhtN3lXSFVCVEdBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
              client-key-data:LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVkbjRSdlR3Nka0YKVVBL1k1cERvaHViT05BaUZsMU5oSWJRM2pTcmYzL0xjNUtjdFgzZk5IaHE4TWFuWlhiRWZFSwpjU2x1UjlSbitCR0RPWm5sY0xlOTNFZHEwT0R4VGxpdXpoU1h6S1RBSHJmdEtsaUhLeHJVdWRGUVlwakdoWCtOCktPalFMUDN2RTA2NjNuSWJsbFlva2tiTGllRWd3eWRwM1ZQWkdJcjZoTmRmd3lsR2lTaUcybDQ3TjlsbWVVWGgKa3oyNmhYbk54NldHN28vZ3VpcEt1SlZ4dmZPU1dLS0daYnJmaFFJREFRQUJBb0lCQUZRVUhlR2ZIT2xYNkFFbQo0eHd1YVZTMTllNGVtRzlJRERDZ1NoUkx6Q2RyUWI3N2tXeGZPdUN5Ny9VSDdaOWZzZGU2dlo5RUtkTEhTdm1ICnR3QU5nNktjZXZPR1IvWlQ0VnpVSnQzTWttT2JiSDJXTGVjcS9wbU9ySEFWdExZTW9rUkR4T1pwK0RkaXlERUEKQ2xoVUZaSW9yQnQyRGk3OXdQOS9heXFQdWEwSCttK0NpV2JSYzhodkRSZWtIZnd2b2pXTWtzNVNUNkZhSmVzNwpXQW1GNnVTaEs2Y3ovZjV5QjgvNjVmQ0tvYVN2RFlkdk1HVHZ2U3BqRlBoZVlScHRnREVWd2VJMElaRFBXdDQ4CmpnWklpQjVLbmpOdXprc1l6eEUvWnRhV05PS3QxVmtKYTduQ1M2SitOM0JESDFwOE9QVWk0ZVpDVTRzd05kRVMKVDRoV0ZZRUNnWUVBOGthR0Y3aGxmSEhBZkwya3MwNUJNb01mTktOUFFkSkxYV01ZUVk0L0FwYWJlaWhOVzZRSwpabDJ1cjNoRkFZZ3B6ZFp3RkUzbEx5VmhnODZSS05XNVZvSWcwUW5qWEpBc1U5VGt1KzNzVXRqWnFHTkNmdWRHClB1dG1qWFNwR1NvQWQxZDdwQkNkbEdMYWZBd1ArREI3VkFCNHRTQklVd1NHY3hDb2pUOU92T0VDZ1lFQTVCc2gKcnpOTHZJcU81MlpyL2xlZ3BWRC96aFhZWmNhaDhQcFFLNUY1VkJNa3MyalRNL25uVXdvYzl1QXllUlYxbm1lTApNajlXTmI2QkhZNXNRZXZaNUFPQ2pHWGxyL24zd29qSitTTVpyQnlLMVVqdjBVakdXcVlncHBXMUxhM21MREV5CmpGbDBhcnB5MllRSkxoK1VoU3R0c2ZKU25qdVVmTXJVR3pRUTh5VUNnWUIyRDJmSXAxTE5FYUY3Sis3YWNZZlQKMVpHZlZQV0tYYS9jRWkzL3hCRndjWFBTVTFGZkZ0RDZrU3hPMVl6SzhrOXN2dEpmRXBaY0l4c2gzOGRjM3NreQpIcmRmSmpKbEtOeHcvWTE1QnJmaXAwbHBoUFVpWWhFWkdCMGhVWGdWaXlJdkJiSjZnSjVKY09LSEVGbTMxK2hCClJ2bUxTZS8waElBQUVsNFFkb2tvQVFLQmdRQzd6Q3FiVjV3UENmUkZSdW02YU9KMXVJNGlXWkhqbVBsU3NJSzQKbS9oTDQ4YmZmbm9EM01jNmNxVU9DOThDR1V6UXNXYkVZNmpTYnBsV2dCOVkxcGg1UlBxQ0pKSkpvMzc3eGlxaQoxdWNYOEJmTktWTm45b1ozc3paR2NCTE9ITkhYcUZsNWUxeUJVaWVrTlRScHFNNWFKVHNXdWU2VEgzSk1tNkN0CkZOeXZrUUtCZ0VlY05hN2UzNTRJcEtlMGowZ0dzWXZuVXNFOVRKSkRzdmhjYmRhL0E5TEZvV2tRNGFHVmt2SlgKSG5yb29ZWDg2OU1FM2YyaHNxUmVsMng2a1phZWF6ZWNnWld0RzkvR2kzWXRqVWJZVktzU2pWZDVhSkFrM2k1cwpEVWRmMFZUU1QrR0hjRDUzL2NkK3M3WnA1WkFzdWx1czdnQmFPWkdzOUx6VXY5aHIrRzJWCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
          • No. 1: Remain unchanged, it defaults to kubernetes
          • No. 2: Enter the address of clusters.cluster.server in the kubeconfig file
          • No. 3: Access the content of certificate-authority-data in the kubeconfig file, and convert it into a base64 encoded file
          ecbo xxx | base64 -d > /opt/crt/ca.crt

          Enter the content of ca.crt into the key colume of Kubernetes service certificate of jenkins kubernetes, and access the content of client-certificate-data and client-key-data in kubeconfig, and convert it into a base64 encoded file

          echo xxxxx== | base64 -d > /opt/crt/client.crt
          echo xxxxx== | base64 -d > /opt/crt/client.key
           
           
          # Generate client p12 authentication file cert.pfx, and download to local
          openssl pkcs12 -export -out /opt/crt/cert.pfx -inkey /opt/crt/client.key -in /opt/crt/client.crt -certfile /opt/crt/ca.crt
          Enter Export Password:
          Verifying - Enter Export Password:
           
          # Note: Custom a password and remember it
          • No. 4: Add credentials in the cloud kubernetes

          Note Upload certificate generated last time and downloaded locally to cert.pfx file, enter the key when adding Password value to generate the cert.pfx file, and select the certificate in No. 4.

          Finally, click the connection test: Its appearance indicates the success of connection.

          6. Test and Verification

          Well, install Jenkins Master through Kubernetes and configure the connection, and next, we can configure a Job to test if the publish will succeed.

          6.1. pipeline type support

          Create a Job of Pipeline type, and name it as my-k8s-jenkins-pipeline, and enter a simple testing script at the Pipeline script as follows:

          def label = "mypod-${UUID.randomUUID().toString()}"
          podTemplate(label: label, cloud: 'kubernetes') {
              node(label) {
                  stage('Run shell') {
                      sh 'sleep 130s'
                      sh 'echo hello world.'
                  }
              }
          }

          To execute the build, you can see a build task in the Build Queue at this point, and after click immediately for building, it will publish successfully after the success of initialization. We can see the entire automatic creation and deletion process through the kubectl command line.

          Note: The image used in the example will time out if dragged directly, and the following command can be used to execute in advance in the machine.

          docker pull hub.baidubce.com/jpaas-public/jenkins/jnlp-slave:v0
          
          
          docker tag hub.baidubce.com/jpaas-public/jenkins/jnlp-slave:v0 jenkins/jnlp-slave:4.0.1-1
          Previous
          CCE Best Practice-Container Network Mode Selection
          Next
          Best Practices for CCE Support Periodic and Timing Scaling Deployment