In our landscape for S/4Hana systems we use dedicated servers. They are provided by Hetzner Online GmbH.
As any responsible company we have an adequate backup solution paired with a RAID configuration. We keep our backups both on Hetzner servers and as an additional safety measure on Amazon S3.
Unfortunately this does not give full protection against hardware malfunctions of components such as the motherboard, RAM or CPU.
We also keep a secondary SAP instance on AWS EC2. In case our Hetzner server would be completely inaccessible. We can quickly bring the AWS EC2 instance online with the usage of backups kept on AWS S3. Our configuration was already described before here:
Enterprise applications with optimized costs – SAP HANA-based systems on Hetzner Online
All this leaves us with the issue of providing the users with information on how to connect to the server. Giving them new configuration after every time we start the AWS EC2 instance would be confusing and disruptive. To overcome that we use HAProxy. This way the users get only one configuration and we can use that to redirect them to the server of our choice.
Instalation
The deployment of HAProxy is quite straight forward. We use a Ubuntu server also hosted on AWS EC2. Before installation first we check the available version by:
apt show haproxy
The standard repository offers a bit older version, the currently supported version are:
To overcome that we add a new repository for HAproxy by:
add-apt-repository ppa:vbernat/haproxy-1.8
Next we update our apt configuration by:
apt-get update
Now when we check again the available version is higher:
apt show haproxy
What’s left is to install the package by:
apt-get install haproxy
You can check if its installed corectly by
haproxy -v
Configuration
First backup the configuration file by:
cp -rp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.backup
Now we can start reconfiguring. For this I use vi but nano is also a good editor if you prefer it.
vi /etc/haproxy/haproxy.cfg
Below is the configuration we use:
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
defaults
log global
mode tcp
option tcplog
option dontlognull
timeout connect 5000
timeout client 5h
timeout server 5h
balance roundrobin
listen sh1
bind proxy1.domain.com:3202
server sh1_host 52.58.185.145:3202 check
server sh2_failover 35.157.123.181:3202 check
listen stats
bind :80
mode http
stats enable
stats hide-version
stats realm Haproxy\ Statistics
stats uri /
stats auth haproxy:<password>
stats refresh 5s
Parameter description
Let’s describe the entries in the config file in more depth.
Program parameters
The first section is called
global. Here are the settings defining the operation of the program as a process. I left this as default. This part of the config shows parameters responsible for running the process as a daemon, there is a group and a user defined for that. Also logging is configured here. The default config will log to /var/log/haproxy.log.
Default parameters
The section name is called
defaults - this settings are inherited by the sections frontend/backend/listen. But can be changed individually for all of them.
I redefined most of the parameters here:
mode tcp
default is http and is not best suited for SAPGui
option tcplog
this will enable advanced logging of TCP connections, default was httplog
option dontlognull
omit logs for sessions for which no data were exchanged between the client and the server
timeout connect 5000
the time limit for a successful server connection in ms
timeout client 5h & timeout server 5h
those two parameters were set to 5h (hours) so session with SAPGui will not be terminated too soon, default was 5 minutes
balance roundrobin
this will select servers in turns one after another
Connections configuration
Connections can be configured in sections called frontend and backend. But as we use a more basic configuration – those two sections can be combined into one.
The combine section name is
listen sh1. I used listen <sid>, but this can be defined according to your preferences.
bind
this defines incoming connections along with the tcp port. I used a DNS entry but IP will also work. If using DNS remember entries must also be defined in /etc/hosts.
server
here you define a unique name for the entry and where the connections should be routed to. An additional parameter for server is check. It forces an availability check of a given connection before switching the traffic to it
Additional connections
To configure more frontend/listen section it is not possible to use DNS aliases pointing to one IP (this option is only supported for HTTP/HTTP protocols).
To have multiple server clusters working on one HAProxy instance they need to be connected via differed ports or IPs.
The following configuration can be added to the file:
listen <sidN>
bind proxyN.domain.com:3200
server <sidN>1 <IP of first server>:3200 check
server <sidN>2 <IP of next server>:3200 check
The limitation is that proxyN.domain.com can’t point to the same address as the previous one proxy1.domain.com. A separate IP is required (additional NIC will be needed).
Alternatively when using the same IP (one NIC) the port needs to be changed to a different one. For example if in previous listen section 3200 was used, now 3201 should be selected:
listen <sidN>
bind proxyN.domain.com:3201
server <sidN>1 <IP of first server>:3200 check
server <sidN>2 <IP of next server>:3200 check
Monitoring
HAProxy also has built in monitoring capabilities with the use of a web interface. The interface looks like this:
The section responsible for it in the our configuration is called
listen stats.
This section is not mandatory for our main purpose but is nice to have. You define here among other things the port on which the console will be working. I used the standard http port. You also define the username and password as well as the time interval for refreshing the site.
In our case you enter the console by going to the address
http:<HAProxy server IP>:<definedport><defined uri>
, for egzample:
http://proxy1.domain.com/