Boost CI/CD Speed with Jenkins, Argo CD & Argo Rollouts: Canary Deploys & Tagging
This guide shows how to combine Jenkins with Argo CD and Argo Rollouts to create a fast, automated CI/CD pipeline that speeds up Argo CD triggers, performs canary releases, and automatically tags GitLab repositories for version control.
This article explains how to use Jenkins together with Argo CD and Argo Rollouts to implement a CI/CD pipeline, covering faster Argo CD triggers, canary releases, and automatic GitLab tagging.
Optimizing Argo CD Trigger Speed
Argo CD polls the Git repository every three minutes, which adds latency. To eliminate this delay, configure the API server to receive webhook events. Argo CD supports GitHub, GitLab, Bitbucket, and other providers; the example uses GitLab.
(1) Configure the webhook token in Argo CD:
<code>kubectl edit secret argocd-secret -n argocd</code> <code>apiVersion: v1
kind: Secret
metadata:
name: argocd-secret
namespace: argocd
type: Opaque
stringData:
# gitlab webhook secret
webhook.gitlab.secret: coolops
</code>After saving, a secret is generated:
<code># kubectl describe secret argocd-secret -n argocd
Name: argocd-secret
Namespace: argocd
Type: Opaque
Data
====
webhook.gitlab.secret: 7 bytes
</code>(2) Configure the webhook in the GitLab repository (screenshot).
Because the cluster uses an invalid internal certificate, disable SSL verification in the webhook settings.
Test the webhook; a successful test confirms correct configuration.
Now any commit to GitLab will trigger Argo CD immediately.
Using Argo Rollouts for Canary Releases
Install Argo Rollouts in the Kubernetes cluster:
<code>kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://raw.githubusercontent.com/argoproj/argo-rollouts/stable/manifests/install.yaml
</code>Install the kubectl plugin for Argo Rollouts:
<code>curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64
chmod +x ./kubectl-argo-rollouts-linux-amd64
mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
</code>Define the rollout and service manifests:
<code>apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: rollouts-simple-java
spec:
replicas: 3
strategy:
canary:
canaryService: rollouts-simple-java-canary
stableService: rollouts-simple-java-stable
trafficRouting:
nginx:
stableIngress: rollouts-simple-java-stable
steps:
- setWeight: 20
- pause: {duration: 60}
- setWeight: 50
- pause: {duration: 10}
- setWeight: 80
- pause: {duration: 10}
revisionHistoryLimit: 2
selector:
matchLabels:
app: rollouts-simple-java
template:
metadata:
labels:
app: rollouts-simple-java
spec:
containers:
- name: myapp
image: registry.cn-hangzhou.aliyuncs.com/rookieops/myapp:latest
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /hello
port: 8080
initialDelaySeconds: 60
periodSeconds: 15
readinessProbe:
httpGet:
path: /hello
port: 8080
periodSeconds: 15
</code> <code>apiVersion: v1
kind: Service
metadata:
name: rollouts-simple-java-canary
spec:
ports:
- port: 8080
targetPort: http
protocol: TCP
name: http
selector:
app: rollouts-simple-java
---
apiVersion: v1
kind: Service
metadata:
name: rollouts-simple-java-stable
spec:
ports:
- port: 8080
targetPort: http
protocol: TCP
name: http
selector:
app: rollouts-simple-java
</code> <code>apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: rollouts-simple-java-stable
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: rollouts-simple-java.coolops.cn
http:
paths:
- path: /
backend:
serviceName: rollouts-simple-java-stable
servicePort: 8080
</code> <code>commonLabels:
app: rollouts-simple-java
resources:
- rollout.yaml
- services.yaml
- ingress.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- name: registry.cn-hangzhou.aliyuncs.com/rookieops/myapp
newTag: "latest"
namespace: dev
</code>Commit these files to the GitLab repository and let Argo CD sync them.
Tagging the Code Repository
Tagging provides a snapshot of the repository, allowing easy retrieval of specific versions without searching commit IDs.
The following Groovy script uses the GitLab API to obtain a project ID and create a tag:
<code>package org.devops
// HTTP request wrapper
def HttpReq(reqType, reqUrl, reqBody){
def gitServer = "http://172.17.100.135:32080/api/v4"
withCredentials([string(credentialsId: 'gitlab-token', variable: 'gitlabToken')]){
result = httpRequest(
customHeaders: [[maskValue: true, name: 'PRIVATE-TOKEN', value: "${gitlabToken}"]],
httpMode: reqType,
contentType: "APPLICATION_JSON",
ignoreSslErrors: true,
requestBody: reqBody,
url: "${gitServer}/${reqUrl}"
)
}
return result
}
// Get project ID by name
def GetProjectID(projectName){
def projectApi = "projects?search=${projectName}"
def response = HttpReq('GET', projectApi, '')
def result = readJSON text: "${response.content}"
for(repo in result){
if(repo['path'] == "${projectName}"){
return repo['id']
}
}
return null
}
// Create a tag in GitLab
def TagGitlab(projectId, tag_name, tag_ref){
def apiUrl = "projects/${projectId}/repository/tags"
def reqBody = "{\"tag_name\": \"${tag_name}\", \"ref\": \"${tag_ref}\"}"
HttpReq('POST', apiUrl, reqBody)
}
</code>In the Jenkins pipeline, after a successful deployment, the
TagGitlabstage calls these methods when the user confirms continuation:
<code>stage('TagGitlab') {
steps {
script {
if ("${isUpdate}" == 'yes' && "${gitBranch}" == 'master') {
repo_id = gitlab.GetProjectID("${repo_name}")
tag_name = "release-${tools.getTime()}"
gitlab.TagGitlab("${repo_id}", "${tag_name}", 'master')
} else {
echo 'No tag created'
}
}
}
}
</code>Final Notes
Argo CD and Argo Rollouts work well together, but keep backups of the YAML files used by Argo CD because the system is stateless and configmaps may be cleared. Also note that Argo Rollouts currently supports only Ingress and ALB for traffic routing.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.