Jenkins POD restarts how to persists Jenkins configuration and plugin - jenkins

I have deployed my Jenkins as part of kubernetes yaml file and also enabled Persist volume claim, when my Jenkins pod is restarts, i lost my all the jobs and configuration which means i need to re-install all Jenkins suggest plugin, configure kubernetes cloud, configure git repo, and create new pipeline job.
cloud you please help me how to avoid above scenario.
vi jenkins-deployment.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: jenkins-master
namespace: jenkins
labels:
app: jenkins-master
spec:
replicas: 1
selector:
matchLabels:
app: jenkins-master
template:
metadata:
labels:
app: jenkins-master
spec:
securityContext:
fsGroup: 1000
containers:
- name: jenkins
image: jenkins/jenkins:lts
imagePullPolicy: Always
ports:
- containerPort: 8080
- containerPort: 50000
readinessProbe:
httpGet:
path: /login
port: 8080
initialDelaySeconds: 300
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 2
failureThreshold: 5
volumeMounts:
- mountPath: "/var"
name: jenkins-home
subPath: jenkins_home
resources:
limits:
cpu: 800m
memory: 3Gi
requests:
cpu: 100m
memory: 3Gi
volumes:
- name: jenkins-home
persistentVolumeClaim:
claimName: pvc-jenkins-home
vi jenkins-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc-jenkins-home
namespace: jenkins
spec:
storageClassName: efs
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Mi
kubectl get pvc -n jenkins
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-jenkins-home Bound pvc-4ccf3f55-6894-4fee-88d7-58dd7584b837 10Mi RWO efs 59m
Please let me know if any details required from my side

Please remove the subpathfrom volumeMounts as subPath will overwrite everything under the /var directory. so it should be just like this
volumeMounts:
- mountPath: /var
name: jenkins-home

Related

Install cassandra exporter for prometheus monitoring in cassandra pod in kubernetes

I am using Cassandra image w.r.t.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: cassandra
labels:
app: cassandra
spec:
serviceName: cassandra
replicas: 3
selector:
matchLabels:
app: cassandra
template:
metadata:
labels:
app: cassandra
spec:
terminationGracePeriodSeconds: 1800
containers:
- name: cassandra
image: gcr.io/google-samples/cassandra:v13
imagePullPolicy: Always
ports:
- containerPort: 7000
name: intra-node
- containerPort: 7001
name: tls-intra-node
- containerPort: 7199
name: jmx
- containerPort: 9042
name: cql
resources:
limits:
cpu: "500m"
memory: 1Gi
requests:
cpu: "500m"
memory: 1Gi
securityContext:
capabilities:
add:
- IPC_LOCK
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- nodetool drain
env:
- name: MAX_HEAP_SIZE
value: 512M
- name: HEAP_NEWSIZE
value: 100M
- name: CASSANDRA_SEEDS
value: "cassandra-0.cassandra.default.svc.cluster.local"
- name: CASSANDRA_CLUSTER_NAME
value: "K8Demo"
- name: CASSANDRA_DC
value: "DC1-K8Demo"
- name: CASSANDRA_RACK
value: "Rack1-K8Demo"
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
readinessProbe:
exec:
command:
- /bin/bash
- -c
- /ready-probe.sh
initialDelaySeconds: 15
timeoutSeconds: 5
# These volume mounts are persistent. They are like inline claims,
# but not exactly because the names need to match exactly one of
# the stateful pod volumes.
volumeMounts:
- name: cassandra-data
mountPath: /cassandra_data
# These are converted to volume claims by the controller
# and mounted at the paths mentioned above.
# do not use these in production until ssd GCEPersistentDisk or other ssd pd
volumeClaimTemplates:
- metadata:
name: cassandra-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: fast
resources:
requests:
storage: 1Gi
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: fast
provisioner: k8s.io/minikube-hostpath
parameters:
type: pd-ssd
Now I need to add below line to cassandra-env.sh in postStart or in cassandra yaml file:
-JVM_OPTS="$JVM_OPTS
-javaagent:$CASSANDRA_HOME/lib/cassandra-exporter-agent-<version>.jar"
Now I was able to achieve this, but after this step, Cassandra requires a restart but as it's already running as a pod, I don't know how to restart the process. So is there any way that this step is done prior to running the pod and not after it is up?
I was suggested below solution:-
This won’t work. Commands that run postStart don’t impact the running container. You need to change the startup commands passed to Cassandra.
The only way that I know to do this is to create a new container image in the artifactory based on the existing image. and pull from there.
But I don't know how to achieve this.

Binary not found in Kubernetes deployment

