Skip to content

Commit

Permalink
Add load balancing method to transport server config
Browse files Browse the repository at this point in the history
  • Loading branch information
soneillf5 committed Apr 26, 2021
1 parent 40db5b5 commit d9bd9aa
Show file tree
Hide file tree
Showing 15 changed files with 366 additions and 23 deletions.
2 changes: 1 addition & 1 deletion cmd/nginx-ingress/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ func main() {
templateExecutorV2, *nginxPlus, isWildcardEnabled, plusCollector, *enablePrometheusMetrics, latencyCollector, *enableLatencyMetrics)
controllerNamespace := os.Getenv("POD_NAMESPACE")

transportServerValidator := cr_validation.NewTransportServerValidator(*enableTLSPassthrough, *enableSnippets)
transportServerValidator := cr_validation.NewTransportServerValidator(*enableTLSPassthrough, *enableSnippets, *nginxPlus)
virtualServerValidator := cr_validation.NewVirtualServerValidator(*nginxPlus)

lbcInput := k8s.NewLoadBalancerControllerInput{
Expand Down
147 changes: 147 additions & 0 deletions deployments/common/crds-v1beta1/k8s.nginx.org_transportservers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.5.0
creationTimestamp: null
name: transportservers.k8s.nginx.org
spec:
additionalPrinterColumns:
- JSONPath: .status.state
description: Current state of the TransportServer. If the resource has a valid status, it means it has been validated and accepted by the Ingress Controller.
name: State
type: string
- JSONPath: .status.reason
name: Reason
type: string
- JSONPath: .metadata.creationTimestamp
name: Age
type: date
group: k8s.nginx.org
names:
kind: TransportServer
listKind: TransportServerList
plural: transportservers
shortNames:
- ts
singular: transportserver
preserveUnknownFields: false
scope: Namespaced
subresources:
status: {}
validation:
openAPIV3Schema:
description: TransportServer defines the TransportServer resource.
type: object
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: TransportServerSpec is the spec of the TransportServer resource.
type: object
properties:
action:
description: Action defines an action.
type: object
properties:
pass:
type: string
host:
type: string
ingressClassName:
type: string
listener:
description: TransportServerListener defines a listener for a TransportServer.
type: object
properties:
name:
type: string
protocol:
type: string
serverSnippets:
type: string
sessionParameters:
description: SessionParameters defines session parameters.
type: object
properties:
timeout:
type: string
upstreamParameters:
description: UpstreamParameters defines parameters for an upstream.
type: object
properties:
connectTimeout:
type: string
nextUpstream:
type: boolean
nextUpstreamTimeout:
type: string
nextUpstreamTries:
type: integer
udpRequests:
type: integer
udpResponses:
type: integer
upstreams:
type: array
items:
description: Upstream defines an upstream.
type: object
properties:
failTimeout:
type: string
healthCheck:
description: HealthCheck defines the parameters for active Upstream HealthChecks.
type: object
properties:
enable:
type: boolean
fails:
type: integer
interval:
type: string
jitter:
type: string
passes:
type: integer
port:
type: integer
timeout:
type: string
loadBalancingMethod:
type: string
maxFails:
type: integer
name:
type: string
port:
type: integer
service:
type: string
status:
description: TransportServerStatus defines the status for the TransportServer resource.
type: object
properties:
message:
type: string
reason:
type: string
state:
type: string
version: v1alpha1
versions:
- name: v1alpha1
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
2 changes: 2 additions & 0 deletions deployments/common/crds/k8s.nginx.org_transportservers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ spec:
type: integer
timeout:
type: string
loadBalancingMethod:
type: string
maxFails:
type: integer
name:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ spec:
type: integer
timeout:
type: string
loadBalancingMethod:
type: string
maxFails:
type: integer
name:
Expand Down
5 changes: 5 additions & 0 deletions docs-web/configuration/transportserver-resource.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ service: secure-app
port: 8443
maxFails: 3
failTimeout: 30s
loadBalancingMethod: least_conn
```

```eval_rst
Expand Down Expand Up @@ -203,6 +204,10 @@ failTimeout: 30s
- The health check configuration for the Upstream. See the `health_check <https://nginx.org/en/docs/stream/ngx_stream_upstream_hc_module.html#health_check>`_ directive. Note: this feature is supported only in NGINX Plus.
- `healthcheck <#upstream-healthcheck>`_
- No
* - ``loadBalancingMethod``
- The method used to load balance the upstream servers. By default, connections are distributed between the servers using a weighted round-robin balancing method. See the `upstream <http://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#upstream>`_ section for available methods and their details.
- ``string``
- No

```

Expand Down
4 changes: 2 additions & 2 deletions internal/configs/parsing_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,12 @@ func validateHashLBMethod(method string) (string, error) {
keyWords := strings.Split(method, " ")

if keyWords[0] == "hash" {
if len(keyWords) == 2 || len(keyWords) == 3 && keyWords[2] == "consistent" {
if len(keyWords) == 2 || (len(keyWords) == 3 && keyWords[2] == "consistent") {
return method, nil
}
}

return "", fmt.Errorf("Invalid load balancing method: %q", method)
return "", fmt.Errorf("invalid load balancing method: %q", method)
}

// ParseBool ensures that the string value is a valid bool
Expand Down
18 changes: 16 additions & 2 deletions internal/configs/transportserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,21 @@ func generateStreamUpstream(upstream *conf_v1alpha1.Upstream, upstreamNamer *ups
}

return version2.StreamUpstream{
Name: name,
Servers: upsServers,
Name: name,
Servers: upsServers,
LoadBalancingMethod: generateLoadBalancingMethod(upstream.LoadBalancingMethod),
}
}

func generateLoadBalancingMethod(method string) string {
if method == "" {
// By default, if unspecified, Nginx uses the 'round_robin' load balancing method.
// We override this default which suits the Ingress Controller better.
return "random two least_conn"
}
if method == "round_robin" {
// By default, Nginx uses round robin. We select this method by not specifying any method.
return ""
}
return method
}
4 changes: 4 additions & 0 deletions internal/configs/transportserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ func TestGenerateTransportServerConfigForTCPSnippets(t *testing.T) {
ResourceNamespace: "default",
Service: "tcp-app-svc",
},
LoadBalancingMethod: "random two least_conn",
},
},
Server: version2.StreamServer{
Expand Down Expand Up @@ -196,6 +197,7 @@ func TestGenerateTransportServerConfigForTCP(t *testing.T) {
ResourceNamespace: "default",
Service: "tcp-app-svc",
},
LoadBalancingMethod: "random two least_conn",
},
},
Server: version2.StreamServer{
Expand Down Expand Up @@ -279,6 +281,7 @@ func TestGenerateTransportServerConfigForTLSPasstrhough(t *testing.T) {
ResourceNamespace: "default",
Service: "tcp-app-svc",
},
LoadBalancingMethod: "random two least_conn",
},
},
Server: version2.StreamServer{
Expand Down Expand Up @@ -368,6 +371,7 @@ func TestGenerateTransportServerConfigForUDP(t *testing.T) {
ResourceNamespace: "default",
Service: "udp-app-svc",
},
LoadBalancingMethod: "random two least_conn",
},
},
Server: version2.StreamServer{
Expand Down
4 changes: 3 additions & 1 deletion internal/configs/version2/nginx-plus.transportserver.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
upstream {{ $u.Name }} {
zone {{ $u.Name }} 256k;

random two least_conn;
{{ if $u.LoadBalancingMethod }}
{{ $u.LoadBalancingMethod }};
{{ end }}

{{ range $s := $u.Servers }}
server {{ $s.Address }} max_fails={{ $s.MaxFails }} fail_timeout={{ $s.FailTimeout }};
Expand Down
4 changes: 3 additions & 1 deletion internal/configs/version2/nginx.transportserver.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
upstream {{ $u.Name }} {
zone {{ $u.Name }} 256k;

random two least_conn;
{{ if $u.LoadBalancingMethod }}
{{ $u.LoadBalancingMethod }};
{{ end }}

{{ range $s := $u.Servers }}
server {{ $s.Address }} max_fails={{ $s.MaxFails }} fail_timeout={{ $s.FailTimeout }};
Expand Down
7 changes: 4 additions & 3 deletions internal/configs/version2/stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ type TransportServerConfig struct {

// StreamUpstream defines a stream upstream.
type StreamUpstream struct {
Name string
Servers []StreamUpstreamServer
UpstreamLabels UpstreamLabels
Name string
Servers []StreamUpstreamServer
UpstreamLabels UpstreamLabels
LoadBalancingMethod string
}

// StreamUpstreamServer defines a stream upstream server.
Expand Down
2 changes: 1 addition & 1 deletion internal/k8s/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func createTestConfiguration() *Configuration {
80: true,
443: true,
}),
validation.NewTransportServerValidator(isTLSPassthroughEnabled, snippetsEnabled),
validation.NewTransportServerValidator(isTLSPassthroughEnabled, snippetsEnabled, isPlus),
isTLSPassthroughEnabled,
)
}
Expand Down
13 changes: 7 additions & 6 deletions pkg/apis/configuration/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,13 @@ type TransportServerListener struct {

// Upstream defines an upstream.
type Upstream struct {
Name string `json:"name"`
Service string `json:"service"`
Port int `json:"port"`
FailTimeout string `json:"failTimeout"`
MaxFails *int `json:"maxFails"`
HealthCheck *HealthCheck `json:"healthCheck"`
Name string `json:"name"`
Service string `json:"service"`
Port int `json:"port"`
FailTimeout string `json:"failTimeout"`
MaxFails *int `json:"maxFails"`
HealthCheck *HealthCheck `json:"healthCheck"`
LoadBalancingMethod string `json:"loadBalancingMethod"`
}

// HealthCheck defines the parameters for active Upstream HealthChecks.
Expand Down
Loading

0 comments on commit d9bd9aa

Please sign in to comment.