2017-11-05 21:35:46 +00:00
/ *
Copyright 2017 The Kubernetes Authors .
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2017-11-05 01:18:28 +00:00
package main
import (
"flag"
"fmt"
"os"
2019-06-11 02:32:17 +00:00
"time"
2017-11-05 01:18:28 +00:00
"github.com/spf13/pflag"
apiv1 "k8s.io/api/core/v1"
2020-08-08 23:31:02 +00:00
"k8s.io/klog/v2"
2017-11-05 01:18:28 +00:00
2017-11-22 13:35:47 +00:00
"k8s.io/ingress-nginx/internal/ingress/annotations/class"
2017-11-23 16:46:23 +00:00
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
2017-11-07 22:02:12 +00:00
"k8s.io/ingress-nginx/internal/ingress/controller"
ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config"
2020-02-10 19:52:50 +00:00
"k8s.io/ingress-nginx/internal/ingress/status"
2017-11-07 22:02:12 +00:00
ing_net "k8s.io/ingress-nginx/internal/net"
2019-01-21 14:29:36 +00:00
"k8s.io/ingress-nginx/internal/nginx"
2017-11-05 01:18:28 +00:00
)
func parseFlags ( ) ( bool , * controller . Configuration , error ) {
var (
flags = pflag . NewFlagSet ( "" , pflag . ExitOnError )
2018-06-11 09:17:50 +00:00
apiserverHost = flags . String ( "apiserver-host" , "" ,
` Address of the Kubernetes API server .
Takes the form "protocol://address:port" . If not specified , it is assumed the
program runs inside a Kubernetes cluster and local discovery is attempted . ` )
2019-12-05 22:12:54 +00:00
rootCAFile = flags . String ( "certificate-authority" , "" ,
` Path to a cert file for the certificate authority . This certificate is used
only when the flag -- apiserver - host is specified . ` )
2018-06-11 09:17:50 +00:00
kubeConfigFile = flags . String ( "kubeconfig" , "" ,
` Path to a kubeconfig file containing authorization and API server information. ` )
2017-11-05 01:18:28 +00:00
defaultSvc = flags . String ( "default-backend-service" , "" ,
2018-06-11 09:17:50 +00:00
` Service used to serve HTTP requests not matching any known server name ( catch - all ) .
Takes the form "namespace/name" . The controller configures NGINX to forward
requests to the first port of this Service . ` )
2017-11-05 01:18:28 +00:00
ingressClass = flags . String ( "ingress-class" , "" ,
2018-06-11 09:17:50 +00:00
` Name of the ingress class this controller satisfies .
2020-03-31 14:14:03 +00:00
The class of an Ingress object is set using the field IngressClassName in Kubernetes clusters version v1 .18 .0 or higher or the annotation "kubernetes.io/ingress.class" ( deprecated ) .
2020-06-26 16:01:55 +00:00
If this parameter is not set it will handle ingresses with either an empty or "nginx" class name . ` )
2017-11-05 01:18:28 +00:00
configMap = flags . String ( "configmap" , "" ,
2018-06-11 09:17:50 +00:00
` Name of the ConfigMap containing custom global configurations for the controller. ` )
2017-11-05 01:18:28 +00:00
publishSvc = flags . String ( "publish-service" , "" ,
2018-06-11 09:17:50 +00:00
` Service fronting the Ingress controller .
Takes the form "namespace/name" . When used together with update - status , the
controller mirrors the address of this service ' s endpoints to the load - balancer
status of all Ingress objects it satisfies . ` )
2017-11-05 01:18:28 +00:00
2018-11-16 16:48:47 +00:00
tcpConfigMapName = flags . String ( "tcp-services-configmap" , "" ,
` Name of the ConfigMap containing the definition of the TCP services to expose .
The key in the map indicates the external port to be used . The value is a
reference to a Service in the form "namespace/name:port" , where "port" can
either be a port number or name . TCP ports 80 and 443 are reserved by the
controller for servicing HTTP traffic . ` )
udpConfigMapName = flags . String ( "udp-services-configmap" , "" ,
` Name of the ConfigMap containing the definition of the UDP services to expose .
The key in the map indicates the external port to be used . The value is a
reference to a Service in the form "namespace/name:port" , where "port" can
either be a port name or number . ` )
2018-06-13 12:47:09 +00:00
resyncPeriod = flags . Duration ( "sync-period" , 0 ,
` Period at which the controller forces the repopulation of its local object stores. Disabled by default. ` )
2017-11-05 01:18:28 +00:00
watchNamespace = flags . String ( "watch-namespace" , apiv1 . NamespaceAll ,
2018-06-11 09:17:50 +00:00
` Namespace the controller watches for updates to Kubernetes objects .
This includes Ingresses , Services and all configuration resources . All
namespaces are watched if this parameter is left empty . ` )
2017-11-05 01:18:28 +00:00
2018-06-11 09:17:50 +00:00
profiling = flags . Bool ( "profiling" , true ,
` Enable profiling via web interface host:port/debug/pprof/ ` )
2017-11-05 01:18:28 +00:00
2018-06-11 09:17:50 +00:00
defSSLCertificate = flags . String ( "default-ssl-certificate" , "" ,
` Secret containing a SSL certificate to be used by the default HTTPS server ( catch - all ) .
Takes the form "namespace/name" . ` )
2017-11-05 01:18:28 +00:00
2018-06-11 09:17:50 +00:00
defHealthzURL = flags . String ( "health-check-path" , "/healthz" ,
` URL path of the health check endpoint .
Configured inside the NGINX status server . All requests received on the port
defined by the healthz - port parameter are forwarded internally to this path . ` )
2017-11-05 01:18:28 +00:00
2019-06-11 02:32:17 +00:00
defHealthCheckTimeout = flags . Int ( "health-check-timeout" , 10 , ` Time limit, in seconds, for a probe to health-check-path to succeed. ` )
2018-10-24 20:02:28 +00:00
2018-06-11 09:17:50 +00:00
updateStatus = flags . Bool ( "update-status" , true ,
` Update the load - balancer status of Ingress objects this controller satisfies .
Requires setting the publish - service parameter to a valid Service reference . ` )
2017-11-05 01:18:28 +00:00
2018-06-11 09:17:50 +00:00
electionID = flags . String ( "election-id" , "ingress-controller-leader" ,
` Election id to use for Ingress status updates. ` )
2017-11-05 01:18:28 +00:00
2018-06-11 09:17:50 +00:00
updateStatusOnShutdown = flags . Bool ( "update-status-on-shutdown" , true ,
` Update the load - balancer status of Ingress objects when the controller shuts down .
Requires the update - status parameter . ` )
2017-11-05 01:18:28 +00:00
useNodeInternalIP = flags . Bool ( "report-node-internal-ip-address" , false ,
2018-06-11 09:17:50 +00:00
` Set the load - balancer status of Ingress objects to internal Node addresses instead of external .
Requires the update - status parameter . ` )
2017-11-05 01:18:28 +00:00
showVersion = flags . Bool ( "version" , false ,
2018-06-11 09:17:50 +00:00
` Show release information about the NGINX Ingress controller and exit. ` )
2017-11-05 01:18:28 +00:00
2018-06-11 09:17:50 +00:00
enableSSLPassthrough = flags . Bool ( "enable-ssl-passthrough" , false ,
` Enable SSL Passthrough. ` )
2017-11-08 20:58:57 +00:00
2018-06-11 09:17:50 +00:00
annotationsPrefix = flags . String ( "annotations-prefix" , "nginx.ingress.kubernetes.io" ,
` Prefix of the Ingress annotations specific to the NGINX controller. ` )
2017-11-13 01:43:28 +00:00
2019-01-11 17:43:02 +00:00
enableSSLChainCompletion = flags . Bool ( "enable-ssl-chain-completion" , false ,
2018-06-11 09:17:50 +00:00
` Autocomplete SSL certificate chains with missing intermediate CA certificates .
2019-07-04 22:06:55 +00:00
Certificates uploaded to Kubernetes must have the "Authority Information Access" X .509 v3
2018-06-11 09:17:50 +00:00
extension for this to succeed . ` )
2017-12-05 19:07:34 +00:00
syncRateLimit = flags . Float32 ( "sync-rate-limit" , 0.3 ,
` Define the sync frequency upper limit ` )
2018-02-27 03:02:19 +00:00
publishStatusAddress = flags . String ( "publish-status-address" , "" ,
2018-06-11 09:17:50 +00:00
` Customized address to set as the load - balancer status of Ingress objects this controller satisfies .
Requires the update - status parameter . ` )
2018-03-18 13:13:41 +00:00
2018-12-04 19:59:54 +00:00
enableMetrics = flags . Bool ( "enable-metrics" , true ,
` Enables the collection of NGINX metrics ` )
2018-12-21 17:10:28 +00:00
metricsPerHost = flags . Bool ( "metrics-per-host" , true ,
` Export metrics per-host ` )
2020-06-20 06:58:14 +00:00
monitorMaxBatchSize = flags . Int ( "monitor-max-batch-size" , 10000 , "Max batch size of NGINX metrics" )
2018-12-04 19:59:54 +00:00
2019-09-28 20:30:57 +00:00
httpPort = flags . Int ( "http-port" , 80 , ` Port to use for servicing HTTP traffic. ` )
httpsPort = flags . Int ( "https-port" , 443 , ` Port to use for servicing HTTPS traffic. ` )
2018-06-12 13:04:26 +00:00
sslProxyPort = flags . Int ( "ssl-passthrough-proxy-port" , 442 , ` Port to use internally for SSL Passthrough. ` )
2018-06-11 09:17:50 +00:00
defServerPort = flags . Int ( "default-server-port" , 8181 , ` Port to use for exposing the default server (catch-all). ` )
healthzPort = flags . Int ( "healthz-port" , 10254 , "Port to use for the healthz endpoint." )
2018-12-11 21:57:46 +00:00
disableCatchAll = flags . Bool ( "disable-catch-all" , false ,
` Disable support for catch-all Ingresses ` )
2019-02-21 19:45:21 +00:00
validationWebhook = flags . String ( "validating-webhook" , "" ,
` The address to start an admission controller on to validate incoming ingresses .
Takes the form "<host>:port" . If not provided , no admission controller is started . ` )
validationWebhookCert = flags . String ( "validating-webhook-certificate" , "" ,
` The path of the validating webhook certificate PEM. ` )
validationWebhookKey = flags . String ( "validating-webhook-key" , "" ,
` The path of the validating webhook key PEM. ` )
2019-09-28 20:30:57 +00:00
statusPort = flags . Int ( "status-port" , 10246 , ` Port to use for the lua HTTP endpoint configuration. ` )
streamPort = flags . Int ( "stream-port" , 10247 , "Port to use for the lua TCP/UDP endpoint configuration." )
profilerPort = flags . Int ( "profiler-port" , 10245 , "Port to use for expose the ingress controller Go profiler when it is enabled." )
2020-02-10 19:52:50 +00:00
statusUpdateInterval = flags . Int ( "status-update-interval" , status . UpdateInterval , "Time interval in seconds in which the status should check if an update is required. Default is 60 seconds" )
2017-11-05 01:18:28 +00:00
)
2020-01-08 22:46:43 +00:00
flags . StringVar ( & nginx . MaxmindLicenseKey , "maxmind-license-key" , "" , ` Maxmind license key to download GeoLite2 Databases .
https : //blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-geolite2-databases`)
2020-03-16 07:26:33 +00:00
flags . StringVar ( & nginx . MaxmindEditionIDs , "maxmind-edition-ids" , "GeoLite2-City,GeoLite2-ASN" , ` Maxmind edition ids to download GeoLite2 Databases. ` )
2020-01-08 22:46:43 +00:00
2017-11-05 01:18:28 +00:00
flag . Set ( "logtostderr" , "true" )
flags . AddGoFlagSet ( flag . CommandLine )
flags . Parse ( os . Args )
// Workaround for this issue:
// https://github.com/kubernetes/kubernetes/issues/17162
flag . CommandLine . Parse ( [ ] string { } )
2017-12-27 03:13:16 +00:00
pflag . VisitAll ( func ( flag * pflag . Flag ) {
2018-12-05 16:27:55 +00:00
klog . V ( 2 ) . Infof ( "FLAG: --%s=%q" , flag . Name , flag . Value )
2017-12-27 03:13:16 +00:00
} )
2017-11-05 01:18:28 +00:00
if * showVersion {
return true , nil , nil
}
2020-02-10 19:52:50 +00:00
if * statusUpdateInterval < 5 {
klog . Warningf ( "The defined time to update the Ingress status too low (%v seconds). Adjusting to 5 seconds" , * statusUpdateInterval )
status . UpdateInterval = 5
} else {
status . UpdateInterval = * statusUpdateInterval
}
2017-11-05 01:18:28 +00:00
if * ingressClass != "" {
2018-12-05 16:27:55 +00:00
klog . Infof ( "Watching for Ingress class: %s" , * ingressClass )
2017-11-05 01:18:28 +00:00
2017-11-22 13:35:47 +00:00
if * ingressClass != class . DefaultClass {
2018-12-05 16:27:55 +00:00
klog . Warningf ( "Only Ingresses with class %q will be processed by this Ingress controller" , * ingressClass )
2017-11-05 01:18:28 +00:00
}
2017-11-22 13:35:47 +00:00
class . IngressClass = * ingressClass
2017-11-05 01:18:28 +00:00
}
2017-11-23 16:46:23 +00:00
parser . AnnotationsPrefix = * annotationsPrefix
2017-11-05 01:18:28 +00:00
// check port collisions
if ! ing_net . IsPortAvailable ( * httpPort ) {
2019-07-08 20:10:38 +00:00
return false , nil , fmt . Errorf ( "port %v is already in use. Please check the flag --http-port" , * httpPort )
2017-11-05 01:18:28 +00:00
}
if ! ing_net . IsPortAvailable ( * httpsPort ) {
2019-07-08 20:10:38 +00:00
return false , nil , fmt . Errorf ( "port %v is already in use. Please check the flag --https-port" , * httpsPort )
2017-11-05 01:18:28 +00:00
}
if ! ing_net . IsPortAvailable ( * defServerPort ) {
2019-07-08 20:10:38 +00:00
return false , nil , fmt . Errorf ( "port %v is already in use. Please check the flag --default-server-port" , * defServerPort )
2017-11-05 01:18:28 +00:00
}
2019-09-28 20:30:57 +00:00
if ! ing_net . IsPortAvailable ( * statusPort ) {
return false , nil , fmt . Errorf ( "port %v is already in use. Please check the flag --status-port" , * statusPort )
}
if ! ing_net . IsPortAvailable ( * streamPort ) {
return false , nil , fmt . Errorf ( "port %v is already in use. Please check the flag --stream-port" , * streamPort )
}
if ! ing_net . IsPortAvailable ( * profilerPort ) {
return false , nil , fmt . Errorf ( "port %v is already in use. Please check the flag --profiler-port" , * profilerPort )
}
nginx . StatusPort = * statusPort
nginx . StreamPort = * streamPort
nginx . ProfilerPort = * profilerPort
2017-11-05 01:18:28 +00:00
if * enableSSLPassthrough && ! ing_net . IsPortAvailable ( * sslProxyPort ) {
2019-07-08 20:10:38 +00:00
return false , nil , fmt . Errorf ( "port %v is already in use. Please check the flag --ssl-passthrough-proxy-port" , * sslProxyPort )
2017-11-05 01:18:28 +00:00
}
2017-11-13 01:43:28 +00:00
if ! * enableSSLChainCompletion {
2018-12-05 16:27:55 +00:00
klog . Warningf ( "SSL certificate chain completion is disabled (--enable-ssl-chain-completion=false)" )
2017-11-13 01:43:28 +00:00
}
2018-10-08 18:00:38 +00:00
if * publishSvc != "" && * publishStatusAddress != "" {
2019-07-08 20:10:38 +00:00
return false , nil , fmt . Errorf ( "flags --publish-service and --publish-status-address are mutually exclusive" )
2018-10-08 18:00:38 +00:00
}
2019-01-21 14:29:36 +00:00
nginx . HealthPath = * defHealthzURL
2019-06-11 02:32:17 +00:00
if * defHealthCheckTimeout > 0 {
nginx . HealthCheckTimeout = time . Duration ( * defHealthCheckTimeout ) * time . Second
}
2019-07-04 22:06:55 +00:00
ngx_config . EnableSSLChainCompletion = * enableSSLChainCompletion
2017-11-05 01:18:28 +00:00
config := & controller . Configuration {
2019-07-04 22:06:55 +00:00
APIServerHost : * apiserverHost ,
KubeConfigFile : * kubeConfigFile ,
UpdateStatus : * updateStatus ,
ElectionID : * electionID ,
EnableProfiling : * profiling ,
EnableMetrics : * enableMetrics ,
MetricsPerHost : * metricsPerHost ,
2020-06-20 06:58:14 +00:00
MonitorMaxBatchSize : * monitorMaxBatchSize ,
2019-07-04 22:06:55 +00:00
EnableSSLPassthrough : * enableSSLPassthrough ,
ResyncPeriod : * resyncPeriod ,
DefaultService : * defaultSvc ,
Namespace : * watchNamespace ,
ConfigMapName : * configMap ,
TCPConfigMapName : * tcpConfigMapName ,
UDPConfigMapName : * udpConfigMapName ,
DefaultSSLCertificate : * defSSLCertificate ,
PublishService : * publishSvc ,
PublishStatusAddress : * publishStatusAddress ,
UpdateStatusOnShutdown : * updateStatusOnShutdown ,
UseNodeInternalIP : * useNodeInternalIP ,
SyncRateLimit : * syncRateLimit ,
2017-11-05 01:18:28 +00:00
ListenPorts : & ngx_config . ListenPorts {
Default : * defServerPort ,
Health : * healthzPort ,
HTTP : * httpPort ,
HTTPS : * httpsPort ,
SSLProxy : * sslProxyPort ,
} ,
2019-02-21 19:45:21 +00:00
DisableCatchAll : * disableCatchAll ,
ValidationWebhook : * validationWebhook ,
ValidationWebhookCertPath : * validationWebhookCert ,
ValidationWebhookKeyPath : * validationWebhookKey ,
2017-11-05 01:18:28 +00:00
}
2019-12-05 22:12:54 +00:00
if * apiserverHost != "" {
config . RootCAFile = * rootCAFile
}
2020-03-16 07:26:33 +00:00
if nginx . MaxmindLicenseKey != "" && nginx . MaxmindEditionIDs != "" {
if err := nginx . ValidateGeoLite2DBEditions ( ) ; err != nil {
return false , nil , err
}
2020-01-08 22:46:43 +00:00
klog . Info ( "downloading maxmind GeoIP2 databases..." )
2020-03-16 07:26:33 +00:00
if err := nginx . DownloadGeoLite2DB ( ) ; err != nil {
2020-01-08 22:46:43 +00:00
klog . Errorf ( "unexpected error downloading GeoIP2 database: %v" , err )
}
2020-03-16 07:26:33 +00:00
config . MaxmindEditionFiles = nginx . MaxmindEditionFiles
2020-01-08 22:46:43 +00:00
}
2017-11-05 01:18:28 +00:00
return false , config , nil
}