Setting up Drove Gateway¶
The Drove Gateway works as a gateway to expose apps running on a drove cluster to rest of the world.
Drove Gateway container uses NGinx and a modified version of Nixy to track drove endpoints. More details about this can be found in the drove-gateway project.
Drove Gateway Nixy Configuration Reference¶
The nixy running inside the gateway container is configured using a custom TOML file. This section looks into this file:
address = "127.0.0.1"# (1)!
port = "6000"
# Drove Options
drove = [#(2)!
"http://controller1.mydomain:10000",
"http://controller1.mydomain:10000"
]
leader_vhost = "drove-staging.mydomain"#(3)!
event_refresh_interval_sec = 5#(5)!
user = ""#(6)!
pass = ""
access_token = ""#(7)!
# Parameters to control which apps are exposed as VHost
routing_tag = "externally_exposed"#(4)!
realm = "api.mydomain,support.mydomain"#(8)!
realm_suffix = "-external.mydomain"#(9)!
# Nginx related config
nginx_config = "/etc/nginx/nginx.conf"#(10)!
nginx_template = "/etc/drove/gateway/nginx.tmpl"#(11)!
nginx_cmd = "nginx"#(12)!
nginx_ignore_check = true#(13)!
# NGinx plus specific options
nginxplusapiaddr="127.0.0.1"#(14)!
nginx_reload_disabled=true#(15)!
maxfailsupstream = 0#(16)!
failtimeoutupstream = "1s"
slowstartupstream = "0s"
-
Nixy listener configuration. Endpoint for nixy itself.
-
List of Drove controllers. Add all controller nodes here. Nixy will automatically determine and track the current leader.
Auto detection is disabled if a single endpoint is specified.
-
Helps create a vhost entry that tracks the leader on the cluster. Use this to expose the Drove endpoint to users. The value for this will be available to the template engine as the
LeaderVHost
variable. -
If some special routing behaviour needs to be implemented in the template based on some tag metadata of the deployed apps, set the routing_tag option to set the tag name to be used. The actual value is derived from app instances and exposed to the template engine as the variable:
RoutingTag
. Optional.In this example, the RoutingTag variable will be set to the value specified in the
routing_tag
tag key specified when deploying the Drove Application. For example, if we want to expose the app we can set it toyes
, and filter the VHost to be exposed in NGinx template whenRoutingTag == "yes"
. -
Drove Gateway/Nixy works on event polling on controller. This is the polling interval. Especially if number of NGinx nodes is high. Default is
2 seconds
. Unless cluster is really busy with a high rate of change of containers, this strikes a good balance between apps becoming discoverable vs putting the leader controller under heavy load. -
user
andpass
are optional params can be used to set basic auth credentials to the calls made to Drove controllers if basic auth is enabled on the cluster. Leave empty if no basic auth is required. -
If cluster has some custom header based auth, the following can be used. The contents on this parameter are passed verbatim to the Authorization HTTP header. Leave empty if no token auth is enabled on the cluster.
-
By default drove-gateway will expose all vhost declared in the spec for all drove apps on a cluster (caveat: filtering can be done using RoutingTag as well). If specific vhosts need to be exposed, set the realms parameter to a comma separated list of realms. Optional.
-
Beside perfect vhost matching, Drove Gateway supports suffix based matches as well. A single suffix is supported. Optional.
-
Path to NGinx config.
-
Path to the template file, based on which the template will be generated.
-
NGinx command to use to reload the config. Set this to
openresty
optionally to use openresty. -
Ignore calling NGinx command to test the config. Set this to false or delete this line on production. Default: false.
-
If using NGinx plus, set the endpoint to the local server here. If left empty, NGinx plus api based vhost update will be disabled.
-
If specific vhosts are exposed, auto-discovery and updation of config (and NGinx reloads) might not be desired as it will cause connection drops. Set the following parameter to true to disable reloads. Nixy will only update upstreams using the nplus APIs. Default: false.
-
Connection parameters for NGinx plus.
NGinx plus
NGinx plus is not shipped with this docker. If you want to use NGinx plus, please build nixy from the source tree here and build your own container.
Relevant directories¶
Location for data and logs are as follows:
/etc/drove/gateway/
- Configuration files/var/log/drove/gateway/
- NGinx Logs
We shall be volume mounting the config and log directories with the same name.
Prerequisite Setup
If not done already, please complete the prerequisite setup on all machines earmarked for the cluster.
Go through the following steps to run drove-gateway
as a service.
Create the TOML config for Nixy¶
Sample config file /etc/drove/gateway/gateway.toml
:
address = "127.0.0.1"
port = "6000"
# Drove Options
drove = [
"http://controller1.mydomain:10000",
"http://controller1.mydomain:10000"
]
leader_vhost = "drove-staging.mydomain"
event_refresh_interval_sec = 5
user = "guest"
pass = "guest"
# Nginx related config
nginx_config = "/etc/nginx/nginx.conf"
nginx_template = "/etc/drove/gateway/nginx.tmpl"
nginx_cmd = "nginx"
nginx_ignore_check = true
Replace domain names
Please remember to update mydomain
to a valid domain you want to use.
Create template for NGinx¶
Create a NGinx template with the following config in /etc/drove/gateway/nginx.tmpl
# Generated by drove-gateway {{datetime}}
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
use epoll;
worker_connections 2048;
multi_accept on;
}
http {
server_names_hash_bucket_size 128;
add_header X-Proxy {{ .Xproxy }} always;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
server_tokens off;
client_max_body_size 128m;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_redirect off;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# time out settings
proxy_send_timeout 120;
proxy_read_timeout 120;
send_timeout 120;
keepalive_timeout 10;
server {
listen 7000 default_server;
server_name _;
# Everything is a 503
location / {
return 503;
}
}
{{if and .LeaderVHost .Leader.Endpoint}}
upstream {{.LeaderVHost}} {
server {{.Leader.Host}}:{{.Leader.Port}};
}
server {
listen 7000;
server_name {{.LeaderVHost}};
location / {
proxy_set_header HOST {{.Leader.Host}};
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_connect_timeout 30;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_pass http://{{.LeaderVHost}};
}
}
{{end}}
{{- range $id, $app := .Apps}}
upstream {{$app.Vhost}} {
{{- range $app.Hosts}}
server {{ .Host }}:{{ .Port }};
{{- end}}
}
server {
listen 7000;
server_name {{$app.Vhost}};
location / {
proxy_set_header HOST $host;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_connect_timeout 30;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_pass http://{{$app.Vhost}};
}
}
{{- end}}
}
The above template will do the following:
- Set NGinx port to 7000. This is the port exposed on the Docker container for the gateway. Do not change this.
- Sets up error and access logs to
/var/log/nginx
. Log rotation is setup for this path already. - Set up a Vhost
drove-staging.mydomain
that will get auto-updated with the current leader of the Drove cluster - Setup automatically updated virtual hosts for all apps on the cluster.
Create environment file¶
We want to configure the drove gateway container using the required environment variables. To do that, put the following in /etc/drove/gateway/gateway.env
:
CONFIG_FILE_PATH=/etc/drove/gateway/gateway.toml
TEMPLATE_FILE_PATH=/etc/drove/gateway/nginx.tmpl
Create systemd file¶
Create a systemd
file. Put the following in /etc/systemd/system/drove.gateway.service
:
[Unit]
Description=Drove Gateway Service
After=docker.service
Requires=docker.service
[Service]
User=drove
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/docker pull ghcr.io/phonepe/drove-gateway:latest
ExecStart=/usr/bin/docker run \
--env-file /etc/drove/gateway/gateway.env \
--volume /etc/drove/gateway:/etc/drove/gateway:ro \
--volume /var/log/drove/gateway:/var/log/nginx \
--network host \
--hostname %H \
--rm \
--name drove.gateway \
ghcr.io/phonepe/drove-gateway:latest
[Install]
WantedBy=multi-user.target
Verify the file with the following command:
systemd-analyze verify drove.gateway.service
Set permissions
chmod 664 /etc/systemd/system/drove.gateway.service
Start the service on all servers¶
Use the following to start the service:
systemctl daemon-reload
systemctl enable drove.gateway
systemctl start drove.gateway
Checking Logs¶
You can check logs using:
journalctl -u drove.gateway -f
NGinx logs would be available at /var/log/drove/gateway
.
Log rotation for NGinx¶
The gateway sets up log rotation for the access and errors logs with the following config:
/var/log/nginx/*.log {
rotate 5
size 10M
dateext
dateformat -%Y-%m-%d
missingok
compress
delaycompress
sharedscripts
notifempty
postrotate
test -r /var/run/nginx.pid && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
This will rotate both error and access logs when they hit 10MB and keep 5 logs.
Configure the above if you want and volume mount your config to /etc/logrotate.d/nginx
to use different scheme as per your requirements.