-
Notifications
You must be signed in to change notification settings - Fork 0
/
nginx.tpl.conf
104 lines (97 loc) · 3.69 KB
/
nginx.tpl.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
{{ $configJSON := env "PROXY_CONFIG" }}
{{ if not $configJSON }}{{ fail "PROXY_CONFIG environment variable is not set" }}{{ end }}
{{- $config := env "PROXY_CONFIG" | decode_json -}}
worker_processes auto;
daemon off;
pid /run/nginx.pid;
user root;
error_log /dev/stderr warn;
worker_rlimit_nofile 65536;
env PROXY_CONFIG;
events {
worker_connections 16384;
multi_accept on;
accept_mutex off;
use epoll;
}
stream {
log_format proxy '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
access_log /dev/stdout proxy;
init_worker_by_lua_block {
cjson = require "cjson"
upstreams = {}
for _, server in pairs(cjson.decode(os.getenv("PROXY_CONFIG"))) do
upstreams[tostring(server.port)] = {
upstream = server.upstream,
counter = 0,
servers = {}
}
end
local function update()
local function updateUpstream(_, us)
local resolver = require "resty.dns.resolver"
local r, err = resolver:new{
nameservers = { "169.254.169.253" },
retrans = 5,
timeout = 2000,
}
if not r then
ngx.log(ngx.ERR, "failed to instantiate the resolver: ", err)
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
local answers, err = r:query(us.upstream, {qtype = r.TYPE_SRV})
local ttl = 60
if not answers then
ngx.log(ngx.ERR, "cannot resolve: ", us.upstream, ", err: ", err)
elseif answers.errcode then
ngx.log(ngx.ERR, "cannot resolve: ", us.upstream, ", err: ", answers.errstr)
else
local ans = answers[1]
local answers, err = r:query(ans.target, {qtype = r.TYPE_A})
if err then
ngx.log(ngx.ERR, "cannot resolve: ", us.upstream, ", err: ", err)
elseif answers.errcode then
ngx.log(ngx.ERR, "cannot resolve: ", us.upstream, ", err: ", answers.errstr)
end
ttl = tonumber(ans.ttl)
local servers = {}
for _, v in ipairs(answers) do
table.insert(servers, { host = v.address, port = ans.port })
end
us["servers"] = servers
end
ngx.timer.at(ttl, updateUpstream, us)
end
for port, us in pairs(upstreams) do
ngx.timer.at(0, updateUpstream, us)
end
end
ngx.timer.at(0, update)
}
upstream us {
server 0.0.0.0:1;
balancer_by_lua_block {
local upstream = upstreams[tostring(ngx.var.server_port)]
if not upstream then
ngx.exit(ngx.HTTP_SERVICE_UNAVAILABLE)
end
if not upstream.servers then
ngx.exit(ngx.HTTP_SERVICE_UNAVAILABLE)
end
-- round robin
local server = upstream.servers[math.fmod(upstream.counter, table.getn(upstream.servers)) + 1]
upstream.counter = upstream.counter + 1
local balancer = require "ngx.balancer"
balancer.set_current_peer(server.host, server.port)
}
}
{{ range $k, $server := $config -}}
server {
listen 0.0.0.0:{{ $server.port }};
proxy_pass us;
}
{{ end -}}
}