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
|
path: /healthz
|
||||||
tls: true
|
tls: true
|
||||||
|
|
||||||
# Local Address and Port describes the IP and Port to bind the service
|
# Bind 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
|
# to.
|
||||||
# example be the public IP of the machine
|
bindAddr: 203.0.113.1
|
||||||
localAddr: 203.0.113.1
|
bindPort: 443
|
||||||
localPort: 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
|
# 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
|
# liveness status and if they are live, they are included in the NAT
|
||||||
# rulesets.
|
# 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
|
# is defined as an integer and increases / decreases the percentage
|
||||||
# of the traffic that specific target will receive. (For example
|
# of the traffic that specific target will receive. (For example
|
||||||
# setting all weights to 1 will distribute the traffic equally between
|
# setting all weights to 1 will distribute the traffic equally between
|
||||||
# them, setting one to 2 will double the traffic to that target.)
|
# 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:
|
targets:
|
||||||
- addr: 10.1.2.4
|
- addr: 10.1.2.4
|
||||||
|
localAddr: 10.1.2.1
|
||||||
port: 443
|
port: 443
|
||||||
weight: 1
|
weight: 1
|
||||||
- addr: 10.1.2.5
|
- addr: 10.1.2.5
|
||||||
|
localAddr: 10.1.2.1
|
||||||
port: 443
|
port: 443
|
||||||
weight: 1
|
weight: 1
|
||||||
- addr: 10.1.2.6
|
- addr: 10.1.2.6
|
||||||
|
localAddr: 10.1.2.1
|
||||||
port: 443
|
port: 443
|
||||||
weight: 1
|
weight: 1
|
||||||
```
|
```
|
||||||
|
|
|
@ -23,9 +23,9 @@ type (
|
||||||
Service struct {
|
Service struct {
|
||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
HealthCheck ServiceHealthCheck `yaml:"healthCheck"`
|
HealthCheck ServiceHealthCheck `yaml:"healthCheck"`
|
||||||
LocalAddr string `yaml:"localAddr"`
|
BindAddr string `yaml:"bindAddr"`
|
||||||
LocalPort int `yaml:"localPort"`
|
BindPort int `yaml:"bindPort"`
|
||||||
LocalProto string `yaml:"localProto"`
|
Proto string `yaml:"proto"`
|
||||||
Targets []Target `yaml:"targets"`
|
Targets []Target `yaml:"targets"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ type (
|
||||||
// to in case it is deemed alive
|
// to in case it is deemed alive
|
||||||
Target struct {
|
Target struct {
|
||||||
Addr string `yaml:"addr"`
|
Addr string `yaml:"addr"`
|
||||||
|
LocalAddr string `yaml:"localAddr"`
|
||||||
Port int `yaml:"port"`
|
Port int `yaml:"port"`
|
||||||
Weight int `yaml:"weight"`
|
Weight int `yaml:"weight"`
|
||||||
}
|
}
|
||||||
|
@ -73,12 +74,12 @@ func Load(fn string) (cf File, err error) {
|
||||||
return cf, nil
|
return cf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proto evaluates the LocalProto and returns tcp if empty
|
// Protocol evaluates the Proto and returns tcp if empty
|
||||||
func (s Service) Proto() string {
|
func (s Service) Protocol() string {
|
||||||
if s.LocalProto == "" {
|
if s.Proto == "" {
|
||||||
return "tcp"
|
return "tcp"
|
||||||
}
|
}
|
||||||
return s.LocalProto
|
return s.Proto
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Target) String() string { return fmt.Sprintf("%s:%d", t.Addr, t.Port) }
|
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
|
// with random distribution and given probability
|
||||||
NATTarget struct {
|
NATTarget struct {
|
||||||
Addr string
|
Addr string
|
||||||
|
BindAddr string
|
||||||
|
BindPort int
|
||||||
LocalAddr string
|
LocalAddr string
|
||||||
LocalPort int
|
|
||||||
Port int
|
Port int
|
||||||
Proto string
|
Proto string
|
||||||
Weight float64
|
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),
|
"--probability", strconv.FormatFloat(nt.Weight/weightLeft, 'f', probPrecision, probBitsize),
|
||||||
|
|
||||||
"-p", nt.Proto,
|
"-p", nt.Proto,
|
||||||
"-d", nt.LocalAddr,
|
"-d", nt.BindAddr,
|
||||||
"--dport", strconv.Itoa(nt.LocalPort),
|
"--dport", strconv.Itoa(nt.BindPort),
|
||||||
|
|
||||||
"-j", "DNAT",
|
"-j", "DNAT",
|
||||||
"--to-destination", fmt.Sprintf("%s:%d", nt.Addr, nt.Port),
|
"--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{
|
tgt := iptables.NATTarget{
|
||||||
Addr: t.Addr,
|
Addr: t.Addr,
|
||||||
LocalAddr: m.svc.LocalAddr,
|
BindAddr: m.svc.BindAddr,
|
||||||
LocalPort: m.svc.LocalPort,
|
BindPort: m.svc.BindPort,
|
||||||
|
LocalAddr: t.LocalAddr,
|
||||||
Port: t.Port,
|
Port: t.Port,
|
||||||
Weight: float64(t.Weight),
|
Weight: float64(t.Weight),
|
||||||
Proto: m.svc.Proto(),
|
Proto: m.svc.Protocol(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := checker.Check(m.svc.HealthCheck.Settings, t); err != nil {
|
if err := checker.Check(m.svc.HealthCheck.Settings, t); err != nil {
|
||||||
|
|
Loading…
Reference in a new issue