I'm trying to deploy rocketmq on my testing cluster. I started from the scripts provided in the apache/rocketmq-docker repo on github, but they do not work. I created my own yaml deployment starting from the one in the repo I previously cited, and it works for mqnamsrv, but not for broker. In the following the 2 deployments:
apiVersion: apps/v1
kind: Deployment
metadata:
name: rocketmq-namesrv
spec:
replicas: 1
selector:
matchLabels:
app: rocketmq-namesrv
template:
metadata:
labels:
app: rocketmq-namesrv
spec:
containers:
- name: namesrv
image: myrepo/rocketmq:4.9.3-alpine
command: ["sh", "mqnamesrv"]
imagePullPolicy: IfNotPresent
resources:
limits:
memory: "128Mi"
cpu: "400m"
ports:
- containerPort: 9876
volumeMounts:
- name: namesrv-log
mountPath: /var/log
volumes:
- name: namesrv-log
persistentVolumeClaim:
claimName: rocketmq-namesrv-pvc
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: rocketmq-broker
spec:
replicas: 1
selector:
matchLabels:
app: rocketmq-broker
template:
metadata:
labels:
app: rocketmq-broker
spec:
containers:
- name: broker
image: myrepo/rocketmq:4.9.3-alpine
command: ["sh", "mqbroker", "-n", "localhost:9876"]
imagePullPolicy: IfNotPresent
resources:
limits:
memory: "128Mi"
cpu: "400m"
ports:
- containerPort: 10909
- containerPort: 10911
volumeMounts:
- name: broker-log
mountPath: /var/log
- name: broker-store
mountPath: /home/rocketmq
volumes:
- name: broker-log
persistentVolumeClaim:
claimName: rocketmq-broker-log-pvc
- name: broker-store
persistentVolumeClaim:
claimName: rocketmq-broker-store-pvc
The image rocketmq:4.9.3-alpine was created following the procedure on the apache/rocketmq-docker repo.
After the deployment the rocketmq-namesrv works, but the broker's pod logs: sh: can't open 'mqbroker': No such file or directory. ut if I try to run manually the container with kubectl run -ti rocketmq-broker --image=myrepo/rocketmq:4.9.3-alpine --restart=Never -- sh mqbroker -n localhost:9876 it works...
What could it be the problem in the yaml? Am I making something wrong?
I think the problem is with the mount path.
- name: broker-store
mountPath: /home/rocketmq
So your binaries won't be there and so the error

WSL2 Kubernetes - How to mount local folder with specifying user/group rights

I am using WSL2 Debian and Docker Desktop and I want to persist my volume data within a local folder (a path to OneDrive in best case).
This works fine but with one exception, everything is owned by root:root. How can I specify the user/group permissions within the volume?
And is there any documentation for this anywhere?
apiVersion: apps/v1
kind: Deployment
metadata:
name: dummy-service
labels:
app: dummy-service
spec:
replicas: 3
selector:
matchLabels:
app: dummy-service
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: dummy-service
spec:
containers:
- name: dotnet
image: alpine
imagePullPolicy: Always
resources:
requests:
cpu: "100m"
memory: "40Mi"
limits:
memory: "64Mi"
ports:
- containerPort: 5000
volumeMounts:
- mountPath: "/app/wwwroot"
name: dummy-volume
readinessProbe:
httpGet:
path: /heartbeat
port: 5000
scheme: HTTP
initialDelaySeconds: 5
timeoutSeconds: 1
periodSeconds: 15
livenessProbe:
httpGet:
path: /heartbeat
port: 5000
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 1
volumes:
- name: dummy-volume
persistentVolumeClaim:
claimName: dummy-pvc
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: dummy-sc
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: dummy-pv
spec:
capacity:
storage: 512Mi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: dummy-sc
local:
path: /run/desktop/mnt/host/c/Users/Markus/OneDrive/Workspace/Volume/Web
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- docker-desktop
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dummy-pvc
spec:
storageClassName: dummy-sc
accessModes:
- ReadWriteMany
resources:
requests:
storage: 512Mi
I can think of three possible solutions for this issue:
You could use the Init Containers. This way the container in a pod which is running as a non-root user can have permissions for the mounted volume. See the example below:
initContainers:
- name: set-permissions
image: <image_name>
# Give user id 555 permissions for the mounted volume
command:
- chown
- -R
- 555:555
- /var/lib/data
volumeMounts:
- name: data
mountPath: /var/lib/data
Another way to give the non-root user an access to the folder where it wants to read and write data is to follow the steps below:
Create user group and assign group ID in Dockerfile.
Create user with user ID and add to the group in Dockerfile.
Change ownership recursively for the folders the user process wants to read/write.
Add the following lines into your Deployment's Pod spec:
spec:
securityContext:
runAsUser: 1099
runAsGroup: 1099
fsGroup: 1099
As described in the docs:
runAsUser: Specifies that for any Containers in the Pod, all processes run with user ID 1099.
runAsGroup: Specifies the primary group ID of 1099 for all processes within any containers of the Pod. If this field is omitted, the primary group ID of the containers will be root(0). Any files created will also be owned by user 1099 and group 1099 when runAsGroup is specified.
fsGroup: Specifies the owner of any volume attached will be owner by group ID 1099.
Configure volume permission and ownership change policy for Pods (I know it does not suit your use case but I will leave this option here for other community members).

