This commit is contained in:
Matej Maťkuliak 2021-05-24 19:48:55 +02:00
parent 8c9cccb2a1
commit 9f24346983
25 changed files with 619 additions and 0 deletions

9
sk1/.env Normal file
View File

@ -0,0 +1,9 @@
# Add Environment Variables
DEBUG=False
SECRET_KEY=5(15ds+i2+%ik6z&!yer+ga9m=e%jcqiz_5wszg)r-z!2--b2d
DB_NAME=postgres
DB_USER=postgres
DB_PASS=postgres
DB_SERVICE=postgres
DB_PORT=5432

26
sk1/README.md Normal file
View File

@ -0,0 +1,26 @@
Jednoducha message web aplikacia pouzivajuca Flask, Nginx a Postgres.
Prerobil som aplikaciu zo zadania z1.
Aplikacia obsahuje 4 pody. Web, Data, Nginx a Postgres.
start skriptom start-app.sh a zastavenie stop-app.sh
Vsetky sluzby, persistent volumes aj deploymenty bezia podla minikube Kubernetes GUI spravne, avsak GUI stranku aplikacie neviem najst/nespusta sa spravne. Myslim ze ide o nejaky networking problem kedze ta ista aplikacia bez Kubernetes funguje spravne. Myslim ze porty mam exposnute spravne, viem to zistit prikazom "kubectl describe services". Tam vidime ze service "web" je exposnuty na porte 8000 ako chceme, napriklad na lokalnej adrese 127.17.0.7:8000. V browseri vsak na tejto adrese nie je frontend ako by som ocakaval. Ak budete mat cas niekedy, velmi by mi pomohlo ak by ste so mnou na to pozreli, kedze toto by som chcel deploynut aj na public cloud v ramci skusky.
Sucastou su 4 .yaml skripty ktore sa aplikuju do Kubernete start-app skriptom.
ngingx-deployment.yaml:
Zakladny deployment ktory vytvori pod
Service nginx pouzivany podom
Persiste volume claim ako trvale ulozisko
data-deployment.yaml:
opat deployment ktory vytvori pod
PVC ulozisko
postgres-deployment.yaml:
Deployment + service
web-deployment.yaml:
Deployment + service + PVC
Prave v tomto yaml subore bude zrejme chyba. Neviem vsak identifikovat kde, kedze podla niekolkych navodov exposujem port webu spravne a aj je zobrazeny "describe services" prikazom.
stop-app.sh odstrani vsetky sucasti vratane persistent volumes

49
sk1/data-deployment.yaml Normal file
View File

@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
service: data
name: data
spec:
replicas: 1
selector:
matchLabels:
service: data
strategy:
type: Recreate
template:
metadata:
labels:
service: data
spec:
containers:
- args:
- "true"
image: postgres:latest
command: ["/bin/sh", "-ec", "while :; do echo '.'; sleep 5 ; done"]
name: data
resources: {}
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: db-data
restartPolicy: Always
volumes:
- name: db-data
persistentVolumeClaim:
claimName: db-data
status: {}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
service: db-data
name: db-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}

46
sk1/docker-compose.yml Normal file
View File

@ -0,0 +1,46 @@
version: '3'
services:
web:
restart: always
build: ./web
expose:
- "8000"
links:
- postgres:postgres
volumes:
- web-data:/usr/src/app/static
env_file:
- .env
command: /usr/local/bin/gunicorn -w 2 -b :8000 app:app
nginx:
restart: always
build: ./nginx
ports:
- "8080:8080"
volumes:
- .:/www/static
- web-data:/usr/src/app/static
links:
- web:web
data:
image: postgres:latest
volumes:
- db-data:/var/lib/postgresql/data
command: "true"
postgres:
restart: always
image: postgres:latest
environment:
- POSTGRES_HOST_AUTH_METHOD=trust
volumes:
- db-data:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
db-data:
web-data:

15
sk1/env-configmap.yaml Normal file
View File

@ -0,0 +1,15 @@
apiVersion: v1
data:
DB_NAME: postgres
DB_PASS: postgres
DB_PORT: "5432"
DB_SERVICE: postgres
DB_USER: postgres
DEBUG: "False"
SECRET_KEY: 5(15ds+i2+%ik6z&!yer+ga9m=e%jcqiz_5wszg)r-z!2--b2d
kind: ConfigMap
metadata:
creationTimestamp: null
labels:
io.kompose.service: web-env
name: env

69
sk1/nginx-deployment.yaml Normal file
View File

@ -0,0 +1,69 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
service: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
service: nginx
strategy:
type: Recreate
template:
metadata:
labels:
service: nginx
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 8080
resources: {}
volumeMounts:
- mountPath: /www/static
name: nginx-claim0
- mountPath: /usr/src/app/static
name: web-data
restartPolicy: Always
volumes:
- name: nginx-claim0
persistentVolumeClaim:
claimName: nginx-claim0
- name: web-data
persistentVolumeClaim:
claimName: web-data
status: {}
---
apiVersion: v1
kind: Service
metadata:
labels:
service: nginx
name: nginx
spec:
ports:
- name: "8080"
port: 8080
targetPort: 8080
selector:
service: nginx
status:
loadBalancer: {}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
service: nginx-claim0
name: nginx-claim0
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}

