Ultimate guide to integrating GitLab CI/CD with Kubernetes for automated deployments, continuous integration, and effective DevOps practices.
Introduction
Integrating GitLab CI/CD with Kubernetes creates a powerful automation workflow for modern DevOps teams. In today’s fast-paced software development environment, combining GitLab’s robust CI/CD pipeline capabilities with Kubernetes’ container orchestration power creates an efficient, automated deployment system. This GitLab Kubernetes integration allows development teams to build, test, and deploy applications continuously while maintaining high availability and scalability.
This comprehensive guide will walk you through the entire process of integrating GitLab CI/CD with Kubernetes, from initial setup to advanced deployment strategies. By the end, you’ll have a fully functional, automated deployment pipeline that leverages the best of both platforms.
Why Integrating GitLab CI/CD with Kubernetes Benefits Your Development Workflow
Before diving into the technical implementation, let’s understand the key benefits of this integration:
- Streamlined Deployment Process: Automate the entire pipeline from code commit to production deployment
- Consistent Environments: Ensure your development, staging, and production environments are identical
- Infrastructure as Code: Define your entire infrastructure through version-controlled configuration files
- Scalability: Easily scale your applications based on demand
- Self-healing Applications: Kubernetes automatically restarts failed containers and replaces unhealthy nodes
- Reduced Operational Overhead: Minimize manual intervention in the deployment process
- Improved Developer Experience: Developers can focus on writing code rather than deployment logistics
Prerequisites for GitLab CI/CD and Kubernetes Integration
To follow this guide, you’ll need:
- A GitLab account (self-hosted or GitLab.com)
- Basic knowledge of GitLab CI/CD
- A Kubernetes cluster (managed service like GKE, EKS, AKS, or self-hosted)
- kubectl installed and configured
- Helm 3 installed (optional but recommended)
- Docker installed for local testing
Step 1: Setting Up Your Kubernetes Cluster for GitLab Integration
Creating a Kubernetes Cluster
If you don’t have a Kubernetes cluster yet, you have several options:
- Google Kubernetes Engine (GKE)
- Amazon Elastic Kubernetes Service (EKS)
- Azure Kubernetes Service (AKS)
- Self-hosted Kubernetes cluster
For this tutorial, we’ll use GKE as an example, but the principles apply to any Kubernetes provider.
# Create a GKE cluster
gcloud container clusters create gitlab-k8s-demo \
--num-nodes=3 \
--machine-type=e2-standard-2 \
--region=us-central1
Setting Up Service Account
To allow GitLab to interact with your Kubernetes cluster, you need to create a service account with appropriate permissions:
# Create a service account
kubectl create serviceaccount gitlab
# Give the service account cluster-admin privileges
kubectl create clusterrolebinding gitlab-admin \
--clusterrole=cluster-admin \
--serviceaccount=default:gitlab
# Get the secret name
SECRET_NAME=$(kubectl get serviceaccount gitlab -o jsonpath='{.secrets[0].name}')
# Get the service account token
TOKEN=$(kubectl get secret $SECRET_NAME -o jsonpath='{.data.token}' | base64 --decode)
# Save the token for later use
echo $TOKEN > gitlab-admin-token.txt
Step 2: Configuring GitLab for Kubernetes Integration
Connecting Your Kubernetes Cluster to GitLab CI/CD
- Navigate to your GitLab project or group
- Go to Infrastructure > Kubernetes clusters
- Click Add Kubernetes cluster
- Select Add existing cluster
- Fill in the required information:
- Kubernetes cluster name: A name for your cluster
- API URL: Your Kubernetes API server endpoint (
kubectl cluster-info
to find this) - CA Certificate: The cluster CA certificate (
kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 --decode
) - Service Token: The token we saved earlier
- Project namespace: The Kubernetes namespace where your resources will be deployed (leave blank to use the project name)
- Click Add Kubernetes cluster
Installing GitLab Components in Your Kubernetes Environment
Once your cluster is connected, GitLab offers several components you can install directly from the interface:
- GitLab Runner: For running CI/CD jobs
- Ingress: For routing external traffic to your services
- Cert-Manager: For automatic SSL certificate management
- Prometheus: For monitoring
- GitLab Managed Apps: For additional functionality
These components streamline the integration process. For this guide, let’s install GitLab Runner and Ingress:
- In your cluster configuration page, find the Applications tab
- Install GitLab Runner and Ingress by clicking their respective install buttons
Step 3: Building Your GitLab CI/CD Pipeline for Kubernetes Deployment
Now let’s set up a CI/CD pipeline that builds, tests, and deploys your application to Kubernetes. Create a .gitlab-ci.yml
file in your project’s root directory:
stages:
- build
- test
- deploy
variables:
DOCKER_REGISTRY: registry.gitlab.com
DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA
KUBERNETES_NAMESPACE: $CI_PROJECT_NAME-$CI_ENVIRONMENT_SLUG
build:
stage: build
image: docker:20.10.16
services:
- docker:20.10.16-dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $DOCKER_IMAGE .
- docker push $DOCKER_IMAGE
only:
- main
- staging
test:
stage: test
image: $DOCKER_IMAGE
script:
- echo "Running tests..."
- npm test # Or your testing command
only:
- main
- staging
deploy:
stage: deploy
image:
name: bitnami/kubectl:latest
entrypoint: [""]
script:
- kubectl config set-cluster k8s --server="$KUBE_URL" --insecure-skip-tls-verify=true
- kubectl config set-credentials admin --token="$KUBE_TOKEN"
- kubectl config set-context default --cluster=k8s --user=admin
- kubectl config use-context default
- sed -i "s/__VERSION__/${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHORT_SHA}/g" kubernetes/deployment.yaml
- kubectl apply -f kubernetes/deployment.yaml -n $KUBERNETES_NAMESPACE
- kubectl apply -f kubernetes/service.yaml -n $KUBERNETES_NAMESPACE
- kubectl apply -f kubernetes/ingress.yaml -n $KUBERNETES_NAMESPACE
- kubectl rollout status deployment/$CI_PROJECT_NAME -n $KUBERNETES_NAMESPACE
environment:
name: $CI_COMMIT_REF_NAME
url: https://$CI_PROJECT_NAME-$CI_ENVIRONMENT_SLUG.$DOMAIN
only:
- main
- staging
Creating Kubernetes Manifests for GitLab CI/CD Pipelines
You’ll need to create Kubernetes manifest files in a kubernetes
directory. Here are simplified examples:
deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: registry.gitlab.com/username/project:__VERSION__
ports:
- containerPort: 8080
resources:
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "200m"
memory: "256Mi"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
service.yaml:
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
type: ClusterIP
ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
rules:
- host: my-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 80
tls:
- hosts:
- my-app.example.com
secretName: my-app-tls
Step 4: Implementing GitLab Auto DevOps for Kubernetes Deployment
GitLab offers Auto DevOps, which automatically detects, builds, tests, deploys, and monitors your applications. To enable Auto DevOps:
- Go to your project’s Settings > CI/CD
- Expand the Auto DevOps section
- Check Default to Auto DevOps pipeline
- Click Save changes
Auto DevOps provides several benefits:
- Auto Build: Automatically detects the application language and builds a Docker image
- Auto Test: Runs language-appropriate tests
- Auto Code Quality: Analyzes your code for quality issues
- Auto SAST: Performs static application security testing
- Auto Deploy: Deploys your application to Kubernetes
- Auto Monitoring: Sets up monitoring with Prometheus
For production-grade applications, you might want to customize Auto DevOps by creating an .auto-deploy-values.yaml
file in your repository:
replicaCount: 3
livenessProbe:
path: /health
readinessProbe:
path: /ready
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 200m
memory: 256Mi
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
Step 5: Kubernetes Monitoring and Observability with GitLab
GitLab integrates with Prometheus and Grafana to provide monitoring for your Kubernetes applications:
- Install Prometheus from the GitLab Cluster Applications page
- Add monitoring configuration to your application:
metrics:
enabled: true
path: /metrics
port: 8080
Benefits of GitLab’s integrated monitoring:
- Real-time metrics: CPU, memory usage, request rates, etc.
- Anomaly detection: Automatically detect unusual patterns
- Error tracking: Identify and diagnose application errors
- Alerts: Set up alerts for critical issues
- Performance insights: Understand application performance over time
Common Challenges and Solutions
Challenge 1: GitLab CI/CD Secrets Management in Kubernetes
Store sensitive information securely using GitLab CI/CD variables and Kubernetes secrets:
# In GitLab CI/CD settings, create variables like:
# - DB_PASSWORD
# - API_KEY
# Then in your .gitlab-ci.yml:
deploy:
script:
- kubectl create secret generic app-secrets \
--from-literal=db-password=$DB_PASSWORD \
--from-literal=api-key=$API_KEY \
-n $KUBERNETES_NAMESPACE
Challenge 2: Kubernetes Resource Management with GitLab CI/CD
Properly configure resource requests and limits:
resources:
limits:
cpu: "1"
memory: "1Gi"
requests:
cpu: "500m"
memory: "512Mi"
Challenge 3: GitLab Kubernetes Zero-Downtime Deployments
Use GitLab CI/CD with Kubernetes deployment strategies:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
Challenge 4: Database Migrations in GitLab and Kubernetes Pipelines
Run migrations before deployment:
deploy:
script:
- kubectl apply -f kubernetes/migration-job.yaml
- kubectl wait --for=condition=complete job/db-migration -n $KUBERNETES_NAMESPACE --timeout=300s
- kubectl apply -f kubernetes/deployment.yaml
Best Practices for Integrating GitLab CI/CD with Kubernetes
- Use Environment Branches: Map Git branches to Kubernetes namespaces
- Implement a Review App Strategy: Create temporary environments for merge requests
- Follow the GitOps Workflow: Keep your infrastructure configuration in Git
- Set Up Proper Resource Limits: Prevent resource contention issues
- Implement Probes: Use liveness and readiness probes for better resilience
- Configure Horizontal Pod Autoscaling: Scale automatically based on metrics
- Use Canary Deployments: Release new versions incrementally
- Set Up Network Policies: Restrict network traffic between pods
- Implement Role-Based Access Control (RBAC): Limit access to cluster resources
- Back Up etcd Data: Regularly back up your Kubernetes state
Conclusion: Maximizing DevOps Efficiency with GitLab CI/CD and Kubernetes
Integrating GitLab CI/CD with Kubernetes creates a powerful platform for modern application development and deployment. This combination provides automation, scalability, resilience, and improved developer workflows.
By following this guide, you’ve set up a complete CI/CD pipeline that automates your application’s build, test, and deployment processes. You’ve learned how to leverage GitLab’s Kubernetes integration features, including Auto DevOps and monitoring capabilities.
Remember that while the initial setup might seem complex, the long-term benefits of this integration far outweigh the upfront investment. Your development team will be more productive, your deployments more reliable, and your applications more robust.
FAQs About GitLab CI/CD and Kubernetes Integration
How do I troubleshoot failed deployments?
Check the GitLab CI/CD job logs and use kubectl describe pod <pod-name>
and kubectl logs <pod-name>
to investigate issues in your Kubernetes deployment.
Can I use this setup with multiple Kubernetes clusters?
Yes, GitLab allows you to connect multiple clusters. You can set up different environments (staging, production) on separate clusters.
How do I roll back to a previous version if there’s an issue?
You can use kubectl rollout undo deployment/<deployment-name>
or deploy a specific previous version using your CI/CD pipeline.
Does this work with GitLab Community Edition?
Yes, most features work with GitLab CE, but some advanced features like cluster management through GitLab require GitLab Premium or Ultimate.
How can I optimize my CI/CD pipeline for faster deployments?
Use caching for dependencies, optimize your Docker images, and consider using GitLab’s parallel execution features to run stages concurrently.
Can I integrate external tools with this setup?
Yes, you can integrate external tools like SonarQube, Snyk, or JFrog Artifactory through GitLab CI/CD integration or direct Kubernetes manifests.
How do I manage multiple environments (dev, staging, prod)?
Use GitLab environments and Kubernetes namespaces to separate your deployments, with different configuration per environment.