Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

309 optimize jenkins on kubernetes setup dockerfile yaml and documentation #310

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 20 additions & 24 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM jenkins/jenkins:lts

USER root

# Install required packages and update package lists
# Install required packages
RUN apt-get update && \
apt-get install -y --no-install-recommends \
apt-transport-https \
Expand All @@ -17,31 +17,27 @@ RUN apt-get update && \
unzip \
jq \
openssh-client && \
# Install Docker CLI
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - && \
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) \
stable" && \
# Detect architecture and install Docker CLI if amd64
if [ "$(dpkg --print-architecture)" = "amd64" ]; then \
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - && \
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" && \
apt-get update && \
apt-get install -y --no-install-recommends docker-ce-cli; \
fi && \
# Install kubectl with the updated repository URL
mkdir -p /etc/apt/keyrings && \
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.26/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg && \
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.26/deb/ /" > /etc/apt/sources.list.d/kubernetes.list && \
apt-get update && \
apt-get install -y --no-install-recommends \
docker-ce-cli && \
# Install kubectl
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | tee -a /etc/apt/sources.list.d/kubernetes.list && \
apt-get update && \
apt-get install -y --no-install-recommends \
kubectl && \
apt-get install -y --no-install-recommends kubectl && \
# Clean up to reduce image size
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Distributed Builds plugins
RUN /usr/local/bin/install-plugins.sh ssh-agent \
email-ext \
mailer \
slack \
htmlpublisher \
greenballs \
simple-theme-plugin \
kubernetes
# Install Distributed Builds plugins using jenkins-plugin-cli
RUN jenkins-plugin-cli --plugins \
ssh-agent email-ext mailer slack htmlpublisher \
greenballs simple-theme-plugin kubernetes

USER jenkins
164 changes: 136 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,136 @@
# WELCOME!

Welcome to the Jenkins Online Meetup featuring Jenkins on Kubernetes! We promise it's going to be more fun than your typical root canal procedure.

Here are some setup notes to get started:

1. Start up minikube.
2. Create a namespace for Jenkins. Think of it like a tiny kingdom ruled by our favorite continuous integration tool.
3. Apply the jenkins-admin-rbac.yaml file to give Jenkins the keys to the kingdom.
4. Create a service for Jenkins to help Kubernetes know where to find it.
5. Deploy Jenkins with the jenkins-deployment.yaml file. It's like bringing a new baby into the world, except this baby's name is Jenkins.
6. Get the IP address of your minikube and feel like a hacker for a brief moment.
7. Check out the nodeport by running kubectl -n jenkins get svc. It's like a fun treasure hunt, but instead of treasure, you get Jenkins.
8. Use the minikube IP address and nodeport to access the Jenkins UI. It's like a portal to a magical land of continuous integration.
9. Head over to build executor status to configure Kubernetes. This is where the real magic happens.
10. Choose config cloud. It's like being the captain of your own cloud kingdom.
11. Add a new cloud. It's like building a new castle for your kingdom.
12. Use kubectl cluster-info | grep master to get the control plane IP. It's like the key to the kingdom.
13. Add that to the Kubernetes field. It's like unlocking a secret door to a room full of candy.
14. Test the connection. It's like solving a mystery and revealing the culprit.
15. Add the Jenkins URL. This is the Jenkins pod IP, like your own personal compass that will guide you to the land of continuous integration.
16. Let's talk about renaming. It's like giving Jenkins a new name, like Prince or Beyonce.
17. Use jenkins/inbound-agent for your jobs. It's like a secret code that only cool people know.
18. Everything else is named inbound-agent. It's like wearing matching outfits with your BFF.
19. Make sure to set the label on the job when you configure it. It's like giving your new puppy a name tag so you don't lose them.
20. Configure a new freestyle job with the inbound-agent label and a shell that just echoes Hello World. It's like teaching your new puppy to sit, but way less messy.

So there you have it - a fun and easy way to get started with Jenkins on Kubernetes! Have fun, and may the continuous integration force be with you!
# Welcome to Jenkins on Kubernetes!

This guide will help you set up Jenkins on Kubernetes using Minikube in a few simple steps. Follow the instructions below to get started.

## Table of Contents

