Deploy Jenkins on Kubernetes using K3s

Posted by NetworkWhois on
After spending countless hours experimenting with different Kubernetes distributions, I've found that K3s provides an excellent lightweight platform for running Jenkins. In this guide, I'll share my hands-on experience deploying Jenkins on K3s, including the challenges I faced and how I overcame them.
Prerequisites
Before we dive in, make sure you have:
- A Linux server with at least 2 CPU cores and 4GB RAM
- K3s installed on your server (Follow my detailed guide: How to Install K3s on Ubuntu)
- kubectl command-line tool installed on your local machine
- Basic knowledge of Kubernetes concepts
Setting Up Storage
Jenkins needs persistent storage to maintain its configuration and build history. Let's create a StorageClass and PersistentVolume:
cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-path
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain
EOF

Creating a Jenkins Namespace
I always recommend isolating Jenkins in its own namespace for better resource management:
kubectl create namespace jenkins

Deploying Jenkins
Here's the Jenkins deployment configuration I've refined through multiple iterations:
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
namespace: jenkins
spec:
replicas: 1
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
containers:
- name: jenkins
image: jenkins/jenkins:lts
ports:
- containerPort: 8080
volumeMounts:
- name: jenkins-home
mountPath: /var/jenkins_home
volumes:
- name: jenkins-home
persistentVolumeClaim:
claimName: jenkins-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-pvc
namespace: jenkins
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: Service
metadata:
name: jenkins
namespace: jenkins
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 30000
selector:
app: jenkins
EOF

Pro Tip: I've set the nodePort to 30000, but you can choose any port between 30000-32767. Just make sure it's not being used by other services.
Accessing Jenkins
Once deployed, wait a few minutes for Jenkins to initialize. You can monitor the pod status:
kubectl get pods -n jenkins

To get the initial admin password:
kubectl exec -n jenkins $(kubectl get pods -n jenkins -l app=jenkins -o jsonpath='{.items[0].metadata.name}') -- cat /var/jenkins_home/secrets/initialAdminPassword

Access Jenkins through your browser using:
http://your-server-ip:30000

Troubleshooting Common Issues
During my deployment journey, I encountered a few hiccups. Here's how to resolve them:
Pod Stuck in Pending State
If your Jenkins pod is stuck in pending state, check the events:
kubectl describe pod -n jenkins $(kubectl get pods -n jenkins -l app=jenkins -o jsonpath='{.items[0].metadata.name}')
Common causes include:
- Insufficient resources - Adjust the resource requests in the deployment YAML
- PVC binding issues - Verify your StorageClass configuration
- Node port conflicts - Change the nodePort value in the service configuration
Security Considerations
Before using Jenkins in production, I strongly recommend:
- Setting up HTTPS using cert-manager or an ingress controller
- Implementing role-based access control (RBAC)
- Regularly updating Jenkins and its plugins
- Backing up the Jenkins home directory regularly
Have you deployed Jenkins on K3s? I'd love to hear about your experience send me an email.
Remember: Always keep your Jenkins instance updated and secured. The configurations provided here are basic examples and should be enhanced based on your security requirements.