Stateless Jenkins - V2 - Basic Recipe Refactor
Now that I successfully followed a blog post and created a Jenkins slave-executor within Kubernetes, the next goal is to refactor the multiple K8s configurations into a single YML and make small Docker and K8s changes.
Create Local Dir ¶
# Navigate to local dir
$ mkdir ~/tutorial/k8s/jenkins/v2
$ cd ~/tutorial/k8s/jenkins/v2
$ minikube start
Create plugins.txt ¶
# List plugins for Jenkins image
$ cat > plugins.txt <<EOF
ssh-slaves
email-ext
mailer
slack
htmlpublisher
greenballs
simple-theme-plugin
kubernetes
workflow-aggregator
EOF
Define and Build Jenkins Dockerfile with plugins.txt ¶
# Define Jenkins image
$ cat > Dockerfile <<EOF
from jenkins/jenkins:2.143
COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt
USER root
RUN apt-get update && apt-get install -y maven
USER jenkins
EOF
# Build Jenkins image for Minikube
$ eval $(minikube docker-env)
$ docker build -t ds/jenkins-v2:2.143 .
Refactor K8s Config and Add ServiceAccount Name to Jenkins Pod ¶
# Define K8s
$ cat > jenkins.yml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: jenkins
spec:
replicas: 1
template:
metadata:
name: jenkins
labels:
name: jenkins
app: jenkins
spec:
serviceAccountName: jenkins
containers:
- name: jenkins
image: ds/jenkins-v2:2.143
env:
- name: JAVA_OPTS
value: -Djenkins.install.runSetupWizard=false
ports:
- name: http-port
containerPort: 8080
- name: jnlp-port
containerPort: 50000
volumeMounts:
- name: jenkins-home
mountPath: /var/jenkins_home
volumes:
- name: jenkins-home
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: jenkins
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
selector:
app: jenkins
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins
namespace: default
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
EOF
# Apply K8s definitions
$ kubectl apply -f jenkins.yml
# Get Jenkins URL
$ echo $(minikube ip):$(kubectl get services/jenkins -o go-template='{{(index .spec.ports 0).nodePort}}')
Manually configure K8s Jenkins executors ¶
# Internal URL of Jenkins Pod
$ kubectl cluster-info | grep master
Kubernetes master is running at https://192.168.99.100:8443
# Jenkins master URL
# Get pod name
$ kubectl get pods | grep jenkins
jenkins-6cbd7855db-xpgxh 1/1 Running 0 11m
$ kubectl describe pod jenkins-6cbd7855db-xpgxh | grep IP:
IP: 172.17.0.6
Manage Jenkins -> Configure System -> Usage (only build jobs with label expressions matching this node).
Navigate to Jenkins Dashboard. Managage Jenkins -> Configure System -> Cloud -> Kubernetes.
Name: "kubernetes"
Kubernetes URL: "https://192.168.99.100:8443" # Internal Jenkins Pod URL
Jenkins URL: "http://172.17.0.6:8080" # Jenkins master URL - be sure it's http
Images -> Kubernetes Pod Template.
Name: "jenkins-slave"
Labels: "jenkins-slave"
Containers:
Container Template
Name: "jenkins-slave"
Docker image: "jenkinsci/jnlp-slave" # using default Jenkins slave image
Remove Jenkins Pod and Docker Image ¶
$ kubectl delete -f jenkins.yml
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ds/jenkins-v2 2.143 d90911d56d00 31 minutes ago 775MB
$ docker rmi d90911d56d00