Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose API/stub_status on a custom port #344

Merged
merged 6 commits into from
Aug 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/cli-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ Usage of ./nginx-ingress:
Format: <namespace>/<name>
-nginx-plus
Enable support for NGINX Plus
-nginx-status
Enable the NGINX stub_status, or the NGINX Plus API. (default true)
-nginx-status-port int
Set the port where the NGINX stub_status or the NGINX Plus API is exposed. [1023 - 65535] (default 8080)
-proxy string
Use a proxy server to connect to Kubernetes API started by "kubectl proxy" command. For testing purposes only.
The Ingress controller does not start NGINX and does not write any generated NGINX configuration files to disk
Expand Down
15 changes: 13 additions & 2 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,21 @@ The public IP can be reported in the status of an ingress resource. To enable:

Read more about the type LoadBalancer [here](https://kubernetes.io/docs/concepts/services-networking/service/#type-loadbalancer).

## 5. Access the Live Activity Monitoring Dashboard
## 5. Access the Live Activity Monitoring Dashboard / Stub_status Page
For NGINX, you can access the [stub_status page](http://nginx.org/en/docs/http/ngx_http_stub_status_module.html):
1. Stub_status is enabled by default. Ensure that the `nginx-status` command-line argument is not set to false.
2. Stub_status is available on port 8080 by default. It is customizable by the `nginx-status-port` command-line argument. If yours is not on 8080, modify the kubectl proxy command below.
1. Use the `kubectl port-forward` command to forward connections to port 8080 on your local machine to port 8080 of an NGINX Ingress controller pod (replace `<nginx-ingress-pod>` with the actual name of a pod):.
```
$ kuebctl port-forward <nginx-ingress-pod> 8080:8080 --namespace=nginx-ingress
```
Open your browser at http://127.0.0.1:8080/stub_status to access the status.


For NGINX Plus, you can access the live activity monitoring dashboard:
1. Use `kubectl port-forward` command to forward connections to port 8080 on your local machine to port 8080 of an NGINX Plus Ingress controller pod (replace <nginx-plus-ingress-pod> with the actual name of a pod):
1. The dashboard is enabled by default. Ensure that the `nginx-status` command-line argument is not set to false.
1. The dashboard is available on port 8080 by default. It is customizable by the `nginx-status-port` command-line argument. If yours is not on 8080, modify the kubectl proxy command below.
1. Use the `kubectl port-forward` command to forward connections to port 8080 on your local machine to port 8080 of an NGINX Plus Ingress controller pod (replace `<nginx-plus-ingress-pod>` with the actual name of a pod):
```
$ kubectl port-forward <nginx-plus-ingress-pod> 8080:8080 --namespace=nginx-ingress
```
Expand Down
8 changes: 4 additions & 4 deletions examples/complete-example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ certificate and the --resolve option to set the Host header of a request with ``
Server name: tea-7cd44fcb4d-xfw2x
...
```
1. If you're using NGINX Plus, you can open the live activity monitoring dashboard:
1. Follow the [instructions](../../docs/installation.md#5-access-the-live-activity-monitoring-dashboard) to access the dashboard.
1. If you go to the Upstream tab, you'll see: ![dashboard](dashboard.png)

1. You can view an NGINX status page, either stub_status for NGINX, or the Live Activity Monitoring Dashboard for NGINX Plus:
1. Follow the [instructions](../../docs/installation.md#5-access-the-live-activity-monitoring-dashboard--stub_status-page) to access the status page.
1. For NGINX Plus, If you go to the Upstream tab, you'll see: ![dashboard](dashboard.png)
2 changes: 1 addition & 1 deletion nginx-controller/controller/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -926,7 +926,7 @@ func TestFindIngressesForSecret(t *testing.T) {
t.Run(test.desc, func(t *testing.T) {
fakeClient := fake.NewSimpleClientset()

templateExecutor, err := nginx.NewTemplateExecutor("../nginx/templates/nginx-plus.tmpl", "../nginx/templates/nginx-plus.ingress.tmpl", true)
templateExecutor, err := nginx.NewTemplateExecutor("../nginx/templates/nginx-plus.tmpl", "../nginx/templates/nginx-plus.ingress.tmpl", true, true, 8080)
if err != nil {
t.Fatalf("templateExecuter could not start: %v", err)
}
Expand Down
37 changes: 35 additions & 2 deletions nginx-controller/main.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package main

import (
"context"
"flag"
"fmt"
"net"
"net/http"
"os"
"os/signal"
Expand Down Expand Up @@ -78,6 +80,12 @@ 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.")

nginxStatusPort = flag.Int("nginx-status-port", 8080,
"Set the port where the NGINX stub_status or the NGINX Plus API is exposed. [1023 - 65535]")

nginxStatus = flag.Bool("nginx-status", true,
"Enable the NGINX stub_status, or the NGINX Plus API.")
)

func main() {
Expand All @@ -89,6 +97,11 @@ func main() {
os.Exit(0)
}

portValidationError := validateStatusPort(*nginxStatusPort)
if portValidationError != nil {
glog.Fatalf("Invalid value for nginx-status-port: %v", portValidationError)
}

glog.Infof("Starting NGINX Ingress controller Version=%v GitCommit=%v\n", version, gitCommit)

var err error
Expand Down Expand Up @@ -131,7 +144,7 @@ func main() {
nginxIngressTemplatePath = *ingressTemplatePath
}

templateExecutor, err := nginx.NewTemplateExecutor(nginxConfTemplatePath, nginxIngressTemplatePath, *healthStatus)
templateExecutor, err := nginx.NewTemplateExecutor(nginxConfTemplatePath, nginxIngressTemplatePath, *healthStatus, *nginxStatus, *nginxStatusPort)
if err != nil {
glog.Fatalf("Error creating TemplateExecutor: %v", err)
}
Expand Down Expand Up @@ -206,7 +219,9 @@ func main() {
var nginxAPI *plus.NginxAPIController
if *nginxPlus {
time.Sleep(500 * time.Millisecond)
nginxAPI, err = plus.NewNginxAPIController(&http.Client{}, "http://127.0.0.1:8080/api", local)
httpClient := getSocketClient()
apiURL := fmt.Sprintf("http://127.0.0.1:%v/api", *nginxStatusPort)
nginxAPI, err = plus.NewNginxAPIController(&httpClient, apiURL, local)
if err != nil {
glog.Fatalf("Failed to create NginxAPIController: %v", err)
}
Expand Down Expand Up @@ -272,3 +287,21 @@ func handleTermination(lbc *controller.LoadBalancerController, ngxc *nginx.Nginx
glog.Infof("Exiting with a status: %v", exitStatus)
os.Exit(exitStatus)
}

// getSocketClient gets an http.Client with the a unix socket transport.
func getSocketClient() http.Client {
return http.Client{
Transport: &http.Transport{
DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
return net.Dial("unix", "/var/run/nginx-plus-api.sock")
},
},
}
}

func validateStatusPort(nginxStatusPort int) error {
if nginxStatusPort < 1023 || nginxStatusPort > 65535 {
return fmt.Errorf("port outside of valid port range [1023 - 65535]: %v", nginxStatusPort)
}
return nil
}
24 changes: 24 additions & 0 deletions nginx-controller/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import (
"testing"
)

func TestValidateStatusPort(t *testing.T) {
badPorts := []int{80, 443, 1, 1022, 65536}
for _, badPort := range badPorts {
err := validateStatusPort(badPort)
if err == nil {
t.Errorf("Expected error for port %v\n", badPort)
}
}

goodPorts := []int{8080, 8081, 8082, 1023, 65535}
for _, goodPort := range goodPorts {
err := validateStatusPort(goodPort)
if err != nil {
t.Errorf("Error for valid port: %v err: %v\n", goodPort, err)
}
}

}
2 changes: 1 addition & 1 deletion nginx-controller/nginx/configurator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ func createExpectedConfigForMergeableCafeIngress() IngressNginxConfig {
}

func createTestConfigurator() *Configurator {
templateExecutor, _ := NewTemplateExecutor("templates/nginx-plus.tmpl", "templates/nginx-plus.ingress.tmpl", true)
templateExecutor, _ := NewTemplateExecutor("templates/nginx-plus.tmpl", "templates/nginx-plus.ingress.tmpl", true, true, 8080)
ngxc := NewNginxController("/etc/nginx", true)
apiCtrl, _ := plus.NewNginxAPIController(&http.Client{}, "", true)
return NewConfigurator(ngxc, NewDefaultConfig(), apiCtrl, templateExecutor)
Expand Down
2 changes: 2 additions & 0 deletions nginx-controller/nginx/nginx.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ type NginxMainConfig struct {
ErrorLogLevel string
StreamLogFormat string
HealthStatus bool
NginxStatus bool
NginxStatusPort int
MainSnippets []string
HTTPSnippets []string
StreamSnippets []string
Expand Down
14 changes: 12 additions & 2 deletions nginx-controller/nginx/template_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import (
// TemplateExecutor executes NGINX configuration templates
type TemplateExecutor struct {
HealthStatus bool
NginxStatus bool
NginxStatusPort int
mainTemplate *template.Template
ingressTemplate *template.Template
}

// NewTemplateExecutor creates a TemplateExecutor
func NewTemplateExecutor(mainTemplatePath string, ingressTemplatePath string, healthStatus bool) (*TemplateExecutor, error) {
func NewTemplateExecutor(mainTemplatePath string, ingressTemplatePath string, healthStatus bool, nginxStatus bool, nginxStatusPort int) (*TemplateExecutor, error) {
// template name must be the base name of the template file https://golang.org/pkg/text/template/#Template.ParseFiles
nginxTemplate, err := template.New(path.Base(mainTemplatePath)).ParseFiles(mainTemplatePath)
if err != nil {
Expand All @@ -26,7 +28,13 @@ func NewTemplateExecutor(mainTemplatePath string, ingressTemplatePath string, he
return nil, err
}

return &TemplateExecutor{mainTemplate: nginxTemplate, ingressTemplate: ingressTemplate, HealthStatus: healthStatus}, nil
return &TemplateExecutor{
mainTemplate: nginxTemplate,
ingressTemplate: ingressTemplate,
HealthStatus: healthStatus,
NginxStatus: nginxStatus,
NginxStatusPort: nginxStatusPort,
}, nil
}

// UpdateMainTemplate updates the main NGINX template
Expand Down Expand Up @@ -54,6 +62,8 @@ func (te *TemplateExecutor) UpdateIngressTemplate(templateString *string) error
// ExecuteMainConfigTemplate generates the content of the main NGINX configuration file
func (te *TemplateExecutor) ExecuteMainConfigTemplate(cfg *NginxMainConfig) ([]byte, error) {
cfg.HealthStatus = te.HealthStatus
cfg.NginxStatus = te.NginxStatus
cfg.NginxStatusPort = te.NginxStatusPort

var configBuffer bytes.Buffer
err := te.mainTemplate.Execute(&configBuffer, cfg)
Expand Down
24 changes: 17 additions & 7 deletions nginx-controller/nginx/templates/nginx-plus.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@ http {
return 404;
}
}


{{- if .NginxStatus }}
# NGINX Plus APIs
server {
listen 8080;
listen {{.NginxStatusPort}};

root /usr/share/nginx/html;

Expand All @@ -97,11 +97,21 @@ http {
location = /dashboard.html {
}

allow 127.0.0.1;
deny all;

location /api {
api write=off;
}
}
{{- end }}

# NGINX Plus API over unix socket
server {
listen unix:/var/run/nginx-plus-api.sock;
access_log off;

location /api {
limit_except GET {
allow 127.0.0.1;
deny all;
}
api write=on;
}
}
Expand All @@ -123,4 +133,4 @@ stream {
{{range $value := .StreamSnippets}}
{{$value}}
{{end}}
}
}
17 changes: 16 additions & 1 deletion nginx-controller/nginx/templates/nginx.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,21 @@ http {
}
}

{{- if .NginxStatus }}
# stub_status
server {
listen {{.NginxStatusPort}};

allow 127.0.0.1;
deny all;

location /stub_status {
stub_status;
}
}
{{- end }}


include /etc/nginx/conf.d/*.conf;
}

Expand All @@ -99,4 +114,4 @@ stream {
{{range $value := .StreamSnippets}}
{{$value}}
{{end}}
}
}