Skip to content
Snippets Groups Projects
Commit 6c57ce17 authored by cedricimt's avatar cedricimt
Browse files

initial commit

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 542 additions and 0 deletions
# ansible - devops- imt
Provisionning d'une base de donnée reliée à une application Kubernetes
## How to run it
***note:***
Un problème de DNS persiste.
Pour le contuorner afin que worker envoie les données et que result les récupère, il faut hardcoder l'IP de la VM sur laquelle est hébergée la base de donnée dans le code de result et de worker.
Je conseil de faire un CTRL + F sur l'IP puis replace all par la votre car il faut également changer l'ip dans le manifeste de kubernetes et pour le backup
- Modifier toute les IP dans le code par l'IP de votre VM
- Modifier le nom du projet GCP par le votre (notamment dans le docker-compose.yaml)
- Configurer l'accès distant à GCP (voir [projet Kubernetes](https://gitlab.imt-atlantique.fr/c22dioll/kubernetes-imt))
- Mettre les images sur GCP (penser à modifier l'ip de la VM)
```
cd docker-project
docker compose build
docker compose push
```
- Créer votre cluster
- Lancer les playbooks :
```
cd tp-ansible-voting-app
ansible-playbook deploy_postgres.yaml
ansible-playbook backup-database.yaml
```
- Depuis la racine du projet :
```
kubectl create -f manifest_ansible.yaml
```
version: '3.8'
services:
seed:
image: europe-west9-docker.pkg.dev/devops-421107/voting-image/seed
container_name: seed
build:
context: ./seed-data
networks:
- front-tier
depends_on:
- nginx
- result
result:
image: europe-west9-docker.pkg.dev/devops-421107/voting-image/result
container_name: result
build:
context: ./result
ports:
- "4000:4200"
networks:
- front-tier
- back-tier
depends_on:
- postgres
environment:
- PORT=4200
vote:
image: europe-west9-docker.pkg.dev/devops-421107/voting-image/vote
container_name: vote
build:
context: ./vote
ports:
- "5000:5000"
networks:
- front-tier
- back-tier
depends_on:
- redis
environment:
- REDIS_HOST=redis
- REDIS_PORT=6379
vote1:
container_name: vote1
build:
context: ./vote
ports:
- "5001:5000"
networks:
- front-tier
- back-tier
depends_on:
- redis
environment:
- REDIS_HOST=redis
- REDIS_PORT=6379
worker:
image: europe-west9-docker.pkg.dev/devops-421107/voting-image/worker
container_name: worker
build:
context: ./worker
networks:
- back-tier
depends_on:
- redis
- postgres
environment:
- REDIS_HOST=redis
- REDIS_PORT=6379
- TARGETPLATFORM=linux-x64
- TARGETARCH=x64
nginx:
# image: europe-west9-docker.pkg.dev/devops-421107/voting-image/nginx
container_name: nginx
build:
context: ./nginx
ports:
- "8000:8000"
- "80:80"
networks:
- front-tier
depends_on:
- vote
postgres:
container_name: db
image: postgres:15-alpine
volumes:
- db-data:/var/lib/postgresql/data
networks:
- back-tier
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=postgres
redis:
container_name: redis
image: redis:alpine
volumes:
- ./healthchecks:/healthchecks
healthcheck:
test: [ "CMD", "/bin/sh", "/healthchecks/redis.sh" ]
interval: 10s
timeout: 5s
retries: 3
networks:
- back-tier
networks:
front-tier:
back-tier:
volumes:
db-data:
\ No newline at end of file
#!/bin/bash
set -eo pipefail
host="$(hostname -i || echo '127.0.0.1')"
user="${POSTGRES_USER:-postgres}"
db="${POSTGRES_DB:-$POSTGRES_USER}"
export PGPASSWORD="${POSTGRES_PASSWORD:-}"
args=(
# force postgres to not use the local unix socket (test "external" connectibility)
--host "$host"
--username "$user"
--dbname "$db"
--quiet --no-align --tuples-only
)
if select="$(echo 'SELECT 1' | psql "${args[@]}")" && [ "$select" = '1' ]; then
exit 0
fi
exit 1
#!/bin/sh
set -eo pipefail
host="$(hostname -i || echo '127.0.0.1')"
if ping="$(redis-cli -h "$host" ping)" && [ "$ping" = 'PONG' ]; then
exit 0
fi
exit 1
Source diff could not be displayed: it is too large. Options to address this: view the blob.
This diff is collapsed.
FROM nginx
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
EXPOSE 8000
\ No newline at end of file
events {
worker_connections 5000;
}
http {
upstream loadbalancer {
least_conn;
server vote:5000;
server vote1:5000;
}
server {
listen 0.0.0.0:80;
listen 0.0.0.0:8000;
location / {
proxy_pass http://loadbalancer;
}
}
}
node_modules/
[ZoneTransfer]
ZoneId=3
FROM node:18-slim
WORKDIR /usr/local/app
COPY package.json .
RUN npm install -g nodemon \
&& npm install \
&& npm cache clean --force
ENV PORT=4000
ENV DB_HOST=34.163.42.86
ENV DB_PORT=5432
ENV DB_USER=postgres
ENV DB_PASS=postgres
ENV DB_NAME=postgres
EXPOSE ${PORT}
COPY . .
CMD [ "node", "server.js" ]
This diff is collapsed.
{
"name": "result",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "MIT",
"dependencies": {
"async": "^3.1.0",
"cookie-parser": "^1.4.6",
"express": "^4.18.2",
"method-override": "^3.0.0",
"pg": "^8.8.0",
"socket.io": "^4.7.2",
"stoppable": "^1.1.0"
}
}
var express = require('express'),
async = require('async'),
{ Pool } = require('pg'),
cookieParser = require('cookie-parser'),
app = express(),
server = require('http').Server(app),
io = require('socket.io')(server);
var port = process.env.PORT || 4500;
io.on('connection', function (socket) {
socket.emit('message', { text : 'Welcome!' });
socket.on('subscribe', function (data) {
socket.join(data.channel);
});
});
var pool = new Pool({
connectionString: 'postgres://postgres:postgres@34.163.42.86/postgres'
});
async.retry(
{times: 1000, interval: 1000},
function(callback) {
pool.connect(function(err, client, done) {
if (err) {
console.error("Waiting for db");
console.log(err)
}
callback(err, client);
});
},
function(err, client) {
if (err) {
return console.error("Giving up");
}
console.log("Connected to db");
getVotes(client);
}
);
function getVotes(client) {
client.query('SELECT vote, COUNT(id) AS count FROM votes GROUP BY vote', [], function(err, result) {
if (err) {
console.error("Error performing query: " + err);
} else {
var votes = collectVotesFromResult(result);
io.sockets.emit("scores", JSON.stringify(votes));
}
setTimeout(function() {getVotes(client) }, 1000);
});
}
function collectVotesFromResult(result) {
var votes = {a: 0, b: 0};
result.rows.forEach(function (row) {
votes[row.vote] = parseInt(row.count);
});
return votes;
}
app.use(cookieParser());
app.use(express.urlencoded());
app.use(express.static(__dirname + '/views'));
app.get('/', function (req, res) {
res.sendFile(path.resolve(__dirname + '/views/index.html'));
});
server.listen(port, function () {
var port = server.address().port;
console.log('App running on port ' + server.address() + ":" + port);
});
This diff is collapsed.
var app = angular.module('catsvsdogs', []);
var socket = io.connect();
var bg1 = document.getElementById('background-stats-1');
var bg2 = document.getElementById('background-stats-2');
app.controller('statsCtrl', function($scope){
$scope.aPercent = 50;
$scope.bPercent = 50;
var updateScores = function(){
socket.on('scores', function (json) {
data = JSON.parse(json);
var a = parseInt(data.a || 0);
var b = parseInt(data.b || 0);
var percentages = getPercentages(a, b);
bg1.style.width = percentages.a + "%";
bg2.style.width = percentages.b + "%";
$scope.$apply(function () {
$scope.aPercent = percentages.a;
$scope.bPercent = percentages.b;
$scope.total = a + b;
});
});
};
var init = function(){
document.body.style.opacity=1;
updateScores();
};
socket.on('message',function(data){
init();
});
});
function getPercentages(a, b) {
var result = {};
if (a + b > 0) {
result.a = Math.round(a / (a + b) * 100);
result.b = 100 - result.a;
} else {
result.a = result.b = 50;
}
return result;
}
\ No newline at end of file
<!DOCTYPE html>
<html ng-app="catsvsdogs">
<head>
<meta charset="utf-8">
<title>Cats vs Dogs -- Result</title>
<base href="/index.html">
<meta name = "viewport" content = "width=device-width, initial-scale = 1.0">
<meta name="keywords" content="docker-compose, docker, stack">
<meta name="author" content="Docker">
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body ng-controller="statsCtrl" >
<div id="background-stats">
<div id="background-stats-1">
</div><!--
--><div id="background-stats-2">
</div>
</div>
<div id="content-container">
<div id="content-container-center">
<div id="choice">
<div class="choice cats">
<div class="label">Cats</div>
<div class="stat">{{aPercent | number:1}}%</div>
</div>
<div class="divider"></div>
<div class="choice dogs">
<div class="label">Dogs</div>
<div class="stat">{{bPercent | number:1}}%</div>
</div>
</div>
</div>
</div>
<div id="result">
<span ng-if="total == 0">No votes yet</span>
<span ng-if="total == 1">{{total}} vote</span>
<span ng-if="total >= 2">{{total}} votes</span>
</div>
<script src="socket.io.js"></script>
<script src="angular.min.js"></script>
<script src="app.js"></script>
</body>
</html>
This diff is collapsed.
@import url(//fonts.googleapis.com/css?family=Open+Sans:400,700,600);
*{
box-sizing:border-box;
}
html,body{
margin:0;
padding:0;
height:100%;
font-family: 'Open Sans';
}
body{
opacity:0;
transition: all 1s linear;
}
.divider{
height: 150px;
width:2px;
background-color: #C0C9CE;
position: relative;
top: 50%;
float: left;
transform: translateY(-50%);
}
#background-stats-1{
background-color: #2196f3;
}
#background-stats-2{
background-color: #00cbca;
}
#content-container{
z-index:2;
position:relative;
margin:0 auto;
display:table;
padding:10px;
max-width:940px;
height:100%;
}
#content-container-center{
display:table-cell;
text-align:center;
vertical-align:middle;
}
#result{
z-index: 3;
position: absolute;
bottom: 40px;
right: 20px;
color: #fff;
opacity: 0.5;
font-size: 45px;
font-weight: 600;
}
#choice{
transition: all 300ms linear;
line-height:1.3em;
background:#fff;
box-shadow: 10px 0 0 #fff, -10px 0 0 #fff;
vertical-align:middle;
font-size:40px;
font-weight: 600;
width: 450px;
height: 200px;
}
#choice a{
text-decoration:none;
}
#choice a:hover, #choice a:focus{
outline:0;
text-decoration:underline;
}
#choice .choice{
width: 49%;
position: relative;
top: 50%;
transform: translateY(-50%);
text-align: left;
padding-left: 50px;
}
#choice .choice .label{
text-transform: uppercase;
}
#choice .choice.dogs{
color: #00cbca;
float: right;
}
#choice .choice.cats{
color: #2196f3;
float: left;
}
#background-stats{
z-index:1;
height:100%;
width:100%;
position:absolute;
}
#background-stats div{
transition: width 400ms ease-in-out;
display:inline-block;
margin-bottom:-4px;
width:50%;
height:100%;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment