message
This commit is contained in:
parent
437a05ee15
commit
2718263509
100
z1/README.md
Normal file
100
z1/README.md
Normal file
@ -0,0 +1,100 @@
|
||||
# Zadanie 1
|
||||
|
||||
## Opis aplikacie
|
||||
|
||||
Tato aplikacia je jednoducha webova aplikacia nasadena pomocou Docker Compose. Umoznuje zapisat meno cez webove rozhranie do databazy PostgreSQL a nasledne zobrazit zoznam ulozenych zaznamov. Aplikacia obsahuje frontend, backend, databazu a webove rozhranie Adminer na pracu s databazou.
|
||||
|
||||
## Potrebny software
|
||||
|
||||
- Linux
|
||||
- Docker
|
||||
- Docker Compose plugin (`docker compose`)
|
||||
|
||||
## Pouzite kontajnery
|
||||
|
||||
- `nginx:latest` - webovy server pre staticke subory frontendu
|
||||
- `node:18` - backend aplikacie postaveny zo suboru `backend/Dockerfile`
|
||||
- `postgres:15` - relacna databaza PostgreSQL
|
||||
- `adminer` - webove rozhranie na pracu s databazou
|
||||
|
||||
## Siete a zvazky
|
||||
|
||||
Docker Compose vytvori predvolenu virtualnu siet, v ktorej spolu komunikujú sluzby:
|
||||
|
||||
- `web`
|
||||
- `backend`
|
||||
- `db`
|
||||
- `adminer`
|
||||
|
||||
Pouzity pomenovany trvaly zvazok:
|
||||
|
||||
- `db_data` - uklada databazove data PostgreSQL, aby zostali zachovane aj po zastaveni aplikacie
|
||||
|
||||
## Konfiguracia kontajnerov
|
||||
|
||||
- `web` bezi v kontajneri s Nginx a spristupnuje frontend na porte `8080`
|
||||
- `backend` bezi v Node.js kontajneri a je dostupny na porte `5000`
|
||||
- `db` bezi ako PostgreSQL databaza s premennymi `POSTGRES_USER`, `POSTGRES_PASSWORD` a `POSTGRES_DB`
|
||||
- `adminer` je dostupny na porte `8081`
|
||||
- vsetky sluzby maju nastavene `restart: always`
|
||||
- backend zavisi od databazy a Adminer zavisi od databazy
|
||||
|
||||
## Navod na pouzitie
|
||||
|
||||
Priecinok projektu:
|
||||
|
||||
```bash
|
||||
cd z1
|
||||
```
|
||||
|
||||
Spustenie aplikacie:
|
||||
|
||||
```bash
|
||||
./start-app.sh
|
||||
```
|
||||
|
||||
Zastavenie aplikacie:
|
||||
|
||||
```bash
|
||||
./stop-app.sh
|
||||
```
|
||||
|
||||
Alternativne je mozne aplikaciu spustit aj priamo cez Docker Compose:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Pristup cez webovy prehliadac
|
||||
|
||||
- Hlavna aplikacia: `http://localhost:8080`
|
||||
- Backend API: `http://localhost:5000`
|
||||
- Adminer: `http://localhost:8081`
|
||||
|
||||
Prihlasovacie udaje do PostgreSQL:
|
||||
|
||||
- system: `PostgreSQL`
|
||||
- server: `db`
|
||||
- username: `user`
|
||||
- password: `password`
|
||||
- database: `mydb`
|
||||
|
||||
## Priklad prace s aplikaciou
|
||||
|
||||
1. Otvorte `http://localhost:8080`
|
||||
2. Zadajte meno do formulara
|
||||
3. Kliknite na tlacidlo `Save & Show`
|
||||
4. Udaj sa ulozi do databazy a zobrazi v zozname
|
||||
|
||||
## Zdroje
|
||||
|
||||
- Docker dokumentacia
|
||||
- Docker Compose dokumentacia
|
||||
- Nginx oficialny image na Docker Hub
|
||||
- Node.js oficialny image na Docker Hub
|
||||
- PostgreSQL oficialny image na Docker Hub
|
||||
- Adminer oficialny image na Docker Hub
|
||||
|
||||
## Pouzitie umelej inteligencie
|
||||
|
||||
Pri priprave dokumentacie a pomocnych skriptov bola pouzita umele inteligencia vo forme AI agenta Codex.
|
||||
6
z1/prepare-app.sh
Normal file
6
z1/prepare-app.sh
Normal file
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
docker compose build
|
||||
docker compose create
|
||||
5
z1/remove-app.sh
Normal file
5
z1/remove-app.sh
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
docker compose down -v --remove-orphans
|
||||
9
z1/start-app.sh
Normal file
9
z1/start-app.sh
Normal file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "Running app ..."
|
||||
docker compose up -d
|
||||
echo "The app is available at http://localhost:8080"
|
||||
echo "Adminer is available at http://localhost:8081"
|
||||
echo "Backend API is available at http://localhost:5000"
|
||||
5
z1/stop-app.sh
Normal file
5
z1/stop-app.sh
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
docker compose stop
|
||||
112
z2/README.md
Normal file
112
z2/README.md
Normal file
@ -0,0 +1,112 @@
|
||||
# Zadanie 2 - Kubernetes web application
|
||||
|
||||
This project deploys a simple web application into Kubernetes. The user enters a name in the browser, the frontend sends it to the backend API, and the backend stores the value in PostgreSQL. The saved names are then displayed back in the browser.
|
||||
|
||||
## Used containers
|
||||
|
||||
- `z2-frontend:latest` - custom Nginx image serving the static frontend and proxying API requests to the backend service.
|
||||
- `z2-backend:latest` - custom Node.js and Express API image that stores and reads user data from PostgreSQL.
|
||||
- `postgres:15-alpine` - database container running inside a StatefulSet with persistent storage.
|
||||
|
||||
## Kubernetes objects
|
||||
|
||||
- `Namespace zkt26-z2` - isolates all application resources into one namespace.
|
||||
- `Deployment backend-deployment` - runs the backend API container.
|
||||
- `Deployment frontend-deployment` - runs the frontend Nginx container.
|
||||
- `Service backend-service` - exposes the backend inside the cluster.
|
||||
- `Service frontend-service` - exposes the frontend on NodePort `30080`.
|
||||
- `Service postgres-service` - stable network endpoint for PostgreSQL.
|
||||
- `PersistentVolume postgres-pv` - host storage for PostgreSQL data.
|
||||
- `PersistentVolumeClaim postgres-pvc` - binds storage for the database pod.
|
||||
- `StatefulSet postgres-statefulset` - runs PostgreSQL with persistent data.
|
||||
|
||||
## Networks and volumes
|
||||
|
||||
The application uses the default Kubernetes cluster networking. Pods communicate with each other through Kubernetes services:
|
||||
|
||||
- `frontend-service` for browser access
|
||||
- `backend-service` for frontend to backend communication
|
||||
- `postgres-service` for backend to database communication
|
||||
|
||||
Persistent data is stored using:
|
||||
|
||||
- `PersistentVolume postgres-pv`
|
||||
- `PersistentVolumeClaim postgres-pvc`
|
||||
|
||||
The volume uses `hostPath` at `/tmp/zkt26-postgres-data`, so the database data remains available even after the pod restarts.
|
||||
|
||||
## Container configuration
|
||||
|
||||
The frontend container is based on Nginx and includes a custom `nginx.conf` that proxies `/api/*` requests to the backend service.
|
||||
|
||||
The backend container uses environment variables for the database connection:
|
||||
|
||||
- `DB_HOST=postgres-service`
|
||||
- `DB_PORT=5432`
|
||||
- `DB_USER=user`
|
||||
- `DB_PASSWORD=password`
|
||||
- `DB_NAME=mydb`
|
||||
|
||||
The PostgreSQL container is configured with:
|
||||
|
||||
- `POSTGRES_USER=user`
|
||||
- `POSTGRES_PASSWORD=password`
|
||||
- `POSTGRES_DB=mydb`
|
||||
|
||||
## How to prepare, start, stop and delete the application
|
||||
|
||||
Run the commands from the `z2` directory:
|
||||
|
||||
```bash
|
||||
chmod +x prepare-app.sh start-app.sh stop-app.sh
|
||||
./prepare-app.sh
|
||||
./start-app.sh
|
||||
```
|
||||
|
||||
To stop and delete the application:
|
||||
|
||||
```bash
|
||||
./stop-app.sh
|
||||
```
|
||||
|
||||
## How to pause the application
|
||||
|
||||
The application can be paused by scaling deployments and the stateful set to zero:
|
||||
|
||||
```bash
|
||||
kubectl scale deployment frontend-deployment --replicas=0 -n zkt26-z2
|
||||
kubectl scale deployment backend-deployment --replicas=0 -n zkt26-z2
|
||||
kubectl scale statefulset postgres-statefulset --replicas=0 -n zkt26-z2
|
||||
```
|
||||
|
||||
To start it again:
|
||||
|
||||
```bash
|
||||
kubectl scale deployment frontend-deployment --replicas=1 -n zkt26-z2
|
||||
kubectl scale deployment backend-deployment --replicas=1 -n zkt26-z2
|
||||
kubectl scale statefulset postgres-statefulset --replicas=1 -n zkt26-z2
|
||||
```
|
||||
|
||||
## How to open the web application
|
||||
|
||||
After starting the application in a standard Kubernetes environment, open the browser at:
|
||||
|
||||
- `http://localhost:30080`
|
||||
|
||||
If you are using Minikube in WSL with the Docker driver, get the real browser URL with:
|
||||
|
||||
```bash
|
||||
minikube service frontend-service -n zkt26-z2 --url
|
||||
```
|
||||
|
||||
Keep that terminal open and open the printed URL in the browser.
|
||||
|
||||
If your Kubernetes environment does not expose NodePort on localhost directly, or if you want a fixed local port, use:
|
||||
|
||||
```bash
|
||||
kubectl port-forward service/frontend-service 8080:80 -n zkt26-z2
|
||||
```
|
||||
|
||||
Then open:
|
||||
|
||||
- `http://localhost:8080`
|
||||
11
z2/backend/Dockerfile
Normal file
11
z2/backend/Dockerfile
Normal file
@ -0,0 +1,11 @@
|
||||
FROM node:18-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY server.js .
|
||||
|
||||
RUN npm init -y && npm install express pg cors
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["node", "server.js"]
|
||||
91
z2/backend/server.js
Normal file
91
z2/backend/server.js
Normal file
@ -0,0 +1,91 @@
|
||||
const express = require("express");
|
||||
const cors = require("cors");
|
||||
const { Pool } = require("pg");
|
||||
|
||||
const app = express();
|
||||
const port = Number(process.env.PORT || 3000);
|
||||
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
|
||||
const pool = new Pool({
|
||||
host: process.env.DB_HOST || "postgres-service",
|
||||
user: process.env.DB_USER || "user",
|
||||
password: process.env.DB_PASSWORD || "password",
|
||||
database: process.env.DB_NAME || "mydb",
|
||||
port: Number(process.env.DB_PORT || 5432)
|
||||
});
|
||||
|
||||
async function prepareDatabase() {
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL
|
||||
)
|
||||
`);
|
||||
}
|
||||
|
||||
async function waitForDatabase(maxAttempts = 20, delayMs = 3000) {
|
||||
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
||||
try {
|
||||
await prepareDatabase();
|
||||
console.log(`Database is ready after attempt ${attempt}.`);
|
||||
return;
|
||||
} catch (error) {
|
||||
console.error(`Database is not ready yet (attempt ${attempt}/${maxAttempts}):`, error.message);
|
||||
|
||||
if (attempt === maxAttempts) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
app.get("/health", async (_req, res) => {
|
||||
try {
|
||||
await pool.query("SELECT 1");
|
||||
res.json({ status: "ok" });
|
||||
} catch (error) {
|
||||
console.error("Healthcheck failed:", error);
|
||||
res.status(500).json({ status: "error" });
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/save", async (req, res) => {
|
||||
const name = (req.body.name || "").trim();
|
||||
|
||||
if (!name) {
|
||||
return res.status(400).send("Name is required");
|
||||
}
|
||||
|
||||
try {
|
||||
await pool.query("INSERT INTO users(name) VALUES($1)", [name]);
|
||||
return res.send(`Saved to DB: ${name}`);
|
||||
} catch (error) {
|
||||
console.error("Insert failed:", error);
|
||||
return res.status(500).send("Error");
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/users", async (_req, res) => {
|
||||
try {
|
||||
const result = await pool.query("SELECT * FROM users ORDER BY id ASC");
|
||||
return res.json(result.rows);
|
||||
} catch (error) {
|
||||
console.error("Select failed:", error);
|
||||
return res.status(500).send("Error");
|
||||
}
|
||||
});
|
||||
|
||||
waitForDatabase()
|
||||
.then(() => {
|
||||
app.listen(port, () => {
|
||||
console.log(`Backend running on port ${port}`);
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Database initialization failed:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
60
z2/deployment.yaml
Normal file
60
z2/deployment.yaml
Normal file
@ -0,0 +1,60 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: backend-deployment
|
||||
namespace: zkt26-z2
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: backend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: backend
|
||||
spec:
|
||||
containers:
|
||||
- name: backend
|
||||
image: z2-backend:v2
|
||||
imagePullPolicy: Never
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
env:
|
||||
- name: DB_HOST
|
||||
value: postgres-service
|
||||
- name: DB_PORT
|
||||
value: "5432"
|
||||
- name: DB_USER
|
||||
value: user
|
||||
- name: DB_PASSWORD
|
||||
value: password
|
||||
- name: DB_NAME
|
||||
value: mydb
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3000
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: frontend-deployment
|
||||
namespace: zkt26-z2
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: frontend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: frontend
|
||||
image: z2-frontend:latest
|
||||
imagePullPolicy: Never
|
||||
ports:
|
||||
- containerPort: 80
|
||||
6
z2/frontend/Dockerfile
Normal file
6
z2/frontend/Dockerfile
Normal file
@ -0,0 +1,6 @@
|
||||
FROM nginx:1.27-alpine
|
||||
|
||||
COPY index.html /usr/share/nginx/html/index.html
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
EXPOSE 80
|
||||
173
z2/frontend/index.html
Normal file
173
z2/frontend/index.html
Normal file
@ -0,0 +1,173 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Kubernetes Demo App</title>
|
||||
<style>
|
||||
:root {
|
||||
color-scheme: light;
|
||||
--bg: #f4efe6;
|
||||
--panel: #fffaf2;
|
||||
--text: #1f2933;
|
||||
--accent: #bf6d2c;
|
||||
--accent-dark: #8e4b17;
|
||||
--border: #e6d7c3;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
font-family: "Trebuchet MS", "Segoe UI", sans-serif;
|
||||
color: var(--text);
|
||||
background:
|
||||
radial-gradient(circle at top, rgba(191, 109, 44, 0.18), transparent 35%),
|
||||
linear-gradient(180deg, #f8f2e9 0%, var(--bg) 100%);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.card {
|
||||
width: min(640px, 100%);
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 20px;
|
||||
padding: 28px;
|
||||
box-shadow: 0 20px 50px rgba(72, 49, 24, 0.12);
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
font-size: clamp(2rem, 5vw, 2.8rem);
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
color: #52606d;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
input {
|
||||
flex: 1 1 260px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 14px 16px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
button {
|
||||
border: 0;
|
||||
border-radius: 12px;
|
||||
padding: 14px 18px;
|
||||
background: var(--accent);
|
||||
color: white;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
transition: transform 0.15s ease, background 0.15s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: var(--accent-dark);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.status {
|
||||
min-height: 24px;
|
||||
margin-bottom: 12px;
|
||||
color: var(--accent-dark);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
li + li {
|
||||
margin-top: 6px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="card">
|
||||
<h1>Kubernetes demo</h1>
|
||||
<p>This frontend sends names to the backend API and loads them back from PostgreSQL running in a StatefulSet.</p>
|
||||
|
||||
<div class="row">
|
||||
<input id="name" placeholder="Enter name">
|
||||
<button onclick="sendAndLoad()">Save and show</button>
|
||||
</div>
|
||||
|
||||
<div id="status" class="status"></div>
|
||||
<ul id="list"></ul>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
async function loadUsers() {
|
||||
const status = document.getElementById("status");
|
||||
|
||||
try {
|
||||
status.textContent = "Loading users...";
|
||||
const res = await fetch("/api/users");
|
||||
const data = await res.json();
|
||||
|
||||
const list = document.getElementById("list");
|
||||
list.innerHTML = "";
|
||||
|
||||
data.forEach((user) => {
|
||||
const li = document.createElement("li");
|
||||
li.innerText = user.name;
|
||||
list.appendChild(li);
|
||||
});
|
||||
|
||||
status.textContent = "Users loaded successfully.";
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
status.textContent = "Cannot connect to backend.";
|
||||
}
|
||||
}
|
||||
|
||||
async function sendAndLoad() {
|
||||
const status = document.getElementById("status");
|
||||
const nameInput = document.getElementById("name");
|
||||
const name = nameInput.value.trim();
|
||||
|
||||
if (!name) {
|
||||
status.textContent = "Please enter a name first.";
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
status.textContent = "Saving user...";
|
||||
await fetch("/api/save", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({ name })
|
||||
});
|
||||
|
||||
nameInput.value = "";
|
||||
await loadUsers();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
status.textContent = "Saving failed.";
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = loadUsers;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
20
z2/frontend/nginx.conf
Normal file
20
z2/frontend/nginx.conf
Normal file
@ -0,0 +1,20 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://backend-service:3000/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
4
z2/namespace.yaml
Normal file
4
z2/namespace.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: zkt26-z2
|
||||
18
z2/prepare-app.sh
Normal file
18
z2/prepare-app.sh
Normal file
@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "Building backend image..."
|
||||
docker build -t z2-backend:v2 ./backend
|
||||
|
||||
echo "Building frontend image..."
|
||||
docker build -t z2-frontend:latest ./frontend
|
||||
|
||||
if command -v minikube >/dev/null 2>&1; then
|
||||
echo "Loading images into minikube..."
|
||||
minikube image load z2-backend:v2
|
||||
minikube image load z2-frontend:latest
|
||||
else
|
||||
echo "minikube not found, skipping image load step."
|
||||
fi
|
||||
|
||||
echo "Preparation finished."
|
||||
37
z2/service.yaml
Normal file
37
z2/service.yaml
Normal file
@ -0,0 +1,37 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: backend-service
|
||||
namespace: zkt26-z2
|
||||
spec:
|
||||
selector:
|
||||
app: backend
|
||||
ports:
|
||||
- port: 3000
|
||||
targetPort: 3000
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: frontend-service
|
||||
namespace: zkt26-z2
|
||||
spec:
|
||||
type: NodePort
|
||||
selector:
|
||||
app: frontend
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
nodePort: 30080
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: postgres-service
|
||||
namespace: zkt26-z2
|
||||
spec:
|
||||
selector:
|
||||
app: postgres
|
||||
ports:
|
||||
- port: 5432
|
||||
targetPort: 5432
|
||||
11
z2/start-app.sh
Normal file
11
z2/start-app.sh
Normal file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
kubectl apply -f namespace.yaml
|
||||
kubectl apply -f statefulset.yaml
|
||||
kubectl apply -f deployment.yaml
|
||||
kubectl apply -f service.yaml
|
||||
|
||||
echo "Application started."
|
||||
echo "Frontend NodePort is 30080."
|
||||
echo "For Minikube on WSL use: minikube service frontend-service -n zkt26-z2 --url"
|
||||
63
z2/statefulset.yaml
Normal file
63
z2/statefulset.yaml
Normal file
@ -0,0 +1,63 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: postgres-pv
|
||||
spec:
|
||||
storageClassName: ""
|
||||
capacity:
|
||||
storage: 1Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath:
|
||||
path: /tmp/zkt26-postgres-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: postgres-pvc
|
||||
namespace: zkt26-z2
|
||||
spec:
|
||||
storageClassName: ""
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
volumeName: postgres-pv
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: postgres-statefulset
|
||||
namespace: zkt26-z2
|
||||
spec:
|
||||
serviceName: postgres-service
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: postgres
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: postgres
|
||||
spec:
|
||||
containers:
|
||||
- name: postgres
|
||||
image: postgres:15-alpine
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
env:
|
||||
- name: POSTGRES_USER
|
||||
value: user
|
||||
- name: POSTGRES_PASSWORD
|
||||
value: password
|
||||
- name: POSTGRES_DB
|
||||
value: mydb
|
||||
volumeMounts:
|
||||
- name: postgres-storage
|
||||
mountPath: /var/lib/postgresql/data
|
||||
volumes:
|
||||
- name: postgres-storage
|
||||
persistentVolumeClaim:
|
||||
claimName: postgres-pvc
|
||||
9
z2/stop-app.sh
Normal file
9
z2/stop-app.sh
Normal file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
kubectl delete -f service.yaml --ignore-not-found
|
||||
kubectl delete -f deployment.yaml --ignore-not-found
|
||||
kubectl delete -f statefulset.yaml --ignore-not-found
|
||||
kubectl delete -f namespace.yaml --ignore-not-found
|
||||
|
||||
echo "Application stopped."
|
||||
Loading…
Reference in New Issue
Block a user