Fix: Add a way to differentiate between bind and local address
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
14e437b11e
commit
e52865a029
4 changed files with 31 additions and 22 deletions
18
README.md
18
README.md
|
@ -63,28 +63,34 @@ healthCheck:
|
|||
path: /healthz
|
||||
tls: true
|
||||
|
||||
# Local Address and Port describes the IP and Port to bind the service
|
||||
# to. The Address given is used for the SNAT and therefore should for
|
||||
# example be the public IP of the machine
|
||||
localAddr: 203.0.113.1
|
||||
localPort: 443
|
||||
# Bind Address and Port describes the IP and Port to bind the service
|
||||
# to.
|
||||
bindAddr: 203.0.113.1
|
||||
bindPort: 443
|
||||
|
||||
# Proto describes which protocol should be routed (defaults to tcp)
|
||||
proto: tcp
|
||||
|
||||
# Targets is a list of routing targets which are checked for their
|
||||
# liveness status and if they are live, they are included in the NAT
|
||||
# rulesets.
|
||||
# Each target consists of an Address, a Port and a Weight. The weight
|
||||
# Each target consists of two Addresses, a Port and a Weight. The weight
|
||||
# is defined as an integer and increases / decreases the percentage
|
||||
# of the traffic that specific target will receive. (For example
|
||||
# setting all weights to 1 will distribute the traffic equally between
|
||||
# them, setting one to 2 will double the traffic to that target.)
|
||||
# The localAddr is used for the SNAT to map the source IP.
|
||||
targets:
|
||||
- addr: 10.1.2.4
|
||||
localAddr: 10.1.2.1
|
||||
port: 443
|
||||
weight: 1
|
||||
- addr: 10.1.2.5
|
||||
localAddr: 10.1.2.1
|
||||
port: 443
|
||||
weight: 1
|
||||
- addr: 10.1.2.6
|
||||
localAddr: 10.1.2.1
|
||||
port: 443
|
||||
weight: 1
|
||||
```
|
||||
|
|
|
@ -23,9 +23,9 @@ type (
|
|||
Service struct {
|
||||
Name string `yaml:"name"`
|
||||
HealthCheck ServiceHealthCheck `yaml:"healthCheck"`
|
||||
LocalAddr string `yaml:"localAddr"`
|
||||
LocalPort int `yaml:"localPort"`
|
||||
LocalProto string `yaml:"localProto"`
|
||||
BindAddr string `yaml:"bindAddr"`
|
||||
BindPort int `yaml:"bindPort"`
|
||||
Proto string `yaml:"proto"`
|
||||
Targets []Target `yaml:"targets"`
|
||||
}
|
||||
|
||||
|
@ -40,9 +40,10 @@ type (
|
|||
// Target represents a load-balancing target to route the traffic
|
||||
// to in case it is deemed alive
|
||||
Target struct {
|
||||
Addr string `yaml:"addr"`
|
||||
Port int `yaml:"port"`
|
||||
Weight int `yaml:"weight"`
|
||||
Addr string `yaml:"addr"`
|
||||
LocalAddr string `yaml:"localAddr"`
|
||||
Port int `yaml:"port"`
|
||||
Weight int `yaml:"weight"`
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -73,12 +74,12 @@ func Load(fn string) (cf File, err error) {
|
|||
return cf, nil
|
||||
}
|
||||
|
||||
// Proto evaluates the LocalProto and returns tcp if empty
|
||||
func (s Service) Proto() string {
|
||||
if s.LocalProto == "" {
|
||||
// Protocol evaluates the Proto and returns tcp if empty
|
||||
func (s Service) Protocol() string {
|
||||
if s.Proto == "" {
|
||||
return "tcp"
|
||||
}
|
||||
return s.LocalProto
|
||||
return s.Proto
|
||||
}
|
||||
|
||||
func (t Target) String() string { return fmt.Sprintf("%s:%d", t.Addr, t.Port) }
|
||||
|
|
|
@ -34,8 +34,9 @@ type (
|
|||
// with random distribution and given probability
|
||||
NATTarget struct {
|
||||
Addr string
|
||||
BindAddr string
|
||||
BindPort int
|
||||
LocalAddr string
|
||||
LocalPort int
|
||||
Port int
|
||||
Proto string
|
||||
Weight float64
|
||||
|
@ -182,8 +183,8 @@ func (c *Client) buildServiceTable(service string, cType chainType) (rules [][]s
|
|||
"--probability", strconv.FormatFloat(nt.Weight/weightLeft, 'f', probPrecision, probBitsize),
|
||||
|
||||
"-p", nt.Proto,
|
||||
"-d", nt.LocalAddr,
|
||||
"--dport", strconv.Itoa(nt.LocalPort),
|
||||
"-d", nt.BindAddr,
|
||||
"--dport", strconv.Itoa(nt.BindPort),
|
||||
|
||||
"-j", "DNAT",
|
||||
"--to-destination", fmt.Sprintf("%s:%d", nt.Addr, nt.Port),
|
||||
|
|
|
@ -67,11 +67,12 @@ func (m Monitor) updateRoutingTargets(checker healthcheck.Checker) (err error) {
|
|||
|
||||
tgt := iptables.NATTarget{
|
||||
Addr: t.Addr,
|
||||
LocalAddr: m.svc.LocalAddr,
|
||||
LocalPort: m.svc.LocalPort,
|
||||
BindAddr: m.svc.BindAddr,
|
||||
BindPort: m.svc.BindPort,
|
||||
LocalAddr: t.LocalAddr,
|
||||
Port: t.Port,
|
||||
Weight: float64(t.Weight),
|
||||
Proto: m.svc.Proto(),
|
||||
Proto: m.svc.Protocol(),
|
||||
}
|
||||
|
||||
if err := checker.Check(m.svc.HealthCheck.Settings, t); err != nil {
|
||||
|
|
Loading…
Reference in a new issue