Mastering CI/CD: Automate Deployments with GitLab, Jenkins, Docker & Kubernetes
This guide demonstrates how to integrate GitLab and Jenkins with Kubernetes to achieve automated, multi-environment deployments, covering project configuration, Dockerfile creation, build scripts, Jenkins pipeline setup, Kubernetes resources, and best practices for scaling, rolling updates, and service management in a production-grade cloud native architecture.
This article explains, from a practical perspective, how to combine the commonly used GitLab and Jenkins with Kubernetes to achieve automated project deployment, using the company's current production architecture as the focus.
Tools and Technologies
GitLab: source code management system.
Jenkins (Jenkins Pipeline): automation build and deployment tool, organizing steps as pipelines.
Docker (Dockerfile): container engine; applications run as Docker containers, Dockerfile defines the image.
Kubernetes: open‑source container orchestration system.
Environment Background
GitLab is used for source code management with branches for dev, test, pre, and master.
Jenkins service is already set up.
A Docker Registry (or Harbor or cloud service) stores images; this guide uses Alibaba Cloud Container Registry.
A Kubernetes cluster is deployed.
Expected Effects
Deploy applications per environment, isolating dev, test, pre, and prod; dev/test/pre share a K8s cluster using different namespaces, while prod runs on Alibaba Cloud ACK.
Configuration is highly reusable; only a few variables need to be changed to deploy new projects.
Push to code can automatically trigger build and deployment for dev, test, and pre; prod uses a separate ACK cluster and Jenkins.
Overall interaction flow diagram is provided.
Project Configuration Files
In the project root, add the following essential files:
Dockerfile – defines how to build the Docker image (example shown for a Java project). Docker_build.sh – tags and pushes the image to the registry.
project.yaml – main YAML file for deploying the project to the K8s cluster.
Dockerfile
# 镜像来源
FROM xxxxxxxxxxxxxxxxxxxxxxxxxx.cr.aliyuncs.com/billion_basic/alpine-java:latest
# 拷贝当前目录的应用到镜像
COPY target/JAR_NAME /application/
# 声明工作目录
WORKDIR /application
# 声明动态容器卷
VOLUME /application/logs
# 启动命令
ENTRYPOINT ["java","-Duser.timezone=Asia/Shanghai","-Djava.security.egd=file:/dev/./urandom"]
CMD ["-jar","-Dspring.profiles.active=SPRING_ENV","-Xms512m","-Xmx1024m","/application/JAR_NAME"]docker_build.sh
#!/bin/bash
# 模块名称
PROJECT_NAME=$1
# 名称空间目录
WORKSPACE="/home/jenkins/workspace"
# 模块目录
PROJECT_PATH=$WORKSPACE/pro_$PROJECT_NAME
# jar 包目录
JAR_PATH=$PROJECT_PATH/target
# jar 包名称
JAR_NAME=$PROJECT_NAME.jar
# dockerfile 目录
dockerFILE_PATH="/$PROJECT_PATH/dockerfile"
sed -i "s/JAR_NAME/$JAR_NAME/g" $PROJECT_PATH/dockerfile
sed -i "s/SPRING_ENV/k8s/g" $PROJECT_PATH/dockerfile
cd $PROJECT_PATH
# 登录阿里云仓库
docker login xxxxxxxxxxxxxxxxxxxxxxxxxx.cr.aliyuncs.com -u 百瓶网 -p xxxxxxxxxxxxxxxxxxxxxxxxxx
# 构建模块镜像
docker build -t $PROJECT_NAME .
docker tag $PROJECT_NAME xxxxxxxxxxxxxxxxxxxxxxxxxx.cr.aliyuncs.com/billion_pro/pro_$PROJECT_NAME:$BUILD_NUMBER
# 推送到阿里云仓库
docker push xxxxxxxxxxxxxxxxxxxxxxxxxx.cr.aliyuncs.com/billion_pro/pro_$PROJECT_NAME:$BUILD_NUMBERproject.yaml
# ------------------- PersistentVolume(定义PV) -------------------
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-billionbottle-wx
namespace: billion-pro
labels:
alicloud-pvname: pv-billionbottle-wx
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
csi:
driver: nasplugin.csi.alibabacloud.com
volumeHandle: pv-billionbottle-wx
volumeAttributes:
server: "xxxxxxxxxxxxx.nas.aliyuncs.com"
path: "/k8s/java"
mountOptions:
- nolock,tcp,noresvport
- vers=3
---
# ------------------- PersistentVolumeClaim(定义PVC) -------------------
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc-billionbottle-wx
namespace: billion-pro
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
selector:
matchLabels:
alicloud-pvname: pv-billionbottle-wx
---
# ------------------- Deployment -------------------
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: billionbottle-wx
name: billionbottle-wx
namespace: billion-pro
spec:
replicas: 2
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: billionbottle-wx
template:
metadata:
labels:
k8s-app: billionbottle-wx
spec:
serviceAccountName: default
imagePullSecrets:
- name: registrykey-k8s
containers:
- name: billionbottle-wx
image: $IMAGE_NAME
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 60
periodSeconds: 60
successThreshold: 1
tcpSocket:
port: 8020
timeoutSeconds: 1
ports:
- containerPort: 8020
protocol: TCP
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 60
periodSeconds: 60
successThreshold: 1
tcpSocket:
port: 8020
timeoutSeconds: 1
resources:
requests:
memory: "1024Mi"
cpu: "300m"
limits:
memory: "1024Mi"
cpu: "300m"
volumeMounts:
- name: pv-billionbottle-key
mountPath: "/home/billionbottle/key"
- name: pvc-billionbottle-wx
mountPath: "/billionbottle/logs"
volumes:
- name: pv-billionbottle-key
persistentVolumeClaim:
claimName: pvc-billionbottle-key
- name: pvc-billionbottle-wx
persistentVolumeClaim:
claimName: pvc-billionbottle-wx
---
# ------------------- Service -------------------
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: billionbottle-wx
name: billionbottle-wx
namespace: billion-pro
spec:
ports:
- port: 8020
targetPort: 8020
type: ClusterIP
selector:
k8s-app: billionbottle-wxJenkins Pipeline (Jenkinsfile)
pipeline {
environment {
BRANCH = sh(returnStdout: true, script: 'echo $branch').trim()
}
agent { node { label 'master' } }
stages {
stage('Git') {
steps { git branch: '${Branch}', credentialsId: '${git_auth}', url: '${git_address}' }
}
stage('maven build') {
steps { sh "mvn clean package -U -DskipTests" }
}
stage('docker build') {
steps { sh "chmod 755 ./deploy/${env}_docker_build.sh && ./deploy/${env}_docker_build.sh ${project_name} ${env}" }
}
stage('K8s deploy') {
steps {
sh "pwd && sed -i 's#\\$IMAGE_NAME#${image_name}#' deploy/${env}_${project_name}.yaml"
kubernetesDeploy configs: "deploy/${env}_${project_name}.yaml", kubeconfigId: "${k8sauth}"
}
}
}
}Jenkins Task Configuration
Create a Pipeline job in Jenkins, select "Pipeline script", configure the Git repository, credentials, and branch (e.g., master). Add the necessary secret credentials for Docker registry access.
Kubernetes Overview
Kubernetes is a container‑based cluster orchestration engine offering scaling, rolling updates, self‑healing, and service discovery. It consists of a Master (API Server, Scheduler, Controller) and Nodes (kubelet, kube‑proxy) with etcd for state storage.
Kubernetes Architecture Diagram
Container Orchestration
Key resources include Deployments (stateless apps), StatefulSets (stateful apps), DaemonSets (daemon processes), and Jobs/CronJobs (batch tasks). Deployments manage ReplicaSets, which control Pods, enabling horizontal scaling and versioned rollouts.
Horizontal Scaling
Adjust the replica count in the ReplicaSet to scale Pods up or down.
Rolling Update
Kubernetes default strategy replaces old Pods with new ones gradually, avoiding downtime. Parameters like maxSurge and maxUnavailable fine‑tune the process.
Service (Microservice)
Services provide stable endpoints and load balancing for Pods, using label selectors (e.g., app=xxx) to group Pods and expose them via a ClusterIP, NodePort, or LoadBalancer.
Kubernetes Networking
Three‑way connectivity is required: node↔pod, node↔node, and pod↔pod across nodes, typically achieved with CNI plugins like Flannel.
Conclusion
The article has introduced the core components of the production environment—GitLab, Jenkins, Docker, and Kubernetes—and explained how they work together to enable automated, multi‑environment deployments. Future updates will cover configuration centers, monitoring, and alerting.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
BaiPing Technology
Official account of the BaiPing app technology team. Dedicated to enhancing human productivity through technology. | DRINK FOR FUN!
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.
