I’m going to show you how to run Jenkins on Amazon EKS and settings for persistent storage for jenkins data and then take a look at a simple pipeline to push docker images on Docker Hub.
Install eksctl
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
Create cluster
eksctl create cluster --name <<project name>> \
--region us-west-2 \
--version 1.21 \
--managed \
--node-type t2.small \
--nodes 1 \
--node-volume-size 200 \
--ssh-access \
--ssh-public-key=~/.ssh/id_rsa.pub \
Jenkins Set up
The cluster is up and running, and I need to set up storage for Jenkins. EFS is a great choice to mount into multiple nodes and if Jenkins pod is down, it recreates on another node. It allows to move around to different nodes. I used follow command to deploy this driver.
Definition of EFS
Amazon Elastic File System (Amazon EFS) is a simple, serverless, set-and-forget, elastic file system. There is no minimum fee or setup charge. You pay only for the storage you use, for read and write access to data stored in Infrequent Access storage classes, and for any provisioned throughput.
Deploy EFS storage driver
kubectl apply -k "github.com/kubernetes-sigs/aws-efs-csi-driver/deploy/kubernetes/overlays/stable/?ref="master"
Mount EFS to cluster
aws efs create-mount-target --file-system-id fs-0721e4a79db1dc2de --subnet-id subnet-04c0bac6fcdf54ac7 --security-group sg-0079072780ab42437
The ID of file system, subnet, security group should be unique so you want to search for your targets’ ID and then use this command to mount.
After creating storage infrastructure, deploy persistent volume.
jenkins.pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: jenkins
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: efs-sc
csi:
driver: efs.csi.aws.com
volumeHandle: fs-0721e4a79db1dc2de #Your file system id
kubectl apply -f jenkins.pv.yaml
jenkins.rbac.yaml
RBAC, Role-based access control, is an authorization mechanism for managing permissions around Kubernetes resources. RBAC allows configuration of flexible authorization policies that can be updated without cluster restarts.
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jenkins
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create","delete","get","list","patch","update"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["create","delete","get","list","patch","update"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["create","delete","get","list","patch","update"]
- apiGroups: [""]
resources: ["services"]
verbs: ["create","delete","get","list","patch","update"]
- apiGroups: [""]
resources: ["ingresses"]
verbs: ["create","delete","get","list","patch","update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: jenkins
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins
namespace: jenkins
jenkins.deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
labels:
app: jenkins
spec:
selector:
matchLabels:
app: jenkins
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: jenkins
spec:
serviceAccountName: jenkins
containers:
- name: jenkins
image: jenkins/jenkins:2.235.1-lts-alpine
imagePullPolicy: IfNotPresent
env:
- name: JAVA_OPTS
value: -Xmx2048m -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85
ports:
- containerPort: 8080
protocol: TCP
- containerPort: 50000
protocol: TCP
volumeMounts:
- mountPath: /var/jenkins_home
name: jenkins
restartPolicy: Always
securityContext:
runAsUser: 0
terminationGracePeriodSeconds: 30
volumes:
- name: jenkins
persistentVolumeClaim:
claimName: jenkins-claim
jenkins.service.yaml
apiVersion: v1
kind: Service
metadata:
name: jenkins
labels:
app: jenkins
spec:
type: ClusterIP
ports:
- name: ui
port: 8080
targetPort: 8080
protocol: TCP
- name: slave
port: 50000
protocol: TCP
- name: http
port: 80
targetPort: 8080
selector:
app: jenkins