Skip to content

Commit

Permalink
add backend-server-naming key
Browse files Browse the repository at this point in the history
This fixes a small regression since v0.8: when dynamic scaling is disabled, backend servers were named with target's ip/port which give some context to logs. The behaviour is slightly different now: default value is sequence despite the dynamic update config, the admin/dev can change it using svc/ing annotation or globally using configmap.
  • Loading branch information
jcmoraisjr committed Jan 24, 2020
1 parent 407f51e commit d311cd6
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 2 deletions.
19 changes: 19 additions & 0 deletions docs/content/en/docs/configuration/keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ The table below describes all supported configuration keys.
| `auth-type` | "basic" | Backend | |
| [`backend-check-interval`](#health-check) | time with suffix | Backend | `2s` |
| [`backend-protocol`](#backend-protocol) | [h1\|h2\|h1-ssl\|h2-ssl] | Backend | `h1` |
| [`backend-server-naming`](#backend-server-naming) | [sequence\|ip\|pod] | Backend | `sequence` |
| [`backend-server-slots-increment`](#dynamic-scaling) | number of slots | Backend | `32` |
| [`balance-algorithm`](#balance-algorithm) | algorithm name | Backend | `roundrobin` |
| [`bind-fronting-proxy`](#bind) | ip + port | Global | |
Expand Down Expand Up @@ -467,6 +468,24 @@ See also:

---

## Backend server naming

| Configuration key | Scope | Default | Since |
|-------------------------|-----------|------------|---------|
| `backend-server-naming` | `Backend` | `sequence` | `v0.10` |

Configures how to name backend servers.

* `sequence`: Names backend servers with a prefixed number sequence: `srv001`, `srv002`, and so on. This is the default configuration and the preferred option if dynamic udpate is used. `seq` is an alias to `sequence`.
* `pod`: Uses the k8s pod name as the backend server name. This option doesn't work on backends whose [`service-upstream`](#service-upstream) is `true`, falling back to `sequence`.
* `ip`: Uses target's `<ip>:<port>` as the server name.

{{% alert title="Note" %}}
HAProxy Ingress won't refuse to change the default naming if dynamic update is `true`, this would however lead to undesired behaviour: empty slots would still be named as sequences, old-named backend servers will dynamically receive new workloads with new pod names or IP numbers which does not relates with the name anymore, making the naming useless, if not wrong.
{{% /alert %}}

---

## Balance algorithm

| Configuration key | Scope | Default | Since |
Expand Down
11 changes: 11 additions & 0 deletions pkg/converters/ingress/annotations/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"strconv"
"strings"

"github.com/jcmoraisjr/haproxy-ingress/pkg/converters/ingress/types"
ingtypes "github.com/jcmoraisjr/haproxy-ingress/pkg/converters/ingress/types"
ingutils "github.com/jcmoraisjr/haproxy-ingress/pkg/converters/ingress/utils"
hatypes "github.com/jcmoraisjr/haproxy-ingress/pkg/haproxy/types"
Expand Down Expand Up @@ -674,6 +675,16 @@ func (c *updater) buildBackendRewriteURL(d *backData) {
}
}

var epNamingRegex = regexp.MustCompile(`^(seq(uence)?|pod|ip)$`)

func (c *updater) buildBackendServerNaming(d *backData) {
// Only warning here. d.backend.EpNaming should be updated before backend.AcquireEndpoint()
naming := d.mapper.Get(types.BackBackendServerNaming)
if !epNamingRegex.MatchString(naming.Value) {
c.logger.Warn("ignoring invalid naming type '%s' on %s, using 'seq' instead", naming.Value, naming.Source)
}
}

func (c *updater) buildBackendSSL(d *backData) {
d.backend.TLS.AddCertHeader = d.mapper.Get(ingtypes.BackAuthTLSCertHeader).Bool()
if cfg := d.mapper.Get(ingtypes.BackSSLCiphersBackend); cfg.Source != nil {
Expand Down
42 changes: 42 additions & 0 deletions pkg/converters/ingress/annotations/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1209,6 +1209,48 @@ func TestRewriteURL(t *testing.T) {
}
}

func TestBackendServerNaming(t *testing.T) {
testCases := []struct {
source Source
naming string
logging string
}{
// 0
{
naming: "seq",
},
// 1
{
naming: "sequence",
},
// 2
{
source: Source{
Namespace: "default",
Name: "ing1",
Type: "ingress",
},
naming: "sequences",
logging: "WARN ignoring invalid naming type 'sequences' on ingress 'default/ing1', using 'seq' instead",
},
// 3
{
naming: "pod",
},
// 4
{
naming: "ip",
},
}
for _, test := range testCases {
c := setup(t)
d := c.createBackendData("default/app", &test.source, map[string]string{ingtypes.BackBackendServerNaming: test.naming}, map[string]string{})
c.createUpdater().buildBackendServerNaming(d)
c.logger.CompareLogging(test.logging)
c.teardown()
}
}

func TestBackendProtocol(t *testing.T) {
testCase := []struct {
source Source
Expand Down
1 change: 1 addition & 0 deletions pkg/converters/ingress/annotations/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ func (c *updater) UpdateBackendConfig(backend *hatypes.Backend, mapper *Mapper)
c.buildBackendProtocol(data)
c.buildBackendProxyProtocol(data)
c.buildBackendRewriteURL(data)
c.buildBackendServerNaming(data)
c.buildBackendSSL(data)
c.buildBackendSSLRedirect(data)
c.buildBackendTimeout(data)
Expand Down
1 change: 1 addition & 0 deletions pkg/converters/ingress/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func createDefaults() map[string]string {
types.HostTimeoutClient: "50s",
types.HostTimeoutClientFin: "50s",
//
types.BackBackendServerNaming: "sequence",
types.BackBackendServerSlotsInc: "1",
types.BackSlotsMinFree: "6",
types.BackBalanceAlgorithm: "roundrobin",
Expand Down
8 changes: 8 additions & 0 deletions pkg/converters/ingress/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,14 @@ func (c *converter) addBackend(source *annotations.Source, hostpath, fullSvcName
}
// Configure endpoints
if !found {
switch mapper.Get(ingtypes.BackBackendServerNaming).Value {
case "ip":
backend.EpNaming = hatypes.EpIPPort
case "pod":
backend.EpNaming = hatypes.EpTargetRef
default:
backend.EpNaming = hatypes.EpSequence
}
if mapper.Get(ingtypes.BackServiceUpstream).Bool() {
if addr, err := convutils.CreateSvcEndpoint(svc, port); err == nil {
backend.AcquireEndpoint(addr.IP, addr.Port, addr.TargetRef)
Expand Down
1 change: 1 addition & 0 deletions pkg/converters/ingress/types/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const (
BackAuthType = "auth-type"
BackBackendCheckInterval = "backend-check-interval"
BackBackendProtocol = "backend-protocol"
BackBackendServerNaming = "backend-server-naming"
BackBackendServerSlotsInc = "backend-server-slots-increment"
BackBalanceAlgorithm = "balance-algorithm"
BackBlueGreenBalance = "blue-green-balance"
Expand Down
15 changes: 14 additions & 1 deletion pkg/haproxy/types/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,21 @@ func (b *Backend) AddEmptyEndpoint() *Endpoint {
}

func (b *Backend) addEndpoint(ip string, port int, targetRef string) *Endpoint {
var name string
switch b.EpNaming {
case EpTargetRef:
names := strings.Split(targetRef, "/")
name = names[len(names)-1]
case EpIPPort:
if ip != "127.0.0.1" {
name = fmt.Sprintf("%s:%d", ip, port)
}
}
if name == "" {
name = fmt.Sprintf("srv%03d", len(b.Endpoints)+1)
}
endpoint := &Endpoint{
Name: fmt.Sprintf("srv%03d", len(b.Endpoints)+1),
Name: name,
IP: ip,
Port: port,
Target: fmt.Sprintf("%s:%d", ip, port),
Expand Down
13 changes: 12 additions & 1 deletion pkg/haproxy/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,16 @@ type HostTLSConfig struct {
TLSNotAfter time.Time
}

// EndpointNaming ...
type EndpointNaming int

// ...
const (
EpSequence EndpointNaming = iota
EpIPPort
EpTargetRef
)

// Backend ...
type Backend struct {
//
Expand All @@ -374,14 +384,15 @@ type Backend struct {
Name string
Port string
Endpoints []*Endpoint
BlueGreen BlueGreenConfig
EpNaming EndpointNaming
Paths []*BackendPath
PathsMap *HostsMap
//
// per backend config
//
AgentCheck AgentCheck
BalanceAlgorithm string
BlueGreen BlueGreenConfig
Cookie Cookie
CustomConfig []string
Dynamic DynBackendConfig
Expand Down

0 comments on commit d311cd6

Please sign in to comment.