A lua module for OpenResty, can dynamically update the upstreams from etcd and kubernetes.
Upstream realtime change from etcd or kubernetes apiserver, without reload.
Weighted round robin load balancing (not for kubernetes because of no weight settings of pod).
Healthcheck
Request statistics
REQUIREMENTS
openresty-1.9.11.1 and newer
balancer_by_lua
ngx.worker.id
lua-resty-http
cjson
USAGE
Prepare Etcd:
etcdctl set /v1/testing/services/${service_name}/${host}:${port} ${value}
The service_name is upstream's name, should be string.
The host is upstream's ip address, domain name not supported.
The port is upstream's port.
The value should be a json, if json parse error, will use the default value below:
weight: upstream peer weight as number, int or float.
check_url: for healthcheck, if enabled, checker will do http request to http://${host}:${port}${check_url}.
slow_start: number of seconds duration that the upstream peer's weight slowly increased from 0 to ${weight}
status: indicates the peer is up or down, must be up if you want the peer work, any other value means peer down.
Init the module:
lua_socket_log_errors off; # recommend
lua_package_path "/path/of/your/environment...";
lua_shared_dict lreu_shm 1m; # for global storage
lua_shared_dict lreu_shm_k8s 1m; # for global storage
init_worker_by_lua_block {
local syncer = require "lreu.syncer"
syncer.init({
etcd_host = "127.0.0.1",
etcd_port = 2379,
etcd_path = "/v1/testing/services/",
storage = ngx.shared.lreu_shm
})
-- if you want to use k8s
local syncer_k8s = require "lreu.syncer_k8s"
sycner_k8s.init({
apiserver_host = "127.0.0.1",
apiserver_port = "6443",
namespace = "default",
token = "the token",
storage = ngx.shared.lreu_shm_k8s
})
-- init the picker before using it in balancer_by_lua
local picker = require "lreu.picker"
-- you can use both etcd and k8s
picker.init(ngx.shared.lreu_shm, ngx.shared.lreu_shm_k8s, true, ngx.shared.hc)
-- if you want to use health check
local health = require "lreu.health"
health.init({
storage = ngx.shared.lreu_upstream,
healthcheck = {
enable = true,
timeout = 3,
interval = 5,
max_fails = 3,
ok_status = {200, 204, 301, 302, 401, 403, 404}
},
logcheck = {
enable = true,
interval = 5,
recover = 60
}
})
}
Use picker in upstream:
upstream test {
server 127.0.0.1:2222; # fake server
balancer_by_lua_block {
local balancer = require "ngx.balancer"
local picker = require "lreu.picker"
local s, err = u.rr("my_test_service")
if not s then
ngx.log(ngx.ERR, err)
return ngx.exit(500)
end
local ok, err = balancer.set_current_peer(s.host, s.port)
if not ok then
ngx.log(ngx.ERR, "failed to set current peer: " .. err)
return ngx.exit(500)
end
}
}
请发表评论