Jenkins container persistence on Kubernetes cluster - PersistentVolumeClaim (VMware/Vsphere)

Trying to persist my jenkins jobs on to vsphere storage when I delete the deployments/services.
I've tried using the standard approach: used StorageClass, then made a PersistentVolumeClaim which is referenced in the .ayml file that will create the deployments.
storage-class.yml:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: mystorage
provisioner: kubernetes.io/vsphere-volume
parameters:
diskformat: zeroedthick
persistent-volume-claim.yml:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc0003
spec:
storageClassName: mystorage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 15Gi
jenkins.yml:
---
apiVersion: v1
kind: Service
metadata:
name: jenkins-auto-ci
labels:
app: jenkins-auto-ci
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
selector:
app: jenkins-auto-ci
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: jenkins-auto-ci
spec:
replicas: 1
template:
metadata:
labels:
app: jenkins-auto-ci
spec:
containers:
- name: jenkins-auto-ci
image: jenkins
resources:
requests:
cpu: 100m
memory: 100Mi
env:
- name: GET_HOSTS_FROM
value: dns
ports:
- name: http-port
containerPort: 80
- name: jnlp-port
containerPort: 50000
volumeMounts:
- name: jenkins-home
mountPath: "/var"
volumes:
- name: jenkins-home
persistentVolumeClaim:
claimName: pvc0003
I expect the jenkins jobs to persist when I delete and recreate the deployments.
You should create VMDK which is Virtual Machine Disk.
You can do that using govc which is vSphere CLI.
govc datastore.disk.create -ds datastore1 -size 2G volumes/myDisk.vmdk
Or using ESXi CLI by ssh into the host as root and executing:
vmkfstools -c 2G /vmfs/volumes/datastore1/volumes/myDisk.vmdk
Once this is done you should create your PV let's call it vsphere_pv.yaml which might look like the following:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0001
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
vsphereVolume:
volumePath: "[datastore1] volumes/myDisk"
fsType: ext4
The datastore1 in this example was created in root folder of vCenter, if you have it in a different location you need to change the volumePath. If it's located in DatastoreCluster then set volumePath to"[DatastoreCluster/datastore1] volumes/myDisk".
Apply the yaml to the Kubernetes by kubectl apply -f vsphere_pv.yaml
You can check if it was created by describing it kubectl describe pv pv0001
Now you need PVC let's call it vsphere_pvc.yaml to consume PV.
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc0001
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
Apply the yaml to the Kubernetes by kubectl apply -f vsphere_pvc.yaml
You can check if it was created by describing it kubectl describe pvc pv0001
Once this is done your yaml might be looking like the following:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: jenkins-auto-ci
spec:
replicas: 1
template:
metadata:
labels:
app: jenkins-auto-ci
spec:
containers:
- name: jenkins-auto-ci
image: jenkins
resources:
requests:
cpu: 100m
memory: 100Mi
env:
- name: GET_HOSTS_FROM
value: dns
ports:
- name: http-port
containerPort: 80
- name: jnlp-port
containerPort: 50000
volumeMounts:
- name: jenkins-home
mountPath: "/var"
volumes:
- name: jenkins-home
persistentVolumeClaim:
claimName: pvc0001
All this is nicely explained on Vmware GitHub vsphere-storage-for-kubernetes.

PVC going empty after pod initialisation time GCP lost+found storage issue

Whatever mount path i add for PVC it is creating lost+found folder and deleting all other content.
I am trying to setup deployment with PVC
FROM python:3.5 AS python-build
ADD . /test
WORKDIR /test
CMD [ "python3", "./run.py" ]
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: test-core
labels:
app: test-core
spec:
selector:
matchLabels:
app: test-core
tier: frontend
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: test-core
tier: frontend
spec:
containers:
- image: <My image>
securityContext:
privileged: true
runAsUser: 1000
resources:
requests:
memory: "128Mi"
cpu: .05
limits:
memory: "256Mi"
cpu: .10
name: test-core
ports:
- containerPort: 9595
name: http
- containerPort: 443
name: https
readinessProbe:
httpGet:
path: /
port: 9595
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 3
successThreshold: 1
failureThreshold: 4
envFrom:
- secretRef:
name: test-secret
- configMapRef:
name: test-new-configmap
volumeMounts:
- name: core-data
mountPath: /test
imagePullPolicy: Always
volumes:
- name: core-data
persistentVolumeClaim:
claimName: core-claim
When i apply this file from kubernetes it's giving an error in the log cannot find file run.py that mean PVC going empty.
Whatever mount path a add it is creating lsot+found folder and deleting all other content.
Thanks
According your Dockerfile, when you run docker build -t <imagename> ., it will copy all files on your current directory to container image. And when you start this container, it will look for run.py.
If one of theese files is run.py, which actually should be, then your deployment yaml file is not correct, because you mount another PV to that directory, which will overwrite your files which you copied before and it won't able to find run.py
Hope it helps.

Resources