Merge pull request #2623 from antoineco/improve-flags-doc
Proofread cmd package and update flags description
This commit is contained in:
commit
238ad76d65
5 changed files with 181 additions and 158 deletions
|
@ -34,12 +34,12 @@ func resetForTesting(usage func()) {
|
||||||
func TestMandatoryFlag(t *testing.T) {
|
func TestMandatoryFlag(t *testing.T) {
|
||||||
_, _, err := parseFlags()
|
_, _, err := parseFlags()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expected and error about default backend service")
|
t.Fatalf("Expected an error about default backend service")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDefaults(t *testing.T) {
|
func TestDefaults(t *testing.T) {
|
||||||
resetForTesting(func() { t.Fatal("bad parse") })
|
resetForTesting(func() { t.Fatal("Parsing failed") })
|
||||||
|
|
||||||
oldArgs := os.Args
|
oldArgs := os.Args
|
||||||
defer func() { os.Args = oldArgs }()
|
defer func() { os.Args = oldArgs }()
|
||||||
|
@ -47,15 +47,15 @@ func TestDefaults(t *testing.T) {
|
||||||
|
|
||||||
showVersion, conf, err := parseFlags()
|
showVersion, conf, err := parseFlags()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error parsing default flags: %v", err)
|
t.Fatalf("Unexpected error parsing default flags: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if showVersion {
|
if showVersion {
|
||||||
t.Fatal("expected false but true was returned for flag show-version")
|
t.Fatal("Expected flag \"show-version\" to be false")
|
||||||
}
|
}
|
||||||
|
|
||||||
if conf == nil {
|
if conf == nil {
|
||||||
t.Fatal("expected a configuration but nil returned")
|
t.Fatal("Expected a controller Configuration")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,101 +39,121 @@ func parseFlags() (bool, *controller.Configuration, error) {
|
||||||
var (
|
var (
|
||||||
flags = pflag.NewFlagSet("", pflag.ExitOnError)
|
flags = pflag.NewFlagSet("", pflag.ExitOnError)
|
||||||
|
|
||||||
apiserverHost = flags.String("apiserver-host", "", "The address of the Kubernetes Apiserver "+
|
apiserverHost = flags.String("apiserver-host", "",
|
||||||
"to connect to in the format of protocol://address:port, e.g., "+
|
`Address of the Kubernetes API server.
|
||||||
"http://localhost:8080. If not specified, the assumption is that the binary runs inside a "+
|
Takes the form "protocol://address:port". If not specified, it is assumed the
|
||||||
"Kubernetes cluster and local discovery is attempted.")
|
program runs inside a Kubernetes cluster and local discovery is attempted.`)
|
||||||
kubeConfigFile = flags.String("kubeconfig", "", "Path to kubeconfig file with authorization and master location information.")
|
|
||||||
|
kubeConfigFile = flags.String("kubeconfig", "",
|
||||||
|
`Path to a kubeconfig file containing authorization and API server information.`)
|
||||||
|
|
||||||
defaultSvc = flags.String("default-backend-service", "",
|
defaultSvc = flags.String("default-backend-service", "",
|
||||||
`Service used to serve a 404 page for the default backend. Takes the form
|
`Service used to serve HTTP requests not matching any known server name (catch-all).
|
||||||
namespace/name. The controller uses the first node port of this Service for
|
Takes the form "namespace/name". The controller configures NGINX to forward
|
||||||
the default backend.`)
|
requests to the first port of this Service.`)
|
||||||
|
|
||||||
ingressClass = flags.String("ingress-class", "",
|
ingressClass = flags.String("ingress-class", "",
|
||||||
`Name of the ingress class to route through this controller.`)
|
`Name of the ingress class this controller satisfies.
|
||||||
|
The class of an Ingress object is set using the annotation "kubernetes.io/ingress.class".
|
||||||
|
All ingress classes are satisfied if this parameter is left empty.`)
|
||||||
|
|
||||||
configMap = flags.String("configmap", "",
|
configMap = flags.String("configmap", "",
|
||||||
`Name of the ConfigMap that contains the custom configuration to use`)
|
`Name of the ConfigMap containing custom global configurations for the controller.`)
|
||||||
|
|
||||||
publishSvc = flags.String("publish-service", "",
|
publishSvc = flags.String("publish-service", "",
|
||||||
`Service fronting the ingress controllers. Takes the form namespace/name.
|
`Service fronting the Ingress controller.
|
||||||
The controller will set the endpoint records on the ingress objects to reflect those on the service.`)
|
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.`)
|
||||||
|
|
||||||
tcpConfigMapName = flags.String("tcp-services-configmap", "",
|
tcpConfigMapName = flags.String("tcp-services-configmap", "",
|
||||||
`Name of the ConfigMap that contains the definition of the TCP services to expose.
|
`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 the name of the
|
The key in the map indicates the external port to be used. The value is a
|
||||||
service with the format namespace/serviceName and the port of the service could be a
|
reference to a Service in the form "namespace/name:port", where "port" can
|
||||||
number of the name of the port.
|
either be a port number or name. TCP ports 80 and 443 are reserved by the
|
||||||
The ports 80 and 443 are not allowed as external ports. This ports are reserved for the backend`)
|
controller for servicing HTTP traffic.`)
|
||||||
|
|
||||||
udpConfigMapName = flags.String("udp-services-configmap", "",
|
udpConfigMapName = flags.String("udp-services-configmap", "",
|
||||||
`Name of the ConfigMap that contains the definition of the UDP services to expose.
|
`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 the name of the
|
The key in the map indicates the external port to be used. The value is a
|
||||||
service with the format namespace/serviceName and the port of the service could be a
|
reference to a Service in the form "namespace/name:port", where "port" can
|
||||||
number of the name of the port.`)
|
either be a port name or number.`)
|
||||||
|
|
||||||
resyncPeriod = flags.Duration("sync-period", 600*time.Second,
|
resyncPeriod = flags.Duration("sync-period", 600*time.Second,
|
||||||
`Relist and confirm cloud resources this often. Default is 10 minutes`)
|
`Period at which the controller forces the repopulation of its local object stores.`)
|
||||||
|
|
||||||
watchNamespace = flags.String("watch-namespace", apiv1.NamespaceAll,
|
watchNamespace = flags.String("watch-namespace", apiv1.NamespaceAll,
|
||||||
`Namespace to watch for Ingress. Default is to watch all namespaces`)
|
`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.`)
|
||||||
|
|
||||||
profiling = flags.Bool("profiling", true, `Enable profiling via web interface host:port/debug/pprof/`)
|
profiling = flags.Bool("profiling", true,
|
||||||
|
`Enable profiling via web interface host:port/debug/pprof/`)
|
||||||
|
|
||||||
defSSLCertificate = flags.String("default-ssl-certificate", "", `Name of the secret
|
defSSLCertificate = flags.String("default-ssl-certificate", "",
|
||||||
that contains a SSL certificate to be used as default for a HTTPS catch-all server.
|
`Secret containing a SSL certificate to be used by the default HTTPS server (catch-all).
|
||||||
Takes the form <namespace>/<secret name>.`)
|
Takes the form "namespace/name".`)
|
||||||
|
|
||||||
defHealthzURL = flags.String("health-check-path", "/healthz", `Defines
|
defHealthzURL = flags.String("health-check-path", "/healthz",
|
||||||
the URL to be used as health check inside in the default server in NGINX.`)
|
`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.`)
|
||||||
|
|
||||||
updateStatus = flags.Bool("update-status", true, `Indicates if the
|
updateStatus = flags.Bool("update-status", true,
|
||||||
ingress controller should update the Ingress status IP/hostname. Default is true`)
|
`Update the load-balancer status of Ingress objects this controller satisfies.
|
||||||
|
Requires setting the publish-service parameter to a valid Service reference.`)
|
||||||
|
|
||||||
electionID = flags.String("election-id", "ingress-controller-leader", `Election id to use for status update.`)
|
electionID = flags.String("election-id", "ingress-controller-leader",
|
||||||
|
`Election id to use for Ingress status updates.`)
|
||||||
|
|
||||||
forceIsolation = flags.Bool("force-namespace-isolation", false,
|
forceIsolation = flags.Bool("force-namespace-isolation", false,
|
||||||
`Force namespace isolation. This flag is required to avoid the reference of secrets or
|
`Force namespace isolation.
|
||||||
configmaps located in a different namespace than the specified in the flag --watch-namespace.`)
|
Prevents Ingress objects from referencing Secrets and ConfigMaps located in a
|
||||||
|
different namespace than their own. May be used together with watch-namespace.`)
|
||||||
|
|
||||||
updateStatusOnShutdown = flags.Bool("update-status-on-shutdown", true, `Indicates if the
|
updateStatusOnShutdown = flags.Bool("update-status-on-shutdown", true,
|
||||||
ingress controller should update the Ingress status IP/hostname when the controller
|
`Update the load-balancer status of Ingress objects when the controller shuts down.
|
||||||
is being stopped. Default is true`)
|
Requires the update-status parameter.`)
|
||||||
|
|
||||||
sortBackends = flags.Bool("sort-backends", false, `Defines if servers inside NGINX upstream should be sorted`)
|
sortBackends = flags.Bool("sort-backends", false,
|
||||||
|
`Sort servers inside NGINX upstreams.`)
|
||||||
|
|
||||||
useNodeInternalIP = flags.Bool("report-node-internal-ip-address", false,
|
useNodeInternalIP = flags.Bool("report-node-internal-ip-address", false,
|
||||||
`Defines if the nodes IP address to be returned in the ingress status should be the internal instead of the external IP address`)
|
`Set the load-balancer status of Ingress objects to internal Node addresses instead of external.
|
||||||
|
Requires the update-status parameter.`)
|
||||||
|
|
||||||
showVersion = flags.Bool("version", false,
|
showVersion = flags.Bool("version", false,
|
||||||
`Shows release information about the NGINX Ingress controller`)
|
`Show release information about the NGINX Ingress controller and exit.`)
|
||||||
|
|
||||||
enableSSLPassthrough = flags.Bool("enable-ssl-passthrough", false, `Enable SSL passthrough feature. Default is disabled`)
|
enableSSLPassthrough = flags.Bool("enable-ssl-passthrough", false,
|
||||||
|
`Enable SSL Passthrough.`)
|
||||||
|
|
||||||
httpPort = flags.Int("http-port", 80, `Indicates the port to use for HTTP traffic`)
|
annotationsPrefix = flags.String("annotations-prefix", "nginx.ingress.kubernetes.io",
|
||||||
httpsPort = flags.Int("https-port", 443, `Indicates the port to use for HTTPS traffic`)
|
`Prefix of the Ingress annotations specific to the NGINX controller.`)
|
||||||
statusPort = flags.Int("status-port", 18080, `Indicates the TCP port to use for exposing the nginx status page`)
|
|
||||||
sslProxyPort = flags.Int("ssl-passtrough-proxy-port", 442, `Default port to use internally for SSL when SSL Passthgough is enabled`)
|
|
||||||
defServerPort = flags.Int("default-server-port", 8181, `Default port to use for exposing the default server (catch all)`)
|
|
||||||
healthzPort = flags.Int("healthz-port", 10254, "port for healthz endpoint.")
|
|
||||||
|
|
||||||
annotationsPrefix = flags.String("annotations-prefix", "nginx.ingress.kubernetes.io", `Prefix of the ingress annotations.`)
|
|
||||||
|
|
||||||
enableSSLChainCompletion = flags.Bool("enable-ssl-chain-completion", true,
|
enableSSLChainCompletion = flags.Bool("enable-ssl-chain-completion", true,
|
||||||
`Defines if the nginx ingress controller should check the secrets for missing intermediate CA certificates.
|
`Autocomplete SSL certificate chains with missing intermediate CA certificates.
|
||||||
If the certificate contain issues chain issues is not possible to enable OCSP.
|
A valid certificate chain is required to enable OCSP stapling. Certificates
|
||||||
Default is true.`)
|
uploaded to Kubernetes must have the "Authority Information Access" X.509 v3
|
||||||
|
extension for this to succeed.`)
|
||||||
|
|
||||||
syncRateLimit = flags.Float32("sync-rate-limit", 0.3,
|
syncRateLimit = flags.Float32("sync-rate-limit", 0.3,
|
||||||
`Define the sync frequency upper limit`)
|
`Define the sync frequency upper limit`)
|
||||||
|
|
||||||
publishStatusAddress = flags.String("publish-status-address", "",
|
publishStatusAddress = flags.String("publish-status-address", "",
|
||||||
`User customized address to be set in the status of ingress resources. The controller will set the
|
`Customized address to set as the load-balancer status of Ingress objects this controller satisfies.
|
||||||
endpoint records on the ingress using this address.`)
|
Requires the update-status parameter.`)
|
||||||
|
|
||||||
dynamicConfigurationEnabled = flags.Bool("enable-dynamic-configuration", false,
|
dynamicConfigurationEnabled = flags.Bool("enable-dynamic-configuration", false,
|
||||||
`When enabled controller will try to avoid Nginx reloads as much as possible by using Lua. Disabled by default.`)
|
`Dynamically refresh backends on topology changes instead of reloading NGINX.
|
||||||
|
Feature backed by OpenResty Lua libraries.`)
|
||||||
|
|
||||||
|
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.`)
|
||||||
|
statusPort = flags.Int("status-port", 18080, `Port to use for exposing NGINX status pages.`)
|
||||||
|
sslProxyPort = flags.Int("ssl-passtrough-proxy-port", 442, `Port to use internally for SSL Passthgough.`)
|
||||||
|
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.")
|
||||||
)
|
)
|
||||||
|
|
||||||
flag.Set("logtostderr", "true")
|
flag.Set("logtostderr", "true")
|
||||||
|
@ -158,10 +178,10 @@ func parseFlags() (bool, *controller.Configuration, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if *ingressClass != "" {
|
if *ingressClass != "" {
|
||||||
glog.Infof("Watching for ingress class: %s", *ingressClass)
|
glog.Infof("Watching for Ingress class: %s", *ingressClass)
|
||||||
|
|
||||||
if *ingressClass != class.DefaultClass {
|
if *ingressClass != class.DefaultClass {
|
||||||
glog.Warningf("only Ingress with class \"%v\" will be processed by this ingress controller", *ingressClass)
|
glog.Warningf("Only Ingresses with class %q will be processed by this ingress controller", *ingressClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
class.IngressClass = *ingressClass
|
class.IngressClass = *ingressClass
|
||||||
|
@ -191,7 +211,7 @@ func parseFlags() (bool, *controller.Configuration, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !*enableSSLChainCompletion {
|
if !*enableSSLChainCompletion {
|
||||||
glog.Warningf("Check of SSL certificate chain is disabled (--enable-ssl-chain-completion=false)")
|
glog.Warningf("SSL certificate chain completion is disabled (--enable-ssl-chain-completion=false)")
|
||||||
}
|
}
|
||||||
|
|
||||||
// LuaJIT is not available on arch s390x and ppc64le
|
// LuaJIT is not available on arch s390x and ppc64le
|
||||||
|
@ -200,7 +220,7 @@ func parseFlags() (bool, *controller.Configuration, error) {
|
||||||
disableLua = true
|
disableLua = true
|
||||||
if *dynamicConfigurationEnabled {
|
if *dynamicConfigurationEnabled {
|
||||||
*dynamicConfigurationEnabled = false
|
*dynamicConfigurationEnabled = false
|
||||||
glog.Warningf("Disabling dynamic configuration feature (LuaJIT is not available in s390x and ppc64le)")
|
glog.Warningf("LuaJIT is not available on s390x and ppc64le architectures: disabling dynamic configuration feature.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,17 @@ import (
|
||||||
"k8s.io/ingress-nginx/version"
|
"k8s.io/ingress-nginx/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// High enough QPS to fit all expected use cases. QPS=0 is not set here, because
|
||||||
|
// client code is overriding it.
|
||||||
|
defaultQPS = 1e6
|
||||||
|
// High enough Burst to fit all expected use cases. Burst=0 is not set here, because
|
||||||
|
// client code is overriding it.
|
||||||
|
defaultBurst = 1e6
|
||||||
|
|
||||||
|
fakeCertificate = "default-fake-certificate"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
|
||||||
|
@ -71,36 +82,38 @@ func main() {
|
||||||
handleFatalInitError(err)
|
handleFatalInitError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ns, name, err := k8s.ParseNameNS(conf.DefaultService)
|
defSvcNs, defSvcName, err := k8s.ParseNameNS(conf.DefaultService)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatal(err)
|
glog.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = kubeClient.CoreV1().Services(ns).Get(name, metav1.GetOptions{})
|
_, err = kubeClient.CoreV1().Services(defSvcNs).Get(defSvcName, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// TODO (antoineco): compare with error types from k8s.io/apimachinery/pkg/api/errors
|
||||||
if strings.Contains(err.Error(), "cannot get services in the namespace") {
|
if strings.Contains(err.Error(), "cannot get services in the namespace") {
|
||||||
glog.Fatalf("✖ It seems the cluster it is running with Authorization enabled (like RBAC) and there is no permissions for the ingress controller. Please check the configuration")
|
glog.Fatalf("✖ The cluster seems to be running with a restrictive Authorization mode and the Ingress controller does not have the required permissions to operate normally.")
|
||||||
}
|
}
|
||||||
glog.Fatalf("no service with name %v found: %v", conf.DefaultService, err)
|
glog.Fatalf("No service with name %v found: %v", conf.DefaultService, err)
|
||||||
}
|
}
|
||||||
glog.Infof("validated %v as the default backend", conf.DefaultService)
|
glog.Infof("Validated %v as the default backend.", conf.DefaultService)
|
||||||
|
|
||||||
if conf.Namespace != "" {
|
if conf.Namespace != "" {
|
||||||
_, err = kubeClient.CoreV1().Namespaces().Get(conf.Namespace, metav1.GetOptions{})
|
_, err = kubeClient.CoreV1().Namespaces().Get(conf.Namespace, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("no namespace with name %v found: %v", conf.Namespace, err)
|
glog.Fatalf("No namespace with name %v found: %v", conf.Namespace, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if conf.ResyncPeriod.Seconds() < 10 {
|
minResyncPeriod := 10 * time.Second
|
||||||
glog.Fatalf("resync period (%vs) is too low", conf.ResyncPeriod.Seconds())
|
if conf.ResyncPeriod < minResyncPeriod {
|
||||||
|
glog.Fatalf("Resync period should be at least %v (current: %v)", minResyncPeriod, conf.ResyncPeriod)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the default SSL certificate (dummy)
|
// create the default SSL certificate (dummy)
|
||||||
defCert, defKey := ssl.GetFakeSSLCert()
|
defCert, defKey := ssl.GetFakeSSLCert()
|
||||||
c, err := ssl.AddOrUpdateCertAndKey(fakeCertificate, defCert, defKey, []byte{}, fs)
|
c, err := ssl.AddOrUpdateCertAndKey(fakeCertificate, defCert, defKey, []byte{}, fs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("Error generating self signed certificate: %v", err)
|
glog.Fatalf("Error generating self-signed certificate: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
conf.FakeCertificatePath = c.PemFileName
|
conf.FakeCertificatePath = c.PemFileName
|
||||||
|
@ -130,24 +143,26 @@ func handleSigterm(ngx *controller.NGINXController, exit exiter) {
|
||||||
|
|
||||||
exitCode := 0
|
exitCode := 0
|
||||||
if err := ngx.Stop(); err != nil {
|
if err := ngx.Stop(); err != nil {
|
||||||
glog.Infof("Error during shutdown %v", err)
|
glog.Infof("Error during shutdown: %v", err)
|
||||||
exitCode = 1
|
exitCode = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
glog.Infof("Handled quit, awaiting pod deletion")
|
glog.Infof("Handled quit, awaiting Pod deletion")
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
|
|
||||||
glog.Infof("Exiting with %v", exitCode)
|
glog.Infof("Exiting with %v", exitCode)
|
||||||
exit(exitCode)
|
exit(exitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createApiserverClient creates new Kubernetes Apiserver client. When kubeconfig or apiserverHost param is empty
|
// createApiserverClient creates a new Kubernetes REST client. apiserverHost is
|
||||||
// the function assumes that it is running inside a Kubernetes cluster and attempts to
|
// the URL of the API server in the format protocol://address:port/pathPrefix,
|
||||||
// discover the Apiserver. Otherwise, it connects to the Apiserver specified.
|
// kubeConfig is the location of a kubeconfig file. If defined, the kubeconfig
|
||||||
//
|
// file is loaded first, the URL of the API server read from the file is then
|
||||||
// apiserverHost param is in the format of protocol://address:port/pathPrefix, e.g.http://localhost:8001.
|
// optionally overriden by the value of apiserverHost.
|
||||||
// kubeConfig location of kubeconfig file
|
// If neither apiserverHost or kubeconfig are passed in, we assume the
|
||||||
func createApiserverClient(apiserverHost string, kubeConfig string) (*kubernetes.Clientset, error) {
|
// controller runs inside Kubernetes and fallback to the in-cluster config. If
|
||||||
|
// the in-cluster config is missing or fails, we fallback to the default config.
|
||||||
|
func createApiserverClient(apiserverHost, kubeConfig string) (*kubernetes.Clientset, error) {
|
||||||
cfg, err := clientcmd.BuildConfigFromFlags(apiserverHost, kubeConfig)
|
cfg, err := clientcmd.BuildConfigFromFlags(apiserverHost, kubeConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -166,7 +181,7 @@ func createApiserverClient(apiserverHost string, kubeConfig string) (*kubernetes
|
||||||
|
|
||||||
var v *discovery.Info
|
var v *discovery.Info
|
||||||
|
|
||||||
// In some environments is possible the client cannot connect the API server in the first request
|
// The client may fail to connect to the API server in the first request.
|
||||||
// https://github.com/kubernetes/ingress-nginx/issues/1968
|
// https://github.com/kubernetes/ingress-nginx/issues/1968
|
||||||
defaultRetry := wait.Backoff{
|
defaultRetry := wait.Backoff{
|
||||||
Steps: 10,
|
Steps: 10,
|
||||||
|
@ -177,7 +192,7 @@ func createApiserverClient(apiserverHost string, kubeConfig string) (*kubernetes
|
||||||
|
|
||||||
var lastErr error
|
var lastErr error
|
||||||
retries := 0
|
retries := 0
|
||||||
glog.V(2).Info("trying to discover Kubernetes version")
|
glog.V(2).Info("Trying to discover Kubernetes version")
|
||||||
err = wait.ExponentialBackoff(defaultRetry, func() (bool, error) {
|
err = wait.ExponentialBackoff(defaultRetry, func() (bool, error) {
|
||||||
v, err = client.Discovery().ServerVersion()
|
v, err = client.Discovery().ServerVersion()
|
||||||
|
|
||||||
|
@ -186,48 +201,35 @@ func createApiserverClient(apiserverHost string, kubeConfig string) (*kubernetes
|
||||||
}
|
}
|
||||||
|
|
||||||
lastErr = err
|
lastErr = err
|
||||||
glog.V(2).Infof("unexpected error discovering Kubernetes version (attempt %v): %v", err, retries)
|
glog.V(2).Infof("Unexpected error discovering Kubernetes version (attempt %v): %v", err, retries)
|
||||||
retries++
|
retries++
|
||||||
return false, nil
|
return false, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
// err is not null only if there was a timeout in the exponential backoff (ErrWaitTimeout)
|
// err is returned in case of timeout in the exponential backoff (ErrWaitTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, lastErr
|
return nil, lastErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// this should not happen, warn the user
|
// this should not happen, warn the user
|
||||||
if retries > 0 {
|
if retries > 0 {
|
||||||
glog.Warningf("it was required to retry %v times before reaching the API server", retries)
|
glog.Warningf("Initial connection to the Kubernetes API server was retried %d times.", retries)
|
||||||
}
|
}
|
||||||
|
|
||||||
glog.Infof("Running in Kubernetes Cluster version v%v.%v (%v) - git (%v) commit %v - platform %v",
|
glog.Infof("Running in Kubernetes cluster version v%v.%v (%v) - git (%v) commit %v - platform %v",
|
||||||
v.Major, v.Minor, v.GitVersion, v.GitTreeState, v.GitCommit, v.Platform)
|
v.Major, v.Minor, v.GitVersion, v.GitTreeState, v.GitCommit, v.Platform)
|
||||||
|
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
// Handler for fatal init errors. Prints a verbose error message and exits.
|
||||||
// High enough QPS to fit all expected use cases. QPS=0 is not set here, because
|
|
||||||
// client code is overriding it.
|
|
||||||
defaultQPS = 1e6
|
|
||||||
// High enough Burst to fit all expected use cases. Burst=0 is not set here, because
|
|
||||||
// client code is overriding it.
|
|
||||||
defaultBurst = 1e6
|
|
||||||
|
|
||||||
fakeCertificate = "default-fake-certificate"
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles fatal init error that prevents server from doing any work. Prints verbose error
|
|
||||||
* messages and quits the server.
|
|
||||||
*/
|
|
||||||
func handleFatalInitError(err error) {
|
func handleFatalInitError(err error) {
|
||||||
glog.Fatalf("Error while initializing connection to Kubernetes apiserver. "+
|
glog.Fatalf("Error while initiating a connection to the Kubernetes API server. "+
|
||||||
"This most likely means that the cluster is misconfigured (e.g., it has "+
|
"This could mean the cluster is misconfigured (e.g. it has invalid API server certificates "+
|
||||||
"invalid apiserver certificates or service accounts configuration). Reason: %s\n"+
|
"or Service Accounts configuration). Reason: %s\n"+
|
||||||
"Refer to the troubleshooting guide for more information: "+
|
"Refer to the troubleshooting guide for more information: "+
|
||||||
"https://github.com/kubernetes/ingress-nginx/blob/master/docs/troubleshooting.md", err)
|
"https://kubernetes.github.io/ingress-nginx/troubleshooting/",
|
||||||
|
err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerHandlers(enableProfiling bool, port int, ic *controller.NGINXController, mux *http.ServeMux) {
|
func registerHandlers(enableProfiling bool, port int, ic *controller.NGINXController, mux *http.ServeMux) {
|
||||||
|
@ -248,7 +250,7 @@ func registerHandlers(enableProfiling bool, port int, ic *controller.NGINXContro
|
||||||
mux.HandleFunc("/stop", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/stop", func(w http.ResponseWriter, r *http.Request) {
|
||||||
err := syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
|
err := syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("unexpected error: %v", err)
|
glog.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -33,15 +33,15 @@ func TestCreateApiserverClient(t *testing.T) {
|
||||||
|
|
||||||
cli, err := createApiserverClient("", kubeConfigFile)
|
cli, err := createApiserverClient("", kubeConfigFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error creating api server client: %v", err)
|
t.Fatalf("Unexpected error creating Kubernetes REST client: %v", err)
|
||||||
}
|
}
|
||||||
if cli == nil {
|
if cli == nil {
|
||||||
t.Fatalf("expected a kubernetes client but none returned")
|
t.Fatal("Expected a REST client but none returned.")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = createApiserverClient("", "")
|
_, err = createApiserverClient("", "")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expected an error creating api server client without an api server URL or kubeconfig file")
|
t.Fatal("Expected an error creating REST client without an API server URL or kubeconfig file.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ func TestHandleSigterm(t *testing.T) {
|
||||||
|
|
||||||
cli, err := createApiserverClient("", kubeConfigFile)
|
cli, err := createApiserverClient("", kubeConfigFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error creating api server client: %v", err)
|
t.Fatalf("Unexpected error creating Kubernetes REST client: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
resetForTesting(func() { t.Fatal("bad parse") })
|
resetForTesting(func() { t.Fatal("bad parse") })
|
||||||
|
@ -67,20 +67,20 @@ func TestHandleSigterm(t *testing.T) {
|
||||||
|
|
||||||
_, conf, err := parseFlags()
|
_, conf, err := parseFlags()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error creating NGINX controller: %v", err)
|
t.Errorf("Unexpected error creating NGINX controller: %v", err)
|
||||||
}
|
}
|
||||||
conf.Client = cli
|
conf.Client = cli
|
||||||
|
|
||||||
fs, err := file.NewFakeFS()
|
fs, err := file.NewFakeFS()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx := controller.NewNGINXController(conf, fs)
|
ngx := controller.NewNGINXController(conf, fs)
|
||||||
|
|
||||||
go handleSigterm(ngx, func(code int) {
|
go handleSigterm(ngx, func(code int) {
|
||||||
if code != 1 {
|
if code != 1 {
|
||||||
t.Errorf("expected exit code 1 but %v received", code)
|
t.Errorf("Expected exit code 1 but %d received", code)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -88,12 +88,13 @@ func TestHandleSigterm(t *testing.T) {
|
||||||
|
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
t.Logf("sending SIGTERM to process PID %v", syscall.Getpid())
|
t.Logf("Sending SIGTERM to PID %d", syscall.Getpid())
|
||||||
err = syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
|
err = syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error sending SIGTERM signal")
|
t.Error("Unexpected error sending SIGTERM signal.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRegisterHandlers(t *testing.T) {
|
func TestRegisterHandlers(t *testing.T) {
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +1,48 @@
|
||||||
# Command line arguments
|
# Command line arguments
|
||||||
|
|
||||||
The following command line arguments are accepted by the main controller executable.
|
The following command line arguments are accepted by the Ingress controller executable.
|
||||||
|
|
||||||
They are set in the container spec of the `nginx-ingress-controller` Deployment object (see `deploy/with-rbac.yaml` or `deploy/without-rbac.yaml`).
|
They are set in the container spec of the `nginx-ingress-controller` Deployment manifest (see `deploy/with-rbac.yaml` or `deploy/without-rbac.yaml`).
|
||||||
|
|
||||||
|
|
||||||
| Argument | Description |
|
| Argument | Description |
|
||||||
|----------|-------------|
|
|----------|-------------|
|
||||||
| `--alsologtostderr` | log to standard error as well as files |
|
| --alsologtostderr | log to standard error as well as files |
|
||||||
| `--annotations-prefix string` | Prefix of the ingress annotations. (default "nginx.ingress.kubernetes.io") |
|
| --annotations-prefix string | Prefix of the Ingress annotations specific to the NGINX controller. (default "nginx.ingress.kubernetes.io") |
|
||||||
| `--apiserver-host string` | The address of the Kubernetes Apiserver to connect to in the format of protocol://address:port, e.g., http://localhost:8080. If not specified, the assumption is that the binary runs inside a Kubernetes cluster and local discovery is attempted. |
|
| --apiserver-host string | 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. |
|
||||||
| `--configmap string` | Name of the ConfigMap that contains the custom configuration to use |
|
| --configmap string | Name of the ConfigMap containing custom global configurations for the controller. |
|
||||||
| `--default-backend-service string` | Service used to serve a 404 page for the default backend. Takes the form namespace/name. The controller uses the first node port of this Service for the default backend. |
|
| --default-backend-service string | 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. |
|
||||||
| `--default-server-port int` | Default port to use for exposing the default server (catch all) (default 8181) |
|
| --default-server-port int | Port to use for exposing the default server (catch-all). (default 8181) |
|
||||||
| `--default-ssl-certificate string` | Name of the secret that contains a SSL certificate to be used as default for a HTTPS catch-all server. Takes the form <namespace>/<secret name>. |
|
| --default-ssl-certificate string | Secret containing a SSL certificate to be used by the default HTTPS server (catch-all). Takes the form "namespace/name". |
|
||||||
| `--election-id string` | Election id to use for status update. (default "ingress-controller-leader") |
|
| --election-id string | Election id to use for Ingress status updates. (default "ingress-controller-leader") |
|
||||||
| `--enable-dynamic-configuration` | When enabled controller will try to avoid Nginx reloads as much as possible by using Lua. Disabled by default. |
|
| --enable-dynamic-configuration | Dynamically refresh backends on topology changes instead of reloading NGINX. Feature backed by OpenResty Lua libraries. |
|
||||||
| `--enable-ssl-chain-completion` | Defines if the nginx ingress controller should check the secrets for missing intermediate CA certificates. If the certificate contain issues chain issues is not possible to enable OCSP. Default is true. (default true) |
|
| --enable-ssl-chain-completion | Autocomplete SSL certificate chains with missing intermediate CA certificates. A valid certificate chain is required to enable OCSP stapling. Certificates uploaded to Kubernetes must have the "Authority Information Access" X.509 v3 extension for this to succeed. (default true) |
|
||||||
| `--enable-ssl-passthrough` | Enable SSL passthrough feature. Default is disabled |
|
| --enable-ssl-passthrough | Enable SSL Passthrough. |
|
||||||
| `--force-namespace-isolation` | Force namespace isolation. This flag is required to avoid the reference of secrets or configmaps located in a different namespace than the specified in the flag --watch-namespace. |
|
| --force-namespace-isolation | Force namespace isolation. Prevents Ingress objects from referencing Secrets and ConfigMaps located in a different namespace than their own. May be used together with watch-namespace. |
|
||||||
| `--health-check-path string` | Defines the URL to be used as health check inside in the default server in NGINX. (default "/healthz") |
|
| --health-check-path string | 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. (default "/healthz") |
|
||||||
| `--healthz-port int` | port for healthz endpoint. (default 10254) |
|
| --healthz-port int | Port to use for the healthz endpoint. (default 10254) |
|
||||||
| `--http-port int` | Indicates the port to use for HTTP traffic (default 80) |
|
| --http-port int | Port to use for servicing HTTP traffic. (default 80) |
|
||||||
| `--https-port int` | Indicates the port to use for HTTPS traffic (default 443) |
|
| --https-port int | Port to use for servicing HTTPS traffic. (default 443) |
|
||||||
| `--ingress-class string` | Name of the ingress class to route through this controller. |
|
| --ingress-class string | Name of the ingress class this controller satisfies. The class of an Ingress object is set using the annotation "kubernetes.io/ingress.class". All ingress classes are satisfied if this parameter is left empty. |
|
||||||
| `--kubeconfig string` | Path to kubeconfig file with authorization and master location information. |
|
| --kubeconfig string | Path to a kubeconfig file containing authorization and API server information. |
|
||||||
| `--log_backtrace_at traceLocation` | when logging hits line file:N, emit a stack trace (default :0) |
|
| --log_backtrace_at traceLocation | when logging hits line file:N, emit a stack trace (default :0) |
|
||||||
| `--log_dir string` | If non-empty, write log files in this directory |
|
| --log_dir string | If non-empty, write log files in this directory |
|
||||||
| `--logtostderr` | log to standard error instead of files (default true) |
|
| --logtostderr | log to standard error instead of files (default true) |
|
||||||
| `--profiling` | Enable profiling via web interface host:port/debug/pprof/ (default true) |
|
| --profiling | Enable profiling via web interface host:port/debug/pprof/ (default true) |
|
||||||
| `--publish-service string` | Service fronting the ingress controllers. Takes the form namespace/name. The controller will set the endpoint records on the ingress objects to reflect those on the service. |
|
| --publish-service string | 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. |
|
||||||
| `--publish-status-address string` | User customized address to be set in the status of ingress resources. The controller will set the endpoint records on the ingress using this address. |
|
| --publish-status-address string | Customized address to set as the load-balancer status of Ingress objects this controller satisfies. Requires the update-status parameter. |
|
||||||
| `--report-node-internal-ip-address` | Defines if the nodes IP address to be returned in the ingress status should be the internal instead of the external IP address |
|
| --report-node-internal-ip-address | Set the load-balancer status of Ingress objects to internal Node addresses instead of external. Requires the update-status parameter. |
|
||||||
| `--sort-backends` | Defines if backends and its endpoints should be sorted |
|
| --sort-backends | Sort servers inside NGINX upstreams. |
|
||||||
| `--ssl-passtrough-proxy-port int` | Default port to use internally for SSL when SSL Passthgough is enabled (default 442) |
|
| --ssl-passtrough-proxy-port int | Port to use internally for SSL Passthgough. (default 442) |
|
||||||
| `--status-port int` | Indicates the TCP port to use for exposing the nginx status page (default 18080) |
|
| --status-port int | Port to use for exposing NGINX status pages. (default 18080) |
|
||||||
| `--stderrthreshold severity` | logs at or above this threshold go to stderr (default 2) |
|
| --stderrthreshold severity | logs at or above this threshold go to stderr (default 2) |
|
||||||
| `--sync-period duration` | Relist and confirm cloud resources this often. Default is 10 minutes (default 10m0s) |
|
| --sync-period duration | Period at which the controller forces the repopulation of its local object stores. (default 10m0s) |
|
||||||
| `--sync-rate-limit float32` | Define the sync frequency upper limit (default 0.3) |
|
| --sync-rate-limit float32 | Define the sync frequency upper limit (default 0.3) |
|
||||||
| `--tcp-services-configmap string` | Name of the ConfigMap that contains the definition of the TCP services to expose. The key in the map indicates the external port to be used. The value is the name of the service with the format namespace/serviceName and the port of the service could be a number of the name of the port. The ports 80 and 443 are not allowed as external ports. This ports are reserved for the backend |
|
| --tcp-services-configmap string | 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. |
|
||||||
| `--udp-services-configmap string` | Name of the ConfigMap that contains the definition of the UDP services to expose. The key in the map indicates the external port to be used. The value is the name of the service with the format namespace/serviceName and the port of the service could be a number of the name of the port. |
|
| --udp-services-configmap string | 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.
|
||||||
| `--update-status` | Indicates if the ingress controller should update the Ingress status IP/hostname. Default is true (default true) |
|
| --update-status | Update the load-balancer status of Ingress objects this controller satisfies. Requires setting the publish-service parameter to a valid Service reference. (default true) |
|
||||||
| `--update-status-on-shutdown` | Indicates if the ingress controller should update the Ingress status IP/hostname when the controller is being stopped. Default is true (default true) |
|
| --update-status-on-shutdown | Update the load-balancer status of Ingress objects when the controller shuts down. Requires the update-status parameter. (default true) |
|
||||||
| `-v`, `--v Level` | log level for V logs |
|
| --v Level | log level for V logs |
|
||||||
| `--version` | Shows release information about the NGINX Ingress controller |
|
| --version | Show release information about the NGINX Ingress controller and exit. |
|
||||||
| `--vmodule moduleSpec` | comma-separated list of pattern=N settings for file-filtered logging |
|
| --vmodule moduleSpec | comma-separated list of pattern=N settings for file-filtered logging |
|
||||||
| `--watch-namespace string` | Namespace to watch for Ingress. Default is to watch all namespaces |
|
| --watch-namespace string | 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. |
|
||||||
|
|
Loading…
Reference in a new issue