z2
This commit is contained in:
parent
7806001c1d
commit
f16847f1fd
BIN
z1/minikube-linux-amd64
Normal file
BIN
z1/minikube-linux-amd64
Normal file
Binary file not shown.
69
z2/README.md
Normal file
69
z2/README.md
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# Visitor Counter Application
|
||||||
|
|
||||||
|
## Description of the Application
|
||||||
|
This application is designed to count the number of visits to a webpage. It utilizes Flask for the backend, Apache for serving static web content, and Redis for storing visitor counts.
|
||||||
|
|
||||||
|
## List of Containers Used
|
||||||
|
|
||||||
|
- **Backend Container**: Built using Flask, this container handles API requests and updates visitor counts in Redis.
|
||||||
|
- **Web Container**: Built using Apache, this container serves static HTML content.
|
||||||
|
- **Redis Container**: Uses the official Redis image to store visitor counts persistently.
|
||||||
|
|
||||||
|
## List of Kubernetes Objects
|
||||||
|
|
||||||
|
- **Deployments**:
|
||||||
|
- **Backend Deployment**: Manages the backend Flask application.
|
||||||
|
- **Web Deployment**: Manages the web Apache server.
|
||||||
|
- **Services**:
|
||||||
|
- **Backend Service**: Exposes the backend application on a specific port.
|
||||||
|
- **Web Service**: Exposes the web server on a specific port.
|
||||||
|
- **Redis Service**: Provides access to the Redis database.
|
||||||
|
- **StatefulSet**:
|
||||||
|
- **Redis StatefulSet**: Ensures persistent storage for Redis data.
|
||||||
|
- **PersistentVolumeClaim (PVC)** and **PersistentVolume (PV)**:
|
||||||
|
- Used for providing persistent storage to Redis.
|
||||||
|
|
||||||
|
## Virtual Networks and Named Volumes
|
||||||
|
|
||||||
|
- **Virtual Networks**: Kubernetes automatically manages pod-to-pod communication within a cluster.
|
||||||
|
- **Named Volumes**: Used for persistent storage in Redis, ensuring data is retained across pod restarts.
|
||||||
|
|
||||||
|
## Container Configuration
|
||||||
|
|
||||||
|
- **Backend Container**: Configured to listen on port 5000 and connect to Redis for storing visitor counts.
|
||||||
|
- **Web Container**: Configured to serve static HTML content on port 80.
|
||||||
|
- **Redis Container**: Configured to store data persistently using a PersistentVolumeClaim.
|
||||||
|
|
||||||
|
## Instructions to Prepare, Run, Pause, and Delete the Application
|
||||||
|
|
||||||
|
1. **Prepare the Application**:
|
||||||
|
Run the `prepare-app.sh` script to build Docker images and load them into Minikube.
|
||||||
|
|
||||||
|
./prepare-app.sh
|
||||||
|
|
||||||
|
|
||||||
|
2. **Run the Application**:
|
||||||
|
Run the `start-app.sh` script to create all necessary Kubernetes objects and start the application.
|
||||||
|
./start-app.sh
|
||||||
|
|
||||||
|
|
||||||
|
3. **Pause the Application**:
|
||||||
|
You can pause the application by scaling down deployments to zero replicas:
|
||||||
|
|
||||||
|
kubectl scale deployment backend-deployment --replicas=0
|
||||||
|
kubectl scale deployment web-deployment --replicas=0
|
||||||
|
|
||||||
|
|
||||||
|
4. **Delete the Application**:
|
||||||
|
Run the `stop-app.sh` script to delete all Kubernetes objects and stop the application.
|
||||||
|
./stop-app.sh
|
||||||
|
|
||||||
|
|
||||||
|
## Instructions to View the Application on the Web
|
||||||
|
|
||||||
|
1. **Access the Web Service**:
|
||||||
|
Use Minikube to access the web service:
|
||||||
|
|
||||||
|
minikube service web-service --url
|
||||||
|
|
||||||
|
This will output a URL that you can use to view the application in your web browser by ctrl+clicking on the link.
|
11
z2/backend/Dockerfile
Normal file
11
z2/backend/Dockerfile
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
FROM python:3.9-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY app.py /app/
|
||||||
|
|
||||||
|
RUN pip install flask redis flask-cors
|
||||||
|
|
||||||
|
EXPOSE 5000
|
||||||
|
|
||||||
|
CMD ["python", "app.py"]
|
18
z2/backend/app.py
Normal file
18
z2/backend/app.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from flask import Flask, jsonify
|
||||||
|
from flask_cors import CORS
|
||||||
|
import redis
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
CORS(app)
|
||||||
|
|
||||||
|
# Connect to Redis (running in a separate container and foldr)
|
||||||
|
redis_client = redis.StrictRedis(host='redis', port=6379, decode_responses=True)
|
||||||
|
|
||||||
|
@app.route('/counter', methods=['GET'])
|
||||||
|
def counter():
|
||||||
|
# Increment visitor count in Redis
|
||||||
|
visits = redis_client.incr('visits')
|
||||||
|
return jsonify({"visits": visits})
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(host='0.0.0.0', port=5000)
|
23
z2/check.sh
Executable file
23
z2/check.sh
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# list all namespaces
|
||||||
|
echo "Namespaces:"
|
||||||
|
kubectl get namespaces
|
||||||
|
|
||||||
|
# list all statefulsets
|
||||||
|
echo "\nStatefulSets:"
|
||||||
|
kubectl get statefulsets
|
||||||
|
|
||||||
|
# list all services
|
||||||
|
echo "\nServices:"
|
||||||
|
kubectl get services
|
||||||
|
|
||||||
|
|
||||||
|
# list all deployments
|
||||||
|
echo "\nDeployments:"
|
||||||
|
kubectl get deployments
|
||||||
|
|
||||||
|
# list all pods
|
||||||
|
echo "\nPods:"
|
||||||
|
kubectl get pods
|
||||||
|
|
28
z2/compose.yaml
Normal file
28
z2/compose.yaml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
build: ./web
|
||||||
|
ports:
|
||||||
|
- "5000:80"
|
||||||
|
depends_on:
|
||||||
|
- backend
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
backend:
|
||||||
|
build: ./backend
|
||||||
|
ports:
|
||||||
|
- "5001:5000"
|
||||||
|
depends_on:
|
||||||
|
- redis
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:alpine
|
||||||
|
command: ["redis-server", "--appendonly", "yes"]
|
||||||
|
volumes:
|
||||||
|
- redis_data:/data
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
redis_data:
|
20
z2/deployment.yaml
Normal file
20
z2/deployment.yaml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: backend-deployment
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: backend-app
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: backend-app
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: backend-container
|
||||||
|
image: backend:latest
|
||||||
|
imagePullPolicy: IfNotPresent #uses local images if available
|
||||||
|
ports:
|
||||||
|
- containerPort: 5000
|
BIN
z2/minikube-linux-amd64
Normal file
BIN
z2/minikube-linux-amd64
Normal file
Binary file not shown.
9
z2/prepare-app.sh
Executable file
9
z2/prepare-app.sh
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# build Docker images for backend and web
|
||||||
|
docker build -t backend:latest ./backend
|
||||||
|
docker build -t web:latest ./web
|
||||||
|
|
||||||
|
# load images into minikube
|
||||||
|
minikube image load backend:latest
|
||||||
|
minikube image load web:latest
|
11
z2/redis-service.yaml
Normal file
11
z2/redis-service.yaml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: redis-service
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: redis-app # This must match the pod label in StatefulSet.
|
||||||
|
ports:
|
||||||
|
- name: redis-port
|
||||||
|
port: 6379 # External port for Redis.
|
||||||
|
targetPort: 6379 # Internal container port.
|
12
z2/service.yaml
Normal file
12
z2/service.yaml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: backend-service
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: backend-app
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 5000
|
||||||
|
targetPort: 5000
|
||||||
|
type: NodePort
|
15
z2/start-app.sh
Executable file
15
z2/start-app.sh
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# start minikube
|
||||||
|
minikube start
|
||||||
|
|
||||||
|
# apply all Kubernetes YAML files
|
||||||
|
kubectl apply -f backend-deployment.yaml
|
||||||
|
kubectl apply -f web-deployment.yaml
|
||||||
|
kubectl apply -f statefulset.yaml
|
||||||
|
kubectl apply -f backend-service.yaml
|
||||||
|
kubectl apply -f web-service.yaml
|
||||||
|
kubectl apply -f redis-service.yaml
|
||||||
|
|
||||||
|
# Output web service URL
|
||||||
|
minikube service web-service --url
|
31
z2/statefulset.yaml
Normal file
31
z2/statefulset.yaml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: redis-statefulset
|
||||||
|
spec:
|
||||||
|
serviceName: "redis-service"
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: redis-app
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: redis-app
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: redis-container
|
||||||
|
image: redis:alpine # Redis image.
|
||||||
|
ports:
|
||||||
|
- containerPort: 6379 # Redis default port.
|
||||||
|
volumeMounts:
|
||||||
|
- name: redis-storage-volume # Mount persistent volume.
|
||||||
|
mountPath: /data # Redis data directory.
|
||||||
|
volumeClaimTemplates:
|
||||||
|
- metadata:
|
||||||
|
name: redis-storage-volume # Persistent Volume Claim.
|
||||||
|
spec:
|
||||||
|
accessModes: ["ReadWriteOnce"]
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 1Gi # Persistent storage size.
|
12
z2/stop-app.sh
Executable file
12
z2/stop-app.sh
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# delete all Kubernetes objects
|
||||||
|
kubectl delete -f backend-deployment.yaml
|
||||||
|
kubectl delete -f web-deployment.yaml
|
||||||
|
kubectl delete -f statefulset.yaml
|
||||||
|
kubectl delete -f backend-service.yaml
|
||||||
|
kubectl delete -f web-service.yaml
|
||||||
|
kubectl delete -f redis-service.yaml
|
||||||
|
|
||||||
|
# stop minikube
|
||||||
|
minikube stop
|
20
z2/web-deployment.yaml
Normal file
20
z2/web-deployment.yaml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: web-deployment
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: web-app
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: web-app
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: web-container
|
||||||
|
image: web:latest
|
||||||
|
imagePullPolicy: IfNotPresent #same thing uses local image if any
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
12
z2/web-service.yaml
Normal file
12
z2/web-service.yaml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: web-service
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: web-app
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
targetPort: 80
|
||||||
|
type: NodePort
|
11
z2/web/Dockerfile
Normal file
11
z2/web/Dockerfile
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
FROM httpd:2.4
|
||||||
|
|
||||||
|
# Copies your static HTML file into the Apache document root
|
||||||
|
COPY index.html /usr/local/apache2/htdocs/
|
||||||
|
|
||||||
|
# Add a proxy configuration for /counter
|
||||||
|
RUN echo "ProxyPass /counter http://backend-service:5000/counter" >> /usr/local/apache2/conf/httpd.conf
|
||||||
|
RUN echo "ProxyPassReverse /counter http://backend-service:5000/counter" >> /usr/local/apache2/conf/httpd.conf
|
||||||
|
|
||||||
|
|
||||||
|
EXPOSE 80
|
28
z2/web/index.html
Normal file
28
z2/web/index.html
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Visitor Counter</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Welcome to the Visitor Counter App!</h1>
|
||||||
|
<h2>Made by ALI</h2>
|
||||||
|
<h3>Also made for assinment 1</h3>
|
||||||
|
<p>This page has been visited <span id="counter">0</span> times.</p>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
async function updateCounter() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/counter');
|
||||||
|
const data = await response.json();
|
||||||
|
document.getElementById('counter').textContent = data.visits;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching counter:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCounter();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user