Tame the Cat
Einen eigenen Tomcat Server zu betreiben, kann unter gewissen Umständen ein aufwendiges und mühsames Unterfangen sein.
Daher haben wir mithilfe von Puppet ein eigenes Tomcat-Hosting-Profil entwickelt. Dabei greifen wir auf das bestehende Puppet Modul von Puppetlabs zurück. Ziel dieses Puppetmodules ist es, in kurzer Zeit einen Tomcatserver bereitzustellen, der alle nötigen Konfigurationen beinhaltet sowie in einer einheitlichen und standardisierten Art und Weise aufgesetzt ist. So soll ein Update der Tomcat Version einfach und schnell möglich sein.
In diesem Blog-Post erläutern wir kurz, was unser Puppet-Modul alles kann und zeigen auf, wie einfach es ist, eine neue Tomcat Instanz aufzusetzen.
Architektur
Bevor wir zur Beschreibung des eigentlichen Moduls kommen, zeigen wir kurz auf, welche Komponenten installiert und konfiguriert werden.
Im oben stehenden Diagramm sehen wir die Grundarchitektur eines klassischen Tomcathostings.
Wir verwenden für unser Setup:
- ein Nginx als Reverse-Proxy für die SSL-Terminierung
- optional Varnish für das Caching
- Mysql/Mariadb und/oder PostgreSQL als Datenbank-Server
Der komplette Server lässt sich dabei in einem yaml-file konfigurieren:
---
classes:
- profile_tomcathosting
profile_tomcathosting::servers:
'tomcat8.5.15':
source_url: 'http://www-eu.apache.org/dist/tomcat/tomcat-8/v8.5.15/bin/apache-tomcat-8.5.15.tar.gz'
'tomcat7':
source_url: 'http://www-eu.apache.org/dist/tomcat/tomcat-7/v7.0.78/bin/apache-tomcat-7.0.78.tar.gz'
profile_tomcathosting::db_root_pw: 'mySuperS3cretR00tPw'
profile_tomcathosting::varnish_version: '4.1'
profile_tomcathosting::varnish_template: 'profile_tomcathosting/varnish/defaultv4.vcl.erb'
profile_tomcathosting::tomcat_base: '/home'
tomcathosting_sites:
'mytomcathosting':
server_name: 'mytomcathosting.com'
db_password: 'anothergre@tp@$w0rd'
use_static: true
use_varnish: true
use_mariadb: true
manage_tls: 'letsencrypt'
offset: 1
suppress_version: false
tomcat_server: 'tomcat8.5.15'
'legacy_tomcathosting':
server_name: 'legacy-tomcathosting.com'
db_password: 'myother_dbP@$swort'
use_static: false
use_varnish: false
use_mariadb: false
use_postgresql: true
manage_tls: 'letsencrypt'
offset: 2
suppress_version: true
tomcat_server: 'tomcat7'
Dies reicht schon, um einen Server mit Tomcat7
sowie Tomcat8
zu installieren, sowie zwei Instanzen, die jeweils einen der beiden installierten Tomcats verwendet.
Die Konfiguration im oben stehenden Listing installiert unter /opt/tomcat8.5.15
sowie unter /opt/tomcat7
jeweils einen Tomcat. So werden zwei neue User angelegt (mytomcathosting
und legacy_tomcathosting
) mit dem Homeverzeichnis unter /home
(default ist /var/lib/tomcat
, wenn tomcat_base
nicht angegeben wird). Dort wird von Puppet im Unterordner tomcat/
die Verzeichnisstruktur für eine Tomcatinstanz eingerichtet. Des Weiteren erstellt Puppet auch die Konfigurationsdateien von Tomcat im Ordner: tomcat/config/.
Für mytomcathosting wird zusätzlich ein Ordner static
im Homeverzeichnis angelegt.
Wenn wir uns die generierte nginx config
genauer ansehen, sehen wir, dass für mytomcathosting
eine zusätzliche Location für static content
konfiguriert wurde. Zudem leitet die proxy_pass Direktive
nicht zur Tomcatinstanz, sondern zum installierten Varnish. Damit Varnish die verschiedenen vhosts unterscheiden kann, setzten wir zusätzlich den varnish_host Header
:
mytomcathosting.com Nginx config server
{
listen *:443 ssl ;
server_name mytomcathosting.com;
ssl on;
ssl_certificate /etc/ssl/certs/mytomcathosting.com-chained.pem;
ssl_certificate_key /etc/ssl/private/mytomcathosting.com-key.pem;
ssl_dhparam /etc/ssl/dh4096.pem;
[...]
add_header Strict-Transport-Security max-age=31536000;
location /static/ {
root /home/mytomcathosting/;
index index.html index.htm index.php;
}
location / {
proxy_pass ;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_redirect off;
proxy_set_header varnish_host mytomcathosting;
proxy_set_header Host mytomcathosting.com;
proxy_set_header X-Scheme $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Server-IP $server_addr;
proxy_set_header X-Forwarded-Server-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Client-IP $remote_addr;
proxy_set_header Proxy "";
}
}
legacy-tomcathosting.com Nginx config server
{
listen *:443 ssl ;
server_name legacy-tomcathosting.com;
ssl on;
ssl_certificate /etc/ssl/certs/legacy-tomcathosting.com-chained.pem;
ssl_certificate_key /etc/ssl/private/legacy-tomcathosting.com-key.pem;
ssl_dhparam /etc/ssl/dh4096.pem;
[...]
add_header Strict-Transport-Security max-age=31536000;
location / {
proxy_pass ;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_redirect off;
proxy_set_header Host legacy-tomcathosting.com;
proxy_set_header X-Scheme $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Server-IP $server_addr;
proxy_set_header X-Forwarded-Server-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Client-IP $remote_addr;
proxy_set_header Proxy "";
}
}
Die angegebenen Zertifikate wurden via Let’s Encrypt erstellt und werden automatisch erneuert.
Zusätzlich wird für mytomcathosting
eine mariadb Datenbank und für legacy-tomcathosting
eine PostgresSQL Datenbank konfiguriert. Damit sichergestellt ist, dass die Tomcat Instanzen auch laufen, erstellt unser Puppet Modul Systemd Unit-Files. Dabei wird als CATALINA_HOME
der Pfad zum ausgewählten Tomcatserver verwendet und als CATALINA_BASE
der Pfad zum Tomcatverzeichnis der Instanz.
Das Unitfile für mytomcathosting sieht daher wie folgt aus:
mytomcathosting Unitfile
[Unit]
Description=tomcat-mytomcathosting Service
[Service]
ExecStart=/opt/tomcat8.5.15/bin/catalina.sh start
ExecStop=/opt/tomcat8.5.15/bin/catalina.sh stop
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=tomcat-mytomcathosting
User=%i
Type=forking
Environment="CATALINA_HOME=/opt/tomcat8.5.15" "CATALINA_BASE=/home/mytomcathosting/tomcat"
[Install]
WantedBy=multi-user.target
Backup und Monitoring
Backup und Monitoring gehören bei uns zur Selbstverständlichkeit. So wird jede konfigurierte Instanz automatisch ins Backup aufgenommen (User Homeverzeichnis, sowie DB Dumps). Monitoringchecks, die überprüfen, ob die Tomcat Instanzen laufen, werden automatisch eingerichtet. Ebenfalls vollautomatisch wird geprüft, ob der konfigurierte Servername erreichbar ist und einen validen HTTP Code zurückgibt.
Tomcat aktualisieren
Eine bestehende Instanz auf eine neuere Tomcatversion zu aktualisieren ist sehr einfach und in wenigen Minuten erledigt. Dabei muss nur im profile_tomcathosting::servers
Hash ein neuer Server mit der gewünschten Version installiert werden und dann in der zu aktualisierenden Instanz im tomcat_server
Feld referenziert werden. Sollte ein Tomcat Server nicht mehr verwendet werden, kann dieser durch das Setzen des ensure:
‘absent’ Parameters im profile_tomcathosting::servers
Hash einfach entfernt werden.
Fazit
Der Betrieb einer Tomcatumgebung ist dank unserem Puppet Modul sehr einfach, schnell und zuverlässig. Dank dem modularen Aufbau der Puppet Module, können wir mit sehr geringem Aufwand verschiedene Tomcat Szenarien abdecken. In nur 15 Minuten können wir eine neue VM (z.b. bei Cloudscale.ch) hochfahren und mit Puppet so konfigurieren, dass wir eine einsatzbereite Tomcatumgebung haben.