1
0
Fork 0

jenkins: Run Jenkins in Kubernetes

Running Jenkins in Kubernetes is relatively straightforward.  The
Kubernetes plugin automatically discovers all the connection and
authentication configuration, so a `kubeconfig` file is no longer
necessary.  I did set the *Jenkins tunnel* option, though, so that
agents will connect directly to the Jenkins JNLP port instead of going
through the ingress controller.

Jobs now run in pods in the *jenkins-job* namespace instead of the
*jenkins* namespace.  The latter is now where the Jenkins controller
runs, and the controller should not have permission to modify its own
resources.
dch-webhooks-secrets
Dustin 2022-11-16 08:55:19 -06:00
parent 19ad5023b8
commit 404fadc68a
3 changed files with 153 additions and 24 deletions

View File

@ -1,38 +1,31 @@
# Jenkins Kubernetes Integration # Jenkins in Kubernetes
## Kubernetes Setup ## Kubernetes Setup
Create *jenkins* user:
```sh
kubeadm kubeconfig user \
--client-name jenkins \
--config kubeadm-user.yaml \
--org jenkins \
> jenkins.kubeconfig
```
Configure Jenkins resources: Configure Jenkins resources:
```sh ```sh
kubectl apply -f jenkins.yaml ln imagepull-gitea jenkins/.dockerconfigjson
kubectl apply -k jenkins
``` ```
## Jenkins Setup ## Jenkins Setup
Install [Kubernetes plugin][0]. Install [Kubernetes plugin][0].
Set *TCP port for inbound agents* setting (*Manage Jenkins* → *Configure Global Set *TCP port for inbound agents* setting (*Manage Jenkins* → *Configure Global
Security*) to *Fixed* and enter a number. Be sure to open this port with Security*) to *Fixed* and enter `40414`.
*firewalld* on the Jenkins server.
Configure Kubernetes (*Manage Jenkins* → *Manage Nodes and Clouds* → *Configure Configure Kubernetes (*Manage Jenkins* → *Manage Nodes and Clouds* → *Configure
Clouds*: Clouds*:
* *Kubernetes URL*: https://kubernetes.pyrocufflink.blue:6443 1. *Add a new cloud* → *Kubernetes*
* *Kubernetes server certificate key*: Contents of `/etc/kubernetes/pki/ca.crt` 2. Enter a name
* *Kubernetes Namespace*: jenkins 3. *Kubernetes Cloud details...*
* *Credentials*: Certificate and private key from `jenkins.kubeconfig` * *Kubernetes URL*: (leave blank; will use Kubernetes service discovery)
* *Kubernetes Namespace*: `jenkins-jobs`
* *Credentials*: `- none -` (will use Service Account token)
* *Jenkins tunnel*: `jenkins.jenkins.svc.cluster.local:` (trailing colon!)
[0]: https://plugins.jenkins.io/kubernetes/ [0]: https://plugins.jenkins.io/kubernetes/

View File

@ -3,12 +3,43 @@ kind: Namespace
metadata: metadata:
name: jenkins name: jenkins
---
apiVersion: v1
kind: Namespace
metadata:
name: jenkins-jobs
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
namespace: jenkins
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins
namespace: jenkins
labels:
app.kubernetes.io/name: jenkins
app.kubernetes.io/component: master
app.kubernetes.io/instance: jenkins
app.kubernetes.io/part-of: jenkins
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
--- ---
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1
kind: Role kind: Role
metadata: metadata:
name: jenkins name: jenkins
namespace: jenkins namespace: jenkins-jobs
rules: rules:
- apiGroups: - apiGroups:
- '' - ''
@ -23,13 +54,106 @@ rules:
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding kind: RoleBinding
metadata: metadata:
name: jenkins-binding name: jenkins
namespace: jenkins namespace: jenkins-jobs
roleRef: roleRef:
apiGroup: rbac.authorization.k8s.io apiGroup: rbac.authorization.k8s.io
kind: Role kind: Role
name: jenkins name: jenkins
subjects: subjects:
- apiGroup: rbac.authorization.k8s.io - kind: ServiceAccount
kind: User
name: jenkins name: jenkins
namespace: jenkins
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: master
app.kubernetes.io/name: jenkins
app.kubernetes.io/instance: jenkins
app.kubernetes.io/part-of: jenkins
name: jenkins
namespace: jenkins
spec:
ports:
- name: http
port: 8080
- name: jnlp
port: 40414
selector:
app.kubernetes.io/component: master
app.kubernetes.io/name: jenkins
app.kubernetes.io/instance: jenkins
type: ClusterIP
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: jenkins
namespace: jenkins
labels:
app.kubernetes.io/name: jenkins
app.kubernetes.io/component: master
app.kubernetes.io/instance: jenkins
app.kubernetes.io/part-of: jenkins
spec:
serviceName: jenkins
selector:
matchLabels:
app.kubernetes.io/name: jenkins
app.kubernetes.io/component: master
app.kubernetes.io/instance: jenkins
template:
metadata:
labels:
app.kubernetes.io/name: jenkins
app.kubernetes.io/component: master
app.kubernetes.io/instance: jenkins
spec:
containers:
- name: jenkins
image: docker.io/jenkins/jenkins:lts
imagePullPolicy: Always
ports:
- name: http
containerPort: 8080
- name: jnlp
containerPort: 40414
volumeMounts:
- name: jenkins-data
mountPath: /var/jenkins_home
securityContext:
runAsUser: 1000
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
serviceAccountName: jenkins
volumes:
- name: jenkins-data
persistentVolumeClaim:
claimName: jenkins
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jenkins
namespace: jenkins
spec:
ingressClassName: nginx
rules:
- host: jenkins.pyrocufflink.blue
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: jenkins
port:
name: http
tls:
- hosts:
- jenkins.pyrocufflink.blue

View File

@ -0,0 +1,12 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- jenkins.yaml
secretGenerator:
- name: imagepull-gitea
namespace: jenkins
type: kubernetes.io/dockerconfigjson
files:
- .dockerconfigjson