From 89d8de586a70cbf63df5c7ff814c0acd582e94b8 Mon Sep 17 00:00:00 2001 From: Michael Pleshakov Date: Thu, 16 Aug 2018 11:25:56 +0100 Subject: [PATCH] Support TCP/UDP load balancing - Add stream-snippets configmap key - Add stream-log-format configmap key --- examples/customization/README.md | 2 ++ examples/customization/nginx-config.yaml | 9 +++++++++ nginx-controller/Dockerfile | 1 + nginx-controller/DockerfileForAlpine | 1 + nginx-controller/DockerfileForPlus | 1 + nginx-controller/nginx/config.go | 12 ++++++++++++ nginx-controller/nginx/configurator.go | 2 ++ nginx-controller/nginx/nginx.go | 2 ++ nginx-controller/nginx/templates/nginx-plus.tmpl | 16 ++++++++++++++++ nginx-controller/nginx/templates/nginx.tmpl | 16 ++++++++++++++++ .../nginx/templates/templates_test.go | 2 ++ 11 files changed, 64 insertions(+) diff --git a/examples/customization/README.md b/examples/customization/README.md index 852b8d63e4..3a9d93c898 100644 --- a/examples/customization/README.md +++ b/examples/customization/README.md @@ -67,6 +67,8 @@ The table below summarizes all of the options. For some of them, there are examp | `nginx.com/health-checks-mandatory-queue` | N/A | When active health checks are mandatory, configures a queue for temporary storing incoming requests during the time when NGINX Plus is checking the health of the endpoints after a configuration reload. | `0` | [Support for Active Health Checks](../health-checks). | | `nginx.com/slow-start` | N/A | Sets the upstream server [slow-start period](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/#server-slow-start). By default, slow-start is activated after a server becomes [available](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/#passive-health-checks) or [healthy](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/#active-health-checks). To enable slow-start for newly added servers, configure [mandatory active health checks](../health-checks). | `"0s"` | | | N/A | `external-status-address` | Sets the address to be reported in the status of Ingress resources. Requires the `-report-status` command-line argument. Overrides the `-external-service` argument. | N/A | [Report Ingress Status](../../docs/report-ingress-status.md). | +| N/A | `stream-snippets` | Sets a custom snippet in stream context. | N/A | | +| N/A | `stream-log-format` | Sets the custom [log format](http://nginx.org/en/docs/stream/ngx_stream_log_module.html#log_format) for TCP/UDP load balancing. | See the [template file](../../nginx-controller/nginx/nginx.conf.tmpl). | | ## Using ConfigMaps diff --git a/examples/customization/nginx-config.yaml b/examples/customization/nginx-config.yaml index 37952c1d99..3eb12325ca 100644 --- a/examples/customization/nginx-config.yaml +++ b/examples/customization/nginx-config.yaml @@ -57,3 +57,12 @@ data: keepalive: "32" # default is 0. When > 0, sets the value of the keepalive directive and adds 'proxy_set_header Connection "";' to a location block. See http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive max-fails: "0" # default is 1. Sets the value of the max_fails parameter of the `server` directive. See https://nginx.org/en/docs/http/ngx_http_upstream_module.html#max_fails fail-timeout: "5s" # default is 10s. Sets the value of the fail_timeout parameter of the `server` directive. See https://nginx.org/en/docs/http/ngx_http_upstream_module.html#fail_timeout + stream-log-format: "$remote_addr $protocol" # stream-log-format default is set in the nginx.conf.tmpl file. Also see http://nginx.org/en/docs/stream/ngx_stream_log_module.html#log_format + stream-snippets: | + upstream tcp-coffee { + server tcp-coffee-svc.default.svc.cluster.local:9944; + } + server { + listen 4456; + proxy_pass tcp-coffee; + } diff --git a/nginx-controller/Dockerfile b/nginx-controller/Dockerfile index 512a9a4cf9..d3e5ffebf1 100644 --- a/nginx-controller/Dockerfile +++ b/nginx-controller/Dockerfile @@ -3,6 +3,7 @@ FROM nginx:1.15.2 # forward nginx access and error logs to stdout and stderr of the ingress # controller process RUN ln -sf /proc/1/fd/1 /var/log/nginx/access.log \ + && ln -sf /proc/1/fd/1 /var/log/nginx/stream-access.log \ && ln -sf /proc/1/fd/2 /var/log/nginx/error.log COPY nginx-ingress nginx/templates/nginx.ingress.tmpl nginx/templates/nginx.tmpl / diff --git a/nginx-controller/DockerfileForAlpine b/nginx-controller/DockerfileForAlpine index 36eb23da32..08e44b88c7 100644 --- a/nginx-controller/DockerfileForAlpine +++ b/nginx-controller/DockerfileForAlpine @@ -3,6 +3,7 @@ FROM nginx:1.15.2-alpine # forward nginx access and error logs to stdout and stderr of the ingress # controller process RUN ln -sf /proc/1/fd/1 /var/log/nginx/access.log \ + && ln -sf /proc/1/fd/1 /var/log/nginx/stream-access.log \ && ln -sf /proc/1/fd/2 /var/log/nginx/error.log COPY nginx-ingress nginx/templates/nginx.ingress.tmpl nginx/templates/nginx.tmpl / diff --git a/nginx-controller/DockerfileForPlus b/nginx-controller/DockerfileForPlus index 23f0cddeb0..3e8530bdce 100644 --- a/nginx-controller/DockerfileForPlus +++ b/nginx-controller/DockerfileForPlus @@ -44,6 +44,7 @@ RUN set -x \ # forward nginx access and error logs to stdout and stderr of the ingress # controller process RUN ln -sf /proc/1/fd/1 /var/log/nginx/access.log \ + && ln -sf /proc/1/fd/1 /var/log/nginx/stream-access.log \ && ln -sf /proc/1/fd/2 /var/log/nginx/error.log diff --git a/nginx-controller/nginx/config.go b/nginx-controller/nginx/config.go index ba9f7730d2..83b12a95bd 100644 --- a/nginx-controller/nginx/config.go +++ b/nginx-controller/nginx/config.go @@ -21,9 +21,11 @@ type Config struct { SSLRedirect bool MainMainSnippets []string MainHTTPSnippets []string + MainStreamSnippets []string MainServerNamesHashBucketSize string MainServerNamesHashMaxSize string MainLogFormat string + MainStreamLogFormat string ProxyBuffering bool ProxyBuffers string ProxyBufferSize string @@ -259,6 +261,9 @@ func ParseConfigMap(cfgm *api_v1.ConfigMap, nginxPlus bool) *Config { if logFormat, exists := cfgm.Data["log-format"]; exists { cfg.MainLogFormat = logFormat } + if streamLogFormat, exists := cfgm.Data["stream-log-format"]; exists { + cfg.MainStreamLogFormat = streamLogFormat + } if proxyBuffering, exists, err := GetMapKeyAsBool(cfgm.Data, "proxy-buffering", cfgm); exists { if err != nil { glog.Error(err) @@ -346,5 +351,12 @@ func ParseConfigMap(cfgm *api_v1.ConfigMap, nginxPlus bool) *Config { if ingressTemplate, exists := cfgm.Data["ingress-template"]; exists { cfg.IngressTemplate = &ingressTemplate } + if mainStreamSnippets, exists, err := GetMapKeyAsStringSlice(cfgm.Data, "stream-snippets", cfgm, "\n"); exists { + if err != nil { + glog.Error(err) + } else { + cfg.MainStreamSnippets = mainStreamSnippets + } + } return cfg } diff --git a/nginx-controller/nginx/configurator.go b/nginx-controller/nginx/configurator.go index 21a6b18e92..34a66a65a3 100644 --- a/nginx-controller/nginx/configurator.go +++ b/nginx-controller/nginx/configurator.go @@ -1082,9 +1082,11 @@ func GenerateNginxMainConfig(config *Config) *NginxMainConfig { nginxCfg := &NginxMainConfig{ MainSnippets: config.MainMainSnippets, HTTPSnippets: config.MainHTTPSnippets, + StreamSnippets: config.MainStreamSnippets, ServerNamesHashBucketSize: config.MainServerNamesHashBucketSize, ServerNamesHashMaxSize: config.MainServerNamesHashMaxSize, LogFormat: config.MainLogFormat, + StreamLogFormat: config.MainStreamLogFormat, SSLProtocols: config.MainServerSSLProtocols, SSLCiphers: config.MainServerSSLCiphers, SSLDHParam: config.MainServerSSLDHParam, diff --git a/nginx-controller/nginx/nginx.go b/nginx-controller/nginx/nginx.go index 83116bd9e4..0dab7192e7 100644 --- a/nginx-controller/nginx/nginx.go +++ b/nginx-controller/nginx/nginx.go @@ -142,9 +142,11 @@ type NginxMainConfig struct { ServerNamesHashBucketSize string ServerNamesHashMaxSize string LogFormat string + StreamLogFormat string HealthStatus bool MainSnippets []string HTTPSnippets []string + StreamSnippets []string // http://nginx.org/en/docs/http/ngx_http_ssl_module.html SSLProtocols string SSLPreferServerCiphers bool diff --git a/nginx-controller/nginx/templates/nginx-plus.tmpl b/nginx-controller/nginx/templates/nginx-plus.tmpl index dbbb12bd67..63887bbefa 100644 --- a/nginx-controller/nginx/templates/nginx-plus.tmpl +++ b/nginx-controller/nginx/templates/nginx-plus.tmpl @@ -108,3 +108,19 @@ http { include /etc/nginx/conf.d/*.conf; } + +stream { + {{if .StreamLogFormat -}} + log_format stream-main '{{.StreamLogFormat}}'; + {{- else -}} + log_format stream-main '$remote_addr [$time_local] ' + '$protocol $status $bytes_sent $bytes_received ' + '$session_time'; + {{- end }} + + access_log /var/log/nginx/stream-access.log stream-main; + + {{range $value := .StreamSnippets}} + {{$value}} + {{end}} +} \ No newline at end of file diff --git a/nginx-controller/nginx/templates/nginx.tmpl b/nginx-controller/nginx/templates/nginx.tmpl index 83537dc87d..4367cd9168 100644 --- a/nginx-controller/nginx/templates/nginx.tmpl +++ b/nginx-controller/nginx/templates/nginx.tmpl @@ -84,3 +84,19 @@ http { include /etc/nginx/conf.d/*.conf; } + +stream { + {{if .StreamLogFormat -}} + log_format stream-main '{{.StreamLogFormat}}'; + {{- else -}} + log_format stream-main '$remote_addr [$time_local] ' + '$protocol $status $bytes_sent $bytes_received ' + '$session_time'; + {{- end }} + + access_log /var/log/nginx/stream-access.log stream-main; + + {{range $value := .StreamSnippets}} + {{$value}} + {{end}} +} \ No newline at end of file diff --git a/nginx-controller/nginx/templates/templates_test.go b/nginx-controller/nginx/templates/templates_test.go index 3bc291515c..27796d538e 100644 --- a/nginx-controller/nginx/templates/templates_test.go +++ b/nginx-controller/nginx/templates/templates_test.go @@ -88,6 +88,8 @@ var mainCfg = nginx.NginxMainConfig{ WorkerShutdownTimeout: "1m", WorkerConnections: "1024", WorkerRlimitNofile: "65536", + StreamSnippets: []string{"# comment"}, + StreamLogFormat: "$remote_addr", } func TestIngressForNGINXPlus(t *testing.T) {