From 685b3bdcb94c1f5258884b55cbca90a338597ce4 Mon Sep 17 00:00:00 2001 From: paulo Date: Sun, 7 Apr 2019 23:44:37 +0100 Subject: [PATCH 1/2] Add ConfigMap name to values.yaml The value is used for `.metadata.name` in the ConfigMap yaml, as well as with the `--nginx-configmaps` flag for the container. --- deployments/helm-chart/Chart.yaml | 2 +- deployments/helm-chart/README.md | 1 + deployments/helm-chart/templates/controller-configmap.yaml | 2 +- deployments/helm-chart/templates/controller-deployment.yaml | 4 ++-- deployments/helm-chart/values.yaml | 4 +++- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/deployments/helm-chart/Chart.yaml b/deployments/helm-chart/Chart.yaml index 2730f067c0..d0c6e2a235 100644 --- a/deployments/helm-chart/Chart.yaml +++ b/deployments/helm-chart/Chart.yaml @@ -1,5 +1,5 @@ name: nginx-ingress -version: 0.3.5 +version: 0.3.6 appVersion: edge description: NGINX Ingress Controller icon: https://raw.githubusercontent.com/nginxinc/kubernetes-ingress/master/deployments/helm-chart/chart-icon.png diff --git a/deployments/helm-chart/README.md b/deployments/helm-chart/README.md index 15867f282a..dbb9de6f74 100644 --- a/deployments/helm-chart/README.md +++ b/deployments/helm-chart/README.md @@ -65,6 +65,7 @@ Parameter | Description | Default `controller.image.repository` | The image repository of the Ingress controller. | nginx/nginx-ingress `controller.image.tag` | The tag of the Ingress controller image. | edge `controller.image.pullPolicy` | The pull policy for the Ingress controller image. | IfNotPresent +`controller.config.name` | The name of the ConfigMap used by the Ingress controller container. `controller.config.entries` | The entries of the ConfigMap for customizing NGINX configuration. | {} `controller.defaultTLS.cert` | The base64-encoded TLS certificate for the default HTTPS server. If not specified, a pre-generated self-signed certificate is used. **Note:** It is recommended that you specify your own certificate. | A pre-generated self-signed certificate. `controller.defaultTLS.key` | The base64-encoded TLS key for the default HTTPS server. **Note:** If not specified, a pre-generated key is used. It is recommended that you specify your own key. | A pre-generated key. diff --git a/deployments/helm-chart/templates/controller-configmap.yaml b/deployments/helm-chart/templates/controller-configmap.yaml index bbcc1f1228..bbf8495d8d 100644 --- a/deployments/helm-chart/templates/controller-configmap.yaml +++ b/deployments/helm-chart/templates/controller-configmap.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: ConfigMap metadata: - name: nginx-config + name: {{ .Values.controller.config.name }} labels: {{- include "nginx-ingress.labels" . | nindent 4 }} data: diff --git a/deployments/helm-chart/templates/controller-deployment.yaml b/deployments/helm-chart/templates/controller-deployment.yaml index 674ce92f1a..d76cede415 100644 --- a/deployments/helm-chart/templates/controller-deployment.yaml +++ b/deployments/helm-chart/templates/controller-deployment.yaml @@ -58,7 +58,7 @@ spec: fieldPath: metadata.name args: - -nginx-plus={{ .Values.controller.nginxplus }} - - -nginx-configmaps=$(POD_NAMESPACE)/nginx-config + - -nginx-configmaps=$(POD_NAMESPACE)/{{ .Values.controller.config.name }} {{- if .Values.controller.defaultTLS.secret }} - -default-server-tls-secret={{ .Values.controller.defaultTLS.secret }} {{ else }} @@ -88,4 +88,4 @@ spec: {{- end }} - -enable-prometheus-metrics={{ .Values.prometheus.create }} - -prometheus-metrics-listen-port={{ .Values.prometheus.port }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/deployments/helm-chart/values.yaml b/deployments/helm-chart/values.yaml index 432fcbcf13..2b8a6fb695 100644 --- a/deployments/helm-chart/values.yaml +++ b/deployments/helm-chart/values.yaml @@ -25,6 +25,8 @@ controller: pullPolicy: IfNotPresent config: + ## The name of the ConfigMap used by the Ingress controller container. + name: nginx-config ## The entries of the ConfigMap for customizing NGINX configuration. entries: {} @@ -164,4 +166,4 @@ prometheus: create: true ## Configures the port to scrape the metrics. - port: 9113 \ No newline at end of file + port: 9113 From 5a6a62c03674e3e229277039eff84a0443072cee Mon Sep 17 00:00:00 2001 From: paulo Date: Mon, 8 Apr 2019 00:40:41 +0100 Subject: [PATCH 2/2] Add option to specify leader election lock name By default, a ConfigMap with the name `leader-election` is used. This can cause problems if multiple deployments of the Ingress controller exist within the same namespace. See #528 --- cmd/nginx-ingress/main.go | 4 ++++ deployments/helm-chart/README.md | 3 ++- deployments/helm-chart/templates/controller-deployment.yaml | 1 + deployments/helm-chart/values.yaml | 6 +++++- docs/cli-arguments.md | 2 ++ docs/report-ingress-status.md | 1 + internal/k8s/controller.go | 5 ++++- internal/k8s/leader.go | 4 ++-- 8 files changed, 21 insertions(+), 5 deletions(-) diff --git a/cmd/nginx-ingress/main.go b/cmd/nginx-ingress/main.go index 544ba5028f..5a9ea2b645 100644 --- a/cmd/nginx-ingress/main.go +++ b/cmd/nginx-ingress/main.go @@ -84,6 +84,9 @@ The external address of the service is used when reporting the status of Ingress leaderElectionEnabled = flag.Bool("enable-leader-election", false, "Enable Leader election to avoid multiple replicas of the controller reporting the status of Ingress resources -- only one replica will report status. See -report-ingress-status flag.") + leaderElectionLockName = flag.String("leader-election-lock-name", "nginx-ingress-leader-election", + `Specifies the name of the ConfigMap, within the same namespace as the controller, used as the lock for leader election. Requires -enable-leader-election.`) + nginxStatusAllowCIDRs = flag.String("nginx-status-allow-cidrs", "127.0.0.1", `Whitelist IPv4 IP/CIDR blocks to allow access to NGINX stub_status or the NGINX Plus API. Separate multiple IP/CIDR by commas.`) nginxStatusPort = flag.Int("nginx-status-port", 8080, @@ -297,6 +300,7 @@ func main() { ControllerNamespace: controllerNamespace, ReportIngressStatus: *reportIngressStatus, IsLeaderElectionEnabled: *leaderElectionEnabled, + LeaderElectionLockName: *leaderElectionLockName, WildcardTLSSecret: *wildcardTLSSecret, ConfigMaps: *nginxConfigMaps, } diff --git a/deployments/helm-chart/README.md b/deployments/helm-chart/README.md index dbb9de6f74..0ef56a2534 100644 --- a/deployments/helm-chart/README.md +++ b/deployments/helm-chart/README.md @@ -65,7 +65,7 @@ Parameter | Description | Default `controller.image.repository` | The image repository of the Ingress controller. | nginx/nginx-ingress `controller.image.tag` | The tag of the Ingress controller image. | edge `controller.image.pullPolicy` | The pull policy for the Ingress controller image. | IfNotPresent -`controller.config.name` | The name of the ConfigMap used by the Ingress controller container. +`controller.config.name` | The name of the ConfigMap used by the Ingress controller. | nginx-config `controller.config.entries` | The entries of the ConfigMap for customizing NGINX configuration. | {} `controller.defaultTLS.cert` | The base64-encoded TLS certificate for the default HTTPS server. If not specified, a pre-generated self-signed certificate is used. **Note:** It is recommended that you specify your own certificate. | A pre-generated self-signed certificate. `controller.defaultTLS.key` | The base64-encoded TLS key for the default HTTPS server. **Note:** If not specified, a pre-generated key is used. It is recommended that you specify your own key. | A pre-generated key. @@ -103,6 +103,7 @@ Parameter | Description | Default `controller.reportIngressStatus.enable` | Update the address field in the status of Ingresses resources with an external address of the Ingress controller. You must also specify the source of the external address either through an external service via `controller.reportIngressStatus.externalService` or the `external-status-address` entry in the ConfigMap via `controller.config.entries`. **Note:** `controller.config.entries.external-status-address` takes precedence if both are set. | true `controller.reportIngressStatus.externalService` | Specifies the name of the service with the type LoadBalancer through which the Ingress controller is exposed externally. The external address of the service is used when reporting the status of Ingress resources. `controller.reportIngressStatus.enable` must be set to `true`. | nginx-ingress `controller.reportIngressStatus.enableLeaderElection` | Enable Leader election to avoid multiple replicas of the controller reporting the status of Ingress resources. `controller.reportIngressStatus.enable` must be set to `true`. | true +`controller.reportIngressStatus.leaderElectionLockName` | Specifies the name of the ConfigMap, within the same namespace as the controller, used as the lock for leader election. controller.reportIngressStatus.enableLeaderElection must be set to true. | nginx-ingress-leader-election `rbac.create` | Configures RBAC. | true `prometheus.create` | Expose NGINX or NGINX Plus metrics in the Prometheus format. | false `prometheus.port` | Configures the port to scrape the metrics. | 9113 diff --git a/deployments/helm-chart/templates/controller-deployment.yaml b/deployments/helm-chart/templates/controller-deployment.yaml index d76cede415..b3ece9fdf4 100644 --- a/deployments/helm-chart/templates/controller-deployment.yaml +++ b/deployments/helm-chart/templates/controller-deployment.yaml @@ -80,6 +80,7 @@ spec: - -report-ingress-status - -external-service={{ .Values.controller.reportIngressStatus.externalService }} - -enable-leader-election={{ .Values.controller.reportIngressStatus.enableLeaderElection }} + - -leader-election-lock-name={{ .Values.controller.reportIngressStatus.leaderElectionLockName }} {{- end }} {{- if .Values.controller.wildcardTLS.secret }} - -wildcard-tls-secret={{ .Values.controller.wildcardTLS.secret }} diff --git a/deployments/helm-chart/values.yaml b/deployments/helm-chart/values.yaml index 2b8a6fb695..25d43bf1ed 100644 --- a/deployments/helm-chart/values.yaml +++ b/deployments/helm-chart/values.yaml @@ -25,8 +25,9 @@ controller: pullPolicy: IfNotPresent config: - ## The name of the ConfigMap used by the Ingress controller container. + ## The name of the ConfigMap used by the Ingress controller. name: nginx-config + ## The entries of the ConfigMap for customizing NGINX configuration. entries: {} @@ -157,6 +158,9 @@ controller: ## Enable Leader election to avoid multiple replicas of the controller reporting the status of Ingress resources. controller.reportIngressStatus.enable must be set to true. enableLeaderElection: true + ## Specifies the name of the ConfigMap, within the same namespace as the controller, used as the lock for leader election. controller.reportIngressStatus.enableLeaderElection must be set to true. + leaderElectionLockName: "nginx-ingress-leader-election" + rbac: ## Configures RBAC. create: true diff --git a/docs/cli-arguments.md b/docs/cli-arguments.md index 8303af3e6f..ea2626fd1c 100644 --- a/docs/cli-arguments.md +++ b/docs/cli-arguments.md @@ -29,6 +29,8 @@ Usage of ./nginx-ingress: -ingress-template-path string Path to the ingress NGINX configuration template for an ingress resource. (default for NGINX "nginx.ingress.tmpl"; default for NGINX Plus "nginx-plus.ingress.tmpl") + -leader-election-lock-name + Specifies the name of the ConfigMap, within the same namespace as the controller, used as the lock for leader election. Requires -enable-leader-election. -log_backtrace_at value when logging hits line file:N, emit a stack trace -log_dir string diff --git a/docs/report-ingress-status.md b/docs/report-ingress-status.md index 88b2b64509..240efe68a6 100644 --- a/docs/report-ingress-status.md +++ b/docs/report-ingress-status.md @@ -17,5 +17,6 @@ The Ingress controller must be configured to report an Ingress status: 2. A Service of the type LoadBalancer configured with an external IP or address and specified by the `-external-service` command-line flag. 3. If you're running multiple replicas of the Ingress controller, enable leader election with the `-enable-leader-election` flag to ensure that only one replica updates an Ingress status. +4. By default, the Ingress controller will use a ConfigMap with the name `nginx-ingress-leader-election` as the lock. This can be customised via the `-leader-election-lock-name` flag. Notes: The Ingress controller does not clear the status of Ingress resources when it is being shut down. diff --git a/internal/k8s/controller.go b/internal/k8s/controller.go index f3ccfd910d..cac9ce8198 100644 --- a/internal/k8s/controller.go +++ b/internal/k8s/controller.go @@ -74,6 +74,7 @@ type LoadBalancerController struct { leaderElector *leaderelection.LeaderElector reportIngressStatus bool isLeaderElectionEnabled bool + leaderElectionLockName string resync time.Duration namespace string controllerNamespace string @@ -96,6 +97,7 @@ type NewLoadBalancerControllerInput struct { ControllerNamespace string ReportIngressStatus bool IsLeaderElectionEnabled bool + LeaderElectionLockName string WildcardTLSSecret string ConfigMaps string } @@ -111,6 +113,7 @@ func NewLoadBalancerController(input NewLoadBalancerControllerInput) *LoadBalanc useIngressClassOnly: input.UseIngressClassOnly, reportIngressStatus: input.ReportIngressStatus, isLeaderElectionEnabled: input.IsLeaderElectionEnabled, + leaderElectionLockName: input.LeaderElectionLockName, resync: input.ResyncPeriod, namespace: input.Namespace, controllerNamespace: input.ControllerNamespace, @@ -168,7 +171,7 @@ func (lbc *LoadBalancerController) UpdateManagedAndMergeableIngresses(ingresses // addLeaderHandler adds the handler for leader election to the controller func (lbc *LoadBalancerController) addLeaderHandler(leaderHandler leaderelection.LeaderCallbacks) { var err error - lbc.leaderElector, err = newLeaderElector(lbc.client, leaderHandler, lbc.controllerNamespace) + lbc.leaderElector, err = newLeaderElector(lbc.client, leaderHandler, lbc.controllerNamespace, lbc.leaderElectionLockName) if err != nil { glog.V(3).Infof("Error starting LeaderElection: %v", err) } diff --git a/internal/k8s/leader.go b/internal/k8s/leader.go index 3b5e300e65..6ac75cb4ec 100644 --- a/internal/k8s/leader.go +++ b/internal/k8s/leader.go @@ -17,7 +17,7 @@ import ( ) // newLeaderElector creates a new LeaderElection and returns the Elector. -func newLeaderElector(client kubernetes.Interface, callbacks leaderelection.LeaderCallbacks, namespace string) (*leaderelection.LeaderElector, error) { +func newLeaderElector(client kubernetes.Interface, callbacks leaderelection.LeaderCallbacks, namespace string, lockName string) (*leaderelection.LeaderElector, error) { podName := os.Getenv("POD_NAME") broadcaster := record.NewBroadcaster() @@ -27,7 +27,7 @@ func newLeaderElector(client kubernetes.Interface, callbacks leaderelection.Lead recorder := broadcaster.NewRecorder(scheme.Scheme, source) lock := resourcelock.ConfigMapLock{ - ConfigMapMeta: metav1.ObjectMeta{Namespace: namespace, Name: "leader-election"}, + ConfigMapMeta: metav1.ObjectMeta{Namespace: namespace, Name: lockName}, Client: client.CoreV1(), LockConfig: resourcelock.ResourceLockConfig{ Identity: podName,