Cloud Native 17 min read

Master CI/CD with Jenkins and GitOps: Step‑by‑Step Cloud‑Native Pipeline

This guide walks you through building a complete CI/CD pipeline using Jenkins, GitOps, Kubernetes, ArgoCD, SonarQube, Docker, and GitLab integration, covering software installation, shared library setup, pipeline scripting, image building, deployment, and webhook triggering in a cloud‑native environment.

Ops Development Stories
Ops Development Stories
Ops Development Stories
Master CI/CD with Jenkins and GitOps: Step‑by‑Step Cloud‑Native Pipeline

CI/CD is no longer a mystery; most enterprises already have it, but this article demonstrates how to implement a full CI/CD workflow using Jenkins and GitOps.

Overall Architecture

The stack includes Kubernetes 1.17.9, Docker 19.03.13, Jenkins 2.249.3, ArgoCD 1.8.0, GitLab Community Edition 11.8.1, SonarQube Community 8.5.1, Traefik 2.3.3, and an Alibaba Cloud code repository.

Software Versions

Kubernetes 1.17.9

Docker 19.03.13

Jenkins 2.249.3

ArgoCD 1.8.0

GitLab Community 11.8.1

SonarQube Community 8.5.1

Traefik 2.3.3

Code repository: Alibaba Cloud

Key Technologies

Jenkins shared library

Jenkins pipeline

Jenkinsfile

ArgoCD

SonarQube API operations

Software Installation

All installation scripts are stored in the GitHub repository https://github.com/cool-ops/kubernetes-software-yaml.git . The article assumes the software is already installed.

Jenkins Plugins

kubernetes

AnsiColor

HTTP Request

SonarQube Scanner

Utility Steps

Email Extension Template

GitLab Hook

GitLab

Configure Kubernetes Cluster in Jenkins

Navigate to Manage Jenkins → Configure System → Cloud and add the cluster information (see image).

Configure Email in Jenkins

Set the administrator email and SMTP service under Manage Jenkins → Configure System → Email (see images).

Prepare Test Code in GitLab

A simple Java project is hosted at https://gitee.com/jokerbai/springboot-helloworld.git and can be imported into your own GitLab repository.

Create a Shared Library in GitLab

Create a repository named

shareLibrary

and add the

src/org/devops

directory with the following Groovy files:

<code>package org.devops

// docker container build

def DockerBuild(buildShell){
    sh "${buildShell}"
}
</code>
<code>package org.devops

// define email content

def SendEmail(status,emailUser){
    emailext body: "...", subject: "Jenkins-${JOB_NAME} build info", to: emailUser
}
</code>
<code>package ore.devops

// encapsulate HTTP request

def HttpReq(requestType,requestUrl,requestBody){
    def sonarServer = "http://sonar.devops.svc.cluster.local:9000/api"
    result = httpRequest authentication: 'sonar-admin-user',
        httpMode: requestType,
        contentType: "APPLICATION_JSON",
        consoleLogResponseBody: true,
        ignoreSslErrors: true,
        requestBody: requestBody,
        url: "${sonarServer}/${requestUrl}"
    return result
}
// other helper methods omitted for brevity
</code>
<code>package org.devops

// format output

def PrintMes(value,color){
    // color mapping omitted for brevity
    ansiColor('xterm'){ println(value) }
}
</code>

Create a YAML Management Repository

Create a repository

devops-cd

and add the following files:

<code>kind: Service
apiVersion: v1
metadata:
  name: the-service
spec:
  selector:
    deployment: hello
  type: NodePort
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080
</code>
<code>apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: the-ingress
spec:
  rules:
  - host: test.coolops.cn
    http:
      paths:
      - backend:
          serviceName: the-service
          servicePort: 8080
        path: /
</code>
<code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: the-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      deployment: hello
  template:
    metadata:
      labels:
        deployment: hello
    spec:
      containers:
      - args:
        - -jar
        - /opt/myapp.jar
        - --server.port=8080
        command:
        - java
        env:
        - name: HOST_IP
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP
        image: registry.cn-hangzhou.aliyuncs.com/rookieops/myapp:latest
        imagePullPolicy: IfNotPresent
        livenessProbe:
          httpGet:
            path: /hello
            port: 8080
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /hello
            port: 8080
        resources:
          limits:
            cpu: "1"
            memory: 2Gi
          requests:
            cpu: 100m
            memory: 1Gi
</code>
<code># Example kustomization
commonLabels:
  app: hello
resources:
- deployment.yaml
- service.yaml
- ingress.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- name: registry.cn-hangzhou.aliyuncs.com/rookieops/myapp
  newTag: "20201127150733_70"
namespace: dev
</code>

Configure Shared Library in Jenkins

Add credentials for Docker Hub, CI‑DevOps, and SonarQube admin user, then configure the shared library under Manage Jenkins → Configure System → Global Pipeline Libraries (see images).

Jenkinsfile Example

<code>def labels = "slave-${UUID.randomUUID().toString()}"
@Library("jenkins_shareLibrary")

def tools = new org.devops.tools()

pipeline {
    agent {
        kubernetes {
            label labels
            yaml """
apiVersion: v1
kind: Pod
metadata:
  labels:
    some-label: some-label-value
spec:
  containers:
  - name: jnlp
    image: registry.cn-hangzhou.aliyuncs.com/rookieops/inbound-agent:4.3-4
  - name: maven
    image: registry.cn-hangzhou.aliyuncs.com/rookieops/maven:3.5.0-alpine
    command: ["cat"]
    tty: true
  - name: docker
    image: registry.cn-hangzhou.aliyuncs.com/rookieops/docker:19.03.11
    command: ["cat"]
    tty: true
    volumeMounts:
    - name: docker-sock
      mountPath: /var/run/docker.sock
"""
        }
    }
    stages {
        stage('Checkout') {
            steps { script { tools.PrintMes("拉代码", "green") } }
        }
        stage('Build') {
            steps { container('maven') { script { tools.PrintMes("编译打包", "green") } } }
        }
        // additional stages omitted for brevity
    }
    post {
        success { script { sendEmail.SendEmail("构建成功", toEmailUser) } }
        failure { script { sendEmail.SendEmail("构建失败", toEmailUser) } }
    }
}
</code>

ArgoCD CD Process

Add the Git repository to ArgoCD, create an application, and sync it to deploy the service (see images). Note: a small ArgoCD bug requires a load‑balance value for ingress health checks.

GitLab Webhook Integration

Generate a token in Jenkins, configure the GitLab project’s webhook with the Jenkins callback URL and token, then test the trigger (see images).

Conclusion

The article provides a complete, step‑by‑step CI/CD setup; minor adjustments may be needed for specific Jenkinsfiles, but the overall process works as described.

ci/cdKubernetesdevopsGitOpsJenkinsArgoCD
Ops Development Stories
Written by

Ops Development Stories

Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.