Répartition de charge EoleSSO en mode cluster
Cette documentation a pour but de décrire la mise en place d'une configuration HAProxy afin de pouvoir mettre plusieurs services EoleSSO en cluster et de gérer la répartition de charge.
Cette documentation décrit également la mise en place de 2 services pour suivre les métriques d'EoleSSO :
Prometheus : https://prometheus.io/
Grafana : https://grafana.net/
On suppose l’existence de 3 serveurs EoleSSO qui écoutent sur le port 443 dont les DNS sont les suivants :
sso-1.ac-academie.fr
;sso-2.ac-academie.fr
;sso-3.ac-academie.fr
.
Un quatrième serveur doit héberger le service ha-proxy avec pour nom DNS sso-ha.ac-academie.fr
.
Attention
Le serveur hébergeant le service ha-proxy du cluster doit avoir un nom de domaine différent de celui du cluster de serveur web même si les 2 noms de domaine pointent sur la même adresse IP.
Remarque
Pour maintenir et déployer la configuration (certificats pour stunnel, metadata, filtres, thèmes, CSS, attributs calculés) sur les différents serveurs EoleSSO il est possible d'utiliser Ansible.
Installation d'HAProxy
Sur le serveur sso-ha.ac-academie.fr
:
# apt-eole install haproxy
Configuration d'HAProxy
Procéder à la configuration basique d'HAProxy (non détaillée ici).
Éditer le fichier de configuration /etc/haproxy/haproxy.cfg et ajouter les lignes suivantes :
global
...
# Les serveurs étant gérés par vous, la vérification ssl peut être désactivée
ssl-server-verify none
frontend https-in
bind <IP DU SERVEUR SSO-HA>:443 ssl crt <CHEMIN DU CERTIFICAT PEM>
option forwardfor
redirect scheme https if !{ ssl_fc }
default_backend sso_servers
backend sso_servers
balance roundrobin
cookie SSONAME insert indirect nocache
server sso-1.ac-academie.fr sso-1.ac-academie.fr:443 ssl cookie sso1 check
server sso-2.ac-academie.fr sso-2.ac-academie.fr:443 ssl cookie sso2 check
server sso-3.ac-academie.fr sso-3.ac-academie.fr:443 ssl cookie sso3 check
Remarque
<IP DU SERVEUR SSO-HA> : est à remplacer par l'adresse IP de votre serveur HAProxy
<CHEMIN DU CERTIFICAT PEM> : chemin du certificat + key
Attention
Penser à redémarrer le service haproxy :
# service haproxy restart
Mise en place de Prometheus et de Grafana
Il faut mettre en place un serveur Prometheus qui sera chargé de collecter les données fournies par nos serveurs EoleSSO et mettre en place Grafana pour avoir un visuel des métriques.
Pour des raisons de simplicité, des micro-services docker sont utilisés pour fournir ces deux applications, aussi il faut installer les paquets docker
et docker-compose
.
Remarque
Il peut être intéressant de dissocier ces services du serveur HAPproxy, car il pourrait servir à d'autres serveurs, ce serveur de monitoring porte le nom DNS monitoring.ac-academie.fr
.
ExempleExemple de configuration de Prometheus
Exemple de configuration, contenu dans le fichier /shared/prometheus/monitoring-compose.yml
:
prometheus:
image: prom/prometheus
ports:
- 9090:9090
volumes:
- /shared/prometheus/etc/:/etc/prometheus/
- /shared/prometheus/data/:/prometheus
grafana:
image: grafana/grafana:4.1.1
ports:
- 3000:3000
volumes:
- /shared/prometheus/grafana/:/var/lib/grafana/
env_file:
- /shared/prometheus/grafana.config.monitoring
Configuration de Prometheus
Le fichier de configuration de prometheus /shared/prometheus/etc/prometheus.yml
contient :
global:
scrape_interval: 60s
scrape_configs:
- job_name: "eole_sso"
metrics_path: /metrics
scheme: https
tls_config:
insecure_skip_verify: true
static_configs:
- targets:
- sso-1.ac-academie.fr
- sso-2.ac-academie.fr
- sso-3.ac-academie.fr
Configuration de Grafana
Configuration de Grafana dans le fichier /shared/prometheus/grafana.config.monitoring
GF_SECURITY_ADMIN_PASSWORD=VOTRE_MOT_DE_PASSE_ADMIN
GF_USERS_ALLOW_SIGN_UP=false
http_proxy=PROXY_HOST:PROXY_PORT
https_proxy=PROXY_HOST:PROXY_PORT
Remarque
Modifier les valeurs de :
VOTRE_MOT_DE_PASSE_ADMIN
PROXY_HOST
PROXY_PORT
Truc & astuce
La documentation de Grafana décrit les paramètres possibles :
ExempleJSON pour le tableau de bord Grafana
{
"annotations": {
"list": []
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"hideControls": false,
"id": 16,
"links": [],
"refresh": "1m",
"rows": [
{
"collapse": false,
"height": 237,
"panels": [
{
"aliasColors": {
"sso-3": "#82B5D8",
"sso-1": "#7EB26D",
"sso-2": "#EAB839"
},
"bars": false,
"datasource": null,
"editable": true,
"error": false,
"fill": 7,
"grid": {},
"id": 9,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 0,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": true,
"steppedLine": false,
"targets": [
{
"expr": "eolesso_login_gauge",
"intervalFactor": 2,
"legendFormat": "{{host}}",
"metric": "eolesso_login_gauge",
"refId": "A",
"step": 120
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "Nombre de tickets de login (TicketCache)",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"bars": true,
"datasource": null,
"editable": true,
"error": false,
"fill": 10,
"grid": {},
"id": 4,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": false,
"linewidth": 0,
"links": [],
"nullPointMode": "null as zero",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": true,
"steppedLine": true,
"targets": [
{
"expr": "(rate(eolesso_sessions_new_counter[10m]))*60*2",
"intervalFactor": 2,
"legendFormat": "{{host}} [{{authclass}}]",
"metric": "eolesso_sessions_new_counter",
"refId": "A",
"step": 120
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "Nb connexions/s",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {
"sso-3": "#82B5D8",
"sso-1": "#7EB26D",
"sso-2": "#EAB839"
},
"bars": false,
"datasource": null,
"editable": true,
"error": false,
"fill": 3,
"grid": {},
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": true,
"steppedLine": false,
"targets": [
{
"expr": "eolesso_sessions_nb_gauge",
"intervalFactor": 1,
"legendFormat": "{{host}}",
"metric": "eolesso_sessions_gauge",
"refId": "A",
"step": 60
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "Nombre de tickets de sessions (auth)",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"repeat": null,
"repeatIteration": null,
"repeatRowId": null,
"showTitle": false,
"title": "Row",
"titleSize": "h6"
},
{
"collapse": false,
"height": "250px",
"panels": [
{
"aliasColors": {
"sso-3": "#82B5D8",
"sso-1": "#7EB26D",
"sso-2": "#EAB839"
},
"bars": false,
"datasource": null,
"editable": true,
"error": false,
"fill": 7,
"grid": {},
"id": 7,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": true,
"steppedLine": true,
"targets": [
{
"expr": "eolesso_calcdata_gauge",
"intervalFactor": 2,
"legendFormat": "{{host}}",
"metric": "eolesso_calcdata_gauge",
"refId": "A",
"step": 60
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "taille du cache des attributs calculés",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "decbytes",
"label": "Octets",
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {
"sso-3": "#82B5D8",
"sso-1": "#7EB26D",
"sso-2": "#EAB839"
},
"bars": false,
"datasource": null,
"editable": true,
"error": false,
"fill": 5,
"grid": {},
"id": 8,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": true,
"steppedLine": false,
"targets": [
{
"expr": "eolesso_userdata_gauge",
"intervalFactor": 2,
"legendFormat": "{{host}}",
"metric": "eolesso_userdata_gauge",
"refId": "A",
"step": 60
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "taille du cache des attributs ldap",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "decbytes",
"label": "Octets",
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"repeat": null,
"repeatIteration": null,
"repeatRowId": null,
"showTitle": false,
"title": "New row",
"titleSize": "h6"
},
{
"collapse": false,
"height": "250px",
"panels": [
{
"aliasColors": {
"sso.ac-reunion.fr:4430": "#82B5D8",
"sso.ac-reunion.fr:4431": "#E5A8E2",
"sso.ac-reunion.fr:4432": "#AEA2E0"
},
"bars": false,
"datasource": null,
"editable": true,
"error": false,
"fill": 0,
"grid": {},
"id": 3,
"legend": {
"alignAsTable": true,
"avg": false,
"current": true,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null as zero",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "process_virtual_memory_bytes{job='eole_sso'}",
"intervalFactor": 2,
"legendFormat": "{{instance}}",
"refId": "A",
"step": 60
}
],
"thresholds": [
{
"colorMode": "critical",
"fill": true,
"line": true,
"op": "gt",
"value": 1517522817
}
],
"timeFrom": null,
"timeShift": null,
"title": "Mémoire utilisée",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "bytes",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {
"sso-3": "#82B5D8",
"sso-1": "#7EB26D",
"sso-2": "#EAB839"
},
"bars": false,
"datasource": null,
"editable": true,
"error": false,
"fill": 4,
"grid": {},
"id": 1,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": true,
"steppedLine": false,
"targets": [
{
"expr": "eolesso_appticket_gauge{job='eole_sso'}",
"intervalFactor": 2,
"legendFormat": "{{host}}",
"metric": "eolesso_appticket_gauge",
"refId": "A",
"step": 60
}
],
"thresholds": [],
"timeFrom": null,
"timeShift": null,
"title": "Nombre de Tickets applicatifs (AppTicket)",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"repeat": null,
"repeatIteration": null,
"repeatRowId": null,
"showTitle": false,
"title": "New row",
"titleSize": "h6"
}
],
"schemaVersion": 14,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-12h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "browser",
"title": "SSO Copy",
"version": 0
}
Monitoring
Lancer l'environnement de monitoring
# cd /shared/prometheus/
# docker-compose -f prometheus-compose.yml start
Par défaut Grafana écoute sur le port 3000 et Prometheus sur le port 9090