Cloud Native 16 min read

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.

BaiPing Technology
BaiPing Technology
BaiPing Technology
Mastering CI/CD: Automate Deployments with GitLab, Jenkins, Docker & Kubernetes

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_NUMBER

project.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-wx

Jenkins 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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Dockerci/cdGitLabJenkins
BaiPing Technology
Written by

BaiPing Technology

Official account of the BaiPing app technology team. Dedicated to enhancing human productivity through technology. | DRINK FOR FUN!

0 followers
Reader feedback

How this landed with the community

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.