Task: Rolling Updates And Rolling Back Deployments in Kubernetes
Date: 7/14/2024
There is a production deployment planned for next week. The Nautilus DevOps team wants to test the deployment update and rollback on Dev environment first so that they can identify the risks in advance. Below you can find more details about the plan they want to execute.
1. Create a namespace xfusion. Create a deployment called httpd-deploy under this new namespace, It should have one container called httpd, use httpd:2.4.25 image and 4 replicas. The deployment should use RollingUpdate strategy with maxSurge=1, and maxUnavailable=2. Also create a NodePort type service named httpd-service and expose the deployment on nodePort: 30008.
2. Now upgrade the deployment to version httpd:2.4.43 using a rolling update.
3. Finally, once all pods are updated undo the recent update and roll back to the previous/original version.
2. Now upgrade the deployment to version httpd:2.4.43 using a rolling update.
3. Finally, once all pods are updated undo the recent update and roll back to the previous/original version.
Solution:
Step 1: Create Namespace
First, create the namespace `xfusion`.
# kubectl create namespace xfusion
Step 2: Create Deployment
Create a deployment named `httpd-deploy` in the `xfusion` namespace with the specified parameters.
# vi httpd-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-deploy
namespace: xfusion
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 2
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: httpd:2.4.25
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: httpd-service
namespace: xfusion
spec:
type: NodePort
selector:
app: httpd
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30008
Apply the deployment and service:
# kubectl apply -f httpd-deploy.yaml
Step 3: Verify the Deployment and Service
Verify that the deployment and service have been created correctly:
# kubectl get deployments -n xfusion
# kubectl get pods -n xfusion
# kubectl get services -n xfusion
Step 4: Upgrade the Deployment
Update the deployment to use the `httpd:2.4.43` image:
# kubectl set image deployment/httpd-deploy httpd=httpd:2.4.43 -n xfusion
Step 5: Verify the Update
Check the status of the rolling update:
# kubectl rollout status deployment/httpd-deploy -n xfusion
### Step 6: Rollback the Deployment
Rollback the deployment to the previous version:
# kubectl rollout undo deployment/httpd-deploy -n xfusion
Step 7: Verify the Rollback
Check the status of the rollback:
# kubectl rollout status deployment/httpd-deploy -n xfusion
Summary
1. Created a namespace `xfusion`.
2. Created a deployment `httpd-deploy` with 4 replicas using the `httpd:2.4.25` image and RollingUpdate strategy.
3. Created a NodePort service `httpd-service` to expose the deployment on port `30008`.
4. Upgraded the deployment to version `httpd:2.4.43`.
5. Rolled back the deployment to the previous version `httpd:2.4.25`.
This process ensures that the deployment can be updated and rolled back as required, minimizing downtime and maintaining application availability.
Task: Kubernetes: Deploy Jenkins on Kubernetes
Date: 7/17/2024
The Nautilus DevOps team is planning to set up a Jenkins CI server to create/manage some deployment pipelines for some of the projects. They want to set up the Jenkins server on Kubernetes cluster. Below you can find more details about the task:
1) Create a namespace jenkins
2) Create a Service for jenkins deployment. Service name should be jenkins-service under jenkins namespace, type should be NodePort, nodePort should be 30008
3) Create a Jenkins Deployment under jenkins namespace, It should be name as jenkins-deployment , labels app should be jenkins , container name should be jenkins-container , use jenkins/jenkins image , containerPort should be 8080 and replicas count should be 1.
Make sure to wait for the pods to be in running state and make sure you are able to access the Jenkins login screen in the browser before hitting the Check button.
Solution:
Here is a step-by-step guide to set up the Jenkins CI server on a Kubernetes cluster based on your requirements:
Step 1: Create Namespace
First, create a namespace named `jenkins`.
# kubectl create namespace jenkins
Step 2: Create Service for Jenkins Deployment
Create a service named `jenkins-service` with type `NodePort` and nodePort `30008`.
# vi jenkins-service.yaml
apiVersion: v1
kind: Service
metadata:
name: jenkins-service
namespace: jenkins
spec:
type: NodePort
selector:
app: jenkins
ports:
- port: 8080
targetPort: 8080
nodePort: 30008
Apply the service configuration:
# kubectl apply -f jenkins-service.yaml
Step 3: Create Jenkins Deployment
Create a deployment named `jenkins-deployment` using the `jenkins/jenkins` image.
# vi jenkins-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins-deployment
namespace: jenkins
labels:
app: jenkins
spec:
replicas: 1
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
containers:
- name: jenkins-container
image: jenkins/jenkins
ports:
- containerPort: 8080
Apply the deployment configuration:
# kubectl apply -f jenkins-deployment.yaml
Step 4: Verify the Deployment and Service
Check the status of the deployment and service to ensure they are running correctly:
# kubectl get pods -n jenkins
# kubectl get services -n jenkins
Wait until the Jenkins pod is in the `Running` state:
# kubectl wait --for=condition=ready pod -l app=jenkins -n jenkins
Step 5: Access Jenkins in Browser
To access the Jenkins login screen in the browser, you need to find the IP address of one of the nodes in your Kubernetes cluster. You can get this information using the following command:
# kubectl get nodes -o wide
Now, open a browser and navigate to `http://<NodeIP>:30008`.
Summary
1. Created a namespace `jenkins`.
2. Created a service `jenkins-service` of type `NodePort` on port `30008`.
3. Created a deployment `jenkins-deployment` with 1 replica using the `jenkins/jenkins` image.
4. Verified the deployment and service status.
5. Accessed the Jenkins login screen in the browser.
By following these steps, you should be able to set up a Jenkins CI server on your Kubernetes cluster and access the Jenkins login screen.
Below are my labs results:
root@kub01:~# kubectl get pods -n jenkins
NAME READY STATUS RESTARTS AGE
jenkins-deployment-668856675c-hsr62 1/1 Running 0 13m
root@kub01:~#
root@kub01:~# kubectl get services -n jenkins
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
jenkins-service NodePort 10.110.39.226 <none> 8080:30008/TCP 14m
root@kub01:~#
root@kub01:~# kubectl wait --for=condition=ready pod -l app=jenkins -n jenkins
pod/jenkins-deployment-668856675c-hsr62 condition met
root@kub01:~#
root@kub01:~# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
kub01 Ready control-plane 28d v1.28.11 172.16.1.230 <none> Ubuntu 20.04.5 LTS 5.4.0-189-generic cri-o://1.28.4
kub02.darole.org Ready <none> 28d v1.28.11 172.16.1.231 <none> Ubuntu 20.04.5 LTS 5.4.0-189-generic cri-o://1.28.4
root@kub01:~#
http://172.16.1.230:30008/
root@kub01:~# kubectl exec -it jenkins-deployment-668856675c-hsr62 -n jenkins -- bash
jenkins@jenkins-deployment-668856675c-hsr62:/$ cat /var/jenkins_home/secrets/initialAdminPassword
f9448ce2a8be4ed69ac292d206efa3ba
jenkins@jenkins-deployment-668856675c-hsr62:/$
root@kub01:~# kubectl delete deploy jenkins-deployment -n jenkins
deployment.apps "jenkins-deployment" deleted
root@kub01:~# kubectl delete service jenkins-service -n jenkins
service "jenkins-service" deleted
root@kub01:~#
Task: Deploy Grafana on Kubernetes Cluster
Date: 7/19/2024
The Nautilus DevOps teams is planning to set up a Grafana tool to collect and analyze analytics from some applications. They are planning to deploy it on Kubernetes cluster. Below you can find more details.
1.) Create a deployment named grafana-deployment-datacenter using any grafana image for Grafana app. Set other parameters as per your choice.
2.) Create NodePort type service with nodePort 32000 to expose the app.
Solution:
To set up the Grafana tool on a Kubernetes cluster as specified, follow these steps:
Step 1: Create Deployment for Grafana
First, create a deployment named `grafana-deployment-nautilus` using a Grafana image.
# vi grafana-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana-deployment-datacenter
labels:
app: grafana
spec:
replicas: 1
selector:
matchLabels:
app: grafana
template:
metadata:
labels:
app: grafana
spec:
containers:
- name: grafana-container
image: grafana/grafana:latest
ports:
- containerPort: 3000
Apply the deployment configuration:
# kubectl apply -f grafana-deployment.yaml
Step 2: Create NodePort Service for Grafana
Next, create a NodePort type service to expose the Grafana app on port `32000`.
# vi grafana-service.yaml
apiVersion: v1
kind: Service
metadata:
name: grafana-service
labels:
app: grafana
spec:
type: NodePort
selector:
app: grafana
ports:
- port: 3000
targetPort: 3000
nodePort: 32000
Apply the service configuration:
# kubectl apply -f grafana-service.yaml
Step 3: Verify Deployment and Service
Check the status of the deployment and service to ensure they are running correctly:
# kubectl get pods
# kubectl get services
Wait until the Grafana pod is in the `Running` state:
# kubectl wait --for=condition=ready pod -l app=grafana
Step 4: Access Grafana in Browser
To access the Grafana login page in the browser, you need to find the IP address of one of the nodes in your Kubernetes cluster. You can get this information using the following command:
# kubectl get nodes -o wide
Now, open a browser and navigate to `http://<NodeIP>:32000`.
### Summary
1. Created a deployment `grafana-deployment-nautilus` using the `grafana/grafana` image.
2. Created a NodePort service `grafana-service` to expose the Grafana app on port `32000`.
3. Verified the deployment and service status.
4. Accessed the Grafana login page in the browser.
By following these steps, you should be able to set up Grafana on your Kubernetes cluster and access the login page.
Task: Kubernetes: Deploy Node App on Kubernetes
Date: 7/21/2024
The Nautilus development team has completed development of one of the node applications, which they are planning to deploy on a Kubernetes cluster. They recently had a meeting with the DevOps team to share their requirements. Based on that, the DevOps team has listed out the exact requirements to deploy the app. Find below more details:
1. Create a deployment using gcr.io/kodekloud/centos-ssh-enabled:node image, replica count must be 2.
2. Create a service to expose this app, the service type must be NodePort, targetPort must be 8080 and nodePort should be 30012.
3. Make sure all the pods are in Running state after the deployment.
4. ou can check the application by clicking on NodeApp button on top bar.
Solution:
To deploy the Node application on the Kubernetes cluster according to the provided specifications, follow these steps:
Step 1: Create the Deployment
Create a deployment using the `gcr.io/kodekloud/centos-ssh-enabled:node` image with 2 replicas.
# vi node-app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: node-app-deployment
labels:
app: node-app
spec:
replicas: 2
selector:
matchLabels:
app: node-app
template:
metadata:
labels:
app: node-app
spec:
containers:
- name: node-app-container
image: gcr.io/kodekloud/centos-ssh-enabled:node
ports:
- containerPort: 8080
Apply the deployment configuration:
# kubectl apply -f node-app-deployment.yaml
Step 2: Create the Service
Create a NodePort type service to expose the Node app, with target port 8080 and node port 30012.
# vi node-app-service.yaml
apiVersion: v1
kind: Service
metadata:
name: node-app-service
labels:
app: node-app
spec:
type: NodePort
selector:
app: node-app
ports:
- port: 8080
targetPort: 8080
nodePort: 30012
Apply the service configuration:
# kubectl apply -f node-app-service.yaml
Step 3: Verify the Deployment and Service
Check the status of the deployment and service to ensure all pods are running correctly:
# kubectl get pods
# kubectl get services
Wait until both Node app pods are in the `Running` state:
# kubectl wait --for=condition=ready pod -l app=node-app --timeout=120s
Step 4: Access the Node Application
To access the Node application, you need the IP address of one of the nodes in your Kubernetes cluster. You can get this information using the following command:
# kubectl get nodes -o wide
Open a browser and navigate to `http://<NodeIP>:30012` to access the Node application.
Summary
1. Created a deployment `node-app-deployment` using the `gcr.io/kodekloud/centos-ssh-enabled:node` image with 2 replicas.
2. Created a NodePort service `node-app-service` to expose the Node app on port `30012`.
3. Verified the deployment and service status.
4. Accessed the Node application in the browser.
By following these steps, you should be able to deploy and access the Node application on your Kubernetes cluster.
Date: 3 Jan 2025
Task: Fix issue with LAMP Environment in Kubernetes
One of the DevOps team member was trying to install a WordPress website on a LAMP stack which is essentially deployed on Kubernetes cluster. It was working well and we could see the installation page a few hours ago. However something is messed up with the stack now due to a website went down. Please look into the issue and fix it:
FYI, deployment name is lamp-wp and its using a service named lamp-service. The Apache is using http default port and nodeport is 30008. From the application logs it has been identified that application is facing some issues while connecting to the database in addition to other issues. Additionally, there are some environment variables associated with the pods like MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD, MYSQL_HOST.
Also do not try to delete/modify any other existing components like deployment name, service name, types, labels etc.
Solution:
1. Check the details for pods
thor@jumphost ~$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/lamp-wp-56c7c454fc-n5qzx 2/2 Running 0 103s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 26m
service/lamp-service NodePort 10.96.164.173 <none> 80:30009/TCP 103s
service/mysql-service ClusterIP 10.96.7.208 <none> 3306/TCP 103s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/lamp-wp 1/1 1 1 103s
NAME DESIRED CURRENT READY AGE
replicaset.apps/lamp-wp-56c7c454fc 1 1 1 103s
thor@jumphost ~$
2. Check the pod details
thor@jumphost ~$ kubectl describe pod/lamp-wp-56c7c454fc-n5qzx
Name: lamp-wp-56c7c454fc-n5qzx
Namespace: default
Priority: 0
Service Account: default
Node: kodekloud-control-plane/172.17.0.2
Start Time: Fri, 03 Jan 2025 13:51:54 +0000
Labels: app=lamp
pod-template-hash=56c7c454fc
tier=frontend
Annotations: <none>
Status: Running
IP: 10.244.0.5
IPs:
IP: 10.244.0.5
Controlled By: ReplicaSet/lamp-wp-56c7c454fc
Containers:
httpd-php-container:
Container ID: containerd://0667c0575f0668dec68e689d2ccd5dd415ea5ec8e6f331619c19911ad06ee354
Image: webdevops/php-apache:alpine-3-php7
Image ID: docker.io/webdevops/php-apache@sha256:bb68c986d4947d4cb49e2753a268e33ad3d69df29c8e9a7728090f4738d5bdb9
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Fri, 03 Jan 2025 13:52:05 +0000
Ready: True
Restart Count: 0
Environment:
MYSQL_ROOT_PASSWORD: <set to the key 'password' in secret 'mysql-root-pass'> Optional: false
MYSQL_DATABASE: <set to the key 'database' in secret 'mysql-db-url'> Optional: false
MYSQL_USER: <set to the key 'username' in secret 'mysql-user-pass'> Optional: false
MYSQL_PASSWORD: <set to the key 'password' in secret 'mysql-user-pass'> Optional: false
MYSQL_HOST: <set to the key 'host' in secret 'mysql-host'> Optional: false
Mounts:
/opt/docker/etc/php/php.ini from php-config-volume (rw,path="php.ini")
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-2mqsb (ro)
mysql-container:
Container ID: containerd://8bbeea4d5643ec60bf1fc0cd4feb35f9550379908c68d597d0407c4f5af7c628
Image: mysql:5.6
Image ID: docker.io/library/mysql@sha256:20575ecebe6216036d25dab5903808211f1e9ba63dc7825ac20cb975e34cfcae
Port: 3306/TCP
Host Port: 0/TCP
State: Running
Started: Fri, 03 Jan 2025 13:52:19 +0000
Ready: True
Restart Count: 0
Environment:
MYSQL_ROOT_PASSWORD: <set to the key 'password' in secret 'mysql-root-pass'> Optional: false
MYSQL_DATABASE: <set to the key 'database' in secret 'mysql-db-url'> Optional: false
MYSQL_USER: <set to the key 'username' in secret 'mysql-user-pass'> Optional: false
MYSQL_PASSWORD: <set to the key 'password' in secret 'mysql-user-pass'> Optional: false
MYSQL_HOST: <set to the key 'host' in secret 'mysql-host'> Optional: false
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-2mqsb (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
php-config-volume:
Type: ConfigMap (a volume populated by a ConfigMap)
Name: php-config
Optional: false
kube-api-access-2mqsb:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m38s default-scheduler Successfully assigned default/lamp-wp-56c7c454fc-n5qzx to kodekloud-control-plane
Normal Pulling 2m37s kubelet Pulling image "webdevops/php-apache:alpine-3-php7"
Normal Pulled 2m27s kubelet Successfully pulled image "webdevops/php-apache:alpine-3-php7" in 9.710543119s (9.710565107s including waiting)
Normal Created 2m27s kubelet Created container httpd-php-container
Normal Started 2m27s kubelet Started container httpd-php-container
Normal Pulling 2m27s kubelet Pulling image "mysql:5.6"
Normal Pulled 2m14s kubelet Successfully pulled image "mysql:5.6" in 12.892638104s (12.892667637s including waiting)
Normal Created 2m14s kubelet Created container mysql-container
Normal Started 2m13s kubelet Started container mysql-container
thor@jumphost ~$
3. Login to container httpd-php-container
thor@jumphost ~$ kubectl exec --stdin --tty lamp-wp-56c7c454fc-n5qzx -c httpd-php-container -- /bin/bash
bash-4.3#
thor@jumphost ~$ kubectl exec --stdin --tty lamp-wp-56c7c454fc-n5qzx -c httpd-php-container -- /bin/bash
4. Check the Apache status.
bash-4.3# service apache2 status
apache:apached RUNNING pid 93, uptime 0:04:58
bash-4.3#
5. Check the index.php file
bash-4.3# cd /app/
bash-4.3# cat index.php
<?php
$dbname = $_ENV['MYSQL_DATABASE'];
$dbuser = $_ENV['MYSQL_USER'];
$dbpass = $_ENV[''MYSQL_PASSWORD""];
$dbhost = $_ENV['MYSQL-HOST'];
$connect = mysqli_connect($dbhost, $dbuser, $dbpass) or die("Unable to Connect to '$dbhost'");
6. Do the required change in index.php file and restart apache2 services
bash-4.3# vi index.php
bash-4.3# service apache2 restart
bash-4.3# cat /app/index.php
<?php
$dbname = $_ENV['MYSQL_DATABASE'];
$dbuser = $_ENV['MYSQL_USER'];
$dbpass = $_ENV['MYSQL_PASSWORD'];
$dbhost = $_ENV['MYSQL_HOST'];
$connect = mysqli_connect($dbhost, $dbuser, $dbpass) or die("Unable to Connect to '$dbhost'");
$test_query = "SHOW TABLES FROM $dbname";
$result = mysqli_query($test_query);
if ($result->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
bash-4.3#
7. Check the URL
bash-4.3# curl http://localhost:80
Connected successfullybash-4.3#
8. Check the ports.
thor@jumphost ~$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 52m
lamp-service NodePort 10.96.164.173 <none> 80:30009/TCP 28m
mysql-service ClusterIP 10.96.7.208 <none> 3306/TCP 28m
thor@jumphost ~$
9. Edit the port
thor@jumphost ~$ kubectl edit service/lamp-service
service/lamp-service edited
10. Check server status
thor@jumphost ~$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 54m
lamp-service NodePort 10.96.164.173 <none> 80:30008/TCP 29m
mysql-service ClusterIP 10.96.7.208 <none> 3306/TCP 29m
thor@jumphost ~$
11. Click on URL
Date: 7 Feb 2025
Task: Deploy Apache Web Server on Kubernetes CLuster
There is an application that needs to be deployed on Kubernetes cluster under Apache web server. The Nautilus application development team has asked the DevOps team to deploy it. We need to develop a template as per requirements mentioned below:
- Create a namespace named as httpd-namespace-datacenter.
- Create a deployment named as httpd-deployment-datacenter under newly created namespace. For the deployment use httpd image with latest tag only and remember to mention the tag i.e httpd:latest, and make sure replica counts are 2.
- Create a service named as httpd-service-datacenter under same namespace to expose the deployment, nodePort should be 30004.
Solutions:
thor@jumphost ~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kodekloud-control-plane Ready control-plane 65m v1.27.16-1+f5da3b717fc217
thor@jumphost ~$ kubectl create namespace httpd-namespace-datacenter
namespace/httpd-namespace-datacenter created
thor@jumphost ~$ kubectl get ns
NAME STATUS AGE
default Active 74m
httpd-deployment-datacenter Active 5m31s
httpd-namespace-datacenter Active 74s
kube-node-lease Active 74m
kube-public Active 74m
kube-system Active 74m
local-path-storage Active 74m
thor@jumphost ~$ cat httpd-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-deployment-datacenter
namespace: httpd-namespace-datacenter
spec:
replicas: 2
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: httpd:latest
ports:
- containerPort: 80
thor@jumphost ~$ kubectl apply -f httpd-deployment.yaml
deployment.apps/httpd-deployment-datacenter created
thor@jumphost ~$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 76m
thor@jumphost ~$ cat httpd-service.yaml
apiVersion: v1
kind: Service
metadata:
name: httpd-service-datacenter
namespace: httpd-namespace-datacenter
spec:
type: NodePort
selector:
app: httpd
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30004
thor@jumphost ~$ kubectl apply -f httpd-service.yaml
service/httpd-service-datacenter created
thor@jumphost ~$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 76m
thor@jumphost ~$ kubectl get service -n httpd-namespace-datacenter
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpd-service-datacenter NodePort 10.96.31.144 <none> 80:30004/TCP 66s
thor@jumphost ~$
Date: 18 Feb 2025
Task: Deploy Lamp Stack on Kubernetes Cluster
The Nautilus DevOps team want to deploy a PHP website on Kubernetes cluster. They are going to use Apache as a web server and Mysql for database. The team had already gathered the requirements and now they want to make this website live. Below you can find more details:
1) Create a config map php-config for php.ini with variables_order = "EGPCS" data.
2) Create a deployment named lamp-wp.
3) Create two containers under it. First container must be httpd-php-container using image webdevops/php-apache:alpine-3-php7 and second container must be mysql-container from image mysql:5.6. Mount php-config configmap in httpd container at /opt/docker/etc/php/php.ini location.
4) Create kubernetes generic secrets for mysql related values like myql root password, mysql user, mysql password, mysql host and mysql database. Set any values of your choice.
5) Add some environment variables for both containers:
a) MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD and MYSQL_HOST. Take their values from the secrets you created. Please make sure to use env field (do not use envFrom) to define the name-value pair of environment variables.
6) Create a node port type service lamp-service to expose the web application, nodePort must be 30008.
7) Create a service for mysql named mysql-service and its port must be 3306.
8) We already have /tmp/index.php file on jump_host server.
a) Copy this file into httpd container under Apache document root i.e /app and replace the dummy values for mysql related variables with the environment variables you have set for mysql related parameters. Please make sure you do not hard code the mysql related details in this file, you must use the environment variables to fetch those values.
b) You must be able to access this index.php on node port 30008 at the end, please note that you should see Connected successfully message while accessing this page.
Solution:
https://www.nbtechsupport.co.in/2021/09/deploy-lamp-stack-on-kubernetes-cluster.html
Date: 22 Feb 2025
Task: Init Containers in Kubernetes
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-datacenter.
- Configure spec as replicas should be 1, labels app should be ic-datacenter, template's metadata lables app should be the same ic-datacenter.
- The initContainers should be named as ic-msg-datacenter, use image fedora, preferably with latest tag and use command '/bin/bash', '-c' and 'echo Init Done - Welcome to xFusionCorp Industries > /ic/ecommerce'. The volume mount should be named as ic-volume-datacenter and mount path should be /ic.
- Main container should be named as ic-main-datacenter, use image fedora, preferably with latest tag and use command '/bin/bash', '-c' and 'while true; do cat /ic/ecommerce; sleep 5; done'. The volume mount should be named as ic-volume-datacenter and mount path should be /ic.
- Volume to be named as ic-volume-datacenter and it should be an emptyDir type.
Solution:
thor@jumphost ~$ cat ic-deploy-datacenter.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ic-deploy-datacenter
spec:
replicas: 1
selector:
matchLabels:
app: ic-datacenter
template:
metadata:
labels:
app: ic-datacenter
spec:
initContainers:
- name: ic-msg-datacenter
image: fedora:latest
command: ['/bin/bash', '-c', 'echo Init Done - Welcome to xFusionCorp Industries > /ic/ecommerce']
volumeMounts:
- name: ic-volume-datacenter
mountPath: /ic
containers:
- name: ic-main-datacenter
image: fedora:latest
command: ['/bin/bash', '-c', 'while true; do cat /ic/ecommerce; sleep 5; done']
volumeMounts:
- name: ic-volume-datacenter
mountPath: /ic
volumes:
- name: ic-volume-datacenter
emptyDir: {}
thor@jumphost ~$ kubectl apply -f ic-deploy-datacenter.yaml
deployment.apps/ic-deploy-datacenter created
thor@jumphost ~$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
ic-deploy-datacenter 1/1 1 1 11s
thor@jumphost ~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
ic-deploy-datacenter-945995ff7-6pz2l 1/1 Running 0 21s
thor@jumphost ~$ kubectl describe pod/ic-deploy-datacenter-945995ff7-6pz2l
Name: ic-deploy-datacenter-945995ff7-6pz2l
Namespace: default
Priority: 0
Service Account: default
Node: kodekloud-control-plane/172.17.0.2
Start Time: Sat, 22 Feb 2025 05:59:39 +0000
Labels: app=ic-datacenter
pod-template-hash=945995ff7
Annotations: <none>
Status: Running
IP: 10.244.0.5
IPs:
IP: 10.244.0.5
Controlled By: ReplicaSet/ic-deploy-datacenter-945995ff7
Init Containers:
ic-msg-datacenter:
Container ID: containerd://e933f359089c24133194a4fa5507a07e9504e8630a44c925b4ede7281f881b1c
Image: fedora:latest
Image ID: docker.io/library/fedora@sha256:3ec60eb34fa1a095c0c34dd37cead9fd38afb62612d43892fcf1d3425c32bc1e
Port: <none>
Host Port: <none>
Command:
/bin/bash
-c
echo Init Done - Welcome to xFusionCorp Industries > /ic/ecommerce
State: Terminated
Reason: Completed
Exit Code: 0
Started: Sat, 22 Feb 2025 05:59:46 +0000
Finished: Sat, 22 Feb 2025 05:59:46 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/ic from ic-volume-datacenter (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-cc8rw (ro)
Containers:
ic-main-datacenter:
Container ID: containerd://09ca4ce6b43d3869ac1c7d87d627c739c0cab4f3ac994d16039bf774ca75abf9
Image: fedora:latest
Image ID: docker.io/library/fedora@sha256:3ec60eb34fa1a095c0c34dd37cead9fd38afb62612d43892fcf1d3425c32bc1e
Port: <none>
Host Port: <none>
Command:
/bin/bash
-c
while true; do cat /ic/ecommerce; sleep 5; done
State: Running
Started: Sat, 22 Feb 2025 05:59:48 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/ic from ic-volume-datacenter (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-cc8rw (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
ic-volume-datacenter:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
kube-api-access-cc8rw:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3m12s default-scheduler Successfully assigned default/ic-deploy-datacenter-945995ff7-6pz2l to kodekloud-control-plane
Normal Pulling 3m11s kubelet Pulling image "fedora:latest"
Normal Pulled 3m5s kubelet Successfully pulled image "fedora:latest" in 5.786731623s (5.786747739s including waiting)
Normal Created 3m5s kubelet Created container ic-msg-datacenter
Normal Started 3m5s kubelet Started container ic-msg-datacenter
Normal Pulling 3m4s kubelet Pulling image "fedora:latest"
Normal Pulled 3m3s kubelet Successfully pulled image "fedora:latest" in 156.530465ms (156.544666ms including waiting)
Normal Created 3m3s kubelet Created container ic-main-datacenter
Normal Started 3m3s kubelet Started container ic-main-datacenter
thor@jumphost ~$ kubectl exec -it ic-deploy-datacenter-945995ff7-6pz2l -c ic-main-datacenter -- /bin/bash
[root@ic-deploy-datacenter-945995ff7-6pz2l /]# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 969G 601G 369G 62% /
tmpfs 103G 0 103G 0% /proc/acpi
udev 103G 0 103G 0% /dev/tty
tmpfs 103G 0 103G 0% /proc/scsi
tmpfs 64M 0 64M 0% /dev
/dev/sda1 969G 601G 369G 62% /ic --- >
tmpfs 103G 0 103G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
tmpfs 205G 12K 205G 1% /run/secrets/kubernetes.io/serviceaccount
tmpfs 103G 0 103G 0% /sys/firmware
[root@ic-deploy-datacenter-945995ff7-6pz2l /]# cat /ic/ecommerce
Init Done - Welcome to xFusionCorp Industries
[root@ic-deploy-datacenter-945995ff7-6pz2l /]#
No comments:
Post a Comment