1. [Code Walkthrough](#code-walkthrough)
2. [Steps to Get Started (Manual)](#steps-to-get-started-manual)
3. [Steps to Get Started (Using `getstarted.sh` Script)](#steps-to-get-started-using-getstartedsh-script)
4. [Opening Issues and Submitting Pull Requests](#opening-issues-and-submitting-pull-requests)

## Code Walkthrough

The project consists of several key files and scripts that are necessary to deploy Jenkins on a Kubernetes cluster. Let's walk through the main components:

### 1. `Dockerfile`

The `Dockerfile` sets up a Jenkins instance with required tools such as Docker CLI and `kubectl`. It installs necessary packages and plugins to make Jenkins work seamlessly within a Kubernetes environment. The final image can be used as a Jenkins master node.

Key steps:
- **Base Image**: Starts with the official Jenkins LTS image.
- **Packages Installation**: Installs essential packages like Docker CLI, `kubectl`, and others.
- **Plugins Installation**: Uses `jenkins-plugin-cli` to install plugins necessary for Kubernetes integration.

### 2. `getstarted.sh`

This script automates the process of setting up Jenkins on Kubernetes. It checks for the existence of Minikube and `kubectl`, installs them if necessary, and then sets up the Kubernetes cluster and Jenkins deployment.

Key steps:
- **Minikube and `kubectl` Installation**: Installs Minikube and `kubectl` if they are not already installed.
- **Kubernetes Cluster Setup**: Starts a Minikube cluster.
- **Jenkins Deployment**: Creates necessary resources like namespace, PersistentVolume, RBAC configurations, and then deploys Jenkins.
- **Port Forwarding**: Automatically forwards the Jenkins service port to your local machine for easy access.

### 3. `jenkins-admin-rbac.yaml`

This file configures Role-Based Access Control (RBAC) for Jenkins, granting it the necessary permissions to interact with Kubernetes resources.

### 4. `jenkins-service.yaml`

Defines the Jenkins service in Kubernetes, exposing it on a specific NodePort for external access.

### 5. `jenkins-deployment.yaml`

This file sets up the actual Jenkins deployment in Kubernetes, specifying the image to use, volume mounts, and other deployment details.

## Steps to Get Started (Manual)

1. **Start Minikube**:
Set up a local Kubernetes cluster by running the following command:
```bash
minikube start
```

2. **Create a Namespace for Jenkins**:
Organize Jenkins resources under a dedicated namespace:
```bash
kubectl create namespace jenkins
```

3. **Apply RBAC Configuration**:
Grant Jenkins the necessary permissions:
```bash
kubectl apply -f jenkins-admin-rbac.yaml
```

4. **Create Jenkins Service**:
Deploy the Jenkins service:
```bash
kubectl apply -f jenkins-service.yaml
```

5. **Deploy Jenkins**:
Deploy the Jenkins instance:
```bash
kubectl apply -f jenkins-deployment.yaml
```

6. **Get Minikube IP**:
Obtain the Minikube IP:
```bash
minikube ip
```

7. **Access Jenkins UI**:
Combine the Minikube IP with the NodePort to access Jenkins. For example:
```bash
http://<Minikube-IP>:<NodePort>
```

8. **Configure Build Executor**:
In Jenkins UI, navigate to "Manage Jenkins" > "Manage Nodes and Clouds" to configure the Kubernetes cloud.

9. **Test the Connection**:
Verify the Kubernetes integration by testing the connection within Jenkins.

10. **Create and Run a Job**:
Set up a freestyle job in Jenkins to confirm everything is functioning as expected.

## Steps to Get Started (Using `getstarted.sh` Script)

To automate the entire setup process, you can use the provided `getstarted.sh` script:

1. **Ensure Prerequisites**:
Ensure that you have a bash-compatible shell, and that the script is executable. If needed, make it executable with:
```bash
chmod +x getstarted.sh
```

2. **Run the Script**:
Execute the script:
```bash
./getstarted.sh
```

3. **Follow the Prompts**:
The script will guide you through the installation process. It will:
- Install Minikube and `kubectl` if they are not already installed.
- Start a Minikube cluster.
- Set up Kubernetes resources and deploy Jenkins.
- Automatically forward the Jenkins service port to your local machine.

4. **Access Jenkins UI**:
Once the script completes, it will provide you with a URL to access Jenkins, such as `http://localhost:8080`. Open this in your web browser.

## Opening Issues and Submitting Pull Requests

If you encounter any issues or have suggestions for new features, you can open an issue or submit a pull request. Here's how:

- **Opening Issues**: Navigate to the [GitHub Issues page](https://github.com/markyjackson-taulia/jenkinsci-on-kubernetes/issues) and create a new issue. Please provide as much detail as possible, including steps to reproduce the problem if applicable.

- **Submitting Pull Requests**: Fork the repository, make your changes, and submit a pull request. Ensure that your code follows the existing style and conventions. If you're adding new functionality, consider adding relevant tests.

**DockerHub Repository**: You can find the pre-built Docker image on DockerHub [here](https://hub.docker.com/repository/docker/anuclei/jenkins-on-kubernetes).

Enjoy a seamless CI/CD experience with Jenkins on Kubernetes!
150 changes: 150 additions & 0 deletions getstarted.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#!/bin/bash

# ASCII Art Welcome
cat << "EOF"
____. __ .__ _____ .__ .__ __ ___.
| | ____ ____ | | _|__| ____ ______ ____ ____ / \ |__| ____ |__| | ____ _\_ |__ ____
| |/ __ \ / \| |/ / |/ \ / ___/ / _ \ / \ / \ / \| |/ \| | |/ / | \ __ \_/ __ \
/\__| \ ___/| | \ <| | | \\___ \ ( <_> ) | \ / Y \ | | \ | <| | / \_\ \ ___/
\________|\___ >___| /__|_ \__|___| /____ > \____/|___| / \____|__ /__|___| /__|__|_ \____/|___ /\___ >
\/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/
EOF

echo "Welcome to Jenkins on Kubernetes!"

# Function to check for command existence
command_exists() {
command -v "$1" >/dev/null 2>&1
}

# Function to install minikube
install_minikube() {
echo "Installing Minikube..."
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 || { echo "Failed to download Minikube. Exiting."; exit 1; }
sudo install minikube /usr/local/bin/ || { echo "Failed to install Minikube. Exiting."; exit 1; }
elif [[ "$OSTYPE" == "darwin"* ]]; then
brew install minikube || { echo "Failed to install Minikube via Homebrew. Exiting."; exit 1; }
else
echo "Unsupported OS for Minikube installation. Please install manually."
exit 1
fi
}

# Function to install kubectl
install_kubectl() {
echo "Installing kubectl..."
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" || { echo "Failed to download kubectl. Exiting."; exit 1; }
chmod +x kubectl
sudo mv kubectl /usr/local/bin/ || { echo "Failed to move kubectl to /usr/local/bin/. Exiting."; exit 1; }
elif [[ "$OSTYPE" == "darwin"* ]]; then
brew install kubectl || { echo "Failed to install kubectl via Homebrew. Exiting."; exit 1; }
else
echo "Unsupported OS for kubectl installation. Please install manually."
exit 1
fi
}

# Check if Minikube is installed
if command_exists minikube; then
echo "Minikube is already installed."
else
read -p "Minikube is not installed. Do you want to install it? (y/n): " install_minikube_choice
if [[ "$install_minikube_choice" == "y" ]]; then
install_minikube
else
echo "Minikube is required. Exiting."
exit 1
fi
fi

# Check if kubectl is installed
if command_exists kubectl; then
echo "kubectl is already installed."
else
read -p "kubectl is not installed. Do you want to install it? (y/n): " install_kubectl_choice
if [[ "$install_kubectl_choice" == "y" ]]; then
install_kubectl
else
echo "kubectl is required. Exiting."
exit 1
fi
fi

# Start Minikube cluster
read -p "Do you want to start a Minikube cluster? (y/n): " start_minikube_choice
if [[ "$start_minikube_choice" == "y" ]]; then
minikube start || { echo "Failed to start Minikube. Exiting."; exit 1; }
else
echo "Minikube cluster is required. Exiting."
exit 1
fi

# Wait for Minikube to be fully ready
echo "Waiting for Minikube to be fully ready..."
sleep 10 # Adjust this value as needed

# Create Jenkins namespace
kubectl create namespace jenkins || { echo "Failed to create Jenkins namespace. Exiting."; exit 1; }

# Create PersistentVolume and PersistentVolumeClaim
echo "Creating PersistentVolume and PersistentVolumeClaim for Jenkins..."
cat <<EOF | kubectl apply -f - || { echo "Failed to create PersistentVolume and PersistentVolumeClaim. Exiting."; exit 1; }
apiVersion: v1
kind: PersistentVolume
metadata:
name: jenkins-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data/jenkins"

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-pvc
namespace: jenkins
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
EOF

# Apply RBAC configuration
kubectl apply -f jenkins-admin-rbac.yaml -n jenkins || { echo "Failed to apply RBAC configuration. Exiting."; exit 1; }

# Deploy Jenkins service
kubectl apply -f jenkins-service.yaml -n jenkins || { echo "Failed to deploy Jenkins service. Exiting."; exit 1; }

# Deploy Jenkins
kubectl apply -f jenkins-deployment.yaml -n jenkins || { echo "Failed to deploy Jenkins. Exiting."; exit 1; }

# Wait for Jenkins to be ready
echo "Waiting for Jenkins to start..."
kubectl rollout status deployment/jenkins -n jenkins || { echo "Jenkins deployment failed. Exiting."; exit 1; }

# Port-forward Jenkins service to access the UI
echo "Forwarding port to access Jenkins UI..."
nohup kubectl port-forward svc/jenkins 8080:8080 -n jenkins >/dev/null 2>&1 &
sleep 5

# Print out Jenkins access information
jenkins_url="http://localhost:8080"
echo "Jenkins is now running on Minikube."
echo "Access Jenkins at: $jenkins_url"

# Launch Jenkins UI in the default web browser
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
xdg-open "$jenkins_url"
elif [[ "$OSTYPE" == "darwin"* ]]; then
open "$jenkins_url"
else
echo "Please manually open your web browser and go to $jenkins_url"
fi
Loading
Loading