5
sk1/nginx/Dockerfile Normal file
View File

@ -0,0 +1,5 @@
FROM tutum/nginx
RUN rm /etc/nginx/sites-enabled/default
COPY sites-enabled/ /etc/nginx/sites-enabled

View File

@ -0,0 +1,17 @@
server {
listen 8080;
server_name example.org;
charset utf-8;
location /static {
alias /usr/src/app/static;
}
location / {
proxy_pass http://web:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

View File

@ -0,0 +1,52 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
service: postgres
name: postgres
spec:
replicas: 1
selector:
matchLabels:
service: postgres
strategy:
type: Recreate
template:
metadata:
labels:
service: postgres
spec:
containers:
- env:
- name: POSTGRES_HOST_AUTH_METHOD
value: trust
image: postgres:latest
name: postgres
ports:
- containerPort: 5432
resources: {}
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: db-data
restartPolicy: Always
volumes:
- name: db-data
persistentVolumeClaim:
claimName: db-data
status: {}
---
apiVersion: v1
kind: Service
metadata:
labels:
service: postgres
name: postgres
spec:
ports:
- name: "5432"
port: 5432
targetPort: 5432
selector:
service: postgres
status:
loadBalancer: {}

18
sk1/start-app.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
#tento script pripravi a spusti vsetko, po jeho ukonceni je aplikacia beziaca a funkcna
#predpoklada sa ze kubectl a minikube su spustene
echo "*Starting setup*"
echo "*Deploying postgres*"
kubectl apply -f postgres-deployment.yaml
echo "*Deploying nginx*"
kubectl apply -f nginx-deployment.yaml
echo "*Deploying data*"
kubectl apply -f data-deployment.yaml
echo "*Deploying web*"
kubectl apply -f web-deployment.yaml
echo "*Deploying configmap*"
kubectl apply -f env-configmap.yaml
echo "*Done*"

32
sk1/stop-app.sh Executable file
View File

@ -0,0 +1,32 @@
#!/bin/bash
#tento script odstrani vsetky deploymenty/pody/service/persistent-volumes
kubectl delete -n default deployment web
echo "*Deployment web deleted*"
kubectl delete -n default deployment data
echo "*Deployment data deleted*"
kubectl delete -n default deployment nginx
echo "*Deployment nginx deleted*"
kubectl delete -n default deployment postgres
echo "*Deployment postgres deleted*"
kubectl delete -n default service web
echo "*Service web deleted*"
kubectl delete -n default service nginx
echo "*Service web deleted*"
kubectl delete -n default service postgres
echo "*Service web deleted*"
kubectl delete -n default configmap env
echo "*Service web deleted*"
kubectl get pv | tail -n+3 | awk '{print $1}' | xargs -I{} kubectl patch pv {} -p '{"metadata":{"finalizers": null}}'
echo "*Finalizers edited so deletes don't hang*"
kubectl delete pvc db-data --grace-period=0 --force --wait=false
echo "*PVC db-data deleted*"
kubectl delete pvc nginx-claim0 --grace-period=0 --force --wait=false
echo "*PVC nginx deleted*"
kubectl delete pvc web-data --grace-period=0 --force --wait=false
echo "*PVC web-data deleted*"
echo "------------"
echo "App stopped"

107
sk1/web-deployment.yaml Normal file
View File

@ -0,0 +1,107 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
service: web
name: web
spec:
replicas: 1
selector:
matchLabels:
service: web
strategy:
type: Recreate
template:
metadata:
labels:
service: web
spec:
containers:
- args:
- /usr/local/bin/gunicorn
- -w
- "2"
- -b
- :8000
- app:app
env:
- name: DB_NAME
valueFrom:
configMapKeyRef:
key: DB_NAME
name: env
- name: DB_PASS
valueFrom:
configMapKeyRef:
key: DB_PASS
name: env
- name: DB_PORT
valueFrom:
configMapKeyRef:
key: DB_PORT
name: env
- name: DB_SERVICE
valueFrom:
configMapKeyRef:
key: DB_SERVICE
name: env
- name: DB_USER
valueFrom:
configMapKeyRef:
key: DB_USER
name: env
- name: DEBUG
valueFrom:
configMapKeyRef:
key: DEBUG
name: env
- name: SECRET_KEY
valueFrom:
configMapKeyRef:
key: SECRET_KEY
name: env
image: nameton/z2_web:2
name: web
ports:
- containerPort: 8000
resources: {}
volumeMounts:
- mountPath: /usr/src/app/static
name: web-data
restartPolicy: Always
volumes:
- name: web-data
persistentVolumeClaim:
claimName: web-data
status: {}
---
apiVersion: v1
kind: Service
metadata:
labels:
service: web
name: web
spec:
ports:
- name: "8000"
port: 8000
targetPort: 8000
selector:
service: web
status:
loadBalancer: {}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
service: web-data
name: web-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}

10
sk1/web/Dockerfile Normal file
View File

@ -0,0 +1,10 @@
FROM python:3.7-slim
RUN python -m pip install --upgrade pip
WORKDIR /usr/src/app
COPY requirements.txt requirements.txt
RUN python -m pip install -r requirements.txt
COPY . .

30
sk1/web/app.py Normal file
View File

@ -0,0 +1,30 @@
# app.py
from flask import Flask
from flask import request, render_template
from flask_sqlalchemy import SQLAlchemy
from config import BaseConfig
app = Flask(__name__)
app.config.from_object(BaseConfig)
db = SQLAlchemy(app)
from models import *
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
text = request.form['text']
post = Post(text)
db.session.add(post)
db.session.commit()
posts = Post.query.order_by(Post.date_posted.desc()).all()
return render_template('index.html', posts=posts)
if __name__ == '__main__':
app.run()

28
sk1/web/config.py Normal file
View File

@ -0,0 +1,28 @@
# config.py
import os
class BaseConfig(object):
SECRET_KEY = os.environ['SECRET_KEY']
DEBUG = os.environ['DEBUG']
DB_NAME = os.environ['DB_NAME']
DB_USER = os.environ['DB_USER']
DB_PASS = os.environ['DB_PASS']
DB_SERVICE = os.environ['DB_SERVICE']
DB_PORT = os.environ['DB_PORT']
SQLALCHEMY_DATABASE_URI = 'postgresql://{0}:{1}@{2}:{3}/{4}'.format(
DB_USER, DB_PASS, DB_SERVICE, DB_PORT, DB_NAME
)
# class BaseConfig(object):
# SECRET_KEY = 'hi'
# DEBUG = True
# DB_NAME = 'postgres'
# DB_SERVICE = 'localhost'
# DB_PORT = 5432
# SQLALCHEMY_DATABASE_URI = 'postgresql://{0}:{1}/{2}'.format(
# DB_SERVICE, DB_PORT, DB_NAME
# )

6
sk1/web/create_db.py Normal file
View File

@ -0,0 +1,6 @@
# create_db.py
from app import db
db.create_all()

18
sk1/web/models.py Normal file
View File

@ -0,0 +1,18 @@
# models.py
import datetime
from app import db
class Post(db.Model):
__tablename__ = 'posts'
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String, nullable=False)
date_posted = db.Column(db.DateTime, nullable=False)
def __init__(self, text):
self.text = text
self.date_posted = datetime.datetime.now()

