31 KiB
Task 61
There are some applications that need to be deployed on Kubernetes cluster and these apps have some pre-requisites where some configurations need to be changed before deploying the app container. Some of these changes cannot be made inside the images so the DevOps team has come up with a solution to use init containers to perform these tasks during deployment. Below is a sample scenario that the team is going to test first.
Create a Deployment named as ic-deploy-xfusion.
Configure spec as replicas should be 1, labels app should be ic-xfusion, template's metadata lables app should be the same ic-xfusion.
The initContainers should be named as ic-msg-xfusion, use image fedora with latest tag and use command '/bin/bash', '-c' and 'echo Init Done - Welcome to xFusionCorp Industries > /ic/blog'. The volume mount should be named as ic-volume-xfusion and mount path should be /ic.
Main container should be named as ic-main-xfusion, use image fedora with latest tag and use command '/bin/bash', '-c' and 'while true; do cat /ic/blog; sleep 5; done'. The volume mount should be named as ic-volume-xfusion and mount path should be /ic.
Volume to be named as ic-volume-xfusion and it should be an emptyDir type.
Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.
Solution
Create ic-deploy-xfusion deployment
kubectl apply -f - <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: ic-deploy-xfusion
labels:
app: ic-xfusion
spec:
replicas: 1
selector:
matchLabels:
app: ic-xfusion
template:
metadata:
labels:
app: ic-xfusion
spec:
initContainers:
- name: ic-msg-xfusion
image: fedora:latest
command: ["/bin/bash", "-c", "echo Init Done - Welcome to xFusionCorp Industries > /ic/blog"]
volumeMounts:
- name: ic-volume-xfusion
mountPath: /ic
containers:
- name: ic-main-xfusion
image: fedora:latest
command: ["/bin/bash", "-c", "while true; do cat /ic/blog; sleep 5; done"]
volumeMounts:
- name: ic-volume-xfusion
mountPath: /ic
volumes:
- name: ic-volume-xfusion
emptyDir: {}
EOF
Verify
kubectl get deployment ic-deploy-xfusion
kubectl get pods -l app=ic-xfusion
kubectl logs -l app=ic-xfusion -c ic-main-xfusion
Want: deployment 1/1 ready, pod Running, and the main container's logs printing Init Done - Welcome to xFusionCorp Industries every 5s.
Task 62
The Nautilus DevOps team is working to deploy some tools in Kubernetes cluster. Some of the tools are licence based so that licence information needs to be stored securely within Kubernetes cluster. Therefore, the team wants to utilize Kubernetes secrets to store those secrets. Below you can find more details about the requirements:
We already have a secret key file ecommerce.txt under the /opt/ directory. Create a generic secret named ecommerce, it should contain the password/license-number present in ecommerce.txt file.
Also create a pod named secret-nautilus.
Configure pod's spec as container name should be secret-container-nautilus, image should be debian with latest tag (remember to mention the tag with image). Use sleep command for container so that it remains in running state. Consume the created secret and mount it under /opt/games within the container.
To verify you can exec into the container secret-container-nautilus, to check the secret key under the mounted path /opt/games. Before hitting the Check button please make sure pod/pods are in running state, also validation can take some time to complete so keep patience.
Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.
Solution
Create secret + pod that mounts it
Step 1 — create the generic secret from the file
kubectl create secret generic ecommerce --from-file=/opt/ecommerce.txt
Step 2 — create the pod mounting the secret at /opt/games
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: secret-nautilus
spec:
containers:
- name: secret-container-nautilus
image: debian:latest
command: ["sleep", "infinity"]
volumeMounts:
- name: secret-volume
mountPath: /opt/games
volumes:
- name: secret-volume
secret:
secretName: ecommerce
EOF
Verify
kubectl get secret ecommerce
kubectl get pod secret-nautilus
kubectl exec secret-nautilus -- ls -l /opt/games
kubectl exec secret-nautilus -- cat /opt/games/ecommerce.txt
Want: secret ecommerce exists, pod Running, and /opt/games/ecommerce.txt present with the license content inside the container.
Task 63
There is an iron gallery app that the Nautilus DevOps team was developing. They have recently customized the app and are going to deploy the same on the Kubernetes cluster. Below you can find more details:
Create a namespace iron-namespace-nautilus
Create a deployment iron-gallery-deployment-nautilus for iron gallery under the same namespace you created.
:- Labels run should be iron-gallery. :- Replicas count should be 1. :- Selector's matchLabels run should be iron-gallery. :- Template labels run should be iron-gallery under metadata. :- The container should be named as iron-gallery-container-nautilus, use kodekloud/irongallery:2.0 image ( use exact image name / tag ). :- Resources limits for memory should be 100Mi and for CPU should be 50m. :- First volumeMount name should be config, its mountPath should be /usr/share/nginx/html/data. :- Second volumeMount name should be images, its mountPath should be /usr/share/nginx/html/uploads. :- First volume name should be config and give it emptyDir and second volume name should be images, also give it emptyDir.
Create a deployment iron-db-deployment-nautilus for iron db under the same namespace. :- Labels db should be mariadb. :- Replicas count should be 1. :- Selector's matchLabels db should be mariadb. :- Template labels db should be mariadb under metadata. :- The container name should be iron-db-container-nautilus, use kodekloud/irondb:2.0 image ( use exact image name / tag ). :- Define environment, set MYSQL_DATABASE its value should be database_apache, set MYSQL_ROOT_PASSWORD and MYSQL_PASSWORD value should be with some complex passwords for DB connections, and MYSQL_USER value should be any custom user ( except root ).
:- Volume mount name should be db and its mountPath should be /var/lib/mysql. Volume name should be db and give it an emptyDir.
Create a service for iron db which should be named iron-db-service-nautilus under the same namespace. Configure spec as selector's db should be mariadb. Protocol should be TCP, port and targetPort should be 3306 and its type should be ClusterIP.
Create a service for iron gallery which should be named iron-gallery-service-nautilus under the same namespace. Configure spec as selector's run should be iron-gallery. Protocol should be TCP, port and targetPort should be 80, nodePort should be 32678 and its type should be NodePort.
Note: We don't need to make connection b/w database and front-end now, if the installation page is coming up it should be enough for now.
The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.
Solution
Iron Gallery app — namespace, deployments, services
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Namespace
metadata:
name: iron-namespace-nautilus
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: iron-gallery-deployment-nautilus
namespace: iron-namespace-nautilus
labels:
run: iron-gallery
spec:
replicas: 1
selector:
matchLabels:
run: iron-gallery
template:
metadata:
labels:
run: iron-gallery
spec:
containers:
- name: iron-gallery-container-nautilus
image: kodekloud/irongallery:2.0
resources:
limits:
memory: "100Mi"
cpu: "50m"
volumeMounts:
- name: config
mountPath: /usr/share/nginx/html/data
- name: images
mountPath: /usr/share/nginx/html/uploads
volumes:
- name: config
emptyDir: {}
- name: images
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: iron-db-deployment-nautilus
namespace: iron-namespace-nautilus
labels:
db: mariadb
spec:
replicas: 1
selector:
matchLabels:
db: mariadb
template:
metadata:
labels:
db: mariadb
spec:
containers:
- name: iron-db-container-nautilus
image: kodekloud/irondb:2.0
env:
- name: MYSQL_DATABASE
value: "database_apache"
- name: MYSQL_ROOT_PASSWORD
value: "R00t_C0mpl3x_P@ss"
- name: MYSQL_PASSWORD
value: "Us3r_C0mpl3x_P@ss"
- name: MYSQL_USER
value: "iron_user"
volumeMounts:
- name: db
mountPath: /var/lib/mysql
volumes:
- name: db
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: iron-db-service-nautilus
namespace: iron-namespace-nautilus
spec:
type: ClusterIP
selector:
db: mariadb
ports:
- protocol: TCP
port: 3306
targetPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: iron-gallery-service-nautilus
namespace: iron-namespace-nautilus
spec:
type: NodePort
selector:
run: iron-gallery
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 32678
EOF
Verify
kubectl get all -n iron-namespace-nautilus
kubectl get pods -n iron-namespace-nautilus
kubectl get svc -n iron-namespace-nautilus
Want: both deployments 1/1, both pods Running, db service ClusterIP on 3306, gallery service NodePort on 32678. Then the iron gallery install page should load via the nodePort.
Task 64
One of the DevOps engineers was trying to deploy a python app on Kubernetes cluster. Unfortunately, due to some mis-configuration, the application is not coming up. Please take a look into it and fix the issues. Application should be accessible on the specified nodePort.
The deployment name is python-deployment-devops, its using poroko/flask-demo-app image. The deployment and service of this app is already deployed.
nodePort should be 32345 and targetPort should be python flask app's default port.
Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.
Solution
kubectl set image deployment/python-deployment-devops python-container-devops=poroko/flask-demo-app
kubectl patch svc python-service-devops --type=json -p='[
{"op":"replace","path":"/spec/ports/0/targetPort","value":5000},
{"op":"replace","path":"/spec/ports/0/nodePort","value":32345}
]'
Task 65
The Nautilus application development team observed some performance issues with one of the application that is deployed in Kubernetes cluster. After looking into number of factors, the team has suggested to use some in-memory caching utility for DB service. After number of discussions, they have decided to use Redis. Initially they would like to deploy Redis on kubernetes cluster for testing and later they will move it to production. Please find below more details about the task:
Create a redis deployment with following parameters:
Create a config map called my-redis-config having maxmemory 2mb in redis-config.
Name of the deployment should be redis-deployment, it should use redis:alpine image and container name should be redis-container. Also make sure it has only 1 replica.
The container should request for 1 CPU.
Mount 2 volumes: a. An Empty directory volume called data at path /redis-master-data. b. A configmap volume called redis-config at path /redis-master. c. The container should expose the port 6379.
Finally, redis-deployment should be up and running.
Solution
Redis deployment with configmap
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: my-redis-config
data:
redis-config: |
maxmemory 2mb
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-deployment
labels:
app: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis-container
image: redis:alpine
resources:
requests:
cpu: "1"
ports:
- containerPort: 6379
volumeMounts:
- name: data
mountPath: /redis-master-data
- name: redis-config
mountPath: /redis-master
volumes:
- name: data
emptyDir: {}
- name: redis-config
configMap:
name: my-redis-config
EOF
Verify
kubectl get configmap my-redis-config
kubectl get deployment redis-deployment
kubectl get pods -l app=redis
kubectl describe pod -l app=redis | grep -A3 -i "requests\|mounts"
Want: configmap exists, deployment 1/1 ready, pod Running, CPU request 1, both volumes mounted.
Task 66
A new MySQL server needs to be deployed on Kubernetes cluster. The Nautilus DevOps team was working on to gather the requirements. Recently they were able to finalize the requirements and shared them with the team members to start working on it. Below you can find the details:
1.) Create a PersistentVolume mysql-pv, its capacity should be 250Mi, set other parameters as per your preference.
2.) Create a PersistentVolumeClaim to request this PersistentVolume storage. Name it as mysql-pv-claim and request a 250Mi of storage. Set other parameters as per your preference.
3.) Create a deployment named mysql-deployment, use any mysql image as per your preference. Mount the PersistentVolume at mount path /var/lib/mysql.
4.) Create a NodePort type service named mysql and set nodePort to 30007.
5.) Create a secret named mysql-root-pass having a key pair value, where key is password and its value is YUIidhb667, create another secret named mysql-user-pass having some key pair values, where first key is username and its value is kodekloud_pop, second key is password and value is BruCStnMT5, create one more secret named mysql-db-url, key name is database and value is kodekloud_db10
6.) Define some environment variables within the container: a.) name: MYSQL_ROOT_PASSWORD, should pick value from secretKeyRef name: mysql-root-pass and key: password b.) name: MYSQL_DATABASE, should pick value from secretKeyRef name: mysql-db-url and key: database c.) name: MYSQL_USER, should pick value from secretKeyRef name: mysql-user-pass key key: username d.) name: MYSQL_PASSWORD, should pick value from secretKeyRef name: mysql-user-pass and key: password
Solution
MySQL deployment with secrets, PV/PVC, service
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Secret
metadata:
name: mysql-root-pass
type: Opaque
stringData:
password: YUIidhb667
---
apiVersion: v1
kind: Secret
metadata:
name: mysql-user-pass
type: Opaque
stringData:
username: kodekloud_pop
password: BruCStnMT5
---
apiVersion: v1
kind: Secret
metadata:
name: mysql-db-url
type: Opaque
stringData:
database: kodekloud_db10
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
storageClassName: manual
capacity:
storage: 250Mi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/mysql-data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 250Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
labels:
app: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-root-pass
key: password
- name: MYSQL_DATABASE
valueFrom:
secretKeyRef:
name: mysql-db-url
key: database
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: mysql-user-pass
key: username
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-user-pass
key: password
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
---
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
type: NodePort
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
nodePort: 30007
EOF
Verify
kubectl get secrets
kubectl get pv mysql-pv
kubectl get pvc mysql-pv-claim
kubectl get deployment mysql-deployment
kubectl get pods -l app=mysql
kubectl get svc mysql
Want: 3 secrets, PV+PVC Bound, deployment 1/1, pod Running, service NodePort 30007.
Task 67
The Nautilus Application development team has finished development of one of the applications and it is ready for deployment. It is a guestbook application that will be used to manage entries for guests/visitors. As per discussion with the DevOps team, they have finalized the infrastructure that will be deployed on Kubernetes cluster. Below you can find more details about it.
BACK-END TIER
Create a deployment named redis-master for Redis master.
a.) Replicas count should be 1. b.) Container name should be master-redis-devops and it should use image redis. c.) Request resources as CPU should be 100m and Memory should be 100Mi. d.) Container port should be redis default port i.e 6379.
Create a service named redis-master for Redis master. Port and targetPort should be Redis default port i.e 6379.
Create another deployment named redis-slave for Redis slave.
a.) Replicas count should be 2. b.) Container name should be slave-redis-devops and it should use gcr.io/google_samples/gb-redisslave:v3 image. c.) Requests resources as CPU should be 100m and Memory should be 100Mi. d.) Define an environment variable named GET_HOSTS_FROM and its value should be dns. e.) Container port should be Redis default port i.e 6379.
Create another service named redis-slave. It should use Redis default port i.e 6379.
Create another service named redis-follower. Port and targetPort should be Redis default port i.e 6379. Its selector app should be redis-slave.
FRONT END TIER
Create a deployment named frontend.
a.) Replicas count should be 3. b.) Container name should be php-redis-devops and it should use gcr.io/google-samples/gb-frontend@sha256:a908df8486ff66f2c4daa0d3d8a2fa09846a1fc8efd65649c0109695c7c5cbff image. c.) Request resources as CPU should be 100m and Memory should be 100Mi. d.) Define an environment variable named as GET_HOSTS_FROM and its value should be dns. e.) Container port should be 80.
Create a service named frontend. Its type should be NodePort, port should be 80 and its nodePort should be 30009.
Finally, you can check the guestbook app by clicking on App button.
You can use any labels as per your choice.
Solution
Guestbook app — full stack
kubectl apply -f - <<'EOF'
# ===== BACK-END: redis-master =====
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-master
labels:
app: redis-master
spec:
replicas: 1
selector:
matchLabels:
app: redis-master
template:
metadata:
labels:
app: redis-master
spec:
containers:
- name: master-redis-devops
image: redis
resources:
requests:
cpu: "100m"
memory: "100Mi"
ports:
- containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: redis-master
spec:
selector:
app: redis-master
ports:
- port: 6379
targetPort: 6379
---
# ===== BACK-END: redis-slave =====
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-slave
labels:
app: redis-slave
spec:
replicas: 2
selector:
matchLabels:
app: redis-slave
template:
metadata:
labels:
app: redis-slave
spec:
containers:
- name: slave-redis-devops
image: gcr.io/google_samples/gb-redisslave:v3
resources:
requests:
cpu: "100m"
memory: "100Mi"
env:
- name: GET_HOSTS_FROM
value: dns
ports:
- containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: redis-slave
spec:
selector:
app: redis-slave
ports:
- port: 6379
targetPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: redis-follower
spec:
selector:
app: redis-slave
ports:
- port: 6379
targetPort: 6379
---
# ===== FRONT-END =====
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
labels:
app: frontend
spec:
replicas: 3
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: php-redis-devops
image: gcr.io/google-samples/gb-frontend@sha256:a908df8486ff66f2c4daa0d3d8a2fa09846a1fc8efd65649c0109695c7c5cbff
resources:
requests:
cpu: "100m"
memory: "100Mi"
env:
- name: GET_HOSTS_FROM
value: dns
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
type: NodePort
selector:
app: frontend
ports:
- port: 80
targetPort: 80
nodePort: 30009
EOF
Verify
kubectl get deployments
kubectl get pods
kubectl get svc
kubectl get pods -o wide | grep -E "redis|frontend"
Want: redis-master 1/1, redis-slave 2/2, frontend 3/3, all four services present, frontend NodePort 30009. Then the App button loads the guestbook.
Task 68
The DevOps team at xFusionCorp Industries is initiating the setup of CI/CD pipelines and has decided to utilize Jenkins as their server. Execute the task according to the provided requirements:
- Install Jenkins on the jenkins server using the apt utility only, and start it using the service command.
If you face a timeout issue while starting the Jenkins service, first check the service status with service jenkins status Then review the logs in /var/log/jenkins/jenkins.log to identify the cause. 2. Jenkin's admin user name should be theadmin, password should be Adm!n321, full name should be Mariyam and email should be mariyam@jenkins.stratos.xfusioncorp.com.
Note:
-
To access the jenkins server, connect from the jump host using the root user with the password S3curePass.
-
After Jenkins server installation, click the Jenkins button on the top bar to access the Jenkins UI and follow on-screen instructions to create an admin user.
Solution
Install Jenkins on jenkins server + create admin user
Access the server
From the jump host, SSH in as root:
ssh root@jenkins
# password: S3curePass
Part 1 — Install Jenkins (CLI)
Step 1: Install Java (Jenkins prerequisite)
apt update
apt install -y fontconfig openjdk-17-jre
java -version
apt update
apt install -y openjdk-21-jre
# make Java 21 the default (in case 17 is still selected)
update-alternatives --config java
Step 2: Add the Jenkins apt repository + signing key
wget -O /usr/share/keyrings/jenkins-keyring.asc \
https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]" \
"https://pkg.jenkins.io/debian-stable binary/" | \
tee /etc/apt/sources.list.d/jenkins.list > /dev/null
Step 3: Install Jenkins
apt update
apt install -y jenkins
Step 4: Start Jenkins using the service command
service jenkins start
service jenkins status
If you hit a startup timeout
service jenkins status
cat /var/log/jenkins/jenkins.log
The log identifies the cause — most commonly a missing/wrong Java version. Ensure openjdk-17-jre is installed and set as default (update-alternatives --config java), then restart:
service jenkins restart
Jenkins can take 60–90s on first start; a first-attempt timeout doesn't always mean failure — re-check status after waiting.
Part 2 — Create the admin user (Web UI)
Step 1: Get the initial unlock password
cat /var/lib/jenkins/secrets/initialAdminPassword
Copy the output.
Step 2: Open the Jenkins UI
Click the Jenkins button on the top bar.
Step 3: Unlock Jenkins
Paste the initial admin password from Step 1 → Continue.
Step 4: Install plugins
Choose "Install suggested plugins" and wait for completion.
Step 5: Create the First Admin User
Fill in exactly:
| Field | Value |
|---|---|
| Username | theadmin |
| Password | Adm!n321 |
| Full name | Mariyam |
mariyam@jenkins.stratos.xfusioncorp.com |
Click Save and Continue → Save and Finish → Start using Jenkins.
Verify
service jenkins statusshows Jenkins active/running.- You can log into the Jenkins UI as
theadmin/Adm!n321. - The dashboard loads with
theadminas the logged-in user.
Key points
- Java first — Jenkins is a Java app; without a JRE it won't start (the exact timeout the task warns about). Java 17 is the safe LTS-compatible choice.
- Repo + keyring required — Jenkins isn't in Ubuntu base repos; add
pkg.jenkins.iowith its signing key beforeapt install jenkins. debian-stable= Jenkins LTS line (more stable than weekly).service jenkins startper the task (notsystemctl).initialAdminPasswordunlocks the first UI screen before you can createtheadmin.- Admin user is created via the web wizard, not CLI — the four field values must be exact for the grader.
- Take a screenshot of the finished admin-user setup / dashboard for review.
Task 69
The Nautilus DevOps team has recently setup a Jenkins server, which they want to use for some CI/CD jobs. Before that they want to install some plugins which will be used in most of the jobs. Please find below more details about the task
- Click on the Jenkins button on the top bar to access the Jenkins UI. Login using username admin and password Adm!n321.
- Once logged in, install the Git and GitLab plugins. You may need to restart Jenkins to complete the plugin installation; if required, opt to Restart Jenkins when installation is complete and no jobs are running on the plugin installation/update page (Update Centre).
Note:
- After restarting Jenkins, wait for the login page to reappear before proceeding.
- For tasks involving web UI changes, capture screenshots to share for review or consider using screen recording software like loom.com for documentation and sharing.
Solution
Install Git + GitLab plugins in Jenkins
Step 1 — Log in
Click the Jenkins button on the top bar. Log in with:
- Username:
admin - Password:
Adm!n321
Step 2 — Navigate to Plugin Manager
Manage Jenkins → Plugins (under System Configuration; older versions: Manage Plugins).
Step 3 — Find and select the plugins
Go to the Available plugins tab.
In the search box, search and check each:
- Search
Git→ check the Git plugin - Search
GitLab→ check the GitLab plugin
Step 4 — Install
Click Install (or Download now and install after restart).
Step 5 — Restart Jenkins
On the installation progress page, check the box: "Restart Jenkins when installation is complete and no jobs are running"
Jenkins restarts. Wait for the login page to reappear before doing anything else.
Step 6 — Verify
After restart, log back in and check:
Manage Jenkins → Plugins → Installed plugins tab → search Git and GitLab — both should be listed.
Task 70
The Nautilus team is integrating Jenkins into their CI/CD pipelines. After setting up a new Jenkins server, they're now configuring user access for the development team, Follow these steps:
- Click on the Jenkins button on the top bar to access the Jenkins UI. Login with username admin and password Adm!n321.
- Create a jenkins user named rose with the password TmPcZjtRQx. Their full name should match Rose.
- Utilize the Project-based Matrix Authorization Strategy to assign overall read permission to the rose user.
- Remove all permissions for Anonymous users (if any) ensuring that the admin user retains overall Administer permissions.
- For the existing job, grant rose user only read permissions, disregarding other permissions such as Agent, SCM etc.
Note:
- You may need to install plugins and restart Jenkins service. After plugins installation, select Restart Jenkins when installation is complete and no jobs are running on plugin installation/update page.
- After restarting the Jenkins service, wait for the Jenkins login page to reappear before proceeding. Avoid clicking Finish immediately after restarting the service.
- Capture screenshots of your configuration for review purposes. Consider using screen recording software like loom.com for documentation and sharing.
Solution:
Configure Jenkins user access for rose
Step 1 — Log in
Click Jenkins button → login admin / Adm!n321.
Step 2 — Install Matrix Authorization Strategy plugin (if not present)
Manage Jenkins → Plugins → Available plugins → search "Matrix Authorization Strategy" → check it → Download now and install after restart.
Wait for Jenkins to fully restart, wait for the login page to reappear, log back in.
Step 3 — Create user rose
Manage Jenkins → Users → Create User:
- Username:
rose - Password:
TmPcZjtRQx - Full name:
Rose - (email can be left blank or any value)
Click Create User.
Step 4 — Switch to Project-based Matrix Authorization Strategy
Manage Jenkins → Security (or Configure Global Security):
- Under Authorization, select "Project-based Matrix Authorization Strategy"
- A permission matrix appears.
Step 5 — Set global permissions
In the matrix:
- Add user
admin→ grant Overall / Administer (full row, or at minimum Administer). Do this FIRST — critical. - Add user
rose→ grant Overall / Read only. - Anonymous row → uncheck ALL permissions (remove everything).
Click Save.
Step 6 — Grant rose read-only on the existing job
Go to the existing job → Configure → enable "Enable project-based security" (checkbox in the job config):
- Add user
rose - Grant only Read (under Job → Read). Leave Agent, SCM, Build, etc. unchecked.
Click Save.
Verify
adminretains Administer (you can still access everything).rosecan log in, sees the job (read), can't configure/build.- Anonymous has no permissions.