9
sk1/web/requirements.txt Normal file
View File

@ -0,0 +1,9 @@
Flask==1.0.2
Flask-SQLAlchemy==2.3.2
Jinja2==2.10
MarkupSafe==1.1.1
SQLAlchemy==1.3.1
Werkzeug==0.15.1
gunicorn==19.9.0
itsdangerous==1.1.0
psycopg2==2.7.7

5
sk1/web/static/css/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
/* custom styles */
.container {
max-width: 500px;
}

View File

@ -0,0 +1 @@

7
sk1/web/static/js/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
// custom scripts

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Flask on Docker</title>
<!-- meta -->
<meta name="description" content="">
<meta name="author" content="">
<meta name="viewport" content="width=device-width,initial-scale=1">
<!-- styles -->
<link href="static/css/bootstrap.min.css" rel="stylesheet">
<link href="static/css/main.css" rel="stylesheet">
{% block css %}{% endblock %}
</head>
<body>
<div class="container">
<br>
<!-- child template -->
{% block content %}{% endblock %}
</div>
<!-- scripts -->
<script src="//code.jquery.com/jquery-1.11.2.min.js" type="text/javascript"></script>
<script src="static/js/bootstrap.min.js" type="text/javascript"></script>
<script src="static/js/main.js" type="text/javascript"></script>
{% block js %}{% endblock %}
</body>
</html>

View File

@ -0,0 +1,27 @@
{% extends "_base.html" %}
{% block content %}
<div class="text-center">
<h1>Welcome!</h1>
</div>
<br>
<form action="/" method="POST">
<div class="form-group">
<input name="text" class="form-control input-lg" type="text" placeholder="Enter a message" required>
</div>
<input type="submit" class="btn btn-primary btn-lg btn-block" value="Submit">
</form>
<br>
<hr>
<div>
{% for post in posts %}
<h4 class="well"><strong>{{post.text}}</strong> - <em>{{post.date_posted.strftime('%Y-%m-%d')}}</em></h4>
{% endfor %}
</div>
{% endblock %}