Merge branch 'master' into xff
6
.gitignore
vendored
|
@ -39,3 +39,9 @@ site
|
|||
|
||||
# temporal github pages
|
||||
gh-pages
|
||||
|
||||
# Docker-based builds
|
||||
/test/binaries
|
||||
/.env
|
||||
/.gocache/
|
||||
/bin/
|
||||
|
|
41
.travis.yml
|
@ -5,29 +5,27 @@ sudo: required
|
|||
services:
|
||||
- docker
|
||||
|
||||
language: go
|
||||
# FIXME(#46924): these two commands are required to enable IPv6,
|
||||
# they shouldn't exist, please revert once more official solutions appeared.
|
||||
# see https://github.com/travis-ci/travis-ci/issues/8891#issuecomment-353403729
|
||||
before_install:
|
||||
- echo '{"ipv6":true,"fixed-cidr-v6":"2001:db8:1::/64"}' | sudo tee /etc/docker/daemon.json
|
||||
- sudo service docker restart
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- luarocks
|
||||
language: generic
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_failure: always
|
||||
on_success: never
|
||||
|
||||
go:
|
||||
- 1.10.2
|
||||
|
||||
go_import_path: k8s.io/ingress-nginx
|
||||
|
||||
# New secure variables can be added using travis encrypt -r kubernetes/ingress-nginx --add K=V
|
||||
env:
|
||||
global:
|
||||
- CHANGE_MINIKUBE_NONE_USER=true
|
||||
- KUBERNETES_VERSION=v1.10.0
|
||||
- DOCKER=docker
|
||||
- SKIP_SNAPSHOT=true
|
||||
- NODE_IP=10.192.0.3
|
||||
- E2E_NODES=6
|
||||
- GH_REF=github.com/kubernetes/ingress-nginx
|
||||
- secure: LIS2XpZufWTcJ53jiRsSZy2Gi1EUJ1XmLg7z3f2ZHeMnyG2Jhk3GW4vod1FNru+PY4PWgddLdCdIl+jqOYXndFlbdAWF3/Oy5fEkYLXdYV7tdlHcPWDkqNFrfiyZ4guChN+b2Nk6FqU7o5fsZAIR7VAbgqNRF5XMo9Mhn/vhDCQRcnbXy7uq7JTrYUkqDbQoyYvT6b480GCY5gags1zp/xZfPDNZEe936o8i5IPTyiykRyNOXN/AH6kd3pR5e1xYgcvJ9KpSVPghcwFE7kJ4fOVMRhRG5ML+IyML+xD0jX43EMNoqRKZ/HS42kIMCInFbJEcxVde7DPNBZ7Y3GAqh7HO6qrE70Dn3ha6DID6zCoH2ArW39BxG4zempjn2VxYoMRGREyZszWQb++dwGoHmo5FHt6zvIrYBG0dA0H8ja9VkZkjFwtYTGHU1ooPzUfJK4O4VBayV8LqZibyZQR+GrmyQc0aagUY7J/fe4A2PJyI4DbkeZ7GX1ELj0ciDz4urQSzUc8l/T3aU3X+FuJItjgYtMLPmqcjA5uifDCtutE8Z9L2gSpanqUdvLSOozuxPho/KNl+2YlF7fXqPW3LnRf5mHD+NbOff306pvKlHJOb2Vmth+HBQ1XDzt/Cy5+sfwS3E0Vmh6UTq/NtkUXxwH10BDMF7FMVlQ4zdHQvyZ0=
|
||||
- secure: rKDoy9IYYYy0fYBs4+9mwuBVq/TcxfFwMfE0ywYWhUUdgzrUYSJAwpoe/96EQ4YmESUefwC2nDNq4G3XzJKYOWf83PaIveb9Z//zmMrCQXjDuDBDLpwV3sXSh7evXiVDohJz4ogBCeMRUCMKYsyKBM9yWfa/iu+yI92dbphpK9peOKW6yBc0uspJlln4swN3GS2WT9LVuPY2Azv9U2UqrXufOPDKG/qEb/Vrn4yZ2lR/50r2k45e9nSvDoByvr10V8ubM5Zc0iP0vBuAUVRdByv6N53Q4gaBGapY6SxhIjIPC/h0rNnuT9EXp7MWaPT5FmBxLt9wnyleT9QhZJnFyaBYqFgcz/DKifYQkryY4M5dLMo/Rt3yATyAy8Y0df1TOoV2dKdqwOOwQ8bXB1wDfyrGxmQj9HY4Ffnphx3wPE1a+Sjuh+S5Epm7XJbPx5pZJqNO2hd4sTbk0Xp3gpPbihny2r/jtNwHl0wpFCfOM68RNrsVRlIwG3UhzbZvblbQ/M/mmWCdgzINjt07I2SGCJxfKG0e98Q49SKUoDoOgQTTRDqTC9IgOEDxyfAkT0Vr6BtlP88Nsgnf6kmboyigBrRAiaDQGTxn3SP6LnQI3CeopaRDYvFZe/rTwPXE9XlKoTn9FTWnAqF3MuWaLslDcDKYEh7OaYJjF01piu6g4Nc=
|
||||
|
@ -38,29 +36,16 @@ jobs:
|
|||
include:
|
||||
- stage: Static Check
|
||||
script:
|
||||
- sudo luarocks install luacheck
|
||||
- make luacheck
|
||||
- mkdir --parents $GOPATH/src/golang.org/x
|
||||
&& git clone --depth=1 https://go.googlesource.com/lint $GOPATH/src/golang.org/x/lint
|
||||
&& go get golang.org/x/lint/golint
|
||||
- go get github.com/vbatts/git-validation
|
||||
- make verify-all
|
||||
- make static-check
|
||||
- stage: Lua Unit Test
|
||||
before_script:
|
||||
- rootfs/etc/nginx/lua/test/up.sh
|
||||
script:
|
||||
- make lua-test
|
||||
- stage: Coverage
|
||||
before_script:
|
||||
# start minikube
|
||||
- test/e2e/up.sh
|
||||
script:
|
||||
- make cover
|
||||
- stage: e2e
|
||||
before_script:
|
||||
- go get github.com/onsi/ginkgo/ginkgo
|
||||
- test/e2e/up.sh
|
||||
- make dev-env
|
||||
script:
|
||||
- make e2e-test
|
||||
# split builds to avoid job timeouts
|
||||
|
@ -71,18 +56,22 @@ jobs:
|
|||
- stage: publish arm
|
||||
if: type = api AND branch = master AND repo = kubernetes/ingress-nginx
|
||||
script:
|
||||
- make register-qemu
|
||||
- .travis/publish.sh arm
|
||||
- stage: publish arm64
|
||||
if: type = api AND branch = master AND repo = kubernetes/ingress-nginx
|
||||
script:
|
||||
- make register-qemu
|
||||
- .travis/publish.sh arm64
|
||||
- stage: publish ppc64le
|
||||
if: type = api AND branch = master AND repo = kubernetes/ingress-nginx
|
||||
script:
|
||||
- make register-qemu
|
||||
- .travis/publish.sh ppc64le
|
||||
- stage: publish s390x
|
||||
if: type = api AND branch = master AND repo = kubernetes/ingress-nginx
|
||||
script:
|
||||
- make register-qemu
|
||||
- .travis/publish.sh s390x
|
||||
- stage: Publish docs
|
||||
if: type = api AND branch = master AND repo = kubernetes/ingress-nginx
|
||||
|
|
293
Changelog.md
|
@ -1,5 +1,298 @@
|
|||
# Changelog
|
||||
|
||||
### 0.18.0
|
||||
|
||||
**Image:** `quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.18.0`
|
||||
|
||||
*New Features:*
|
||||
|
||||
- NGINX 1.15.2
|
||||
- Dynamic configuration is enabled by default
|
||||
- Support for AJP protocol
|
||||
- Use of authbind to bind privileged ports
|
||||
- Replace minikube with [kubeadm-dind-cluster](https://github.com/kubernetes-sigs/kubeadm-dind-cluster) to run e2e tests
|
||||
|
||||
*Changes:*
|
||||
|
||||
- [X] [#2789](https://github.com/kubernetes/ingress-nginx/pull/2789) Remove KubeConfig Dependency for Store Tests
|
||||
- [X] [#2794](https://github.com/kubernetes/ingress-nginx/pull/2794) enable dynamic backend configuration by default
|
||||
- [X] [#2795](https://github.com/kubernetes/ingress-nginx/pull/2795) start minikube before trying to build the image
|
||||
- [X] [#2804](https://github.com/kubernetes/ingress-nginx/pull/2804) add support for ExternalName service type in dynamic mode
|
||||
- [X] [#2808](https://github.com/kubernetes/ingress-nginx/pull/2808) fix the bug #2799, add prefix (?i) in rewrite statement.
|
||||
- [X] [#2811](https://github.com/kubernetes/ingress-nginx/pull/2811) Escape $request_uri for external auth
|
||||
- [X] [#2812](https://github.com/kubernetes/ingress-nginx/pull/2812) modified annotation name "rewrite-to" to "rewrite-target" in comments
|
||||
- [X] [#2819](https://github.com/kubernetes/ingress-nginx/pull/2819) Catch errors waiting for controller deployment
|
||||
- [X] [#2823](https://github.com/kubernetes/ingress-nginx/pull/2823) Multiple optimizations to build targets
|
||||
- [X] [#2825](https://github.com/kubernetes/ingress-nginx/pull/2825) Refactoring of how we run as user
|
||||
- [X] [#2826](https://github.com/kubernetes/ingress-nginx/pull/2826) Remove setcap from image and update nginx to 0.15.1
|
||||
- [X] [#2827](https://github.com/kubernetes/ingress-nginx/pull/2827) Use nginx image as base and install go on top
|
||||
- [X] [#2829](https://github.com/kubernetes/ingress-nginx/pull/2829) use resty-cli for running lua unit tests
|
||||
- [X] [#2830](https://github.com/kubernetes/ingress-nginx/pull/2830) Remove lua mocks
|
||||
- [X] [#2834](https://github.com/kubernetes/ingress-nginx/pull/2834) Added permanent-redirect-code
|
||||
- [X] [#2844](https://github.com/kubernetes/ingress-nginx/pull/2844) Do not allow invalid latency values in metrics
|
||||
- [X] [#2852](https://github.com/kubernetes/ingress-nginx/pull/2852) fix custom-error-pages functionality in dynamic mode
|
||||
- [X] [#2853](https://github.com/kubernetes/ingress-nginx/pull/2853) improve annotations/default_backend e2e test
|
||||
- [X] [#2858](https://github.com/kubernetes/ingress-nginx/pull/2858) Update build image
|
||||
- [X] [#2859](https://github.com/kubernetes/ingress-nginx/pull/2859) Fix inconsistent metric labels
|
||||
- [X] [#2863](https://github.com/kubernetes/ingress-nginx/pull/2863) Replace minikube for e2e tests
|
||||
- [X] [#2867](https://github.com/kubernetes/ingress-nginx/pull/2867) fix bug with lua e2e test suite
|
||||
- [X] [#2868](https://github.com/kubernetes/ingress-nginx/pull/2868) Use an existing e2e image
|
||||
- [X] [#2869](https://github.com/kubernetes/ingress-nginx/pull/2869) describe under what circumstances and how we avoid Nginx reload
|
||||
- [X] [#2871](https://github.com/kubernetes/ingress-nginx/pull/2871) Add support for AJP protocol
|
||||
- [X] [#2872](https://github.com/kubernetes/ingress-nginx/pull/2872) Update nginx to 1.15.2
|
||||
- [X] [#2874](https://github.com/kubernetes/ingress-nginx/pull/2874) Delay initial prometheus status metric
|
||||
- [X] [#2876](https://github.com/kubernetes/ingress-nginx/pull/2876) Remove dashboard an tune sync-frequency
|
||||
- [X] [#2877](https://github.com/kubernetes/ingress-nginx/pull/2877) Refactor entrypoint to avoid issues with volumes
|
||||
- [X] [#2885](https://github.com/kubernetes/ingress-nginx/pull/2885) fix: Sort TCP/UDP upstream order
|
||||
- [X] [#2888](https://github.com/kubernetes/ingress-nginx/pull/2888) Fix grafana datasources
|
||||
- [X] [#2890](https://github.com/kubernetes/ingress-nginx/pull/2890) Usability improvements to build steps
|
||||
- [X] [#2893](https://github.com/kubernetes/ingress-nginx/pull/2893) Update nginx image
|
||||
- [X] [#2894](https://github.com/kubernetes/ingress-nginx/pull/2894) Use authbind to bind privileged ports
|
||||
- [X] [#2895](https://github.com/kubernetes/ingress-nginx/pull/2895) support custom configuration to main context of nginx config
|
||||
- [X] [#2896](https://github.com/kubernetes/ingress-nginx/pull/2896) support configuring multi_accept directive via configmap
|
||||
- [X] [#2897](https://github.com/kubernetes/ingress-nginx/pull/2897) Enable reuse-port by default
|
||||
- [X] [#2905](https://github.com/kubernetes/ingress-nginx/pull/2905) Fix IPV6 detection
|
||||
|
||||
*Documentation:*
|
||||
|
||||
- [X] [#2816](https://github.com/kubernetes/ingress-nginx/pull/2816) doc log-format: add variables about ingress
|
||||
- [X] [#2866](https://github.com/kubernetes/ingress-nginx/pull/2866) Update index.md
|
||||
- [X] [#2898](https://github.com/kubernetes/ingress-nginx/pull/2898) Fix default sync-period doc
|
||||
- [X] [#2903](https://github.com/kubernetes/ingress-nginx/pull/2903) Very minor grammar fix
|
||||
|
||||
### 0.17.1
|
||||
|
||||
**Image:** `quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.17.1`
|
||||
|
||||
*Changes:*
|
||||
|
||||
- [X] [#2782](https://github.com/kubernetes/ingress-nginx/pull/2782) Add Better Error Handling for SSLSessionTicketKey
|
||||
- [X] [#2790](https://github.com/kubernetes/ingress-nginx/pull/2790) Update prometheus labels
|
||||
|
||||
*Documentation:*
|
||||
|
||||
- [X] [#2770](https://github.com/kubernetes/ingress-nginx/pull/2770) Basic-Auth doc misleading: fix double quotes leading to nginx config error
|
||||
|
||||
### 0.17.0
|
||||
|
||||
**Image:** `quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.17.0`
|
||||
|
||||
*New Features:*
|
||||
|
||||
- [Grafana dashboards](https://github.com/kubernetes/ingress-nginx/tree/master/deploy/grafana/dashboards)
|
||||
|
||||
*Changes:*
|
||||
|
||||
- [X] [#2705](https://github.com/kubernetes/ingress-nginx/pull/2705) Remove duplicated securityContext
|
||||
- [X] [#2719](https://github.com/kubernetes/ingress-nginx/pull/2719) Sample rate configmap option for zipkin in nginx-opentracing
|
||||
- [X] [#2726](https://github.com/kubernetes/ingress-nginx/pull/2726) Cleanup prometheus metrics after a reload
|
||||
- [X] [#2727](https://github.com/kubernetes/ingress-nginx/pull/2727) Add e2e tests for Client-Body-Buffer-Size
|
||||
- [X] [#2732](https://github.com/kubernetes/ingress-nginx/pull/2732) Improve logging
|
||||
- [X] [#2741](https://github.com/kubernetes/ingress-nginx/pull/2741) Add redirect uri for oauth2 login
|
||||
- [X] [#2744](https://github.com/kubernetes/ingress-nginx/pull/2744) fix: Use the correct opentracing plugin for Jaeger
|
||||
- [X] [#2747](https://github.com/kubernetes/ingress-nginx/pull/2747) Update opentracing-cpp and modsecurity
|
||||
- [X] [#2748](https://github.com/kubernetes/ingress-nginx/pull/2748) Update nginx image to 0.54
|
||||
- [X] [#2749](https://github.com/kubernetes/ingress-nginx/pull/2749) Use docker to build go binaries
|
||||
- [X] [#2754](https://github.com/kubernetes/ingress-nginx/pull/2754) Allow gzip compression level to be controlled via ConfigMap
|
||||
- [X] [#2760](https://github.com/kubernetes/ingress-nginx/pull/2760) Fix ingress rule parsing error
|
||||
- [X] [#2767](https://github.com/kubernetes/ingress-nginx/pull/2767) Fix regression introduced in #2732
|
||||
- [X] [#2771](https://github.com/kubernetes/ingress-nginx/pull/2771) Grafana Dashboard
|
||||
- [X] [#2775](https://github.com/kubernetes/ingress-nginx/pull/2775) Simplify handler registration and updates prometheus
|
||||
- [X] [#2776](https://github.com/kubernetes/ingress-nginx/pull/2776) Fix configuration hash calculation
|
||||
|
||||
*Documentation:*
|
||||
|
||||
- [X] [#2717](https://github.com/kubernetes/ingress-nginx/pull/2717) GCE/GKE proxy mentioned for Azure
|
||||
- [X] [#2743](https://github.com/kubernetes/ingress-nginx/pull/2743) Clarify Installation Document by Separating Helm Steps
|
||||
- [X] [#2761](https://github.com/kubernetes/ingress-nginx/pull/2761) Fix spelling mistake
|
||||
- [X] [#2764](https://github.com/kubernetes/ingress-nginx/pull/2764) Use language neutral links to MDN
|
||||
- [X] [#2765](https://github.com/kubernetes/ingress-nginx/pull/2765) Add FOSSA status badge
|
||||
- [X] [#2777](https://github.com/kubernetes/ingress-nginx/pull/2777) Build docs using local docker image [ci skip]
|
||||
|
||||
### 0.16.2
|
||||
|
||||
**Image:** `quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.16.2`
|
||||
|
||||
*Breaking changes:*
|
||||
|
||||
Running as user requires an update in the deployment manifest.
|
||||
|
||||
```yaml
|
||||
securityContext:
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- NET_BIND_SERVICE
|
||||
# www-data -> 33
|
||||
runAsUser: 33
|
||||
```
|
||||
|
||||
Note: the deploy [guide](https://kubernetes.github.io/ingress-nginx/deploy/#mandatory-command) contains this change
|
||||
|
||||
*Changes:*
|
||||
|
||||
- [X] [#2678](https://github.com/kubernetes/ingress-nginx/pull/2678) Refactor server type to include SSLCert
|
||||
- [X] [#2685](https://github.com/kubernetes/ingress-nginx/pull/2685) Fix qemu docker build
|
||||
- [X] [#2696](https://github.com/kubernetes/ingress-nginx/pull/2696) If server_tokens is disabled completely remove the Server header
|
||||
- [X] [#2698](https://github.com/kubernetes/ingress-nginx/pull/2698) Improve best-cert guessing with empty tls.hosts
|
||||
- [X] [#2701](https://github.com/kubernetes/ingress-nginx/pull/2701) Remove prometheus labels with high cardinality
|
||||
|
||||
*Documentation:*
|
||||
|
||||
- [X] [#2368](https://github.com/kubernetes/ingress-nginx/pull/2368) [aggregate] Fix typos across codebase
|
||||
- [X] [#2681](https://github.com/kubernetes/ingress-nginx/pull/2681) Typo fix in error message: encounted->encountered
|
||||
- [X] [#2697](https://github.com/kubernetes/ingress-nginx/pull/2697) Enhance Distributed Tracing Documentation
|
||||
|
||||
### 0.16.1
|
||||
|
||||
**Image:** `quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.16.1`
|
||||
|
||||
*Breaking changes:*
|
||||
|
||||
Running as user requires an update in the deployment manifest.
|
||||
|
||||
```yaml
|
||||
securityContext:
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- NET_BIND_SERVICE
|
||||
# www-data -> 33
|
||||
runAsUser: 33
|
||||
```
|
||||
|
||||
Note: the deploy [guide](https://kubernetes.github.io/ingress-nginx/deploy/#mandatory-command) contains this change
|
||||
|
||||
*New Features:*
|
||||
|
||||
- Run as user dropping root privileges
|
||||
- New prometheus metric implementation (VTS module was removed)
|
||||
- [InfluxDB integration](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#influxdb)
|
||||
- [Module GeoIP2](https://github.com/leev/ngx_http_geoip2_module)
|
||||
|
||||
*Changes:*
|
||||
|
||||
- [X] [#2692](https://github.com/kubernetes/ingress-nginx/pull/2692) Fix initial read of configuration configmap
|
||||
- [X] [#2693](https://github.com/kubernetes/ingress-nginx/pull/2693) Revert #2669
|
||||
- [X] [#2694](https://github.com/kubernetes/ingress-nginx/pull/2694) Add note about status update
|
||||
|
||||
|
||||
### 0.16.0
|
||||
|
||||
**Image:** `quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.16.1`
|
||||
|
||||
*Breaking changes:*
|
||||
|
||||
Running as user requires an update in the deployment manifest.
|
||||
|
||||
```yaml
|
||||
securityContext:
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- NET_BIND_SERVICE
|
||||
# www-data -> 33
|
||||
runAsUser: 33
|
||||
```
|
||||
|
||||
Note: the deploy [guide](https://kubernetes.github.io/ingress-nginx/deploy/#mandatory-command) contains this change
|
||||
|
||||
*New Features:*
|
||||
|
||||
- Run as user dropping root privileges
|
||||
- New prometheus metric implementation (VTS module was removed)
|
||||
- [InfluxDB integration](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#influxdb)
|
||||
- [Module GeoIP2](https://github.com/leev/ngx_http_geoip2_module)
|
||||
|
||||
*Changes:*
|
||||
|
||||
- [X] [#2423](https://github.com/kubernetes/ingress-nginx/pull/2423) Resolves issue with proxy-redirect nginx configuration
|
||||
- [X] [#2451](https://github.com/kubernetes/ingress-nginx/pull/2451) fix for #1930, make sessions sticky, for ingress with multiple rules …
|
||||
- [X] [#2484](https://github.com/kubernetes/ingress-nginx/pull/2484) Fix bugs in Lua implementation of sticky sessions
|
||||
- [X] [#2486](https://github.com/kubernetes/ingress-nginx/pull/2486) Extend kubernetes interrelation variables in nginx.tmpl
|
||||
- [X] [#2504](https://github.com/kubernetes/ingress-nginx/pull/2504) Add Timeout For TLS Passthrough
|
||||
- [X] [#2505](https://github.com/kubernetes/ingress-nginx/pull/2505) Annotations for the InfluxDB module
|
||||
- [X] [#2517](https://github.com/kubernetes/ingress-nginx/pull/2517) Fix typo about the kind of request
|
||||
- [X] [#2523](https://github.com/kubernetes/ingress-nginx/pull/2523) Add tests for bind-address
|
||||
- [X] [#2524](https://github.com/kubernetes/ingress-nginx/pull/2524) Add support for grpc_set_header
|
||||
- [X] [#2526](https://github.com/kubernetes/ingress-nginx/pull/2526) Fix upstream hash lua test
|
||||
- [X] [#2528](https://github.com/kubernetes/ingress-nginx/pull/2528) Remove go-bindata
|
||||
- [X] [#2533](https://github.com/kubernetes/ingress-nginx/pull/2533) NGINX image update: add the influxdb module
|
||||
- [X] [#2534](https://github.com/kubernetes/ingress-nginx/pull/2534) Set Focus for E2E Tests
|
||||
- [X] [#2537](https://github.com/kubernetes/ingress-nginx/pull/2537) Update nginx modules
|
||||
- [X] [#2542](https://github.com/kubernetes/ingress-nginx/pull/2542) Instrument controller to show configReload metrics
|
||||
- [X] [#2543](https://github.com/kubernetes/ingress-nginx/pull/2543) introduce a balancer interface
|
||||
- [X] [#2548](https://github.com/kubernetes/ingress-nginx/pull/2548) Implement generate-request-id
|
||||
- [X] [#2554](https://github.com/kubernetes/ingress-nginx/pull/2554) use better defaults for proxy-next-upstream(-tries)
|
||||
- [X] [#2558](https://github.com/kubernetes/ingress-nginx/pull/2558) Update qemu to 2.12.0 [ci skip]
|
||||
- [X] [#2559](https://github.com/kubernetes/ingress-nginx/pull/2559) Add geoip2 module and DB to nginx build
|
||||
- [X] [#2564](https://github.com/kubernetes/ingress-nginx/pull/2564) Add security contacts file [ci skip]
|
||||
- [X] [#2569](https://github.com/kubernetes/ingress-nginx/pull/2569) Update nginx modules to fix core dump [ci skip]
|
||||
- [X] [#2570](https://github.com/kubernetes/ingress-nginx/pull/2570) Enable core dumps during tests
|
||||
- [X] [#2573](https://github.com/kubernetes/ingress-nginx/pull/2573) Refactor e2e tests and update go dependencies
|
||||
- [X] [#2574](https://github.com/kubernetes/ingress-nginx/pull/2574) Fix default-backend annotation
|
||||
- [X] [#2575](https://github.com/kubernetes/ingress-nginx/pull/2575) Print information about NGINX version
|
||||
- [X] [#2577](https://github.com/kubernetes/ingress-nginx/pull/2577) make sure ingress-nginx instances are watching their namespace only during test runs
|
||||
- [X] [#2588](https://github.com/kubernetes/ingress-nginx/pull/2588) Update nginx dependencies
|
||||
- [X] [#2590](https://github.com/kubernetes/ingress-nginx/pull/2590) Typo fix: muthual autentication -> mutual authentication
|
||||
- [X] [#2591](https://github.com/kubernetes/ingress-nginx/pull/2591) Access log improvements
|
||||
- [X] [#2597](https://github.com/kubernetes/ingress-nginx/pull/2597) Fix arm paths for liblua.so and lua_package_cpath
|
||||
- [X] [#2598](https://github.com/kubernetes/ingress-nginx/pull/2598) Always sort upstream list to provide stable iteration order
|
||||
- [X] [#2600](https://github.com/kubernetes/ingress-nginx/pull/2600) typo fix futher to further && preformance to performance
|
||||
- [X] [#2602](https://github.com/kubernetes/ingress-nginx/pull/2602) Crossplat fixes
|
||||
- [X] [#2603](https://github.com/kubernetes/ingress-nginx/pull/2603) Bump nginx influxdb module to f8732268d44aea706ecf8d9c6036e9b6dacc99b2
|
||||
- [X] [#2608](https://github.com/kubernetes/ingress-nginx/pull/2608) Expose UDP message on /metrics endpoint
|
||||
- [X] [#2611](https://github.com/kubernetes/ingress-nginx/pull/2611) Add metric emitter lua module
|
||||
- [X] [#2614](https://github.com/kubernetes/ingress-nginx/pull/2614) fix nginx conf test error when not found active service endpoints
|
||||
- [X] [#2617](https://github.com/kubernetes/ingress-nginx/pull/2617) Update go to 1.10.3
|
||||
- [X] [#2618](https://github.com/kubernetes/ingress-nginx/pull/2618) Update nginx to 1.15.0 and remove VTS module
|
||||
- [X] [#2619](https://github.com/kubernetes/ingress-nginx/pull/2619) Run as user dropping privileges
|
||||
- [X] [#2623](https://github.com/kubernetes/ingress-nginx/pull/2623) Proofread cmd package and update flags description
|
||||
- [X] [#2634](https://github.com/kubernetes/ingress-nginx/pull/2634) Disable resync period
|
||||
- [X] [#2636](https://github.com/kubernetes/ingress-nginx/pull/2636) Add missing equality comparisons for ingress.Server
|
||||
- [X] [#2638](https://github.com/kubernetes/ingress-nginx/pull/2638) Wait the result of the controller deployment before running any test
|
||||
- [X] [#2639](https://github.com/kubernetes/ingress-nginx/pull/2639) Clarify log messages in controller package
|
||||
- [X] [#2643](https://github.com/kubernetes/ingress-nginx/pull/2643) Remove VTS from the ingress controller
|
||||
- [X] [#2644](https://github.com/kubernetes/ingress-nginx/pull/2644) Update nginx image version
|
||||
- [X] [#2646](https://github.com/kubernetes/ingress-nginx/pull/2646) Rollback nginx 1.15.0 to 1.13.12
|
||||
- [X] [#2649](https://github.com/kubernetes/ingress-nginx/pull/2649) Add support for IPV6 in stream upstream servers
|
||||
- [X] [#2652](https://github.com/kubernetes/ingress-nginx/pull/2652) Use a unix socket instead udp for reception of metrics
|
||||
- [X] [#2653](https://github.com/kubernetes/ingress-nginx/pull/2653) Remove dummy file watcher
|
||||
- [X] [#2654](https://github.com/kubernetes/ingress-nginx/pull/2654) Hotfix: influxdb module enable disable toggle
|
||||
- [X] [#2656](https://github.com/kubernetes/ingress-nginx/pull/2656) Improve configuration change detection
|
||||
- [X] [#2658](https://github.com/kubernetes/ingress-nginx/pull/2658) Do not wait informer initialization to read configuration
|
||||
- [X] [#2659](https://github.com/kubernetes/ingress-nginx/pull/2659) Update nginx image
|
||||
- [X] [#2660](https://github.com/kubernetes/ingress-nginx/pull/2660) Change modsecurity directories
|
||||
- [X] [#2661](https://github.com/kubernetes/ingress-nginx/pull/2661) Add additional header when debug is enabled
|
||||
- [X] [#2664](https://github.com/kubernetes/ingress-nginx/pull/2664) refactor some lua code
|
||||
- [X] [#2669](https://github.com/kubernetes/ingress-nginx/pull/2669) Remove unnecessary sync when the leader change
|
||||
- [X] [#2672](https://github.com/kubernetes/ingress-nginx/pull/2672) After a configmap change parse ingress annotations (again)
|
||||
- [X] [#2673](https://github.com/kubernetes/ingress-nginx/pull/2673) Add new approvers to the project
|
||||
- [X] [#2674](https://github.com/kubernetes/ingress-nginx/pull/2674) Add e2e test for configmap change and reload
|
||||
- [X] [#2675](https://github.com/kubernetes/ingress-nginx/pull/2675) Update opentracing nginx module
|
||||
- [X] [#2676](https://github.com/kubernetes/ingress-nginx/pull/2676) Update opentracing configuration
|
||||
|
||||
*Documentation:*
|
||||
|
||||
- [X] [#2479](https://github.com/kubernetes/ingress-nginx/pull/2479) Document how the NGINX Ingress controller build nginx.conf
|
||||
- [X] [#2515](https://github.com/kubernetes/ingress-nginx/pull/2515) Simplify installation and e2e manifests
|
||||
- [X] [#2531](https://github.com/kubernetes/ingress-nginx/pull/2531) Mention the #ingress-nginx Slack channel
|
||||
- [X] [#2540](https://github.com/kubernetes/ingress-nginx/pull/2540) DOCS: Correct ssl-passthrough annotation description.
|
||||
- [X] [#2544](https://github.com/kubernetes/ingress-nginx/pull/2544) [docs] Fix manifest URL for GKE + Azure
|
||||
- [X] [#2566](https://github.com/kubernetes/ingress-nginx/pull/2566) Fix wrong default value for `enable-brotli`
|
||||
- [X] [#2581](https://github.com/kubernetes/ingress-nginx/pull/2581) Improved link in modsecurity.md
|
||||
- [X] [#2583](https://github.com/kubernetes/ingress-nginx/pull/2583) docs: add secret scheme details to the example
|
||||
- [X] [#2592](https://github.com/kubernetes/ingress-nginx/pull/2592) Typo fix: are be->are/to on->to
|
||||
- [X] [#2595](https://github.com/kubernetes/ingress-nginx/pull/2595) Typo fix: successfull->successful
|
||||
- [X] [#2601](https://github.com/kubernetes/ingress-nginx/pull/2601) fix changelog link in README.md
|
||||
- [X] [#2624](https://github.com/kubernetes/ingress-nginx/pull/2624) Fix minor documentation example
|
||||
- [X] [#2625](https://github.com/kubernetes/ingress-nginx/pull/2625) Add annotation doc on proxy buffer size
|
||||
- [X] [#2630](https://github.com/kubernetes/ingress-nginx/pull/2630) Update documentation for custom error pages
|
||||
- [X] [#2666](https://github.com/kubernetes/ingress-nginx/pull/2666) Add documentation for proxy-cookie-domain annotation (#2034)
|
||||
|
||||
### 0.15.0
|
||||
|
||||
**Image:** `quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.15.0`
|
||||
|
|
142
Gopkg.lock
generated
|
@ -4,8 +4,8 @@
|
|||
[[projects]]
|
||||
name = "cloud.google.com/go"
|
||||
packages = ["compute/metadata"]
|
||||
revision = "0fd7230b2a7505833d5f69b75cbd6c9582401479"
|
||||
version = "v0.23.0"
|
||||
revision = "aad3f485ee528456e0768f20397b4d9dd941e755"
|
||||
version = "v0.25.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/Azure/go-autorest"
|
||||
|
@ -15,7 +15,8 @@
|
|||
"autorest/azure",
|
||||
"autorest/date"
|
||||
]
|
||||
revision = "d4e6b95c12a08b4de2d48b45d5b4d594e5d32fab"
|
||||
revision = "1f7cd6cfe0adea687ad44a512dfe76140f804318"
|
||||
version = "v10.12.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -80,7 +81,7 @@
|
|||
branch = "master"
|
||||
name = "github.com/fullsailor/pkcs7"
|
||||
packages = ["."]
|
||||
revision = "ae226422660e5ca10db350d33f81c6608f3fbcdd"
|
||||
revision = "8306686428a5fe132eac8cb7c4848af725098bd4"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/ghodss/yaml"
|
||||
|
@ -123,6 +124,12 @@
|
|||
revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/google/btree"
|
||||
packages = ["."]
|
||||
revision = "e89373fe6b4a7413d7acd6da1725b83ef713e6e4"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/google/gofuzz"
|
||||
|
@ -151,7 +158,16 @@
|
|||
"openstack/utils",
|
||||
"pagination"
|
||||
]
|
||||
revision = "282f25e4025de0a42015d2e2b5faef1d920aad3c"
|
||||
revision = "45c2d035713fa44f366921035a44610ac5d45beb"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/gregjones/httpcache"
|
||||
packages = [
|
||||
".",
|
||||
"diskcache"
|
||||
]
|
||||
revision = "9cad4c3443a7200dd6400aef47183728de563a38"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -162,12 +178,6 @@
|
|||
]
|
||||
revision = "0fb14efe8c47ae851c0034ed7a448854d3d34cf3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/howeyc/gopass"
|
||||
packages = ["."]
|
||||
revision = "bf9dde6d0d2c004a008c27aaee91170c786f6db8"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/imdario/mergo"
|
||||
packages = ["."]
|
||||
|
@ -177,14 +187,8 @@
|
|||
[[projects]]
|
||||
name = "github.com/json-iterator/go"
|
||||
packages = ["."]
|
||||
revision = "ca39e5af3ece67bbcda3d0f4f56a8e24d9f2dad4"
|
||||
version = "1.1.3"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/kr/pty"
|
||||
packages = ["."]
|
||||
revision = "282ce0e5322c82529687d609ee670fac7c7d917c"
|
||||
version = "v1.1.1"
|
||||
revision = "ab8a2e0c74be9d3be70b3184d9acc634935ded82"
|
||||
version = "1.1.4"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -198,8 +202,8 @@
|
|||
[[projects]]
|
||||
name = "github.com/matttproud/golang_protobuf_extensions"
|
||||
packages = ["pbutil"]
|
||||
revision = "3247c84500bff8d9fb6d579d800f20b3e091582c"
|
||||
version = "v1.0.0"
|
||||
revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -207,6 +211,12 @@
|
|||
packages = ["."]
|
||||
revision = "4fdf99ab29366514c69ccccddab5dc58b8d84062"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mitchellh/hashstructure"
|
||||
packages = ["."]
|
||||
revision = "2bca23e0e452137f789efbc8610126fd8b94f73b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mitchellh/mapstructure"
|
||||
|
@ -222,8 +232,8 @@
|
|||
[[projects]]
|
||||
name = "github.com/modern-go/reflect2"
|
||||
packages = ["."]
|
||||
revision = "1df9eeb2bb81f327b96228865c5687bc2194af3f"
|
||||
version = "1.0.0"
|
||||
revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd"
|
||||
version = "1.0.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -309,6 +319,18 @@
|
|||
revision = "e790cca94e6cc75c7064b1332e63811d4aae1a53"
|
||||
version = "v1.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/petar/GoLLRB"
|
||||
packages = ["llrb"]
|
||||
revision = "53be0d36a84c2a886ca057d34b6aa4468df9ccb4"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/peterbourgon/diskv"
|
||||
packages = ["."]
|
||||
revision = "5f041e8faa004a95c88a202771f4cc3e991971e6"
|
||||
version = "v2.0.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
|
@ -316,19 +338,19 @@
|
|||
version = "v0.8.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/prometheus/client_golang"
|
||||
packages = [
|
||||
"prometheus",
|
||||
"prometheus/promhttp"
|
||||
]
|
||||
revision = "c5b7fccd204277076155f10851dad72b76a49317"
|
||||
version = "v0.8.0"
|
||||
revision = "ee1c9d7e23df7f011bdf6f12a5c9e7f0ae10a1fe"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/prometheus/client_model"
|
||||
packages = ["go"]
|
||||
revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c"
|
||||
revision = "5c3871d89910bfb32f5fcab2aa4b9ec68e65a99f"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -349,7 +371,7 @@
|
|||
"nfs",
|
||||
"xfs"
|
||||
]
|
||||
revision = "8b1c2da0d56deffdbb9e48d4414b4e674bd8083e"
|
||||
revision = "ae68e2d4c00fed4943b5f6698d504a5fe083da8a"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/afero"
|
||||
|
@ -357,8 +379,8 @@
|
|||
".",
|
||||
"mem"
|
||||
]
|
||||
revision = "63644898a8da0bc22138abf860edaf5277b6102e"
|
||||
version = "v1.1.0"
|
||||
revision = "787d034dfe70e44075ccc060d346146ef53270ad"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/pflag"
|
||||
|
@ -369,8 +391,8 @@
|
|||
[[projects]]
|
||||
name = "github.com/zakjan/cert-chain-resolver"
|
||||
packages = ["certUtil"]
|
||||
revision = "c222fb53d84f5c835aab8027b5d422d4089f9d29"
|
||||
version = "1.0.1"
|
||||
revision = "6076e1ded27284d6df12668dba6bee76fc17f84e"
|
||||
version = "1.0.2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -380,7 +402,7 @@
|
|||
"ed25519/internal/edwards25519",
|
||||
"ssh/terminal"
|
||||
]
|
||||
revision = "a3beeb748656e13e54256fd2cde19e058f41f60f"
|
||||
revision = "a49355c7e3f8fe157a85be2f77e6e269a0f89602"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -399,7 +421,7 @@
|
|||
"publicsuffix",
|
||||
"trace"
|
||||
]
|
||||
revision = "dfa909b99c79129e1100513e5cd36307665e5723"
|
||||
revision = "cffdcf672aee934982473246bc7e9a8ba446aa9b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -411,7 +433,7 @@
|
|||
"jws",
|
||||
"jwt"
|
||||
]
|
||||
revision = "770e5ebd4ab27c4d70b0983674d138217f5e2c72"
|
||||
revision = "ef147856a6ddbb60760db74283d2424e98c87bff"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -420,7 +442,7 @@
|
|||
"unix",
|
||||
"windows"
|
||||
]
|
||||
revision = "c11f84a56e43e20a78cee75a7c034031ecf57d1f"
|
||||
revision = "1b2967e3c290b7c545b3db0deeda16e9be4f98a2"
|
||||
|
||||
[[projects]]
|
||||
name = "golang.org/x/text"
|
||||
|
@ -475,14 +497,14 @@
|
|||
"internal/urlfetch",
|
||||
"urlfetch"
|
||||
]
|
||||
revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
|
||||
version = "v1.0.0"
|
||||
revision = "b1f26356af11148e710935ed1ac8a7f5702c7612"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "google.golang.org/genproto"
|
||||
packages = ["googleapis/rpc/status"]
|
||||
revision = "694d95ba50e67b2e363f3483057db5d4910c18f9"
|
||||
revision = "e92b116572682a5b432ddd840aeaba2a559eeff1"
|
||||
|
||||
[[projects]]
|
||||
name = "google.golang.org/grpc"
|
||||
|
@ -491,15 +513,16 @@
|
|||
"balancer",
|
||||
"balancer/base",
|
||||
"balancer/roundrobin",
|
||||
"channelz",
|
||||
"codes",
|
||||
"connectivity",
|
||||
"credentials",
|
||||
"encoding",
|
||||
"encoding/proto",
|
||||
"grpclb/grpc_lb_v1/messages",
|
||||
"grpclog",
|
||||
"internal",
|
||||
"internal/backoff",
|
||||
"internal/channelz",
|
||||
"internal/grpcrand",
|
||||
"keepalive",
|
||||
"metadata",
|
||||
"naming",
|
||||
|
@ -512,8 +535,8 @@
|
|||
"tap",
|
||||
"transport"
|
||||
]
|
||||
revision = "41344da2231b913fa3d983840a57a6b1b7b631a1"
|
||||
version = "v1.12.0"
|
||||
revision = "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
|
||||
version = "v1.13.0"
|
||||
|
||||
[[projects]]
|
||||
name = "gopkg.in/fsnotify/fsnotify.v1"
|
||||
|
@ -577,12 +600,13 @@
|
|||
"rbac/v1alpha1",
|
||||
"rbac/v1beta1",
|
||||
"scheduling/v1alpha1",
|
||||
"scheduling/v1beta1",
|
||||
"settings/v1alpha1",
|
||||
"storage/v1",
|
||||
"storage/v1alpha1",
|
||||
"storage/v1beta1"
|
||||
]
|
||||
revision = "kubernetes-1.10.3"
|
||||
revision = "kubernetes-1.11.0"
|
||||
|
||||
[[projects]]
|
||||
name = "k8s.io/apiextensions-apiserver"
|
||||
|
@ -594,7 +618,7 @@
|
|||
"pkg/client/clientset/clientset/typed/apiextensions/v1beta1",
|
||||
"pkg/features"
|
||||
]
|
||||
revision = "kubernetes-1.10.3"
|
||||
revision = "kubernetes-1.11.0"
|
||||
|
||||
[[projects]]
|
||||
name = "k8s.io/apimachinery"
|
||||
|
@ -604,9 +628,6 @@
|
|||
"pkg/api/meta",
|
||||
"pkg/api/resource",
|
||||
"pkg/api/validation",
|
||||
"pkg/apimachinery",
|
||||
"pkg/apimachinery/announced",
|
||||
"pkg/apimachinery/registered",
|
||||
"pkg/apis/meta/internalversion",
|
||||
"pkg/apis/meta/v1",
|
||||
"pkg/apis/meta/v1/unstructured",
|
||||
|
@ -652,7 +673,7 @@
|
|||
"third_party/forked/golang/netutil",
|
||||
"third_party/forked/golang/reflect"
|
||||
]
|
||||
revision = "kubernetes-1.10.3"
|
||||
revision = "kubernetes-1.11.0"
|
||||
|
||||
[[projects]]
|
||||
name = "k8s.io/apiserver"
|
||||
|
@ -665,7 +686,7 @@
|
|||
"pkg/util/feature",
|
||||
"pkg/util/logs"
|
||||
]
|
||||
revision = "kubernetes-1.10.3"
|
||||
revision = "kubernetes-1.11.0"
|
||||
|
||||
[[projects]]
|
||||
name = "k8s.io/client-go"
|
||||
|
@ -706,6 +727,7 @@
|
|||
"informers/rbac/v1beta1",
|
||||
"informers/scheduling",
|
||||
"informers/scheduling/v1alpha1",
|
||||
"informers/scheduling/v1beta1",
|
||||
"informers/settings",
|
||||
"informers/settings/v1alpha1",
|
||||
"informers/storage",
|
||||
|
@ -763,6 +785,8 @@
|
|||
"kubernetes/typed/rbac/v1beta1/fake",
|
||||
"kubernetes/typed/scheduling/v1alpha1",
|
||||
"kubernetes/typed/scheduling/v1alpha1/fake",
|
||||
"kubernetes/typed/scheduling/v1beta1",
|
||||
"kubernetes/typed/scheduling/v1beta1/fake",
|
||||
"kubernetes/typed/settings/v1alpha1",
|
||||
"kubernetes/typed/settings/v1alpha1/fake",
|
||||
"kubernetes/typed/storage/v1",
|
||||
|
@ -791,12 +815,14 @@
|
|||
"listers/rbac/v1alpha1",
|
||||
"listers/rbac/v1beta1",
|
||||
"listers/scheduling/v1alpha1",
|
||||
"listers/scheduling/v1beta1",
|
||||
"listers/settings/v1alpha1",
|
||||
"listers/storage/v1",
|
||||
"listers/storage/v1alpha1",
|
||||
"listers/storage/v1beta1",
|
||||
"pkg/apis/clientauthentication",
|
||||
"pkg/apis/clientauthentication/v1alpha1",
|
||||
"pkg/apis/clientauthentication/v1beta1",
|
||||
"pkg/version",
|
||||
"plugin/pkg/client/auth",
|
||||
"plugin/pkg/client/auth/azure",
|
||||
|
@ -826,6 +852,7 @@
|
|||
"util/buffer",
|
||||
"util/cert",
|
||||
"util/cert/triple",
|
||||
"util/connrotation",
|
||||
"util/exec",
|
||||
"util/flowcontrol",
|
||||
"util/homedir",
|
||||
|
@ -834,13 +861,13 @@
|
|||
"util/retry",
|
||||
"util/workqueue"
|
||||
]
|
||||
revision = "kubernetes-1.10.3"
|
||||
revision = "kubernetes-1.11.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "k8s.io/kube-openapi"
|
||||
packages = ["pkg/util/proto"]
|
||||
revision = "41e43949ca69d04b66104069ed3ffd619b289b3d"
|
||||
revision = "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803"
|
||||
|
||||
[[projects]]
|
||||
name = "k8s.io/kubernetes"
|
||||
|
@ -858,6 +885,8 @@
|
|||
"pkg/apis/core/validation",
|
||||
"pkg/apis/extensions",
|
||||
"pkg/apis/networking",
|
||||
"pkg/apis/policy",
|
||||
"pkg/apis/scheduling",
|
||||
"pkg/capabilities",
|
||||
"pkg/cloudprovider",
|
||||
"pkg/controller",
|
||||
|
@ -867,10 +896,13 @@
|
|||
"pkg/kubelet/container",
|
||||
"pkg/kubelet/types",
|
||||
"pkg/kubelet/util/format",
|
||||
"pkg/kubelet/util/ioutils",
|
||||
"pkg/kubelet/util/sliceutils",
|
||||
"pkg/master/ports",
|
||||
"pkg/scheduler/algorithm",
|
||||
"pkg/scheduler/algorithm/priorities/util",
|
||||
"pkg/scheduler/api",
|
||||
"pkg/scheduler/cache",
|
||||
"pkg/scheduler/util",
|
||||
"pkg/security/apparmor",
|
||||
"pkg/serviceaccount",
|
||||
"pkg/util/file",
|
||||
|
@ -889,17 +921,17 @@
|
|||
"pkg/volume/util/recyclerclient",
|
||||
"third_party/forked/golang/expansion"
|
||||
]
|
||||
revision = "v1.10.3"
|
||||
revision = "v1.11.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "k8s.io/utils"
|
||||
packages = ["exec"]
|
||||
revision = "258e2a2fa64568210fbd6267cf1d8fd87c3cb86e"
|
||||
revision = "ab9069044f32ba0c6da081bb46bb0b12e3862c21"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "5feeef324f0cbac72e0234d5f649fc7c4233f4e2bb4477e454e047b5461d7569"
|
||||
inputs-digest = "a9315cc322f719f566fce26b3f0de8594ab9d4a074febfc1f0de3c99371c37c4"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
|
14
Gopkg.toml
|
@ -78,7 +78,7 @@
|
|||
|
||||
[[constraint]]
|
||||
name = "github.com/prometheus/client_golang"
|
||||
version = "0.8.0"
|
||||
branch = "master"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/pflag"
|
||||
|
@ -98,24 +98,24 @@
|
|||
|
||||
[[constraint]]
|
||||
name = "k8s.io/kubernetes"
|
||||
revision = "v1.10.3"
|
||||
revision = "v1.11.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/api"
|
||||
revision = "kubernetes-1.10.3"
|
||||
revision = "kubernetes-1.11.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/apimachinery"
|
||||
revision = "kubernetes-1.10.3"
|
||||
revision = "kubernetes-1.11.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/client-go"
|
||||
revision = "kubernetes-1.10.3"
|
||||
revision = "kubernetes-1.11.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/apiextensions-apiserver"
|
||||
revision = "kubernetes-1.10.3"
|
||||
revision = "kubernetes-1.11.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/apiserver"
|
||||
revision = "kubernetes-1.10.3"
|
||||
revision = "kubernetes-1.11.0"
|
||||
|
|
154
Makefile
|
@ -15,22 +15,22 @@
|
|||
.PHONY: all
|
||||
all: all-container
|
||||
|
||||
BUILDTAGS=
|
||||
|
||||
# Use the 0.0 tag for testing, it shouldn't clobber any release builds
|
||||
TAG?=0.15.0
|
||||
REGISTRY?=quay.io/kubernetes-ingress-controller
|
||||
GOOS?=linux
|
||||
DOCKER?=docker
|
||||
SED_I?=sed -i
|
||||
TAG ?= 0.18.0
|
||||
REGISTRY ?= quay.io/kubernetes-ingress-controller
|
||||
DOCKER ?= docker
|
||||
SED_I ?= sed -i
|
||||
GOHOSTOS ?= $(shell go env GOHOSTOS)
|
||||
|
||||
# e2e settings
|
||||
# Allow limiting the scope of the e2e tests. By default run everything
|
||||
FOCUS?=.*
|
||||
FOCUS ?= .*
|
||||
# number of parallel test
|
||||
E2E_NODES?=3
|
||||
E2E_NODES ?= 4
|
||||
# slow test only if takes > 40s
|
||||
SLOW_E2E_THRESHOLD ?= 40
|
||||
|
||||
NODE_IP ?= $(shell minikube ip)
|
||||
|
||||
ifeq ($(GOHOSTOS),darwin)
|
||||
SED_I=sed -i ''
|
||||
|
@ -38,28 +38,30 @@ endif
|
|||
|
||||
REPO_INFO=$(shell git config --get remote.origin.url)
|
||||
|
||||
ifndef COMMIT
|
||||
COMMIT := git-$(shell git rev-parse --short HEAD)
|
||||
ifndef GIT_COMMIT
|
||||
GIT_COMMIT := git-$(shell git rev-parse --short HEAD)
|
||||
endif
|
||||
|
||||
PKG=k8s.io/ingress-nginx
|
||||
PKG = k8s.io/ingress-nginx
|
||||
|
||||
ARCH ?= $(shell go env GOARCH)
|
||||
GOARCH = ${ARCH}
|
||||
DUMB_ARCH = ${ARCH}
|
||||
|
||||
GOBUILD_FLAGS :=
|
||||
|
||||
ALL_ARCH = amd64 arm arm64 ppc64le s390x
|
||||
|
||||
QEMUVERSION=v2.12.0
|
||||
QEMUVERSION = v2.12.0-1
|
||||
|
||||
BUSTED_ARGS=-v --pattern=_test
|
||||
BUSTED_ARGS =-v --pattern=_test
|
||||
|
||||
IMGNAME = nginx-ingress-controller
|
||||
IMAGE = $(REGISTRY)/$(IMGNAME)
|
||||
MULTI_ARCH_IMG = $(IMAGE)-$(ARCH)
|
||||
|
||||
# Set default base image dynamically for each arch
|
||||
BASEIMAGE?=quay.io/kubernetes-ingress-controller/nginx-$(ARCH):0.49
|
||||
BASEIMAGE?=quay.io/kubernetes-ingress-controller/nginx-$(ARCH):0.58
|
||||
|
||||
ifeq ($(ARCH),arm)
|
||||
QEMUARCH=arm
|
||||
|
@ -67,7 +69,7 @@ ifeq ($(ARCH),arm)
|
|||
DUMB_ARCH=armhf
|
||||
endif
|
||||
ifeq ($(ARCH),arm64)
|
||||
QEMUARCH=aarch64
|
||||
QEMUARCH=aarch64
|
||||
endif
|
||||
ifeq ($(ARCH),ppc64le)
|
||||
QEMUARCH=ppc64le
|
||||
|
@ -75,11 +77,19 @@ ifeq ($(ARCH),ppc64le)
|
|||
DUMB_ARCH=ppc64el
|
||||
endif
|
||||
ifeq ($(ARCH),s390x)
|
||||
QEMUARCH=s390x
|
||||
QEMUARCH=s390x
|
||||
endif
|
||||
|
||||
TEMP_DIR := $(shell mktemp -d)
|
||||
|
||||
DEF_VARS:=ARCH=$(ARCH) \
|
||||
TAG=$(TAG) \
|
||||
PKG=$(PKG) \
|
||||
GOARCH=$(GOARCH) \
|
||||
GIT_COMMIT=$(GIT_COMMIT) \
|
||||
REPO_INFO=$(REPO_INFO) \
|
||||
PWD=$(PWD)
|
||||
|
||||
DOCKERFILE := $(TEMP_DIR)/rootfs/Dockerfile
|
||||
|
||||
.PHONY: image-info
|
||||
|
@ -101,10 +111,15 @@ all-container: $(addprefix sub-container-,$(ALL_ARCH))
|
|||
all-push: $(addprefix sub-push-,$(ALL_ARCH))
|
||||
|
||||
.PHONY: container
|
||||
container: .container-$(ARCH)
|
||||
container: clean-container .container-$(ARCH)
|
||||
|
||||
.PHONY: .container-$(ARCH)
|
||||
.container-$(ARCH):
|
||||
@echo "+ Copying artifact to temporary directory"
|
||||
mkdir -p $(TEMP_DIR)/rootfs
|
||||
cp bin/$(ARCH)/nginx-ingress-controller $(TEMP_DIR)/rootfs/nginx-ingress-controller
|
||||
|
||||
@echo "+ Building container image $(MULTI_ARCH_IMG):$(TAG)"
|
||||
cp -RP ./* $(TEMP_DIR)
|
||||
$(SED_I) "s|BASEIMAGE|$(BASEIMAGE)|g" $(DOCKERFILE)
|
||||
$(SED_I) "s|QEMUARCH|$(QEMUARCH)|g" $(DOCKERFILE)
|
||||
|
@ -119,13 +134,18 @@ else
|
|||
$(SED_I) "s/CROSS_BUILD_//g" $(DOCKERFILE)
|
||||
endif
|
||||
|
||||
$(DOCKER) build -t $(MULTI_ARCH_IMG):$(TAG) $(TEMP_DIR)/rootfs
|
||||
$(DOCKER) build --no-cache --pull -t $(MULTI_ARCH_IMG):$(TAG) $(TEMP_DIR)/rootfs
|
||||
|
||||
ifeq ($(ARCH), amd64)
|
||||
# This is for maintaining backward compatibility
|
||||
$(DOCKER) tag $(MULTI_ARCH_IMG):$(TAG) $(IMAGE):$(TAG)
|
||||
endif
|
||||
|
||||
.PHONY: clean-container
|
||||
clean-container:
|
||||
@echo "+ Deleting container image $(MULTI_ARCH_IMG):$(TAG)"
|
||||
$(DOCKER) rmi -f $(MULTI_ARCH_IMG):$(TAG) || true
|
||||
|
||||
.PHONY: register-qemu
|
||||
register-qemu:
|
||||
# Register /usr/bin/qemu-ARCH-static as the handler for binaries in multiple platforms
|
||||
|
@ -141,78 +161,68 @@ ifeq ($(ARCH), amd64)
|
|||
$(DOCKER) push $(IMAGE):$(TAG)
|
||||
endif
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
@echo "+ Building bin/$(ARCH)/nginx-ingress-controller"
|
||||
@$(DEF_VARS) \
|
||||
GOBUILD_FLAGS="$(GOBUILD_FLAGS)" \
|
||||
build/go-in-docker.sh build/build.sh
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(DOCKER) rmi -f $(MULTI_ARCH_IMG):$(TAG) || true
|
||||
rm -rf bin/ .gocache/ .env
|
||||
|
||||
.PHONY: build
|
||||
build: clean
|
||||
CGO_ENABLED=0 GOOS=${GOOS} GOARCH=${GOARCH} go build -a -installsuffix cgo \
|
||||
-ldflags "-s -w -X ${PKG}/version.RELEASE=${TAG} -X ${PKG}/version.COMMIT=${COMMIT} -X ${PKG}/version.REPO=${REPO_INFO}" \
|
||||
-o ${TEMP_DIR}/rootfs/nginx-ingress-controller ${PKG}/cmd/nginx
|
||||
|
||||
.PHONY: verify-all
|
||||
verify-all:
|
||||
@./hack/verify-all.sh
|
||||
.PHONY: static-check
|
||||
static-check:
|
||||
@$(DEF_VARS) \
|
||||
build/go-in-docker.sh build/static-check.sh
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
@go test -v -race -tags "$(BUILDTAGS) cgo" $(shell go list ${PKG}/... | grep -v vendor | grep -v '/test/e2e')
|
||||
@$(DEF_VARS) \
|
||||
NODE_IP=$(NODE_IP) \
|
||||
DOCKER_OPTS="-i --net=host" \
|
||||
build/go-in-docker.sh build/test.sh
|
||||
|
||||
.PHONY: lua-test
|
||||
lua-test:
|
||||
@busted $(BUSTED_ARGS) ./rootfs/etc/nginx/lua/test;
|
||||
@$(DEF_VARS) \
|
||||
BUSTED_ARGS="$(BUSTED_ARGS)" \
|
||||
build/go-in-docker.sh build/test-lua.sh
|
||||
|
||||
.PHONY: e2e-test
|
||||
e2e-test:
|
||||
@ginkgo version || go get -u github.com/onsi/ginkgo/ginkgo
|
||||
@ginkgo build ./test/e2e
|
||||
@KUBECONFIG=${HOME}/.kube/config ginkgo \
|
||||
-randomizeSuites \
|
||||
-randomizeAllSpecs \
|
||||
-flakeAttempts=2 \
|
||||
--focus=$(FOCUS) \
|
||||
-p \
|
||||
-trace \
|
||||
-nodes=$(E2E_NODES) \
|
||||
./test/e2e/e2e.test
|
||||
@$(DEF_VARS) \
|
||||
FOCUS=$(FOCUS) \
|
||||
E2E_NODES=$(E2E_NODES) \
|
||||
DOCKER_OPTS="-i --net=host" \
|
||||
NODE_IP=$(NODE_IP) \
|
||||
SLOW_E2E_THRESHOLD=$(SLOW_E2E_THRESHOLD) \
|
||||
build/go-in-docker.sh build/e2e-tests.sh
|
||||
|
||||
.PHONY: cover
|
||||
cover:
|
||||
@rm -rf coverage.txt
|
||||
@for d in `go list ./... | grep -v vendor | grep -v '/test/e2e' | grep -v 'images/grpc-fortune-teller'`; do \
|
||||
t=$$(date +%s); \
|
||||
go test -coverprofile=cover.out -covermode=atomic $$d || exit 1; \
|
||||
echo "Coverage test $$d took $$(($$(date +%s)-t)) seconds"; \
|
||||
if [ -f cover.out ]; then \
|
||||
cat cover.out >> coverage.txt; \
|
||||
rm cover.out; \
|
||||
fi; \
|
||||
done
|
||||
@echo "Uploading coverage results..."
|
||||
@$(DEF_VARS) \
|
||||
DOCKER_OPTS="-i --net=host" \
|
||||
build/go-in-docker.sh build/cover.sh
|
||||
|
||||
echo "Uploading coverage results..."
|
||||
@curl -s https://codecov.io/bash | bash
|
||||
|
||||
.PHONY: vet
|
||||
vet:
|
||||
@go vet $(shell go list ${PKG}/... | grep -v vendor)
|
||||
|
||||
.PHONY: luacheck
|
||||
luacheck:
|
||||
luacheck -q ./rootfs/etc/nginx/lua/
|
||||
|
||||
.PHONY: release
|
||||
release: all-container all-push
|
||||
echo "done"
|
||||
|
||||
.PHONY: docker-build
|
||||
docker-build: all-container
|
||||
|
||||
.PHONY: docker-push
|
||||
docker-push: all-push
|
||||
|
||||
.PHONY: check_dead_links
|
||||
check_dead_links:
|
||||
docker run -t -v $$PWD:/tmp aledbf/awesome_bot:0.1 --allow-dupe --allow-redirect $(shell find $$PWD -mindepth 1 -name "*.md" -printf '%P\n' | grep -v vendor | grep -v Changelog.md)
|
||||
docker run -t \
|
||||
-v $$PWD:/tmp aledbf/awesome_bot:0.1 \
|
||||
--allow-dupe \
|
||||
--allow-redirect $(shell find $$PWD -mindepth 1 -name "*.md" -printf '%P\n' | grep -v vendor | grep -v Changelog.md)
|
||||
|
||||
.PHONY: dep-ensure
|
||||
dep-ensure:
|
||||
|
@ -223,12 +233,22 @@ dep-ensure:
|
|||
|
||||
.PHONY: dev-env
|
||||
dev-env:
|
||||
@./hack/build-dev-env.sh
|
||||
@build/dev-env.sh
|
||||
|
||||
.PHONY: live-docs
|
||||
live-docs:
|
||||
@docker run --rm -it -p 3000:3000 -v ${PWD}:/docs aledbf/mkdocs:0.1
|
||||
@docker build --pull -t ingress-nginx/mkdocs build/mkdocs
|
||||
@docker run --rm -it -p 3000:3000 -v ${PWD}:/docs ingress-nginx/mkdocs
|
||||
|
||||
.PHONY: build-docs
|
||||
build-docs:
|
||||
@docker run --rm -it -v ${PWD}:/docs aledbf/mkdocs:0.1 build
|
||||
@docker build --pull -t ingress-nginx/mkdocs build/mkdocs
|
||||
@docker run --rm -it -v ${PWD}:/docs ingress-nginx/mkdocs build
|
||||
|
||||
.PHONY: misspell
|
||||
misspell:
|
||||
@go get github.com/client9/misspell/cmd/misspell
|
||||
misspell \
|
||||
-locale US \
|
||||
-error \
|
||||
cmd/* internal/* deploy/* docs/* design/* test/* README.md
|
||||
|
|
2
OWNERS
|
@ -4,6 +4,8 @@ approvers:
|
|||
- sig-network-leads
|
||||
- ingress-nginx-admins
|
||||
- ingress-nginx-maintainers
|
||||
- ElvinEfendi
|
||||
- antoineco
|
||||
|
||||
reviewers:
|
||||
- aledbf
|
||||
|
|
24
README.md
|
@ -10,18 +10,16 @@
|
|||
[](https://github.com/kubernetes/ingress-nginx/blob/master/LICENSE)
|
||||
[](https://github.com/kubernetes/ingress-nginx/stargazers)
|
||||
[](https://github.com/kubernetes/ingress-nginx/blob/master/CONTRIBUTING.md)
|
||||
|
||||
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fkubernetes%2Fingress-nginx?ref=badge_shield)
|
||||
|
||||
# Get Involved
|
||||
|
||||
* **Contributing**: Pull requests are welcome!
|
||||
* Read [`CONTRIBUTING.md`](CONTRIBUTING.md) and check out [help-wanted](https://github.com/kubernetes/ingress-nginx/labels/help%20wanted) issues
|
||||
* Submit github issues for any feature enhancements, bugs or documentation problems
|
||||
* **Support**: Join to [Kubernetes Slack](http://slack.kubernetes.io/) to ask questions to get support from the maintainers and other developers
|
||||
* Questions/comments can also be posted as [github issues](https://github.com/kubernetes/ingress-nginx/issues)
|
||||
* **Discuss**: Tweet using the `#IngressNginx` hashtag
|
||||
|
||||
- **Contributing**: Pull requests are welcome!
|
||||
- Read [`CONTRIBUTING.md`](CONTRIBUTING.md) and check out [help-wanted](https://github.com/kubernetes/ingress-nginx/labels/help%20wanted) issues
|
||||
- Submit github issues for any feature enhancements, bugs or documentation problems
|
||||
- **Support**: Join to [Kubernetes Slack](http://slack.kubernetes.io/) to ask questions to get support from the maintainers and other developers
|
||||
- Questions/comments can also be posted as [github issues](https://github.com/kubernetes/ingress-nginx/issues)
|
||||
- **Discuss**: Tweet using the `#IngressNginx` hashtag
|
||||
|
||||
## Description
|
||||
|
||||
|
@ -37,41 +35,33 @@ The Ingress resource embodies this idea, and an Ingress controller is meant to h
|
|||
|
||||
An Ingress Controller is a daemon, deployed as a Kubernetes Pod, that watches the apiserver's `/ingresses` endpoint for updates to the [Ingress resource](https://kubernetes.io/docs/concepts/services-networking/ingress/). Its job is to satisfy requests for Ingresses.
|
||||
|
||||
|
||||
## Documentation
|
||||
|
||||
To check out [Live Docs](https://kubernetes.github.io/ingress-nginx/)
|
||||
|
||||
|
||||
## Questions
|
||||
|
||||
For questions and support please use the [#ingress-nginx](https://kubernetes.slack.com/messages/CANQGM8BA/) channel in the [Kubernetes Slack](http://slack.kubernetes.io/) or [kubernetes-users](https://groups.google.com/forum/#!forum/kubernetes-users) mailing list. The issue list of this repo is **exclusively** for bug reports and feature requests.
|
||||
|
||||
|
||||
## Issues
|
||||
|
||||
Please make sure to read the [Issue Reporting Checklist](https://github.com/kubernetes/ingress-nginx/blob/master/CONTRIBUTING.md#issue-reporting-guidelines) before opening an issue. Issues not conforming to the guidelines may be closed immediately.
|
||||
|
||||
|
||||
## Changelog
|
||||
|
||||
Detailed changes for each release are documented in the [Changelog.md](Changelog.md)
|
||||
|
||||
|
||||
## Contribution
|
||||
|
||||
Please make sure to read the [Contributing Guide](CONTRIBUTING.md) before making a pull request.
|
||||
|
||||
Thank you to all the people who already contributed to NGINX Ingress Controller!
|
||||
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project adheres to the [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md).
|
||||
By participating in this project you agree to abide by its terms.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
[Apache License 2.0](https://github.com/kubernetes/ingress-nginx/blob/master/LICENSE)
|
||||
|
||||
|
|
50
build/build.sh
Executable file
|
@ -0,0 +1,50 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright 2018 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.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
declare -a mandatory
|
||||
mandatory=(
|
||||
PKG
|
||||
ARCH
|
||||
GIT_COMMIT
|
||||
REPO_INFO
|
||||
TAG
|
||||
)
|
||||
|
||||
missing=false
|
||||
for var in "${mandatory[@]}"; do
|
||||
if [[ -z "${!var:-}" ]]; then
|
||||
echo "Environment variable $var must be set"
|
||||
missing=true
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$missing" = true ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export CGO_ENABLED=0
|
||||
|
||||
go build \
|
||||
${GOBUILD_FLAGS} \
|
||||
-ldflags "-s -w \
|
||||
-X ${PKG}/version.RELEASE=${TAG} \
|
||||
-X ${PKG}/version.COMMIT=${GIT_COMMIT} \
|
||||
-X ${PKG}/version.REPO=${REPO_INFO}" \
|
||||
-o bin/${ARCH}/nginx-ingress-controller ${PKG}/cmd/nginx
|
35
build/cover.sh
Executable file
|
@ -0,0 +1,35 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright 2018 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.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
if [ -z "${PKG}" ]; then
|
||||
echo "PKG must be set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf coverage.txt
|
||||
for d in `go list ${PKG}/... | grep -v vendor | grep -v '/test/e2e' | grep -v images`; do
|
||||
t=$(date +%s);
|
||||
go test -coverprofile=cover.out -covermode=atomic $d || exit 1;
|
||||
echo "Coverage test $d took $(($(date +%s)-$t)) seconds";
|
||||
if [ -f cover.out ]; then
|
||||
cat cover.out >> coverage.txt;
|
||||
rm cover.out;
|
||||
fi;
|
||||
done
|
|
@ -14,17 +14,32 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
: "${NAMESPACE:=ingress-nginx}"
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
SKIP_MINIKUBE_START=${SKIP_MINIKUBE_START:-}
|
||||
NAMESPACE="${NAMESPACE:-ingress-nginx}"
|
||||
echo "NAMESPACE is set to ${NAMESPACE}"
|
||||
|
||||
test $(minikube status | grep Running | wc -l) -eq 2 && $(minikube status | grep -q 'Correctly Configured') || minikube start
|
||||
eval $(minikube docker-env)
|
||||
|
||||
export TAG=dev
|
||||
export REGISTRY=ingress-controller
|
||||
export ARCH=amd64
|
||||
export REGISTRY=${REGISTRY:-ingress-controller}
|
||||
|
||||
DEV_IMAGE=${REGISTRY}/nginx-ingress-controller:${TAG}
|
||||
|
||||
if [ -z "${SKIP_MINIKUBE_START}" ]; then
|
||||
test $(minikube status | grep Running | wc -l) -eq 2 && $(minikube status | grep -q 'Correctly Configured') || minikube start \
|
||||
--extra-config=kubelet.sync-frequency=1s \
|
||||
--extra-config=apiserver.authorization-mode=RBAC
|
||||
|
||||
eval $(minikube docker-env)
|
||||
fi
|
||||
|
||||
echo "[dev-env] building container"
|
||||
ARCH=amd64 make build container
|
||||
make build container
|
||||
|
||||
docker save "${DEV_IMAGE}" | (eval $(minikube docker-env) && docker load) || true
|
||||
|
||||
echo "[dev-env] installing kubectl"
|
||||
kubectl version || brew install kubectl
|
||||
|
@ -38,4 +53,4 @@ kubectl set image \
|
|||
deployments \
|
||||
--namespace ingress-nginx \
|
||||
--selector app=ingress-nginx \
|
||||
nginx-ingress-controller=${REGISTRY}/nginx-ingress-controller:${TAG}
|
||||
nginx-ingress-controller=${DEV_IMAGE}
|
69
build/e2e-tests.sh
Executable file
|
@ -0,0 +1,69 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright 2018 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.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
declare -a mandatory
|
||||
mandatory=(
|
||||
NODE_IP
|
||||
SLOW_E2E_THRESHOLD
|
||||
PKG
|
||||
FOCUS
|
||||
E2E_NODES
|
||||
)
|
||||
|
||||
missing=false
|
||||
for var in ${mandatory[@]}; do
|
||||
if [[ -z "${!var+x}" ]]; then
|
||||
echo "Environment variable $var must be set"
|
||||
missing=true
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$missing" = true ];then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/..
|
||||
|
||||
mkdir -p ${SCRIPT_ROOT}/test/binaries
|
||||
|
||||
TEST_BINARIES=$( cd "${SCRIPT_ROOT}/test/binaries" ; pwd -P )
|
||||
|
||||
export PATH=${TEST_BINARIES}:$PATH
|
||||
|
||||
if ! [ -x "$(command -v kubectl)" ]; then
|
||||
echo "downloading kubectl..."
|
||||
curl -sSLo ${TEST_BINARIES}/kubectl \
|
||||
https://storage.googleapis.com/kubernetes-release/release/v1.11.0/bin/linux/amd64/kubectl
|
||||
chmod +x ${TEST_BINARIES}/kubectl
|
||||
fi
|
||||
|
||||
ginkgo build ./test/e2e
|
||||
|
||||
exec -- \
|
||||
ginkgo \
|
||||
-randomizeSuites \
|
||||
-randomizeAllSpecs \
|
||||
-flakeAttempts=2 \
|
||||
--focus=${FOCUS} \
|
||||
-p \
|
||||
-trace \
|
||||
-nodes=${E2E_NODES} \
|
||||
-slowSpecThreshold=${SLOW_E2E_THRESHOLD} \
|
||||
test/e2e/e2e.test
|
81
build/go-in-docker.sh
Executable file
|
@ -0,0 +1,81 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright 2018 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.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
declare -a mandatory
|
||||
mandatory=(
|
||||
PKG
|
||||
ARCH
|
||||
GIT_COMMIT
|
||||
REPO_INFO
|
||||
TAG
|
||||
HOME
|
||||
)
|
||||
|
||||
missing=false
|
||||
for var in ${mandatory[@]}; do
|
||||
if [[ -z "${!var+x}" ]]; then
|
||||
echo "Environment variable $var must be set"
|
||||
missing=true
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$missing" = true ];then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
E2E_IMAGE=quay.io/kubernetes-ingress-controller/e2e:v08152018-56ed290
|
||||
|
||||
DOCKER_OPTS=${DOCKER_OPTS:-""}
|
||||
|
||||
FLAGS=$@
|
||||
|
||||
tee .env << EOF
|
||||
PKG=${PKG:-""}
|
||||
ARCH=${ARCH:-""}
|
||||
GIT_COMMIT=${GIT_COMMIT:-""}
|
||||
E2E_NODES=${E2E_NODES:-4}
|
||||
FOCUS=${FOCUS:-.*}
|
||||
TAG=${TAG:-"0.0"}
|
||||
HOME=${HOME:-/root}
|
||||
KUBECONFIG=${HOME}/.kube/config
|
||||
GOARCH=${GOARCH}
|
||||
GOBUILD_FLAGS=${GOBUILD_FLAGS:-"-v"}
|
||||
PWD=${PWD}
|
||||
BUSTED_ARGS=${BUSTED_ARGS:-""}
|
||||
REPO_INFO=${REPO_INFO:-local}
|
||||
NODE_IP=${NODE_IP:-127.0.0.1}
|
||||
SLOW_E2E_THRESHOLD=${SLOW_E2E_THRESHOLD:-40}
|
||||
EOF
|
||||
|
||||
docker run \
|
||||
--tty \
|
||||
--rm \
|
||||
${DOCKER_OPTS} \
|
||||
-v ${HOME}/.kube:/${HOME}/.kube \
|
||||
-v ${HOME}/.minikube:${HOME}/.minikube \
|
||||
-v ${PWD}:/go/src/${PKG} \
|
||||
-v ${PWD}/.gocache:${HOME}/.cache/go-build \
|
||||
-v ${PWD}/bin/${ARCH}:/go/bin/linux_${ARCH} \
|
||||
-w /go/src/${PKG} \
|
||||
--env-file .env \
|
||||
--entrypoint ${FLAGS} \
|
||||
${E2E_IMAGE}
|
||||
|
||||
rm .env
|
39
build/mkdocs/Dockerfile
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Copyright 2018 The Kubernetes Authors. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
FROM alpine:3.7
|
||||
|
||||
RUN apk update && apk add --no-cache \
|
||||
git \
|
||||
git-fast-import \
|
||||
openssh \
|
||||
python3 \
|
||||
python3-dev \
|
||||
curl \
|
||||
&& python3 -m ensurepip \
|
||||
&& rm -r /usr/lib/python*/ensurepip \
|
||||
&& pip3 install --upgrade pip setuptools \
|
||||
&& rm -r /root/.cache \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
RUN curl -sSL https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/requirements-docs.txt -o requirements.txt \
|
||||
&& pip install -U -r requirements.txt
|
||||
|
||||
WORKDIR /docs
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
ENTRYPOINT ["mkdocs"]
|
||||
|
||||
CMD ["serve", "--dev-addr=0.0.0.0:3000", "--livereload"]
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2018 The Kubernetes Authors.
|
||||
#
|
||||
|
@ -14,17 +14,15 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
install()
|
||||
{
|
||||
package="$1"
|
||||
version="$2"
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
if luarocks list --porcelain $package $version | grep -q "installed"; then
|
||||
echo $package already installed, skipping ;
|
||||
else
|
||||
sudo luarocks install $package $version;
|
||||
fi
|
||||
}
|
||||
if [ -z "${PKG}" ]; then
|
||||
echo "PKG must be set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
install busted 2.0.rc12
|
||||
install lua-cjson 2.1.0-1
|
||||
hack/verify-all.sh
|
||||
|
||||
luacheck -q rootfs/etc/nginx/lua/
|
29
build/test-lua.sh
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright 2018 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.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
resty \
|
||||
-I ./rootfs/etc/nginx/lua \
|
||||
-I /usr/local/lib/lua \
|
||||
-I /usr/lib/lua-platform-path/lua/5.1 \
|
||||
--shdict "configuration_data 5M" \
|
||||
--shdict "certificate_data 16M" \
|
||||
--shdict "balancer_ewma 1M" \
|
||||
--shdict "balancer_ewma_last_touched_at 1M" \
|
||||
./rootfs/etc/nginx/lua/test/run.lua ${BUSTED_ARGS} ./rootfs/etc/nginx/lua/test/
|
18
images/echoheaders/run.sh → build/test.sh
Normal file → Executable file
|
@ -14,12 +14,14 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
echo "Generating self-signed cert"
|
||||
mkdir -p /certs
|
||||
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \
|
||||
-keyout /certs/privateKey.key \
|
||||
-out /certs/certificate.crt \
|
||||
-subj "/C=UK/ST=Warwickshire/L=Leamington/O=OrgName/OU=IT Department/CN=example.com"
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
echo "Starting nginx"
|
||||
nginx -g "daemon off;"
|
||||
if [ -z "${PKG}" ]; then
|
||||
echo "PKG must be set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
go test -v -race -tags "cgo" \
|
||||
$(go list ${PKG}/... | grep -v vendor | grep -v '/test/e2e' | grep -v images | grep -v "docs/examples")
|
|
@ -34,12 +34,12 @@ func resetForTesting(usage func()) {
|
|||
func TestMandatoryFlag(t *testing.T) {
|
||||
_, _, err := parseFlags()
|
||||
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) {
|
||||
resetForTesting(func() { t.Fatal("bad parse") })
|
||||
resetForTesting(func() { t.Fatal("Parsing failed") })
|
||||
|
||||
oldArgs := os.Args
|
||||
defer func() { os.Args = oldArgs }()
|
||||
|
@ -47,15 +47,15 @@ func TestDefaults(t *testing.T) {
|
|||
|
||||
showVersion, conf, err := parseFlags()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error parsing default flags: %v", err)
|
||||
t.Fatalf("Unexpected error parsing default flags: %v", err)
|
||||
}
|
||||
|
||||
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 {
|
||||
t.Fatal("expected a configuration but nil returned")
|
||||
t.Fatal("Expected a controller Configuration")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/pflag"
|
||||
|
@ -39,101 +38,121 @@ func parseFlags() (bool, *controller.Configuration, error) {
|
|||
var (
|
||||
flags = pflag.NewFlagSet("", pflag.ExitOnError)
|
||||
|
||||
apiserverHost = flags.String("apiserver-host", "", "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.")
|
||||
kubeConfigFile = flags.String("kubeconfig", "", "Path to kubeconfig file with authorization and master location information.")
|
||||
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.`)
|
||||
|
||||
kubeConfigFile = flags.String("kubeconfig", "",
|
||||
`Path to a kubeconfig file containing authorization and API server information.`)
|
||||
|
||||
defaultSvc = flags.String("default-backend-service", "",
|
||||
`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.`)
|
||||
`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.`)
|
||||
|
||||
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", "",
|
||||
`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", "",
|
||||
`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.`)
|
||||
`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.`)
|
||||
|
||||
tcpConfigMapName = flags.String("tcp-services-configmap", "",
|
||||
`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`)
|
||||
`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 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.`)
|
||||
`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.`)
|
||||
|
||||
resyncPeriod = flags.Duration("sync-period", 600*time.Second,
|
||||
`Relist and confirm cloud resources this often. Default is 10 minutes`)
|
||||
resyncPeriod = flags.Duration("sync-period", 0,
|
||||
`Period at which the controller forces the repopulation of its local object stores. Disabled by default.`)
|
||||
|
||||
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
|
||||
that contains a SSL certificate to be used as default for a HTTPS catch-all server.
|
||||
Takes the form <namespace>/<secret name>.`)
|
||||
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".`)
|
||||
|
||||
defHealthzURL = flags.String("health-check-path", "/healthz", `Defines
|
||||
the URL to be used as health check inside in the default server in NGINX.`)
|
||||
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.`)
|
||||
|
||||
updateStatus = flags.Bool("update-status", true, `Indicates if the
|
||||
ingress controller should update the Ingress status IP/hostname. Default is true`)
|
||||
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.`)
|
||||
|
||||
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,
|
||||
`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.
|
||||
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
|
||||
ingress controller should update the Ingress status IP/hostname when the controller
|
||||
is being stopped. Default is true`)
|
||||
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.`)
|
||||
|
||||
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,
|
||||
`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,
|
||||
`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`)
|
||||
httpsPort = flags.Int("https-port", 443, `Indicates the port to use for HTTPS traffic`)
|
||||
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.`)
|
||||
annotationsPrefix = flags.String("annotations-prefix", "nginx.ingress.kubernetes.io",
|
||||
`Prefix of the Ingress annotations specific to the NGINX controller.`)
|
||||
|
||||
enableSSLChainCompletion = flags.Bool("enable-ssl-chain-completion", true,
|
||||
`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.`)
|
||||
`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.`)
|
||||
|
||||
syncRateLimit = flags.Float32("sync-rate-limit", 0.3,
|
||||
`Define the sync frequency upper limit`)
|
||||
|
||||
publishStatusAddress = flags.String("publish-status-address", "",
|
||||
`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.`)
|
||||
`Customized address to set as the load-balancer status of Ingress objects this controller satisfies.
|
||||
Requires the update-status parameter.`)
|
||||
|
||||
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.`)
|
||||
dynamicConfigurationEnabled = flags.Bool("enable-dynamic-configuration", true,
|
||||
`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-passthrough-proxy-port", 442, `Port to use internally for SSL Passthrough.`)
|
||||
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")
|
||||
|
@ -158,10 +177,10 @@ func parseFlags() (bool, *controller.Configuration, error) {
|
|||
}
|
||||
|
||||
if *ingressClass != "" {
|
||||
glog.Infof("Watching for ingress class: %s", *ingressClass)
|
||||
glog.Infof("Watching for Ingress class: %s", *ingressClass)
|
||||
|
||||
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
|
||||
|
@ -187,11 +206,11 @@ func parseFlags() (bool, *controller.Configuration, error) {
|
|||
}
|
||||
|
||||
if *enableSSLPassthrough && !ing_net.IsPortAvailable(*sslProxyPort) {
|
||||
return false, nil, fmt.Errorf("Port %v is already in use. Please check the flag --ssl-passtrough-proxy-port", *sslProxyPort)
|
||||
return false, nil, fmt.Errorf("Port %v is already in use. Please check the flag --ssl-passthrough-proxy-port", *sslProxyPort)
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -200,7 +219,7 @@ func parseFlags() (bool, *controller.Configuration, error) {
|
|||
disableLua = true
|
||||
if *dynamicConfigurationEnabled {
|
||||
*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.")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -40,11 +41,23 @@ import (
|
|||
|
||||
"k8s.io/ingress-nginx/internal/file"
|
||||
"k8s.io/ingress-nginx/internal/ingress/controller"
|
||||
"k8s.io/ingress-nginx/internal/ingress/metric"
|
||||
"k8s.io/ingress-nginx/internal/k8s"
|
||||
"k8s.io/ingress-nginx/internal/net/ssl"
|
||||
"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() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
|
@ -71,36 +84,33 @@ func main() {
|
|||
handleFatalInitError(err)
|
||||
}
|
||||
|
||||
ns, name, err := k8s.ParseNameNS(conf.DefaultService)
|
||||
defSvcNs, defSvcName, err := k8s.ParseNameNS(conf.DefaultService)
|
||||
if err != nil {
|
||||
glog.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = kubeClient.CoreV1().Services(ns).Get(name, metav1.GetOptions{})
|
||||
_, err = kubeClient.CoreV1().Services(defSvcNs).Get(defSvcName, metav1.GetOptions{})
|
||||
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") {
|
||||
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 != "" {
|
||||
_, err = kubeClient.CoreV1().Namespaces().Get(conf.Namespace, metav1.GetOptions{})
|
||||
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 {
|
||||
glog.Fatalf("resync period (%vs) is too low", conf.ResyncPeriod.Seconds())
|
||||
}
|
||||
|
||||
// create the default SSL certificate (dummy)
|
||||
defCert, defKey := ssl.GetFakeSSLCert()
|
||||
c, err := ssl.AddOrUpdateCertAndKey(fakeCertificate, defCert, defKey, []byte{}, fs)
|
||||
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
|
||||
|
@ -108,14 +118,33 @@ func main() {
|
|||
|
||||
conf.Client = kubeClient
|
||||
|
||||
ngx := controller.NewNGINXController(conf, fs)
|
||||
reg := prometheus.NewRegistry()
|
||||
|
||||
reg.MustRegister(prometheus.NewGoCollector())
|
||||
reg.MustRegister(prometheus.NewProcessCollector(os.Getpid(), ""))
|
||||
|
||||
mc, err := metric.NewCollector(conf.ListenPorts.Status, reg)
|
||||
if err != nil {
|
||||
glog.Fatalf("Error creating prometheus collector: %v", err)
|
||||
}
|
||||
mc.Start()
|
||||
|
||||
ngx := controller.NewNGINXController(conf, mc, fs)
|
||||
go handleSigterm(ngx, func(code int) {
|
||||
os.Exit(code)
|
||||
})
|
||||
|
||||
mux := http.NewServeMux()
|
||||
go registerHandlers(conf.EnableProfiling, conf.ListenPorts.Health, ngx, mux)
|
||||
|
||||
if conf.EnableProfiling {
|
||||
registerProfiler(mux)
|
||||
}
|
||||
|
||||
registerHealthz(ngx, mux)
|
||||
registerMetrics(reg, mux)
|
||||
registerHandlers(mux)
|
||||
|
||||
go startHTTPServer(conf.ListenPorts.Health, mux)
|
||||
|
||||
ngx.Start()
|
||||
}
|
||||
|
@ -130,24 +159,26 @@ func handleSigterm(ngx *controller.NGINXController, exit exiter) {
|
|||
|
||||
exitCode := 0
|
||||
if err := ngx.Stop(); err != nil {
|
||||
glog.Infof("Error during shutdown %v", err)
|
||||
glog.Infof("Error during shutdown: %v", err)
|
||||
exitCode = 1
|
||||
}
|
||||
|
||||
glog.Infof("Handled quit, awaiting pod deletion")
|
||||
glog.Infof("Handled quit, awaiting Pod deletion")
|
||||
time.Sleep(10 * time.Second)
|
||||
|
||||
glog.Infof("Exiting with %v", exitCode)
|
||||
exit(exitCode)
|
||||
}
|
||||
|
||||
// createApiserverClient creates new Kubernetes Apiserver client. When kubeconfig or apiserverHost param is empty
|
||||
// the function assumes that it is running inside a Kubernetes cluster and attempts to
|
||||
// discover the Apiserver. Otherwise, it connects to the Apiserver specified.
|
||||
//
|
||||
// apiserverHost param is in the format of protocol://address:port/pathPrefix, e.g.http://localhost:8001.
|
||||
// kubeConfig location of kubeconfig file
|
||||
func createApiserverClient(apiserverHost string, kubeConfig string) (*kubernetes.Clientset, error) {
|
||||
// createApiserverClient creates a new Kubernetes REST client. apiserverHost is
|
||||
// the URL of the API server in the format protocol://address:port/pathPrefix,
|
||||
// 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
|
||||
// optionally overridden by the value of apiserverHost.
|
||||
// If neither apiserverHost nor kubeConfig are passed in, we assume the
|
||||
// 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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -166,7 +197,7 @@ func createApiserverClient(apiserverHost string, kubeConfig string) (*kubernetes
|
|||
|
||||
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
|
||||
defaultRetry := wait.Backoff{
|
||||
Steps: 10,
|
||||
|
@ -177,7 +208,7 @@ func createApiserverClient(apiserverHost string, kubeConfig string) (*kubernetes
|
|||
|
||||
var lastErr error
|
||||
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) {
|
||||
v, err = client.Discovery().ServerVersion()
|
||||
|
||||
|
@ -186,59 +217,38 @@ func createApiserverClient(apiserverHost string, kubeConfig string) (*kubernetes
|
|||
}
|
||||
|
||||
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++
|
||||
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 {
|
||||
return nil, lastErr
|
||||
}
|
||||
|
||||
// this should not happen, warn the user
|
||||
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)
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
/**
|
||||
* Handles fatal init error that prevents server from doing any work. Prints verbose error
|
||||
* messages and quits the server.
|
||||
*/
|
||||
// Handler for fatal init errors. Prints a verbose error message and exits.
|
||||
func handleFatalInitError(err error) {
|
||||
glog.Fatalf("Error while initializing connection to Kubernetes apiserver. "+
|
||||
"This most likely means that the cluster is misconfigured (e.g., it has "+
|
||||
"invalid apiserver certificates or service accounts configuration). Reason: %s\n"+
|
||||
glog.Fatalf("Error while initiating a connection to the Kubernetes API server. "+
|
||||
"This could mean the cluster is misconfigured (e.g. it has invalid API server certificates "+
|
||||
"or Service Accounts configuration). Reason: %s\n"+
|
||||
"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) {
|
||||
// expose health check endpoint (/healthz)
|
||||
healthz.InstallHandler(mux,
|
||||
healthz.PingHealthz,
|
||||
ic,
|
||||
)
|
||||
|
||||
mux.Handle("/metrics", promhttp.Handler())
|
||||
|
||||
func registerHandlers(mux *http.ServeMux) {
|
||||
mux.HandleFunc("/build", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
b, _ := json.Marshal(version.String())
|
||||
|
@ -248,23 +258,44 @@ func registerHandlers(enableProfiling bool, port int, ic *controller.NGINXContro
|
|||
mux.HandleFunc("/stop", func(w http.ResponseWriter, r *http.Request) {
|
||||
err := syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
|
||||
if err != nil {
|
||||
glog.Errorf("unexpected error: %v", err)
|
||||
glog.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if enableProfiling {
|
||||
mux.HandleFunc("/debug/pprof/", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/heap", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/mutex", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/goroutine", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/threadcreate", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/block", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
|
||||
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
|
||||
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
|
||||
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
|
||||
}
|
||||
func registerHealthz(ic *controller.NGINXController, mux *http.ServeMux) {
|
||||
// expose health check endpoint (/healthz)
|
||||
healthz.InstallHandler(mux,
|
||||
healthz.PingHealthz,
|
||||
ic,
|
||||
)
|
||||
}
|
||||
|
||||
func registerMetrics(reg *prometheus.Registry, mux *http.ServeMux) {
|
||||
mux.Handle(
|
||||
"/metrics",
|
||||
promhttp.InstrumentMetricHandler(
|
||||
reg,
|
||||
promhttp.HandlerFor(reg, promhttp.HandlerOpts{}),
|
||||
),
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
func registerProfiler(mux *http.ServeMux) {
|
||||
mux.HandleFunc("/debug/pprof/", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/heap", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/mutex", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/goroutine", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/threadcreate", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/block", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
|
||||
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
|
||||
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
|
||||
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
|
||||
}
|
||||
|
||||
func startHTTPServer(port int, mux *http.ServeMux) {
|
||||
server := &http.Server{
|
||||
Addr: fmt.Sprintf(":%v", port),
|
||||
Handler: mux,
|
||||
|
|
|
@ -18,46 +18,51 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/ingress-nginx/internal/file"
|
||||
"k8s.io/ingress-nginx/internal/ingress/controller"
|
||||
"os"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/ingress-nginx/internal/file"
|
||||
"k8s.io/ingress-nginx/internal/ingress/controller"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestCreateApiserverClient(t *testing.T) {
|
||||
home := os.Getenv("HOME")
|
||||
kubeConfigFile := fmt.Sprintf("%v/.kube/config", home)
|
||||
|
||||
cli, err := createApiserverClient("", kubeConfigFile)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error creating api server client: %v", err)
|
||||
}
|
||||
if cli == nil {
|
||||
t.Fatalf("expected a kubernetes client but none returned")
|
||||
}
|
||||
|
||||
_, err = createApiserverClient("", "")
|
||||
_, err := createApiserverClient("", "")
|
||||
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.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleSigterm(t *testing.T) {
|
||||
home := os.Getenv("HOME")
|
||||
kubeConfigFile := fmt.Sprintf("%v/.kube/config", home)
|
||||
clientSet := fake.NewSimpleClientset()
|
||||
|
||||
cli, err := createApiserverClient("", kubeConfigFile)
|
||||
ns := "test"
|
||||
|
||||
cm := createConfigMap(clientSet, ns, t)
|
||||
defer deleteConfigMap(cm, ns, clientSet, t)
|
||||
|
||||
name := "test"
|
||||
pod := v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns,
|
||||
},
|
||||
}
|
||||
|
||||
_, err := clientSet.CoreV1().Pods(ns).Create(&pod)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error creating api server client: %v", err)
|
||||
t.Fatalf("error creating pod %v: %v", pod, err)
|
||||
}
|
||||
|
||||
resetForTesting(func() { t.Fatal("bad parse") })
|
||||
|
||||
os.Setenv("POD_NAME", "test")
|
||||
os.Setenv("POD_NAMESPACE", "test")
|
||||
os.Setenv("POD_NAME", name)
|
||||
os.Setenv("POD_NAMESPACE", ns)
|
||||
defer os.Setenv("POD_NAME", "")
|
||||
defer os.Setenv("POD_NAMESPACE", "")
|
||||
|
||||
|
@ -67,20 +72,20 @@ func TestHandleSigterm(t *testing.T) {
|
|||
|
||||
_, conf, err := parseFlags()
|
||||
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 = clientSet
|
||||
|
||||
fs, err := file.NewFakeFS()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
ngx := controller.NewNGINXController(conf, fs)
|
||||
ngx := controller.NewNGINXController(conf, nil, fs)
|
||||
|
||||
go handleSigterm(ngx, func(code int) {
|
||||
if code != 1 {
|
||||
t.Errorf("expected exit code 1 but %v received", code)
|
||||
t.Errorf("Expected exit code 1 but %d received", code)
|
||||
}
|
||||
|
||||
return
|
||||
|
@ -88,12 +93,45 @@ func TestHandleSigterm(t *testing.T) {
|
|||
|
||||
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)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error sending SIGTERM signal")
|
||||
t.Error("Unexpected error sending SIGTERM signal.")
|
||||
}
|
||||
|
||||
err = clientSet.CoreV1().Pods(ns).Delete(name, &metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("error deleting pod %v: %v", pod, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterHandlers(t *testing.T) {
|
||||
func createConfigMap(clientSet kubernetes.Interface, ns string, t *testing.T) string {
|
||||
t.Helper()
|
||||
t.Log("Creating temporal config map")
|
||||
|
||||
configMap := &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "config",
|
||||
SelfLink: fmt.Sprintf("/api/v1/namespaces/%s/configmaps/config", ns),
|
||||
},
|
||||
}
|
||||
|
||||
cm, err := clientSet.CoreV1().ConfigMaps(ns).Create(configMap)
|
||||
if err != nil {
|
||||
t.Errorf("error creating the configuration map: %v", err)
|
||||
}
|
||||
t.Logf("Temporal configmap %v created", cm)
|
||||
|
||||
return cm.Name
|
||||
}
|
||||
|
||||
func deleteConfigMap(cm, ns string, clientSet kubernetes.Interface, t *testing.T) {
|
||||
t.Helper()
|
||||
t.Logf("Deleting temporal configmap %v", cm)
|
||||
|
||||
err := clientSet.CoreV1().ConfigMaps(ns).Delete(cm, &metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("error deleting the configmap: %v", err)
|
||||
}
|
||||
t.Logf("Temporal configmap %v deleted", cm)
|
||||
}
|
||||
|
|
19
deploy/grafana/dashboards/README.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Grafana Dashboards
|
||||
Ingress-nginx supports a rich collection of prometheus metrics. If you have prometheus and grafana installed on your cluster then prometheus will already be scraping this data due to the `scrape` annotation on the deployment.
|
||||
|
||||
This folder contains a dashboard that you can import:
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
- Ability to filter by Namespace, Controller Class and Controller
|
||||
- Visbility of Request Volume, connections, success rates, config reloads and configs out of sync.
|
||||
- Network IO pressure, memory and CPU use
|
||||
- Ingress P50, P95 and P99 percentile response times with IN/OUT throughput
|
||||
- SSL certificate expiry
|
||||
- Annotational overlays to show when config reloads happened
|
||||
|
||||
## Requirements
|
||||
|
||||
- **Grafana v5.2.0** (or newer)
|
1218
deploy/grafana/dashboards/nginx.yaml
Normal file
BIN
deploy/grafana/dashboards/screenshot.png
Normal file
After Width: | Height: | Size: 606 KiB |
|
@ -242,7 +242,7 @@ spec:
|
|||
serviceAccountName: nginx-ingress-serviceaccount
|
||||
containers:
|
||||
- name: nginx-ingress-controller
|
||||
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.15.0
|
||||
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.18.0
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
||||
|
@ -251,6 +251,14 @@ spec:
|
|||
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
|
||||
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
|
||||
- --annotations-prefix=nginx.ingress.kubernetes.io
|
||||
securityContext:
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- NET_BIND_SERVICE
|
||||
# www-data -> 33
|
||||
runAsUser: 33
|
||||
env:
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
|
@ -284,5 +292,3 @@ spec:
|
|||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
runAsNonRoot: false
|
||||
|
|
41
deploy/monitoring/configuration.yaml
Normal file
|
@ -0,0 +1,41 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: prometheus-configuration
|
||||
labels:
|
||||
name: prometheus-configuration
|
||||
namespace: ingress-nginx
|
||||
data:
|
||||
prometheus.yml: |-
|
||||
global:
|
||||
scrape_interval: 10s
|
||||
scrape_configs:
|
||||
- job_name: 'ingress-nginx-endpoints'
|
||||
kubernetes_sd_configs:
|
||||
- role: pod
|
||||
namespaces:
|
||||
names:
|
||||
- ingress-nginx
|
||||
|
||||
relabel_configs:
|
||||
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
|
||||
action: keep
|
||||
regex: true
|
||||
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scheme]
|
||||
action: replace
|
||||
target_label: __scheme__
|
||||
regex: (https?)
|
||||
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
|
||||
action: replace
|
||||
target_label: __metrics_path__
|
||||
regex: (.+)
|
||||
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
|
||||
action: replace
|
||||
target_label: __address__
|
||||
regex: ([^:]+)(?::\d+)?;(\d+)
|
||||
replacement: $1:$2
|
||||
|
||||
- source_labels: [__meta_kubernetes_service_name]
|
||||
regex: prometheus-service
|
||||
action: drop
|
||||
|
57
deploy/monitoring/grafana.yaml
Normal file
|
@ -0,0 +1,57 @@
|
|||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
name: grafana
|
||||
name: grafana
|
||||
namespace: ingress-nginx
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: grafana
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 1
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: grafana
|
||||
spec:
|
||||
containers:
|
||||
- image: grafana/grafana
|
||||
name: grafana
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
protocol: TCP
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 2500Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
volumeMounts:
|
||||
- mountPath: /var/lib/grafana
|
||||
name: data
|
||||
restartPolicy: Always
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: data
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: grafana
|
||||
namespace: ingress-nginx
|
||||
spec:
|
||||
ports:
|
||||
- port: 3000
|
||||
protocol: TCP
|
||||
targetPort: 3000
|
||||
selector:
|
||||
app: grafana
|
||||
type: NodePort
|
89
deploy/monitoring/prometheus.yaml
Normal file
|
@ -0,0 +1,89 @@
|
|||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: prometheus-server
|
||||
namespace: ingress-nginx
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources:
|
||||
- services
|
||||
- endpoints
|
||||
- pods
|
||||
verbs: ["get", "list", "watch"]
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: prometheus-server
|
||||
namespace: ingress-nginx
|
||||
|
||||
---
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: prometheus-server
|
||||
namespace: ingress-nginx
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: prometheus-server
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: prometheus-server
|
||||
namespace: ingress-nginx
|
||||
|
||||
---
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: prometheus-server
|
||||
namespace: ingress-nginx
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: prometheus-server
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: prometheus-server
|
||||
spec:
|
||||
serviceAccountName: prometheus-server
|
||||
containers:
|
||||
- name: prometheus
|
||||
image: prom/prometheus:v2.3.2
|
||||
args:
|
||||
- "--config.file=/etc/prometheus/prometheus.yml"
|
||||
- "--storage.tsdb.path=/prometheus/"
|
||||
ports:
|
||||
- containerPort: 9090
|
||||
volumeMounts:
|
||||
- name: prometheus-config-volume
|
||||
mountPath: /etc/prometheus/
|
||||
- name: prometheus-storage-volume
|
||||
mountPath: /prometheus/
|
||||
volumes:
|
||||
- name: prometheus-config-volume
|
||||
configMap:
|
||||
name: prometheus-configuration
|
||||
- name: prometheus-storage-volume
|
||||
emptyDir: {}
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: prometheus-service
|
||||
namespace: ingress-nginx
|
||||
spec:
|
||||
selector:
|
||||
app: prometheus-server
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 9090
|
||||
targetPort: 9090
|
|
@ -21,7 +21,7 @@ spec:
|
|||
serviceAccountName: nginx-ingress-serviceaccount
|
||||
containers:
|
||||
- name: nginx-ingress-controller
|
||||
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.15.0
|
||||
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.18.0
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
||||
|
@ -30,6 +30,14 @@ spec:
|
|||
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
|
||||
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
|
||||
- --annotations-prefix=nginx.ingress.kubernetes.io
|
||||
securityContext:
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- NET_BIND_SERVICE
|
||||
# www-data -> 33
|
||||
runAsUser: 33
|
||||
env:
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
|
@ -63,5 +71,3 @@ spec:
|
|||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
runAsNonRoot: false
|
||||
|
|
|
@ -2,17 +2,18 @@
|
|||
|
||||
## Contents
|
||||
|
||||
- [Mandatory command](#mandatory-command)
|
||||
- [Custom Provider](#custom-provider)
|
||||
- [Docker for Mac](#docker-for-mac)
|
||||
- [minikube](#minikube)
|
||||
- [AWS](#aws)
|
||||
- [GCE - GKE](#gce---gke)
|
||||
- [Azure](#azure)
|
||||
- [Baremetal](#baremetal)
|
||||
- [Generic Deployment](#generic-deployment)
|
||||
- [Mandatory command](#mandatory-command)
|
||||
- [Provider Specific Steps](#provider-specific-steps)
|
||||
- [Docker for Mac](#docker-for-mac)
|
||||
- [minikube](#minikube)
|
||||
- [AWS](#aws)
|
||||
- [GCE - GKE](#gce---gke)
|
||||
- [Azure](#azure)
|
||||
- [Baremetal](#baremetal)
|
||||
- [Verify installation](#verify-installation)
|
||||
- [Detect installed version](#detect-installed-version)
|
||||
- [Using Helm](#using-helm)
|
||||
- [Verify installation](#verify-installation)
|
||||
- [Detect installed version](#detect-installed-version)
|
||||
|
||||
## Generic Deployment
|
||||
|
||||
|
@ -24,16 +25,14 @@ The following resources are required for a generic deployment.
|
|||
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml
|
||||
```
|
||||
|
||||
## Custom Service Provider Deployment
|
||||
### Provider Specific Steps
|
||||
|
||||
There are cloud provider specific yaml files.
|
||||
|
||||
### Docker for Mac
|
||||
#### Docker for Mac
|
||||
|
||||
Kubernetes is available for Docker for Mac's Edge channel. Switch to the [Edge
|
||||
channel][edge] and [enable Kubernetes][enable].
|
||||
Kubernetes is available in Docker for Mac (from [version 18.06.0-ce](https://docs.docker.com/docker-for-mac/release-notes/#stable-releases-of-2018))
|
||||
|
||||
[edge]: https://docs.docker.com/docker-for-mac/install/
|
||||
[enable]: https://docs.docker.com/docker-for-mac/#kubernetes
|
||||
|
||||
Create a service
|
||||
|
@ -42,7 +41,7 @@ Create a service
|
|||
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/cloud-generic.yaml
|
||||
```
|
||||
|
||||
### minikube
|
||||
#### minikube
|
||||
|
||||
For standard usage:
|
||||
|
||||
|
@ -68,13 +67,13 @@ default-http-backend-66b447d9cf-rrlf9 1/1 Running 0 12s
|
|||
nginx-ingress-controller-fdcdcd6dd-vvpgs 1/1 Running 0 11s
|
||||
```
|
||||
|
||||
### AWS
|
||||
#### AWS
|
||||
|
||||
In AWS we use an Elastic Load Balancer (ELB) to expose the NGINX Ingress controller behind a Service of `Type=LoadBalancer`.
|
||||
Since Kubernetes v1.9.0 it is possible to use a classic load balancer (ELB) or network load balancer (NLB)
|
||||
Please check the [elastic load balancing AWS details page](https://aws.amazon.com/es/elasticloadbalancing/details/)
|
||||
|
||||
#### Elastic Load Balancer - ELB
|
||||
##### Elastic Load Balancer - ELB
|
||||
|
||||
This setup requires to choose in which layer (L4 or L7) we want to configure the ELB:
|
||||
|
||||
|
@ -102,7 +101,7 @@ This example creates an ELB with just two listeners, one in port 80 and another
|
|||
|
||||

|
||||
|
||||
#### Network Load Balancer (NLB)
|
||||
##### Network Load Balancer (NLB)
|
||||
|
||||
This type of load balancer is supported since v1.10.0 as an ALPHA feature.
|
||||
|
||||
|
@ -110,7 +109,7 @@ This type of load balancer is supported since v1.10.0 as an ALPHA feature.
|
|||
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/aws/service-nlb.yaml
|
||||
```
|
||||
|
||||
### GCE - GKE
|
||||
#### GCE - GKE
|
||||
|
||||
```console
|
||||
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/cloud-generic.yaml
|
||||
|
@ -118,16 +117,15 @@ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/mast
|
|||
|
||||
**Important Note:** proxy protocol is not supported in GCE/GKE
|
||||
|
||||
### Azure
|
||||
#### Azure
|
||||
|
||||
|
||||
```console
|
||||
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/cloud-generic.yaml
|
||||
```
|
||||
|
||||
**Important Note:** proxy protocol is not supported in GCE/GKE
|
||||
|
||||
### Baremetal
|
||||
#### Baremetal
|
||||
|
||||
Using [NodePort](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport):
|
||||
|
||||
|
@ -135,9 +133,30 @@ Using [NodePort](https://kubernetes.io/docs/concepts/services-networking/service
|
|||
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml
|
||||
```
|
||||
|
||||
### Verify installation
|
||||
|
||||
To check if the ingress controller pods have started, run the following command:
|
||||
|
||||
```console
|
||||
kubectl get pods --all-namespaces -l app=ingress-nginx --watch
|
||||
```
|
||||
|
||||
Once the operator pods are running, you can cancel the above command by typing `Ctrl+C`.
|
||||
Now, you are ready to create your first ingress.
|
||||
|
||||
### Detect installed version
|
||||
|
||||
To detect which version of the ingress controller is running, exec into the pod and run `nginx-ingress-controller version` command.
|
||||
|
||||
```console
|
||||
POD_NAMESPACE=ingress-nginx
|
||||
POD_NAME=$(kubectl get pods -n $POD_NAMESPACE -l app=ingress-nginx -o jsonpath={.items[0].metadata.name})
|
||||
kubectl exec -it $POD_NAME -n $POD_NAMESPACE -- /nginx-ingress-controller --version
|
||||
```
|
||||
|
||||
## Using Helm
|
||||
|
||||
NGINX Ingress controller can be installed via [Helm](https://helm.sh/) using the chart [stable/nginx](https://github.com/kubernetes/charts/tree/master/stable/nginx-ingress) from the official charts repository.
|
||||
NGINX Ingress controller can be installed via [Helm](https://helm.sh/) using the chart [stable/nginx-ingress](https://github.com/kubernetes/charts/tree/master/stable/nginx-ingress) from the official charts repository.
|
||||
To install the chart with the release name `my-nginx`:
|
||||
|
||||
```console
|
||||
|
@ -150,23 +169,10 @@ If the kubernetes cluster has RBAC enabled, then run:
|
|||
helm install stable/nginx-ingress --name my-nginx --set rbac.create=true
|
||||
```
|
||||
|
||||
## Verify installation
|
||||
|
||||
To check if the ingress controller pods have started, run the following command:
|
||||
Detect installed version:
|
||||
|
||||
```console
|
||||
kubectl get pods --all-namespaces -l app=ingress-nginx --watch
|
||||
POD_NAME=$(kubectl get pods -l app=nginx-ingress -o jsonpath={.items[0].metadata.name})
|
||||
kubectl exec -it $POD_NAME -- /nginx-ingress-controller --version
|
||||
```
|
||||
|
||||
Once the operator pods are running, you can cancel the above command by typing `Ctrl+C`.
|
||||
Now, you are ready to create your first ingress.
|
||||
|
||||
## Detect installed version
|
||||
|
||||
To detect which version of the ingress controller is running, exec into the pod and run `nginx-ingress-controller version` command.
|
||||
|
||||
```console
|
||||
POD_NAMESPACE=ingress-nginx
|
||||
POD_NAME=$(kubectl get pods -n $POD_NAMESPACE -l app=ingress-nginx -o jsonpath={.items[0].metadata.name})
|
||||
kubectl exec -it $POD_NAME -n $POD_NAMESPACE -- /nginx-ingress-controller --version
|
||||
```
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# Upgrading
|
||||
|
||||
!!! important
|
||||
No matter the method you use for upgrading, *if you use template overrides,
|
||||
make sure your templates are compatible with the new version of ingress-nginx*.
|
||||
No matter the method you use for upgrading, _if you use template overrides,
|
||||
make sure your templates are compatible with the new version of ingress-nginx_.
|
||||
|
||||
## Without Helm
|
||||
|
||||
|
@ -33,12 +33,11 @@ The easiest way to do this is e.g. (do note you may need to change the name para
|
|||
|
||||
```
|
||||
kubectl set image deployment/nginx-ingress-controller \
|
||||
nginx-ingress-controller=nginx:quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.15.0
|
||||
nginx-ingress-controller=nginx:quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.18.0
|
||||
```
|
||||
|
||||
For interactive editing, use `kubectl edit deployment nginx-ingress-controller`.
|
||||
|
||||
|
||||
## With Helm
|
||||
|
||||
If you installed ingress-nginx using the Helm command in the deployment docs so its name is `ngx-ingress`,
|
||||
|
@ -47,4 +46,3 @@ you should be able to upgrade using
|
|||
```shell
|
||||
helm upgrade --reuse-values ngx-ingress stable/nginx-ingress
|
||||
```
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ metadata:
|
|||
# name of the secret that contains the user/password definitions
|
||||
nginx.ingress.kubernetes.io/auth-secret: basic-auth
|
||||
# message to display with an appropriate context why the authentication is required
|
||||
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required - foo"
|
||||
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo'
|
||||
spec:
|
||||
rules:
|
||||
- host: foo.bar.com
|
||||
|
|
|
@ -24,8 +24,8 @@ Sample:
|
|||
metadata:
|
||||
name: application
|
||||
annotations:
|
||||
"nginx.ingress.kubernetes.io/auth-url": "https://$host/oauth2/auth"
|
||||
"nginx.ingress.kubernetes.io/auth-signin": "https://$host/oauth2/sign_in"
|
||||
nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
|
||||
nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"
|
||||
...
|
||||
```
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@ apiVersion: extensions/v1beta1
|
|||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/auth-signin: https://$host/oauth2/start
|
||||
nginx.ingress.kubernetes.io/auth-url: https://$host/oauth2/auth
|
||||
nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
|
||||
nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"
|
||||
name: external-auth-oauth2
|
||||
namespace: kube-system
|
||||
spec:
|
||||
|
|
|
@ -28,7 +28,7 @@ spec:
|
|||
value: <Client ID>
|
||||
- name: OAUTH2_PROXY_CLIENT_SECRET
|
||||
value: <Client Secret>
|
||||
# python -c 'import os,base64; print base64.b64encode(os.urandom(16))'
|
||||
# docker run -ti --rm python:3-alpine python -c 'import secrets,base64; print(base64.b64encode(base64.b64encode(secrets.token_bytes(16))));'
|
||||
- name: OAUTH2_PROXY_COOKIE_SECRET
|
||||
value: SECRET
|
||||
image: docker.io/colemickens/oauth2_proxy:latest
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## Ingress
|
||||
|
||||
The Ingress in this example adds a custom header to Nginx configuration that only applies to that specific Ingress. If you want to add headers that apply globally to all Ingresses, please have a look at [this example](/docs/examples/customization/custom-headers).
|
||||
The Ingress in this example adds a custom header to Nginx configuration that only applies to that specific Ingress. If you want to add headers that apply globally to all Ingresses, please have a look at [this example](/examples/customization/custom-headers/README).
|
||||
|
||||
```console
|
||||
$ kubectl apply -f ingress.yaml
|
||||
|
|
|
@ -5,7 +5,6 @@ metadata:
|
|||
annotations:
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_set_headers "Request-Id: $req_id";
|
||||
|
||||
spec:
|
||||
rules:
|
||||
- host: custom.configuration.com
|
||||
|
|
|
@ -1,82 +1,83 @@
|
|||
# Custom Errors
|
||||
|
||||
This example shows how is possible to use a custom backend to render custom error pages. The code of this example is located here [custom-error-pages](https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/customization/custom-errors)
|
||||
This example demonstrates how to use a custom backend to render custom error pages.
|
||||
|
||||
## Customized default backend
|
||||
|
||||
The idea is to use the headers `X-Code` and `X-Format` that NGINX pass to the backend in case of an error to find out the best existent representation of the response to be returned. i.e. if the request contains an `Accept` header of type `json` the error should be in that format and not in `html` (the default in NGINX).
|
||||
|
||||
First create the custom backend to use in the Ingress controller
|
||||
First, create the custom `default-backend`. It will be used by the Ingress controller later on.
|
||||
|
||||
```
|
||||
$ kubectl create -f custom-default-backend.yaml
|
||||
service "nginx-errors" created
|
||||
replicationcontroller "nginx-errors" created
|
||||
deployment.apps "nginx-errors" created
|
||||
```
|
||||
|
||||
```
|
||||
$ kubectl get svc
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
echoheaders 10.3.0.7 nodes 80/TCP 23d
|
||||
kubernetes 10.3.0.1 <none> 443/TCP 34d
|
||||
nginx-errors 10.3.0.102 <none> 80/TCP 11s
|
||||
```
|
||||
This should have created a Deployment and a Service with the name `nginx-errors`.
|
||||
|
||||
```
|
||||
$ kubectl get rc
|
||||
CONTROLLER REPLICAS AGE
|
||||
echoheaders 1 19d
|
||||
nginx-errors 1 19s
|
||||
$ kubectl get deploy,svc
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
deployment.apps/nginx-errors 1 1 1 10s
|
||||
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
service/nginx-errors ClusterIP 10.0.0.12 <none> 80/TCP 10s
|
||||
```
|
||||
|
||||
Next create the Ingress controller executing
|
||||
```
|
||||
$ kubectl create -f rc-custom-errors.yaml
|
||||
```
|
||||
## Ingress controller configuration
|
||||
|
||||
Now to check if this is working we use curl:
|
||||
If you do not already have an instance of the the NGINX Ingress controller running, deploy it according to the
|
||||
[deployment guide][deploy], then follow these steps:
|
||||
|
||||
1. Edit the `nginx-ingress-controller` Deployment and set the value of the `--default-backend` flag to the name of the
|
||||
newly created error backend.
|
||||
|
||||
2. Edit the `nginx-configuration` ConfigMap and create the key `custom-http-errors` with a value of `404,503`.
|
||||
|
||||
3. Take note of the IP address assigned to the NGINX Ingress controller Service.
|
||||
```
|
||||
$ kubectl get svc ingress-nginx
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
ingress-nginx ClusterIP 10.0.0.13 <none> 80/TCP,443/TCP 10m
|
||||
```
|
||||
|
||||
!!! Note
|
||||
The `ingress-nginx` Service is of type `ClusterIP` in this example. This may vary depending on your environment.
|
||||
Make sure you can use the Service to reach NGINX before proceeding with the rest of this example.
|
||||
|
||||
[deploy]: ../../../deploy/
|
||||
|
||||
## Testing error pages
|
||||
|
||||
Let us send a couple of HTTP requests using cURL and validate everything is working as expected.
|
||||
|
||||
A request to the default backend returns a 404 error with a custom message:
|
||||
|
||||
```
|
||||
$ curl -v http://172.17.4.99/
|
||||
* Trying 172.17.4.99...
|
||||
* Connected to 172.17.4.99 (172.17.4.99) port 80 (#0)
|
||||
> GET / HTTP/1.1
|
||||
> Host: 172.17.4.99
|
||||
> User-Agent: curl/7.43.0
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 404 Not Found
|
||||
< Server: nginx/1.10.0
|
||||
< Date: Wed, 04 May 2016 02:53:45 GMT
|
||||
< Content-Type: text/html
|
||||
< Transfer-Encoding: chunked
|
||||
< Connection: keep-alive
|
||||
< Vary: Accept-Encoding
|
||||
<
|
||||
$ curl -D- http://10.0.0.13/
|
||||
HTTP/1.1 404 Not Found
|
||||
Server: nginx/1.13.12
|
||||
Date: Tue, 12 Jun 2018 19:11:24 GMT
|
||||
Content-Type: */*
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
|
||||
<span>The page you're looking for could not be found.</span>
|
||||
|
||||
* Connection #0 to host 172.17.4.99 left intact
|
||||
```
|
||||
|
||||
Specifying json as expected format:
|
||||
A request with a custom `Accept` header returns the corresponding document type (JSON):
|
||||
|
||||
```
|
||||
$ curl -v http://172.17.4.99/ -H 'Accept: application/json'
|
||||
* Trying 172.17.4.99...
|
||||
* Connected to 172.17.4.99 (172.17.4.99) port 80 (#0)
|
||||
> GET / HTTP/1.1
|
||||
> Host: 172.17.4.99
|
||||
> User-Agent: curl/7.43.0
|
||||
> Accept: application/json
|
||||
>
|
||||
< HTTP/1.1 404 Not Found
|
||||
< Server: nginx/1.10.0
|
||||
< Date: Wed, 04 May 2016 02:54:00 GMT
|
||||
< Content-Type: text/html
|
||||
< Transfer-Encoding: chunked
|
||||
< Connection: keep-alive
|
||||
< Vary: Accept-Encoding
|
||||
<
|
||||
$ curl -D- -H 'Accept: application/json' http://10.0.0.13/
|
||||
HTTP/1.1 404 Not Found
|
||||
Server: nginx/1.13.12
|
||||
Date: Tue, 12 Jun 2018 19:12:36 GMT
|
||||
Content-Type: application/json
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Vary: Accept-Encoding
|
||||
|
||||
{ "message": "The page you're looking for could not be found" }
|
||||
|
||||
* Connection #0 to host 172.17.4.99 left intact
|
||||
```
|
||||
|
||||
To go further with this example, feel free to deploy your own applications and Ingress objects, and validate that the
|
||||
responses are still in the correct format when a backend returns 503 (eg. if you scale a Deployment down to 0 replica).
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
|
@ -5,27 +6,35 @@ metadata:
|
|||
labels:
|
||||
app: nginx-errors
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: nginx-errors
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8080
|
||||
name: http
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1beta2
|
||||
metadata:
|
||||
name: nginx-errors
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx-errors
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx-errors
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx-errors
|
||||
image: aledbf/nginx-error-server:0.1
|
||||
- name: nginx-error-server
|
||||
image: quay.io/kubernetes-ingress-controller/custom-error-pages-amd64:0.3
|
||||
ports:
|
||||
- containerPort: 80
|
||||
- containerPort: 8080
|
||||
# Setting the environment variable DEBUG we can see the headers sent
|
||||
# by the ingress controller to the backend in the client response.
|
||||
# env:
|
||||
# - name: DEBUG
|
||||
# value: "true"
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: nginx-ingress-controller
|
||||
labels:
|
||||
k8s-app: nginx-ingress-lb
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
k8s-app: nginx-ingress-lb
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: nginx-ingress-lb
|
||||
name: nginx-ingress-lb
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 60
|
||||
containers:
|
||||
- image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.15.0
|
||||
name: nginx-ingress-lb
|
||||
imagePullPolicy: Always
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 10254
|
||||
scheme: HTTP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 10254
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 10
|
||||
timeoutSeconds: 1
|
||||
# use downward API
|
||||
env:
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
ports:
|
||||
- containerPort: 80
|
||||
hostPort: 80
|
||||
- containerPort: 443
|
||||
hostPort: 443
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --default-backend-service=$(POD_NAMESPACE)/nginx-errors
|
||||
securityContext:
|
||||
runAsNonRoot: false
|
|
@ -42,6 +42,3 @@ $ kubectl exec nginx-ingress-controller-v1ppm cat /etc/nginx/nginx.conf
|
|||
}
|
||||
....
|
||||
```
|
||||
|
||||
|
||||

|
||||
|
|
Before Width: | Height: | Size: 59 KiB |
|
@ -1,103 +0,0 @@
|
|||
# Custom VTS metrics with Prometheus
|
||||
|
||||
This example aims to demonstrate the deployment of an nginx ingress controller and use a ConfigMap to enable [nginx vts module](https://github.com/vozlt/nginx-module-vts
|
||||
) to export metrics in prometheus format.
|
||||
|
||||
## vts-metrics
|
||||
|
||||
Vts-metrics export NGINX metrics. To deploy all the files simply run `kubectl apply -f nginx`. A deployment and service will be
|
||||
created which already has a `prometheus.io/scrape: 'true'` annotation and if you added
|
||||
the recommended Prometheus service-endpoint scraping [configuration](https://raw.githubusercontent.com/prometheus/prometheus/master/documentation/examples/prometheus-kubernetes.yml),
|
||||
Prometheus will scrape it automatically and you start using the generated metrics right away.
|
||||
|
||||
## Custom configuration
|
||||
|
||||
```console
|
||||
apiVersion: v1
|
||||
data:
|
||||
enable-vts-status: "true"
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: nginx-configuration
|
||||
namespace: ingress-nginx
|
||||
labels:
|
||||
app: ingress-nginx
|
||||
```
|
||||
|
||||
```console
|
||||
$ kubectl apply -f nginx-vts-metrics-conf.yaml
|
||||
```
|
||||
|
||||
## Result
|
||||
|
||||
Check whether the ingress controller successfully generated the NGINX vts status:
|
||||
|
||||
```console
|
||||
$ kubectl exec nginx-ingress-controller-873061567-4n3k2 -n ingress-nginx cat /etc/nginx/nginx.conf|grep vhost_traffic_status_display
|
||||
vhost_traffic_status_display;
|
||||
vhost_traffic_status_display_format html;
|
||||
```
|
||||
|
||||
### NGINX vts dashboard
|
||||
|
||||
The vts dashboard provides real time metrics.
|
||||
|
||||

|
||||
|
||||
Because the vts port it's not yet exposed, you should forward the controller port to see it.
|
||||
|
||||
```console
|
||||
$ kubectl port-forward $(kubectl get pods --selector=k8s-app=nginx-ingress-controller -n ingress-nginx --output=jsonpath={.items..metadata.name}) -n ingress-nginx 18080
|
||||
```
|
||||
|
||||
Now open the url [http://localhost:18080/nginx_status](http://localhost:18080/nginx_status) in your browser.
|
||||
|
||||
### Prometheus metrics output
|
||||
|
||||
NGINX Ingress controller already has a parser to convert vts metrics to Prometheus format. It exports prometheus metrics to the address `:10254/metrics`.
|
||||
|
||||
```console
|
||||
$ kubectl exec -ti -n ingress-nginx $(kubectl get pods --selector=k8s-app=nginx-ingress-controller -n kube-system --output=jsonpath={.items..metadata.name}) curl localhost:10254/metrics
|
||||
ingress_controller_ssl_expire_time_seconds{host="foo.bar.com"} -6.21355968e+10
|
||||
# HELP ingress_controller_success Cumulative number of Ingress controller reload operations
|
||||
# TYPE ingress_controller_success counter
|
||||
ingress_controller_success{count="reloads"} 3
|
||||
# HELP nginx_bytes_total Nginx bytes count
|
||||
# TYPE nginx_bytes_total counter
|
||||
nginx_bytes_total{direction="in",ingress_class="nginx",namespace="",server_zone="*"} 3708
|
||||
nginx_bytes_total{direction="in",ingress_class="nginx",namespace="",server_zone="_"} 3708
|
||||
nginx_bytes_total{direction="out",ingress_class="nginx",namespace="",server_zone="*"} 5256
|
||||
nginx_bytes_total{direction="out",ingress_class="nginx",namespace="",server_zone="_"} 5256
|
||||
```
|
||||
|
||||
### Customize metrics
|
||||
|
||||
The default [vts vhost key](https://github.com/vozlt/nginx-module-vts#vhost_traffic_status_filter_by_set_key) is `$geoip_country_code country::*` that expose metrics grouped by server and country code. The example below show how to have metrics grouped by server and server path.
|
||||
|
||||

|
||||
|
||||
## NGINX custom configuration ( http level )
|
||||
|
||||
```
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
data:
|
||||
enable-vts-status: "true"
|
||||
vts-default-filter-key: "$server_name"
|
||||
...
|
||||
```
|
||||
|
||||
## Customize ingress
|
||||
|
||||
```
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/vts-filter-key: $uri $server_name
|
||||
name: ingress
|
||||
```
|
||||
|
||||
## Result
|
||||
|
||||

|
Before Width: | Height: | Size: 969 KiB |
Before Width: | Height: | Size: 451 KiB |
Before Width: | Height: | Size: 244 KiB |
|
@ -1,9 +0,0 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
enable-vts-status: "true"
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: nginx-configuration
|
||||
namespace: ingress-nginx
|
||||
labels:
|
||||
app: ingress-nginx
|
|
@ -14,7 +14,7 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: http-svc
|
||||
image: gcr.io/google_containers/echoserver:1.8
|
||||
image: gcr.io/kubernetes-e2e-test-images/echoserver:2.1
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
env:
|
||||
|
|
|
@ -13,10 +13,9 @@ Auth | [OAuth external auth](auth/oauth-external-auth/README.md) | TODO | TODO
|
|||
Customization | [Configuration snippets](customization/configuration-snippets/README.md) | customize nginx location configuration using annotations | Advanced
|
||||
Customization | [Custom configuration](customization/custom-configuration/README.md) | TODO | TODO
|
||||
Customization | [Custom DH parameters for perfect forward secrecy](customization/ssl-dh-param/README.md) | TODO | TODO
|
||||
Customization | [Custom errors](customization/custom-errors/README.md) | TODO | TODO
|
||||
Customization | [Custom errors](customization/custom-errors/README.md) | serve custom error pages from the default backend | Intermediate
|
||||
Customization | [Custom headers](customization/custom-headers/README.md) | set custom headers before sending traffic to backends | Advanced
|
||||
Customization | [Custom upstream check](customization/custom-upstream-check/README.md) | TODO | TODO
|
||||
Customization | [Custom VTS metrics with Prometheus](customization/custom-vts-metrics-prometheus/README.md) | TODO | TODO
|
||||
Customization | [External authentication with response header propagation](customization/external-auth-headers/README.md) | TODO | TODO
|
||||
Customization | [Sysctl tuning](customization/sysctl/README.md) | TODO | TODO
|
||||
Features | [Rewrite](rewrite/README.md) | TODO | TODO
|
||||
|
|
|
@ -58,7 +58,7 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: http-svc
|
||||
image: gcr.io/google_containers/echoserver:1.8
|
||||
image: gcr.io/kubernetes-e2e-test-images/echoserver:2.1
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
env:
|
||||
|
|
|
@ -21,7 +21,7 @@ spec:
|
|||
# hostNetwork: true
|
||||
terminationGracePeriodSeconds: 60
|
||||
containers:
|
||||
- image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.15.0
|
||||
- image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.18.0
|
||||
name: nginx-ingress-controller
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
|
@ -53,5 +53,3 @@ spec:
|
|||
- /nginx-ingress-controller
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
||||
- --publish-service=$(POD_NAMESPACE)/nginx-ingress-lb
|
||||
securityContext:
|
||||
runAsNonRoot: false
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
# How it works
|
||||
|
||||
The objective of this document explains how the NGINX Ingress controller works, in particular how the NGINX model is built and why we need a one.
|
||||
The objective of this document is to explain how the NGINX Ingress controller works, in particular how the NGINX model is built and why we need one.
|
||||
|
||||
## NGINX configuration
|
||||
|
||||
The goal of this Ingress controller is the assembly of a configuration file (nginx.conf). The main implication of this requirement is the need to reload NGINX after any change in the configuration file.
|
||||
The goal of this Ingress controller is the assembly of a configuration file (nginx.conf). The main implication of this requirement is the need to reload NGINX after any change in the configuration file. _Though it is important to note that we don't reload Nginx on changes that impact only an `upstream` configuration (i.e Endpoints change when you deploy your app)_. We use https://github.com/openresty/lua-nginx-module to achieve this. Check [below](#avoiding-reloads-on-endpoints-changes) to learn more about how it's done.
|
||||
|
||||
## NGINX model
|
||||
|
||||
Usually, a Kubernetes Controller utilizes the [synchronization loop pattern](1) to check if the desired state in the controller is updated or a change is required. To this purpose, we need to build a model using different objects from the cluster, in particular (in no special order) Ingresses, Services, Endpoints, Secrets, and Configmaps to generate a point in time configuration file that reflects the state of the cluster.
|
||||
|
||||
To get this object from the cluster, we use [Kubernetes Informers](2), in particular, `FilteredSharedInformer`. This informers allows reacting to changes in using [callbacks](3) to individual changes when a new object is added, modified or removed. Unfortunately, there is no way to know if a particular change is going to affect the final configuration file. Therefore on every change, we have to rebuild a new model from scratch based on the state of cluster and compare it to the current model. If the new model equals to the current one, then we avoid generating a new NGINX configuration and [trigger a reload](7). Otherwise, we create a new NGINX configuration based on the new model, replace the current model and [trigger a reload](7).
|
||||
To get this object from the cluster, we use [Kubernetes Informers](2), in particular, `FilteredSharedInformer`. This informers allows reacting to changes in using [callbacks](3) to individual changes when a new object is added, modified or removed. Unfortunately, there is no way to know if a particular change is going to affect the final configuration file. Therefore on every change, we have to rebuild a new model from scratch based on the state of cluster and compare it to the current model. If the new model equals to the current one, then we avoid generating a new NGINX configuration and triggering a reload. Otherwise, we check if the difference is only about Endpoints. If so we then send the new list of Endpoints to a Lua handler running inside Nginx using HTTP POST request and again avoid generating a new NGINX configuration and triggering a reload. If the difference between running and new model is about more than just Endpoints we create a new NGINX configuration based on the new model, replace the current model and trigger a reload.
|
||||
|
||||
One of the uses of the model is to avoid unnecessary reloads when there's no change in the state and to detect conflicts in definitions.
|
||||
|
||||
|
@ -39,16 +39,21 @@ The next list describes the scenarios when a reload is required:
|
|||
|
||||
- New Ingress Resource Created.
|
||||
- TLS section is added to existing Ingress.
|
||||
- Change in Ingress annotations.
|
||||
- Change in Ingress annotations that impacts more than just upstream configuration. For instance `load-balance` annotation does not require a reload.
|
||||
- A path is added/removed from an Ingress.
|
||||
- An Ingress, Service, Secret is removed.
|
||||
- Some missing referenced object from the Ingress is available, like a Service, Secret or Endpoint.
|
||||
- Some missing referenced object from the Ingress is available, like a Service or Secret.
|
||||
- A Secret is updated.
|
||||
|
||||
## Avoiding reloads
|
||||
|
||||
In some cases, it is possible to avoid reloads, in particular when there is a change in the endpoints, i.e., a pod is started or replaced. It is out of the scope of this Ingress controller to remove reloads completely. This would require an incredible amount of work and at some point makes no sense. This can change only if NGINX changes the way new configurations are read, basically, new changes do not replace worker processes.
|
||||
|
||||
### Avoiding reloads on Endpoints changes
|
||||
On every endpoint change the controller fetches endpoints from all the services it sees and generates corresponding Backend objects. It then sends these objects to a Lua handler running inside Nginx. The Lua code in turn stores those backends in a shared memory zone. Then for every request Lua code running in [`balancer_by_lua`](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/balancer.md) context detects what endpoints it should choose upstream peer from and applies the configured load balancing algorithm to choose the peer. Then Nginx takes care of the rest. This way we avoid reloading Nginx on endpoint changes. _Note_ that this includes annotation changes that affects only `upstream` configuration in Nginx as well.
|
||||
|
||||
In a relatively big clusters with frequently deploying apps this feature saves significant number of Nginx reloads which can otherwise affect response latency, load balancing quality (after every reload Nginx resets the state of load balancing) and so on.
|
||||
|
||||
[0]: https://github.com/openresty/lua-nginx-module/pull/1259
|
||||
[1]: https://coreos.com/kubernetes/docs/latest/replication-controller.html#the-reconciliation-loop-in-detail
|
||||
[2]: https://godoc.org/k8s.io/client-go/informers#NewFilteredSharedInformerFactory
|
||||
|
@ -56,4 +61,4 @@ In some cases, it is possible to avoid reloads, in particular when there is a ch
|
|||
[4]: https://github.com/kubernetes/ingress-nginx/blob/master/internal/task/queue.go#L38
|
||||
[5]: https://golang.org/pkg/sync/#Mutex
|
||||
[6]: https://github.com/kubernetes/ingress-nginx/blob/master/rootfs/etc/nginx/template/nginx.tmpl
|
||||
[7]: http://nginx.org/en/docs/beginners_guide.html#control
|
||||
[7]: http://nginx.org/en/docs/beginners_guide.html#control
|
||||
|
|
BIN
docs/images/grafana.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
docs/images/jaeger-demo.png
Normal file
After Width: | Height: | Size: 141 KiB |
BIN
docs/images/prometheus-dashboard.png
Normal file
After Width: | Height: | Size: 112 KiB |
|
@ -1,14 +0,0 @@
|
|||
# Ingress Controller Catalog
|
||||
|
||||
This is a non-comprehensive list of existing ingress controllers.
|
||||
|
||||
* [Dummy controller backend](/examples/custom-controller)
|
||||
* [HAProxy Ingress controller](https://github.com/jcmoraisjr/haproxy-ingress)
|
||||
* [Linkerd](https://linkerd.io/config/0.9.1/linkerd/index.html#ingress-identifier)
|
||||
* [traefik](https://docs.traefik.io/configuration/backends/kubernetes/)
|
||||
* [AWS Application Load Balancer Ingress Controller](https://github.com/coreos/alb-ingress-controller)
|
||||
* [kube-ingress-aws-controller](https://github.com/zalando-incubator/kube-ingress-aws-controller)
|
||||
* [Voyager: HAProxy Ingress Controller](https://github.com/appscode/voyager)
|
||||
* [External Nginx Ingress Controller](https://github.com/unibet/ext_nginx)
|
||||
* [Heptio Contour controller](https://github.com/heptio/contour)
|
||||
* [LemonLDAP::NG kubernetes controller](https://github.com/lemonldap-ng-controller/lemonldap-ng-controller) adds WebSSO, Access Management and Identity Federation to NGINX Ingress Controller
|
|
@ -1,48 +1,48 @@
|
|||
# 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 |
|
||||
|----------|-------------|
|
||||
| `--alsologtostderr` | log to standard error as well as files |
|
||||
| `--annotations-prefix string` | Prefix of the ingress annotations. (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. |
|
||||
| `--configmap string` | Name of the ConfigMap that contains the custom configuration to use |
|
||||
| `--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-server-port int` | Default 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>. |
|
||||
| `--election-id string` | Election id to use for status update. (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-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-passthrough` | Enable SSL passthrough feature. Default is disabled |
|
||||
| `--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. |
|
||||
| `--health-check-path string` | Defines the URL to be used as health check inside in the default server in NGINX. (default "/healthz") |
|
||||
| `--healthz-port int` | port for healthz endpoint. (default 10254) |
|
||||
| `--http-port int` | Indicates the port to use for HTTP traffic (default 80) |
|
||||
| `--https-port int` | Indicates the port to use for HTTPS traffic (default 443) |
|
||||
| `--ingress-class string` | Name of the ingress class to route through this controller. |
|
||||
| `--kubeconfig string` | Path to kubeconfig file with authorization and master location information. |
|
||||
| `--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 |
|
||||
| `--logtostderr` | log to standard error instead of files (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-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. |
|
||||
| `--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 |
|
||||
| `--sort-backends` | Defines if backends and its endpoints should be sorted |
|
||||
| `--ssl-passtrough-proxy-port int` | Default port to use internally for SSL when SSL Passthgough is enabled (default 442) |
|
||||
| `--status-port int` | Indicates the TCP port to use for exposing the nginx status page (default 18080) |
|
||||
| `--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-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 |
|
||||
| `--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. |
|
||||
| `--update-status` | Indicates if the ingress controller should update the Ingress status IP/hostname. Default is true (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) |
|
||||
| `-v`, `--v Level` | log level for V logs |
|
||||
| `--version` | Shows release information about the NGINX Ingress controller |
|
||||
| `--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 |
|
||||
| --alsologtostderr | log to standard error as well as files |
|
||||
| --annotations-prefix string | Prefix of the Ingress annotations specific to the NGINX controller. (default "nginx.ingress.kubernetes.io") |
|
||||
| --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 containing custom global configurations for the controller. |
|
||||
| --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 | Port to use for exposing the default server (catch-all). (default 8181) |
|
||||
| --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 Ingress status updates. (default "ingress-controller-leader") |
|
||||
| --enable-dynamic-configuration | Dynamically refresh backends on topology changes instead of reloading NGINX. Feature backed by OpenResty Lua libraries. (enabled by default) |
|
||||
| --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. |
|
||||
| --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 | 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 to use for the healthz endpoint. (default 10254) |
|
||||
| --http-port int | Port to use for servicing HTTP traffic. (default 80) |
|
||||
| --https-port int | Port to use for servicing HTTPS traffic. (default 443) |
|
||||
| --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 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_dir string | If non-empty, write log files in this directory |
|
||||
| --logtostderr | log to standard error instead of files (default true) |
|
||||
| --profiling | Enable profiling via web interface host:port/debug/pprof/ (default true) |
|
||||
| --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 | 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 | Set the load-balancer status of Ingress objects to internal Node addresses instead of external. Requires the update-status parameter. |
|
||||
| --sort-backends | Sort servers inside NGINX upstreams. |
|
||||
| --ssl-passthrough-proxy-port int | Port to use internally for SSL Passthrough. (default 442) |
|
||||
| --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) |
|
||||
| --sync-period duration | Period at which the controller forces the repopulation of its local object stores. (default is 0) |
|
||||
| --sync-rate-limit float32 | Define the sync frequency upper limit (default 0.3) |
|
||||
| --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 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 | 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 | Update the load-balancer status of Ingress objects when the controller shuts down. Requires the update-status parameter. (default true) |
|
||||
| --v Level | log level for V logs |
|
||||
| --version | Show release information about the NGINX Ingress controller and exit. |
|
||||
| --vmodule moduleSpec | comma-separated list of pattern=N settings for file-filtered logging |
|
||||
| --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. |
|
||||
|
|
|
@ -1,19 +1,30 @@
|
|||
# Custom errors
|
||||
|
||||
In case of an error in a request the body of the response is obtained from the `default backend`.
|
||||
Each request to the default backend includes two headers:
|
||||
When the [`custom-http-errors`][cm-custom-http-errors] option is enabled, the Ingress controller configures NGINX so
|
||||
that it passes several HTTP headers down to its `default-backend` in case of error:
|
||||
|
||||
- `X-Code` indicates the HTTP code to be returned to the client.
|
||||
- `X-Format` the value of the `Accept` header.
|
||||
| Header | Value |
|
||||
| ---------------- | ------------------------------------------------ |
|
||||
| `X-Code` | HTTP status code retuned by the request |
|
||||
| `X-Format` | Value of the `Accept` header sent by the client |
|
||||
| `X-Original-URI` | URI that caused the error |
|
||||
| `X-Namespace` | Namespace where the backend Service is located |
|
||||
| `X-Ingress-Name` | Name of the Ingress where the backend is defined |
|
||||
| `X-Service-Name` | Name of the Service backing the backend |
|
||||
| `X-Service-Port` | Port number of the Service backing the backend |
|
||||
|
||||
A custom error backend can use this information to return the best possible representation of an error page. For
|
||||
example, if the value of the `Accept` header send by the client was `application/json`, a carefully crafted backend
|
||||
could decide to return the error payload as a JSON document instead of HTML.
|
||||
|
||||
!!! Important
|
||||
The custom backend must return the correct HTTP status code to be returned. NGINX does not change the response from the custom default backend.
|
||||
The custom backend is expected to return the correct HTTP status code instead of `200`. NGINX does not change
|
||||
the response from the custom default backend.
|
||||
|
||||
Using these two headers it's possible to use a custom backend service like [this one](https://github.com/kubernetes/ingress-nginx/tree/master/images/custom-error-pages) that inspects each request and returns a custom error page with the format expected by the client. Please check the example [custom-errors](https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/customization/custom-errors).
|
||||
An example of such custom backend is available inside the source repository at [images/custom-error-pages][img-custom-error-pages].
|
||||
|
||||
NGINX sends additional headers that can be used to build custom response:
|
||||
See also the [Custom errors][example-custom-errors] example.
|
||||
|
||||
- X-Original-URI
|
||||
- X-Namespace
|
||||
- X-Ingress-Name
|
||||
- X-Service-Name
|
||||
[cm-custom-http-errors]: ./nginx-configuration/configmap.md#custom-http-errors
|
||||
[img-custom-error-pages]: https://github.com/kubernetes/ingress-nginx/tree/master/images/custom-error-pages
|
||||
[example-custom-errors]: ../examples/customization/custom-errors
|
||||
|
|
|
@ -12,7 +12,8 @@ The next example shows how to expose the service `example-go` running in the nam
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: tcp-configmap-example
|
||||
name: tcp-services
|
||||
namespace: ingress-nginx
|
||||
data:
|
||||
9000: "default/example-go:8080"
|
||||
```
|
||||
|
@ -24,7 +25,8 @@ The next example shows how to expose the service `kube-dns` running in the names
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: udp-configmap-example
|
||||
name: udp-services
|
||||
namespace: ingress-nginx
|
||||
data:
|
||||
53: "kube-system/kube-dns:53"
|
||||
```
|
||||
|
|
90
docs/user-guide/monitoring.md
Normal file
|
@ -0,0 +1,90 @@
|
|||
# Prometheus and Grafana installation
|
||||
|
||||
This tutorial will show you how to install [Prometheus](https://prometheus.io/) and [Grafana](https://grafana.com/) for scraping the metrics of the NGINX Ingress controller.
|
||||
|
||||
!!! Important: this example uses `emptyDir` volumes for Prometheus and Grafana. This means once the pod gets terminated you will lose all the data.
|
||||
|
||||
## Before You Begin
|
||||
|
||||
The NGINX Ingress controller should already be deployed according to the deployment instructions [here](../deploy/index.md).
|
||||
|
||||
Note that the yaml files used in this tutorial are stored in the [deploy/monitoring](https://github.com/kubernetes/ingress-nginx/tree/master/deploy/monitoring) folder of the GitHub repository [kubernetes/ingress-nginx](https://github.com/kubernetes/ingress-nginx).
|
||||
|
||||
## Deploy and configure Prometheus Server
|
||||
|
||||
The Prometheus server must be configured so that it can discover endpoints of services. If a Prometheus server is already running in the cluster and if it is configured in a way that it can find the ingress controller pods, no extra configuration is needed.
|
||||
|
||||
If there is no existing Prometheus server running, the rest of this tutorial will guide you through the steps needed to deploy a properly configured Prometheus server.
|
||||
|
||||
Running the following command deploys the prometheus configuration in Kubernetes:
|
||||
|
||||
```console
|
||||
kubectl create -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/monitoring/configuration.yaml
|
||||
configmap "prometheus-configuration" created
|
||||
```
|
||||
|
||||
Running the following command deploys prometheus in Kubernetes:
|
||||
|
||||
```console
|
||||
kubectl create -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/monitoring/prometheus.yaml
|
||||
clusterrole "prometheus-server" created
|
||||
serviceaccount "prometheus-server" created
|
||||
clusterrolebinding "prometheus-server" created
|
||||
deployment "prometheus-server" created
|
||||
service "prometheus-service" created
|
||||
```
|
||||
|
||||
### Prometheus Dashboard
|
||||
|
||||
Open Prometheus dashboard in a web browser:
|
||||
|
||||
```console
|
||||
kubectl get svc -n ingress-nginx
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
default-http-backend ClusterIP 10.103.59.201 <none> 80/TCP 3d
|
||||
ingress-nginx NodePort 10.97.44.72 <none> 80:30100/TCP,443:30154/TCP,10254:32049/TCP 5h
|
||||
prometheus NodePort 10.98.233.86 <none> 9090:32630/TCP 1m
|
||||
```
|
||||
|
||||
Obtain the IP address of the nodes in the running cluster:
|
||||
|
||||
```console
|
||||
kubectl get nodes -o wide
|
||||
```
|
||||
|
||||
In some cases where the node only have internal IP adresses we need to execute:
|
||||
|
||||
```console
|
||||
kubectl get nodes --selector=kubernetes.io/role!=master -o jsonpath={.items[*].status.addresses[?\(@.type==\"InternalIP\"\)].address}
|
||||
10.192.0.2 10.192.0.3 10.192.0.4
|
||||
```
|
||||
|
||||
Open your browser and visit the following URL: _http://{node IP address}:{prometheus-svc-nodeport}_ to load the Prometheus Dashboard.
|
||||
|
||||
According to the above example, this URL will be http://10.192.0.3:32630
|
||||
|
||||

|
||||
|
||||
### Grafana
|
||||
|
||||
```console
|
||||
kubectl create -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/monitoring/grafana.yaml
|
||||
```
|
||||
|
||||
```console
|
||||
kubectl get svc -n ingress-nginx
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
default-http-backend ClusterIP 10.103.59.201 <none> 80/TCP 3d
|
||||
ingress-nginx NodePort 10.97.44.72 <none> 80:30100/TCP,443:30154/TCP,10254:32049/TCP 5h
|
||||
prometheus NodePort 10.98.233.86 <none> 9090:32630/TCP 10m
|
||||
grafana NodePort 10.98.233.86 <none> 9090:31086/TCP 10m
|
||||
```
|
||||
|
||||
Open your browser and visit the following URL: _http://{node IP address}:{grafana-svc-nodeport}_ to load the Grafana Dashboard.
|
||||
According to the above example, this URL will be http://10.192.0.3:31086
|
||||
|
||||
The username and password is `admin`
|
||||
|
||||
After the login you can import the Grafana dashboard from _https://github.com/kubernetes/ingress-nginx/tree/master/deploy/grafana/dashboards_
|
||||
|
||||

|
|
@ -27,6 +27,7 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz
|
|||
|[nginx.ingress.kubernetes.io/auth-tls-error-page](#client-certificate-authentication)|string|
|
||||
|[nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream](#client-certificate-authentication)|"true" or "false"|
|
||||
|[nginx.ingress.kubernetes.io/auth-url](#external-authentication)|string|
|
||||
|[nginx.ingress.kubernetes.io/backend-protocol](#backend-protocol)|string|HTTP,HTTPS,GRPC,GRPCS,AJP|
|
||||
|[nginx.ingress.kubernetes.io/base-url-scheme](#rewrite)|string|
|
||||
|[nginx.ingress.kubernetes.io/client-body-buffer-size](#client-body-buffer-size)|string|
|
||||
|[nginx.ingress.kubernetes.io/configuration-snippet](#configuration-snippet)|string|
|
||||
|
@ -43,7 +44,9 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz
|
|||
|[nginx.ingress.kubernetes.io/limit-connections](#rate-limiting)|number|
|
||||
|[nginx.ingress.kubernetes.io/limit-rps](#rate-limiting)|number|
|
||||
|[nginx.ingress.kubernetes.io/permanent-redirect](#permanent-redirect)|string|
|
||||
|[nginx.ingress.kubernetes.io/permanent-redirect-code](#permanent-redirect-code)|number|
|
||||
|[nginx.ingress.kubernetes.io/proxy-body-size](#custom-max-body-size)|string|
|
||||
|[nginx.ingress.kubernetes.io/proxy-cookie-domain](#proxy-cookie-domain)|string|
|
||||
|[nginx.ingress.kubernetes.io/proxy-connect-timeout](#custom-timeouts)|number|
|
||||
|[nginx.ingress.kubernetes.io/proxy-send-timeout](#custom-timeouts)|number|
|
||||
|[nginx.ingress.kubernetes.io/proxy-read-timeout](#custom-timeouts)|number|
|
||||
|
@ -70,6 +73,7 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz
|
|||
|[nginx.ingress.kubernetes.io/upstream-vhost](#custom-nginx-upstream-vhost)|string|
|
||||
|[nginx.ingress.kubernetes.io/whitelist-source-range](#whitelist-source-range)|CIDR|
|
||||
|[nginx.ingress.kubernetes.io/proxy-buffering](#proxy-buffering)|string|
|
||||
|[nginx.ingress.kubernetes.io/proxy-buffer-size](#proxy-buffer-size)|string|
|
||||
|[nginx.ingress.kubernetes.io/ssl-ciphers](#ssl-ciphers)|string|
|
||||
|[nginx.ingress.kubernetes.io/connection-proxy-header](#connection-proxy-header)|string|
|
||||
|[nginx.ingress.kubernetes.io/enable-access-log](#enable-access-log)|"true" or "false"|
|
||||
|
@ -150,7 +154,7 @@ nginx.ingress.kubernetes.io/auth-realm: "realm string"
|
|||
NGINX exposes some flags in the [upstream configuration](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream) that enable the configuration of each server in the upstream. The Ingress controller allows custom `max_fails` and `fail_timeout` parameters in a global context using `upstream-max-fails` and `upstream-fail-timeout` in the NGINX ConfigMap or in a particular Ingress rule. `upstream-max-fails` defaults to 0. This means NGINX will respect the container's `readinessProbe` if it is defined. If there is no probe and no values for `upstream-max-fails` NGINX will continue to send traffic to the container.
|
||||
|
||||
|
||||
!!! tip
|
||||
!!! tip
|
||||
With the default configuration NGINX will not health check your backends. Whenever the endpoints controller notices a readiness probe failure, that pod's IP will be removed from the list of endpoints. This will trigger the NGINX controller to also remove it from the upstreams.**
|
||||
|
||||
To use custom values in an Ingress rule define these annotations:
|
||||
|
@ -208,9 +212,9 @@ The annotations are:
|
|||
|
||||
!!! attention
|
||||
TLS with Client Authentication is **not** possible in Cloudflare and might result in unexpected behavior.
|
||||
|
||||
|
||||
Cloudflare only allows Authenticated Origin Pulls and is required to use their own certificate: [https://blog.cloudflare.com/protecting-the-origin-with-tls-authenticated-origin-pulls/](https://blog.cloudflare.com/protecting-the-origin-with-tls-authenticated-origin-pulls/)
|
||||
|
||||
|
||||
Only Authenticated Origin Pulls are allowed and can be configured by following their tutorial: [https://support.cloudflare.com/hc/en-us/articles/204494148-Setting-up-NGINX-to-use-TLS-Authenticated-Origin-Pulls](https://support.cloudflare.com/hc/en-us/articles/204494148-Setting-up-NGINX-to-use-TLS-Authenticated-Origin-Pulls)
|
||||
|
||||
|
||||
|
@ -364,6 +368,10 @@ To configure this setting globally for all Ingress rules, the `limit-rate-after`
|
|||
|
||||
This annotation allows to return a permanent redirect instead of sending data to the upstream. For example `nginx.ingress.kubernetes.io/permanent-redirect: https://www.google.com` would redirect everything to Google.
|
||||
|
||||
### Permanent Redirect Code
|
||||
|
||||
This annotation allows you to modify the status code used for permanent redirects. For example `nginx.ingress.kubernetes.io/permanent-redirect-code: '308'` would return your permanent-redirect with a 308.
|
||||
|
||||
### SSL Passthrough
|
||||
|
||||
The annotation `nginx.ingress.kubernetes.io/ssl-passthrough` allows to configure TLS termination in the pod and not in NGINX.
|
||||
|
@ -375,7 +383,9 @@ The annotation `nginx.ingress.kubernetes.io/ssl-passthrough` allows to configure
|
|||
!!! attention
|
||||
The use of this annotation requires the flag `--enable-ssl-passthrough` (By default it is disabled).
|
||||
|
||||
### Secure backends
|
||||
### Secure backends DEPRECATED (since 0.18.0)
|
||||
|
||||
Please use `nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"`
|
||||
|
||||
By default NGINX uses plain HTTP to reach the services.
|
||||
Adding the annotation `nginx.ingress.kubernetes.io/secure-backends: "true"` in the Ingress rule changes the protocol to HTTPS.
|
||||
|
@ -464,6 +474,12 @@ To use custom values in an Ingress rule define these annotation:
|
|||
nginx.ingress.kubernetes.io/proxy-body-size: 8m
|
||||
```
|
||||
|
||||
### Proxy cookie domain
|
||||
|
||||
Sets a text that [should be changed in the domain attribute](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_domain) of the "Set-Cookie" header fields of a proxied server response.
|
||||
|
||||
To configure this setting globally for all Ingress rules, the `proxy-cookie-domain` value may be set in the [NGINX ConfigMap][configmap].
|
||||
|
||||
### Proxy buffering
|
||||
|
||||
Enable or disable proxy buffering [`proxy_buffering`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering).
|
||||
|
@ -476,6 +492,16 @@ To use custom values in an Ingress rule define these annotation:
|
|||
nginx.ingress.kubernetes.io/proxy-buffering: "on"
|
||||
```
|
||||
|
||||
### Proxy buffer size
|
||||
|
||||
Sets the size of the buffer [`proxy_buffer_size`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size) used for reading the first part of the response received from the proxied server.
|
||||
By default proxy buffer size is set as "4k"
|
||||
|
||||
To configure this setting globally, set `proxy-buffer-size` in [NGINX ConfigMap][configmap]. To use custom values in an Ingress rule, define this annotation:
|
||||
```yaml
|
||||
nginx.ingress.kubernetes.io/proxy-buffer-size: "8k"
|
||||
```
|
||||
|
||||
### SSL ciphers
|
||||
|
||||
Specifies the [enabled ciphers](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers).
|
||||
|
@ -546,7 +572,9 @@ nginx.ingress.kubernetes.io/lua-resty-waf-extra-rules: '[=[ { "access": [ { "act
|
|||
|
||||
For details on how to write WAF rules, please refer to [https://github.com/p0pr0ck5/lua-resty-waf](https://github.com/p0pr0ck5/lua-resty-waf).
|
||||
|
||||
### gRPC backend
|
||||
### gRPC backend DEPRECATED (since 0.18.0)
|
||||
|
||||
Please use `nginx.ingress.kubernetes.io/backend-protocol: "GRPC"` or `nginx.ingress.kubernetes.io/backend-protocol: "GRPCS"`
|
||||
|
||||
Since NGINX 1.13.10 it is possible to expose [gRPC services natively](http://nginx.org/en/docs/http/ngx_http_grpc_module.html)
|
||||
|
||||
|
@ -568,15 +596,29 @@ using the [nginx-influxdb-module](https://github.com/influxdata/nginx-influxdb-m
|
|||
nginx.ingress.kubernetes.io/enable-influxdb: "true"
|
||||
nginx.ingress.kubernetes.io/influxdb-measurement: "nginx-reqs"
|
||||
nginx.ingress.kubernetes.io/influxdb-port: "8089"
|
||||
nginx.ingress.kubernetes.io/influxdb-host: "influxdb"
|
||||
nginx.ingress.kubernetes.io/influxdb-host: "127.0.0.1"
|
||||
nginx.ingress.kubernetes.io/influxdb-server-name: "nginx-ingress"
|
||||
```
|
||||
|
||||
For the `influxdb-host` parameter you have two options:
|
||||
|
||||
To use the module in the Kubernetes Nginx ingress controller, you have two options:
|
||||
|
||||
- Use an InfluxDB server configured to enable the [UDP protocol](https://docs.influxdata.com/influxdb/v1.5/supported_protocols/udp/).
|
||||
- Use an InfluxDB server configured with the [UDP protocol](https://docs.influxdata.com/influxdb/v1.5/supported_protocols/udp/) enabled.
|
||||
- Deploy Telegraf as a sidecar proxy to the Ingress controller configured to listen UDP with the [socket listener input](https://github.com/influxdata/telegraf/tree/release-1.6/plugins/inputs/socket_listener) and to write using
|
||||
anyone of the [outputs plugins](https://github.com/influxdata/telegraf/tree/release-1.6/plugins/outputs)
|
||||
anyone of the [outputs plugins](https://github.com/influxdata/telegraf/tree/release-1.7/plugins/outputs) like InfluxDB, Apache Kafka,
|
||||
Prometheus, etc.. (recommended)
|
||||
|
||||
It's important to remember that there's no DNS resolver at this stage so you will have to configure
|
||||
an ip address to `nginx.ingress.kubernetes.io/influxdb-host`. If you deploy Influx or Telegraf as sidecar (another container in the same pod) this becomes straightforward since you can directly use `127.0.0.1`.
|
||||
|
||||
### Backend Protocol
|
||||
|
||||
Using `backend-protocol` annotations is possible to indicate how NGINX should communicate with the backend service.
|
||||
Valid Values: HTTP, HTTPS, GRPC, GRPCS and AJP
|
||||
|
||||
By default NGINX uses `HTTP`.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
|
||||
```
|
||||
|
|
|
@ -44,10 +44,6 @@ The following table shows a configuration option's name, type, and the default v
|
|||
|[disable-ipv6-dns](#disable-ipv6-dns)|bool|false|
|
||||
|[enable-underscores-in-headers](#enable-underscores-in-headers)|bool|false|
|
||||
|[ignore-invalid-headers](#ignore-invalid-headers)|bool|true|
|
||||
|[enable-vts-status](#enable-vts-status)|bool|false|
|
||||
|[vts-status-zone-size](#vts-status-zone-size)|string|"10m"|
|
||||
|[vts-sum-key](#vts-sum-key)|string|"*"|
|
||||
|[vts-default-filter-key](#vts-default-filter-key)|string|"$geoip_country_code country::*"|
|
||||
|[retry-non-idempotent](#retry-non-idempotent)|bool|"false"|
|
||||
|[error-log-level](#error-log-level)|string|"notice"|
|
||||
|[http2-max-field-size](#http2-max-field-size)|string|"4k"|
|
||||
|
@ -62,6 +58,7 @@ The following table shows a configuration option's name, type, and the default v
|
|||
|[log-format-escape-json](#log-format-escape-json)|bool|"false"|
|
||||
|[log-format-upstream](#log-format-upstream)|string|`%v - [$the_real_ip] - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status`|
|
||||
|[log-format-stream](#log-format-stream)|string|`[$time_local] $protocol $status $bytes_sent $bytes_received $session_time`|
|
||||
|[enable-multi-accept](#enable-multi-accept)|bool|"true"|
|
||||
|[max-worker-connections](#max-worker-connections)|int|16384|
|
||||
|[map-hash-bucket-size](#max-worker-connections)|int|64|
|
||||
|[nginx-status-ipv4-whitelist](#nginx-status-ipv4-whitelist)|[]string|"127.0.0.1"|
|
||||
|
@ -72,6 +69,7 @@ The following table shows a configuration option's name, type, and the default v
|
|||
|[server-name-hash-bucket-size](#server-name-hash-bucket-size)|int|`<size of the processor’s cache line>`
|
||||
|[proxy-headers-hash-max-size](#proxy-headers-hash-max-size)|int|512|
|
||||
|[proxy-headers-hash-bucket-size](#proxy-headers-hash-bucket-size)|int|64|
|
||||
|[reuse-port](#reuse-port)|bool|"true"|
|
||||
|[server-tokens](#server-tokens)|bool|"true"|
|
||||
|[ssl-ciphers](#ssl-ciphers)|string|"ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"|
|
||||
|[ssl-ecdh-curve](#ssl-ecdh-curve)|string|"auto"|
|
||||
|
@ -91,11 +89,12 @@ The following table shows a configuration option's name, type, and the default v
|
|||
|[brotli-level](#brotli-level)|int|4|
|
||||
|[brotli-types](#brotli-types)|string|"application/xml+rss application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/plain text/x-component"|
|
||||
|[use-http2](#use-http2)|bool|"true"|
|
||||
|[gzip-level](#gzip-level)|int|5|
|
||||
|[gzip-types](#gzip-types)|string|"application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/plain text/x-component"|
|
||||
|[worker-processes](#worker-processes)|string|`<Number of CPUs>`|
|
||||
|[worker-cpu-affinity](#worker-cpu-affinity)|string|""|
|
||||
|[worker-shutdown-timeout](#worker-shutdown-timeout)|string|"10s"|
|
||||
|[load-balance](#load-balance)|string|"least_conn"|
|
||||
|[load-balance](#load-balance)|string|"round_robin"|
|
||||
|[variables-hash-bucket-size](#variables-hash-bucket-size)|int|128|
|
||||
|[variables-hash-max-size](#variables-hash-max-size)|int|2048|
|
||||
|[upstream-keepalive-connections](#upstream-keepalive-connections)|int|32|
|
||||
|
@ -112,15 +111,17 @@ The following table shows a configuration option's name, type, and the default v
|
|||
|[zipkin-collector-host](#zipkin-collector-host)|string|""|
|
||||
|[zipkin-collector-port](#zipkin-collector-port)|int|9411|
|
||||
|[zipkin-service-name](#zipkin-service-name)|string|"nginx"|
|
||||
|[zipkin-sample-rate](#zipkin-sample-rate)|float|1.0|
|
||||
|[jaeger-collector-host](#jaeger-collector-host)|string|""|
|
||||
|[jaeger-collector-port](#jaeger-collector-port)|int|6831|
|
||||
|[jaeger-service-name](#jaeger-service-name)|string|"nginx"|
|
||||
|[jaeger-sampler-type](#jaeger-sampler-type)|string|"const"|
|
||||
|[jaeger-sampler-param](#jaeger-sampler-param)|string|"1"|
|
||||
|[main-snippet](#main-snippet)|string|""|
|
||||
|[http-snippet](#http-snippet)|string|""|
|
||||
|[server-snippet](#server-snippet)|string|""|
|
||||
|[location-snippet](#location-snippet)|string|""|
|
||||
|[custom-http-errors](#custom-http-errors)|[]int]|[]int{}|
|
||||
|[custom-http-errors](#custom-http-errors)|[]int|[]int{}|
|
||||
|[proxy-body-size](#proxy-body-size)|string|"1m"|
|
||||
|[proxy-connect-timeout](#proxy-connect-timeout)|int|5|
|
||||
|[proxy-read-timeout](#proxy-read-timeout)|int|60|
|
||||
|
@ -241,32 +242,6 @@ Enables underscores in header names. _**default:**_ is disabled
|
|||
Set if header fields with invalid names should be ignored.
|
||||
_**default:**_ is enabled
|
||||
|
||||
## enable-vts-status
|
||||
|
||||
Allows the replacement of the default status page with a third party module named [nginx-module-vts](https://github.com/vozlt/nginx-module-vts).
|
||||
_**default:**_ is disabled
|
||||
|
||||
## vts-status-zone-size
|
||||
|
||||
Vts config on http level sets parameters for a shared memory zone that will keep states for various keys. The cache is shared between all worker processes. _**default:**_ 10m
|
||||
|
||||
_References:_
|
||||
[https://github.com/vozlt/nginx-module-vts#vhost_traffic_status_zone](https://github.com/vozlt/nginx-module-vts#vhost_traffic_status_zone)
|
||||
|
||||
## vts-default-filter-key
|
||||
|
||||
Vts config on http level enables the keys by user defined variable. The key is a key string to calculate traffic. The name is a group string to calculate traffic. The key and name can contain variables such as $host, $server_name. The name's group belongs to filterZones if specified. The key's group belongs to serverZones if not specified second argument name. _**default:**_ $geoip_country_code country::*
|
||||
|
||||
_References:_
|
||||
[https://github.com/vozlt/nginx-module-vts#vhost_traffic_status_filter_by_set_key](https://github.com/vozlt/nginx-module-vts#vhost_traffic_status_filter_by_set_key)
|
||||
|
||||
## vts-sum-key
|
||||
|
||||
For metrics keyed (or when using Prometheus, labeled) by server zone, this value is used to indicate metrics for all server zones combined. _**default:**_ *
|
||||
|
||||
_References:_
|
||||
[https://github.com/vozlt/nginx-module-vts#vhost_traffic_status_display_sum_key](https://github.com/vozlt/nginx-module-vts#vhost_traffic_status_display_sum_key)
|
||||
|
||||
## retry-non-idempotent
|
||||
|
||||
Since 1.9.13 NGINX will not retry non-idempotent requests (POST, LOCK, PATCH) in case of an error in the upstream server. The previous behavior can be restored using the value "true".
|
||||
|
@ -360,6 +335,14 @@ Please check the [log-format](log-format.md) for definition of each field.
|
|||
|
||||
Sets the nginx [stream format](https://nginx.org/en/docs/stream/ngx_stream_log_module.html#log_format).
|
||||
|
||||
## enable-multi-accept
|
||||
|
||||
If disabled, a worker process will accept one new connection at a time. Otherwise, a worker process will accept all new connections at a time.
|
||||
_**default:**_ true
|
||||
|
||||
_References:_
|
||||
[http://nginx.org/en/docs/ngx_core_module.html#multi_accept](http://nginx.org/en/docs/ngx_core_module.html#multi_accept)
|
||||
|
||||
## max-worker-connections
|
||||
|
||||
Sets the maximum number of simultaneous connections that can be opened by each [worker process](http://nginx.org/en/docs/ngx_core_module.html#worker_connections)
|
||||
|
@ -401,7 +384,12 @@ _References:_
|
|||
- [http://nginx.org/en/docs/hash.html](http://nginx.org/en/docs/hash.html)
|
||||
- [https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_headers_hash_max_size](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_headers_hash_max_size)
|
||||
|
||||
## proxy-headers-hash-bucket-size
|
||||
## reuse-port
|
||||
|
||||
Instructs NGINX to create an individual listening socket for each worker process (using the SO_REUSEPORT socket option), allowing a kernel to distribute incoming connections between worker processes
|
||||
_**default:**_ true
|
||||
|
||||
## proxy-headers-hash-bucket-size
|
||||
|
||||
Sets the size of the bucket for the proxy headers hash tables.
|
||||
|
||||
|
@ -463,8 +451,9 @@ Enables or disables session resumption through [TLS session tickets](http://ngin
|
|||
## ssl-session-ticket-key
|
||||
|
||||
Sets the secret key used to encrypt and decrypt TLS session tickets. The value must be a valid base64 string.
|
||||
To create a ticket: `openssl rand 80 | openssl enc -A -base64`
|
||||
|
||||
[TLS session ticket-key](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_tickets), by default, a randomly generated key is used. To create a ticket: `openssl rand 80 | base64 -w0`
|
||||
[TLS session ticket-key](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_tickets), by default, a randomly generated key is used.
|
||||
|
||||
## ssl-session-timeout
|
||||
|
||||
|
@ -483,7 +472,7 @@ Enables or disables the [PROXY protocol](https://www.nginx.com/resources/admin-g
|
|||
|
||||
## proxy-protocol-header-timeout
|
||||
|
||||
Sets the timeout value for receiving the proxy-protocol headers. The default of 5 seconds prevents the TLS passthrough handler from waiting indefinetly on a dropped connection.
|
||||
Sets the timeout value for receiving the proxy-protocol headers. The default of 5 seconds prevents the TLS passthrough handler from waiting indefinitely on a dropped connection.
|
||||
_**default:**_ 5s
|
||||
|
||||
## use-gzip
|
||||
|
@ -516,6 +505,10 @@ _**default:**_ `application/xml+rss application/atom+xml application/javascript
|
|||
|
||||
Enables or disables [HTTP/2](http://nginx.org/en/docs/http/ngx_http_v2_module.html) support in secure connections.
|
||||
|
||||
## gzip-level
|
||||
|
||||
Sets the gzip Compression Level that will be used. _**default:**_ 5
|
||||
|
||||
## gzip-types
|
||||
|
||||
Sets the MIME types in addition to "text/html" to compress. The special value "\*" matches any MIME type. Responses with the "text/html" type are always compressed if `use-gzip` is enabled.
|
||||
|
@ -544,11 +537,11 @@ Sets the algorithm to use for load balancing.
|
|||
The value can either be:
|
||||
|
||||
- round_robin: to use the default round robin loadbalancer
|
||||
- least_conn: to use the least connected method
|
||||
- ip_hash: to use a hash of the server for routing.
|
||||
- ewma: to use the peak ewma method for routing (only available with `enable-dynamic-configuration` flag)
|
||||
- least_conn: to use the least connected method (_note_ that this is available only in non-dynamic mode: `--enable-dynamic-configuration=false`)
|
||||
- ip_hash: to use a hash of the server for routing (_note_ that this is available only in non-dynamic mode: `--enable-dynamic-configuration=false`, but alternatively you can consider using `nginx.ingress.kubernetes.io/upstream-hash-by`)
|
||||
- ewma: to use the Peak EWMA method for routing ([implementation](https://github.com/kubernetes/ingress-nginx/blob/master/rootfs/etc/nginx/lua/balancer/ewma.lua))
|
||||
|
||||
The default is least_conn.
|
||||
The default is `round_robin`.
|
||||
|
||||
_References:_
|
||||
[http://nginx.org/en/docs/http/load_balancing.html](http://nginx.org/en/docs/http/load_balancing.html)
|
||||
|
@ -638,6 +631,10 @@ Specifies the port to use when uploading traces. _**default:**_ 9411
|
|||
|
||||
Specifies the service name to use for any traces created. _**default:**_ nginx
|
||||
|
||||
## zipkin-sample-rate
|
||||
|
||||
Specifies sample rate for any traces created. _**default:**_ 1.0
|
||||
|
||||
## jaeger-collector-host
|
||||
|
||||
Specifies the host to use when uploading traces. It must be a valid URL.
|
||||
|
@ -659,20 +656,21 @@ Specifies the sampler to be used when sampling traces. The available samplers ar
|
|||
Specifies the argument to be passed to the sampler constructor. Must be a number.
|
||||
For const this should be 0 to never sample and 1 to always sample. _**default:**_ 1
|
||||
|
||||
## main-snippet
|
||||
|
||||
Adds custom configuration to the main section of the nginx configuration.
|
||||
|
||||
## http-snippet
|
||||
|
||||
Adds custom configuration to the http section of the nginx configuration.
|
||||
_**default:**_ ""
|
||||
|
||||
## server-snippet
|
||||
|
||||
Adds custom configuration to all the servers in the nginx configuration.
|
||||
_**default:**_ ""
|
||||
|
||||
## location-snippet
|
||||
|
||||
Adds custom configuration to all the locations in the nginx configuration.
|
||||
_**default:**_ ""
|
||||
|
||||
## custom-http-errors
|
||||
|
||||
|
@ -761,7 +759,7 @@ _References:_
|
|||
## http-redirect-code
|
||||
|
||||
Sets the HTTP status code to be used in redirects.
|
||||
Supported codes are [301](https://developer.mozilla.org/es/docs/Web/HTTP/Status/301),[302](https://developer.mozilla.org/es/docs/Web/HTTP/Status/302),[307](https://developer.mozilla.org/es/docs/Web/HTTP/Status/307) and [308](https://developer.mozilla.org/es/docs/Web/HTTP/Status/308)
|
||||
Supported codes are [301](https://developer.mozilla.org/docs/Web/HTTP/Status/301),[302](https://developer.mozilla.org/docs/Web/HTTP/Status/302),[307](https://developer.mozilla.org/docs/Web/HTTP/Status/307) and [308](https://developer.mozilla.org/docs/Web/HTTP/Status/308)
|
||||
_**default:**_ 308
|
||||
|
||||
> __Why the default code is 308?__
|
||||
|
|
|
@ -31,6 +31,15 @@ log_format upstreaminfo
|
|||
| `$upstream_response_time` | time spent on receiving the response from the upstream server as seconds with millisecond resolution |
|
||||
| `$upstream_status` | status code of the response obtained from the upstream server |
|
||||
|
||||
Additional available variables:
|
||||
|
||||
| Placeholder | Description |
|
||||
|-------------|-------------|
|
||||
| `$namespace` | namespace of the ingress |
|
||||
| `$ingress_name` | name of the ingress |
|
||||
| `$service_name` | name of the service |
|
||||
| `$service_port` | port of the service |
|
||||
|
||||
|
||||
Sources:
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
# NGINX status page
|
||||
|
||||
The [ngx_http_stub_status_module](http://nginx.org/en/docs/http/ngx_http_stub_status_module.html) module provides access to basic status information.
|
||||
This is the default module active in the url `/nginx_status` in the status port (default is 18080).
|
||||
|
||||
This controller provides an alternative to this module using the [nginx-module-vts](https://github.com/vozlt/nginx-module-vts) module.
|
||||
To use this module just set in the configuration configmap `enable-vts-status: "true"`.
|
||||
|
||||

|
||||
|
||||
To extract the information in JSON format the module provides a custom URL: `/nginx_status/format/json`
|
|
@ -7,7 +7,7 @@ The [ModSecurity-nginx](https://github.com/SpiderLabs/ModSecurity-nginx) connect
|
|||
The default ModSecurity configuration file is located in `/etc/nginx/modsecurity/modsecurity.conf`. This is the only file located in this directory and contains the default recommended configuration. Using a volume we can replace this file with the desired configuration.
|
||||
To enable the ModSecurity feature we need to specify `enable-modsecurity: "true"` in the configuration configmap.
|
||||
|
||||
>__Note:__ the default configuration use detection only, because that minimises the chances of post-installation disruption.
|
||||
>__Note:__ the default configuration use detection only, because that minimizes the chances of post-installation disruption.
|
||||
The file `/var/log/modsec_audit.log` contains the log of ModSecurity.
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,59 @@
|
|||
# OpenTracing
|
||||
|
||||
Enables requests served by nginx for distributed tracing via The OpenTracing Project.
|
||||
|
||||
Using the third party module [opentracing-contrib/nginx-opentracing](https://github.com/opentracing-contrib/nginx-opentracing) the NGINX ingress controller can configure NGINX to enable [OpenTracing](http://opentracing.io) instrumentation.
|
||||
By default this feature is disabled.
|
||||
|
||||
To enable the instrumentation we just need to enable the instrumentation in the configuration configmap and set the host where we should send the traces.
|
||||
## Usage
|
||||
|
||||
To enable the instrumentation we must enable opentracing in the configuration configmap:
|
||||
```
|
||||
data:
|
||||
enable-opentracing: "true"
|
||||
```
|
||||
|
||||
We must also set the host to use when uploading traces:
|
||||
|
||||
```
|
||||
zipkin-collector-host: zipkin.default.svc.cluster.local
|
||||
jaeger-collector-host: jaeger-collector.default.svc.cluster.local
|
||||
```
|
||||
|
||||
Next you will need to deploy a distributed tracing system which uses OpenTracing. Both [Zipkin](https://github.com/openzipkin/zipkin) and
|
||||
[Jaeger](https://github.com/jaegertracing/jaeger) have been tested.
|
||||
|
||||
Other optional configuration options:
|
||||
```
|
||||
# specifies the port to use when uploading traces
|
||||
zipkin-collector-port
|
||||
|
||||
# specifies the service name to use for any traces created, Default: nginx
|
||||
zipkin-service-name
|
||||
|
||||
# specifies sample rate for any traces created. Default: 1.0
|
||||
zipkin-sample-rate
|
||||
|
||||
# specifies the port to use when uploading traces
|
||||
jaeger-collector-port
|
||||
|
||||
# specifies the service name to use for any traces created, Default: nginx
|
||||
jaeger-service-name
|
||||
|
||||
# specifies the sampler to be used when sampling traces.
|
||||
# The available samplers are: const, probabilistic, ratelimiting, remote, Default: const
|
||||
jaeger-sampler-type
|
||||
|
||||
# specifies the argument to be passed to the sampler constructor, Default: 1
|
||||
jaeger-sampler-param
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
The following examples show how to deploy and test different distributed tracing systems. These example can be performed
|
||||
using Minikube.
|
||||
|
||||
### Zipkin
|
||||
|
||||
In the [rnburn/zipkin-date-server](https://github.com/rnburn/zipkin-date-server)
|
||||
github repository is an example of a dockerized date service. To install the example and zipkin collector run:
|
||||
|
@ -23,20 +73,111 @@ data:
|
|||
enable-opentracing: "true"
|
||||
zipkin-collector-host: zipkin.default.svc.cluster.local
|
||||
metadata:
|
||||
name: nginx-configuration
|
||||
namespace: ingress-nginx
|
||||
labels:
|
||||
app: ingress-nginx
|
||||
name: nginx-load-balancer-conf
|
||||
namespace: kube-system
|
||||
' | kubectl replace -f -
|
||||
```
|
||||
|
||||
Using curl we can generate some traces:
|
||||
|
||||
```console
|
||||
$ curl -v http://$(minikube ip)
|
||||
$ curl -v http://$(minikube ip)
|
||||
```
|
||||
|
||||
In the zipkin interface we can see the details:
|
||||
|
||||

|
||||
|
||||
### Jaeger
|
||||
|
||||
1. Enable Ingress addon in minikube:
|
||||
```
|
||||
$ minikube addons enable ingress
|
||||
```
|
||||
|
||||
2. Add minikube IP to /etc/hosts:
|
||||
```
|
||||
$ echo "$(minikube ip) example.com" | sudo tee -a /etc/hosts
|
||||
```
|
||||
|
||||
3. Apply a Basic Service and Ingress Resource:
|
||||
```
|
||||
# Create Echoheaders Deployment
|
||||
$ kubectl run echoheaders --image=k8s.gcr.io/echoserver:1.4 --replicas=1 --port=8080
|
||||
|
||||
# Expose as a Cluster-IP
|
||||
$ kubectl expose deployment echoheaders --port=80 --target-port=8080 --name=echoheaders-x
|
||||
|
||||
# Apply the Ingress Resource
|
||||
$ echo '
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: echo-ingress
|
||||
spec:
|
||||
rules:
|
||||
- host: example.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: echoheaders-x
|
||||
servicePort: 80
|
||||
path: /echo
|
||||
' | kubectl apply -f -
|
||||
```
|
||||
|
||||
4. Enable OpenTracing and set the zipkin-collector-host:
|
||||
```
|
||||
$ echo '
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
data:
|
||||
enable-opentracing: "true"
|
||||
zipkin-collector-host: zipkin.default.svc.cluster.local
|
||||
jaeger-collector-host: jaeger-collector.default.svc.cluster.local
|
||||
metadata:
|
||||
name: nginx-load-balancer-conf
|
||||
namespace: kube-system
|
||||
' | kubectl replace -f -
|
||||
```
|
||||
|
||||
5. Apply the Jaeger All-In-One Template:
|
||||
```
|
||||
$ kubectl apply -f https://raw.githubusercontent.com/jaegertracing/jaeger-kubernetes/master/all-in-one/jaeger-all-in-one-template.yml
|
||||
```
|
||||
|
||||
6. Make a few requests to the Service:
|
||||
```
|
||||
$ curl example.com/echo -d "meow"
|
||||
|
||||
CLIENT VALUES:
|
||||
client_address=172.17.0.5
|
||||
command=POST
|
||||
real path=/echo
|
||||
query=nil
|
||||
request_version=1.1
|
||||
request_uri=http://example.com:8080/echo
|
||||
|
||||
SERVER VALUES:
|
||||
server_version=nginx: 1.10.0 - lua: 10001
|
||||
|
||||
HEADERS RECEIVED:
|
||||
accept=*/*
|
||||
connection=close
|
||||
content-length=4
|
||||
content-type=application/x-www-form-urlencoded
|
||||
host=example.com
|
||||
user-agent=curl/7.54.0
|
||||
x-forwarded-for=192.168.99.1
|
||||
x-forwarded-host=example.com
|
||||
x-forwarded-port=80
|
||||
x-forwarded-proto=http
|
||||
x-original-uri=/echo
|
||||
x-real-ip=192.168.99.1
|
||||
x-scheme=http
|
||||
BODY:
|
||||
meow
|
||||
```
|
||||
|
||||
7. View the Jaeger UI:
|
||||
```
|
||||
$ minikube service jaeger-query --url
|
||||
|
||||
http://192.168.99.100:30183
|
||||
```
|
||||
|
||||
In the jaeger interface we can see the details:
|
||||

|
||||
|
|
|
@ -50,6 +50,7 @@ args = parser.parse_args()
|
|||
|
||||
verbose_out = sys.stderr if args.verbose else open("/dev/null", "w")
|
||||
|
||||
|
||||
def get_refs():
|
||||
refs = {}
|
||||
|
||||
|
@ -63,6 +64,7 @@ def get_refs():
|
|||
|
||||
return refs
|
||||
|
||||
|
||||
def file_passes(filename, refs, regexs):
|
||||
try:
|
||||
f = open(filename, 'r')
|
||||
|
@ -127,10 +129,19 @@ def file_passes(filename, refs, regexs):
|
|||
|
||||
return True
|
||||
|
||||
|
||||
def file_extension(filename):
|
||||
return os.path.splitext(filename)[1].split(".")[-1].lower()
|
||||
|
||||
skipped_dirs = ['.git', "vendor", "test/e2e/framework/framework.go", "test/e2e/generated/bindata.go", "hack/boilerplate/test", "internal/file/bindata.go"]
|
||||
|
||||
skipped_dirs = [
|
||||
'.git',
|
||||
"vendor",
|
||||
"test/e2e/framework/framework.go",
|
||||
"hack/boilerplate/test",
|
||||
"test/e2e/dind-cluster-v1.11.sh"
|
||||
]
|
||||
|
||||
|
||||
def normalize_files(files):
|
||||
newfiles = []
|
||||
|
@ -143,6 +154,7 @@ def normalize_files(files):
|
|||
newfiles[i] = os.path.join(args.rootdir, pathname)
|
||||
return newfiles
|
||||
|
||||
|
||||
def get_files(extensions):
|
||||
files = []
|
||||
if len(args.filenames) > 0:
|
||||
|
@ -170,19 +182,23 @@ def get_files(extensions):
|
|||
outfiles.append(pathname)
|
||||
return outfiles
|
||||
|
||||
|
||||
def get_regexs():
|
||||
regexs = {}
|
||||
# Search for "YEAR" which exists in the boilerplate, but shouldn't in the real thing
|
||||
regexs["year"] = re.compile( 'YEAR' )
|
||||
regexs["year"] = re.compile('YEAR')
|
||||
# dates can be 2014, 2015, 2016, ..., CURRENT_YEAR, company holder names can be anything
|
||||
years = range(2014, date.today().year + 1)
|
||||
regexs["date"] = re.compile( '(%s)' % "|".join(map(lambda l: str(l), years)) )
|
||||
regexs["date"] = re.compile(
|
||||
'(%s)' % "|".join(map(lambda l: str(l), years)))
|
||||
# strip // +build \n\n build constraints
|
||||
regexs["go_build_constraints"] = re.compile(r"^(// \+build.*\n)+\n", re.MULTILINE)
|
||||
regexs["go_build_constraints"] = re.compile(
|
||||
r"^(// \+build.*\n)+\n", re.MULTILINE)
|
||||
# strip #!.* from shell scripts
|
||||
regexs["shebang"] = re.compile(r"^(#!.*\n)\n*", re.MULTILINE)
|
||||
return regexs
|
||||
|
||||
|
||||
def main():
|
||||
regexs = get_regexs()
|
||||
refs = get_refs()
|
||||
|
@ -194,5 +210,6 @@ def main():
|
|||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
sys.exit(main())
|
||||
|
|
|
@ -3,7 +3,7 @@ all: all-container
|
|||
BUILDTAGS=
|
||||
|
||||
# Use the 0.0 tag for testing, it shouldn't clobber any release builds
|
||||
TAG?=0.1
|
||||
TAG?=0.3
|
||||
REGISTRY?=quay.io/kubernetes-ingress-controller
|
||||
GOOS?=linux
|
||||
DOCKER?=docker
|
||||
|
@ -26,11 +26,11 @@ ARCH ?= $(shell go env GOARCH)
|
|||
GOARCH = ${ARCH}
|
||||
DUMB_ARCH = ${ARCH}
|
||||
|
||||
BASEIMAGE?=alpine:3.6
|
||||
BASEIMAGE?=alpine:3.7
|
||||
|
||||
ALL_ARCH = amd64 arm arm64 ppc64le
|
||||
|
||||
QEMUVERSION=v2.9.1
|
||||
QEMUVERSION=v2.12.0-1
|
||||
|
||||
IMGNAME = custom-error-pages
|
||||
IMAGE = $(REGISTRY)/$(IMGNAME)
|
||||
|
@ -74,7 +74,7 @@ ifeq ($(ARCH),amd64)
|
|||
else
|
||||
# When cross-building, only the placeholder "CROSS_BUILD_" should be removed
|
||||
# Register /usr/bin/qemu-ARCH-static as the handler for ARM binaries in the kernel
|
||||
$(DOCKER) run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
# $(DOCKER) run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
curl -sSL https://github.com/multiarch/qemu-user-static/releases/download/$(QEMUVERSION)/x86_64_qemu-$(QEMUARCH)-static.tar.gz | tar -xz -C $(TEMP_DIR)/rootfs
|
||||
$(SED_I) "s/CROSS_BUILD_//g" $(DOCKERFILE)
|
||||
endif
|
||||
|
@ -103,3 +103,8 @@ build: clean
|
|||
|
||||
release: all-container all-push
|
||||
echo "done"
|
||||
|
||||
.PHONY: register-qemu
|
||||
register-qemu:
|
||||
# Register /usr/bin/qemu-ARCH-static as the handler for binaries in multiple platforms
|
||||
$(DOCKER) run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
# custom-error-pages
|
||||
|
||||
Example of Custom error pages for the NGINX Ingress controller
|
||||
|
|
|
@ -39,15 +39,34 @@ const (
|
|||
|
||||
// ContentType name of the header that defines the format of the reply
|
||||
ContentType = "Content-Type"
|
||||
|
||||
// OriginalURI name of the header with the original URL from NGINX
|
||||
OriginalURI = "X-Original-URI"
|
||||
|
||||
// Namespace name of the header that contains information about the Ingress namespace
|
||||
Namespace = "X-Namespace"
|
||||
|
||||
// IngressName name of the header that contains the matched Ingress
|
||||
IngressName = "X-Ingress-Name"
|
||||
|
||||
// ServiceName name of the header that contains the matched Service in the Ingress
|
||||
ServiceName = "X-Service-Name"
|
||||
|
||||
// ServicePort name of the header that contains the matched Service port in the Ingress
|
||||
ServicePort = "X-Service-Port"
|
||||
|
||||
// ErrFilesPathVar is the name of the environment variable indicating
|
||||
// the location on disk of files served by the handler.
|
||||
ErrFilesPathVar = "ERROR_FILES_PATH"
|
||||
)
|
||||
|
||||
func main() {
|
||||
path := "/www"
|
||||
if os.Getenv("PATH") != "" {
|
||||
path = os.Getenv("PATH")
|
||||
errFilesPath := "/www"
|
||||
if os.Getenv(ErrFilesPathVar) != "" {
|
||||
errFilesPath = os.Getenv(ErrFilesPathVar)
|
||||
}
|
||||
|
||||
http.HandleFunc("/", errorHandler(path))
|
||||
http.HandleFunc("/", errorHandler(errFilesPath))
|
||||
|
||||
http.Handle("/metrics", promhttp.Handler())
|
||||
|
||||
|
@ -63,18 +82,28 @@ func errorHandler(path string) func(http.ResponseWriter, *http.Request) {
|
|||
start := time.Now()
|
||||
ext := "html"
|
||||
|
||||
if os.Getenv("DEBUG") != "" {
|
||||
w.Header().Set(FormatHeader, r.Header.Get(FormatHeader))
|
||||
w.Header().Set(CodeHeader, r.Header.Get(CodeHeader))
|
||||
w.Header().Set(ContentType, r.Header.Get(ContentType))
|
||||
w.Header().Set(OriginalURI, r.Header.Get(OriginalURI))
|
||||
w.Header().Set(Namespace, r.Header.Get(Namespace))
|
||||
w.Header().Set(IngressName, r.Header.Get(IngressName))
|
||||
w.Header().Set(ServiceName, r.Header.Get(ServiceName))
|
||||
w.Header().Set(ServicePort, r.Header.Get(ServicePort))
|
||||
}
|
||||
|
||||
format := r.Header.Get(FormatHeader)
|
||||
if format == "" {
|
||||
format = "text/html"
|
||||
log.Printf("forma not specified. Using %v\n", format)
|
||||
log.Printf("format not specified. Using %v", format)
|
||||
}
|
||||
|
||||
mediaType, _, _ := mime.ParseMediaType(format)
|
||||
cext, err := mime.ExtensionsByType(mediaType)
|
||||
cext, err := mime.ExtensionsByType(format)
|
||||
if err != nil {
|
||||
log.Printf("unexpected error reading media type extension: %v. Using %v\n", err, ext)
|
||||
log.Printf("unexpected error reading media type extension: %v. Using %v", err, ext)
|
||||
} else if len(cext) == 0 {
|
||||
log.Printf("couldn't get media type extension. Using %v\n", ext)
|
||||
log.Printf("couldn't get media type extension. Using %v", ext)
|
||||
} else {
|
||||
ext = cext[0]
|
||||
}
|
||||
|
@ -84,7 +113,7 @@ func errorHandler(path string) func(http.ResponseWriter, *http.Request) {
|
|||
code, err := strconv.Atoi(errCode)
|
||||
if err != nil {
|
||||
code = 404
|
||||
log.Printf("unexpected error reading return code: %v. Using %v\n", err, code)
|
||||
log.Printf("unexpected error reading return code: %v. Using %v", err, code)
|
||||
}
|
||||
w.WriteHeader(code)
|
||||
|
||||
|
@ -94,22 +123,22 @@ func errorHandler(path string) func(http.ResponseWriter, *http.Request) {
|
|||
file := fmt.Sprintf("%v/%v%v", path, code, ext)
|
||||
f, err := os.Open(file)
|
||||
if err != nil {
|
||||
log.Printf("unexpected error opening file: %v\n", err)
|
||||
log.Printf("unexpected error opening file: %v", err)
|
||||
scode := strconv.Itoa(code)
|
||||
file := fmt.Sprintf("%v/%cxx%v", path, scode[0], ext)
|
||||
f, err := os.Open(file)
|
||||
if err != nil {
|
||||
log.Printf("unexpected error opening file: %v\n", err)
|
||||
log.Printf("unexpected error opening file: %v", err)
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
log.Printf("serving custom error response for code %v and format %v from file %v\n", code, format, file)
|
||||
log.Printf("serving custom error response for code %v and format %v from file %v", code, format, file)
|
||||
io.Copy(w, f)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
log.Printf("serving custom error response for code %v and format %v from file %v\n", code, format, file)
|
||||
log.Printf("serving custom error response for code %v and format %v from file %v", code, format, file)
|
||||
io.Copy(w, f)
|
||||
|
||||
duration := time.Now().Sub(start).Seconds()
|
||||
|
|
1830
images/custom-error-pages/rootfs/etc/mime.types
Normal file
62
images/e2e/Dockerfile
Normal file
|
@ -0,0 +1,62 @@
|
|||
# Copyright 2018 The Kubernetes Authors. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
FROM quay.io/kubernetes-ingress-controller/nginx-amd64:0.57
|
||||
|
||||
RUN clean-install \
|
||||
g++ \
|
||||
gcc \
|
||||
git \
|
||||
libc6-dev \
|
||||
make \
|
||||
wget \
|
||||
luarocks \
|
||||
pkg-config
|
||||
|
||||
ENV GOLANG_VERSION 1.10.3
|
||||
ENV GO_ARCH linux-amd64
|
||||
ENV GOLANG_SHA fa1b0e45d3b647c252f51f5e1204aba049cde4af177ef9f2181f43004f901035
|
||||
|
||||
RUN set -eux; \
|
||||
url="https://golang.org/dl/go${GOLANG_VERSION}.${GO_ARCH}.tar.gz"; \
|
||||
wget -O go.tgz "$url"; \
|
||||
echo "${GOLANG_SHA} *go.tgz" | sha256sum -c -; \
|
||||
tar -C /usr/local -xzf go.tgz; \
|
||||
rm go.tgz; \
|
||||
export PATH="/usr/local/go/bin:$PATH"; \
|
||||
go version
|
||||
|
||||
ENV GOPATH /go
|
||||
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
|
||||
|
||||
RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH"
|
||||
|
||||
WORKDIR $GOPATH
|
||||
|
||||
ENV RESTY_CLI_VERSION 0.22rc2
|
||||
ENV RESTY_CLI_SHA 1ec64d204469a04da553c95eaafb2e5601a03acb8f26cc10ae16b15525228c12
|
||||
RUN set -eux; \
|
||||
url="https://github.com/openresty/resty-cli/archive/v${RESTY_CLI_VERSION}.tar.gz"; \
|
||||
wget -O resty_cli.tgz "$url"; \
|
||||
echo "${RESTY_CLI_SHA} *resty_cli.tgz" | sha256sum -c -; \
|
||||
tar -C /tmp -xzf resty_cli.tgz; \
|
||||
rm resty_cli.tgz; \
|
||||
mv /tmp/resty-cli-${RESTY_CLI_VERSION}/bin/* /usr/local/bin/; \
|
||||
resty -V
|
||||
|
||||
RUN luarocks install luacheck \
|
||||
&& luarocks install busted 2.0.rc12
|
||||
|
||||
RUN go get github.com/onsi/ginkgo/ginkgo \
|
||||
&& go get golang.org/x/lint/golint
|
27
images/e2e/Makefile
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Copyright 2018 The Kubernetes Authors. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
TAG ?=v$(shell date +%m%d%Y)-$(shell git rev-parse --short HEAD)
|
||||
REGISTRY ?= quay.io/kubernetes-ingress-controller
|
||||
DOCKER ?= docker
|
||||
|
||||
IMAGE = $(REGISTRY)/e2e
|
||||
|
||||
all: docker-build docker-push
|
||||
|
||||
docker-build:
|
||||
$(DOCKER) build -t $(IMAGE):$(TAG) .
|
||||
|
||||
docker-push:
|
||||
$(DOCKER) push $(IMAGE):$(TAG)
|
|
@ -1,64 +0,0 @@
|
|||
# Copyright 2017 The Kubernetes Authors. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
TAG ?= 1.10
|
||||
REGISTRY ?= gcr.io/google_containers
|
||||
ARCH ?= $(shell go env GOARCH)
|
||||
ALL_ARCH = amd64 arm ppc64le
|
||||
|
||||
QEMUVERSION=v2.7.0
|
||||
|
||||
IMGNAME = echoserver
|
||||
IMAGE = $(REGISTRY)/$(IMGNAME)
|
||||
MULTI_ARCH_IMG = $(IMAGE)-$(ARCH)
|
||||
|
||||
# Set default base image dynamically for each arch
|
||||
BASEIMAGE?=gcr.io/google_containers/nginx-slim-$(ARCH):0.21
|
||||
|
||||
TEMP_DIR := $(shell mktemp -d)
|
||||
|
||||
all: all-container
|
||||
|
||||
sub-container-%:
|
||||
$(MAKE) ARCH=$* container
|
||||
|
||||
sub-push-%:
|
||||
$(MAKE) ARCH=$* push
|
||||
|
||||
all-container: $(addprefix sub-container-,$(ALL_ARCH))
|
||||
|
||||
all-push: $(addprefix sub-push-,$(ALL_ARCH))
|
||||
|
||||
container: .container-$(ARCH)
|
||||
.container-$(ARCH):
|
||||
cp ./* $(TEMP_DIR)
|
||||
cd $(TEMP_DIR) && sed -i 's|BASEIMAGE|$(BASEIMAGE)|g' Dockerfile
|
||||
|
||||
docker build -t $(MULTI_ARCH_IMG):$(TAG) $(TEMP_DIR)
|
||||
|
||||
ifeq ($(ARCH), amd64)
|
||||
# This is for to maintain the backward compatibility
|
||||
docker tag $(MULTI_ARCH_IMG):$(TAG) $(IMAGE):$(TAG)
|
||||
endif
|
||||
|
||||
push: .push-$(ARCH)
|
||||
.push-$(ARCH): .container-$(ARCH)
|
||||
gcloud docker -- push $(MULTI_ARCH_IMG):$(TAG)
|
||||
ifeq ($(ARCH), amd64)
|
||||
gcloud docker -- push $(IMAGE):$(TAG)
|
||||
endif
|
||||
|
||||
clean: $(addprefix sub-clean-,$(ALL_ARCH))
|
||||
sub-clean-%:
|
||||
docker rmi -f $(IMAGE)-$*:$(TAG) || true
|
|
@ -1,10 +0,0 @@
|
|||
# Echoserver
|
||||
|
||||
This is a simple server that responds with the http headers it received.
|
||||
|
||||
Image Versions >= 1.10 support HTTP2 on :8443.
|
||||
Image Versions >= 1.9 expose HTTPS endpoint on :8443.
|
||||
Image versions >= 1.4 removes the redirect introduced in 1.3.
|
||||
Image versions >= 1.3 redirect requests on :80 with `X-Forwarded-Proto: http` to :443.
|
||||
Image versions > 1.0 run an nginx server, and implement the echoserver using lua in the nginx config.
|
||||
Image versions <= 1.0 run a python http server instead of nginx, and don't redirect any requests.
|
|
@ -1,59 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: echoheaders
|
||||
labels:
|
||||
app: echoheaders
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
name: http
|
||||
- port: 443
|
||||
targetPort: 8443
|
||||
protocol: TCP
|
||||
name: https
|
||||
selector:
|
||||
app: echoheaders
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: echoheaders
|
||||
labels:
|
||||
app: echoheaders
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: echoheaders
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: echoheaders
|
||||
spec:
|
||||
containers:
|
||||
- name: echoheaders
|
||||
image: gcr.io/google_containers/echoserver:1.10
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
- containerPort: 8443
|
||||
env:
|
||||
- name: NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
|
@ -1,92 +0,0 @@
|
|||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
env HOSTNAME;
|
||||
env NODE_NAME;
|
||||
env POD_NAME;
|
||||
env POD_NAMESPACE;
|
||||
env POD_IP;
|
||||
|
||||
http {
|
||||
default_type 'text/plain';
|
||||
# maximum allowed size of the client request body. By default this is 1m.
|
||||
# Request with bigger bodies nginx will return error code 413.
|
||||
# http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size
|
||||
client_max_body_size 10m;
|
||||
|
||||
init_by_lua_block {
|
||||
local template = require("template")
|
||||
-- template syntax documented here:
|
||||
-- https://github.com/bungle/lua-resty-template/blob/master/README.md
|
||||
tmpl = template.compile([[
|
||||
|
||||
|
||||
Hostname: {{os.getenv("HOSTNAME") or "N/A"}}
|
||||
|
||||
Pod Information:
|
||||
{% if os.getenv("POD_NAME") then %}
|
||||
node name: {{os.getenv("NODE_NAME") or "N/A"}}
|
||||
pod name: {{os.getenv("POD_NAME") or "N/A"}}
|
||||
pod namespace: {{os.getenv("POD_NAMESPACE") or "N/A"}}
|
||||
pod IP: {{os.getenv("POD_IP") or "N/A"}}
|
||||
{% else %}
|
||||
-no pod information available-
|
||||
{% end %}
|
||||
|
||||
Server values:
|
||||
server_version=nginx: {{ngx.var.nginx_version}} - lua: {{ngx.config.ngx_lua_version}}
|
||||
|
||||
Request Information:
|
||||
client_address={{ngx.var.remote_addr}}
|
||||
method={{ngx.req.get_method()}}
|
||||
real path={{ngx.var.request_uri}}
|
||||
query={{ngx.var.query_string or ""}}
|
||||
request_version={{ngx.req.http_version()}}
|
||||
request_scheme={{ngx.var.scheme}}
|
||||
request_uri={{ngx.var.scheme.."://"..ngx.var.host..":"..ngx.var.server_port..ngx.var.request_uri}}
|
||||
|
||||
Request Headers:
|
||||
{% for i, key in ipairs(keys) do %}
|
||||
{{key}}={{headers[key]}}
|
||||
{% end %}
|
||||
|
||||
Request Body:
|
||||
{{ngx.var.request_body or " -no body in request-"}}
|
||||
]])
|
||||
}
|
||||
|
||||
server {
|
||||
# please check the benefits of reuseport https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1
|
||||
# basically instructs to create an individual listening socket for each worker process (using the SO_REUSEPORT
|
||||
# socket option), allowing a kernel to distribute incoming connections between worker processes.
|
||||
listen 8080 default_server reuseport;
|
||||
listen 8443 default_server ssl http2 reuseport;
|
||||
|
||||
ssl_certificate /certs/certificate.crt;
|
||||
ssl_certificate_key /certs/privateKey.key;
|
||||
|
||||
# Replace '_' with your hostname.
|
||||
server_name _;
|
||||
|
||||
# set long keepalive_timeout because some loadbalancer proxies expect the connection
|
||||
# to remain open for at least ten minutes.
|
||||
keepalive_timeout 620s;
|
||||
|
||||
location / {
|
||||
lua_need_request_body on;
|
||||
content_by_lua_block {
|
||||
ngx.header["Server"] = "echoserver"
|
||||
|
||||
local headers = ngx.req.get_headers()
|
||||
local keys = {}
|
||||
for key, val in pairs(headers) do
|
||||
table.insert(keys, key)
|
||||
end
|
||||
table.sort(keys)
|
||||
|
||||
ngx.say(tmpl({os=os, ngx=ngx, keys=keys, headers=headers}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,509 +0,0 @@
|
|||
-- vendored from https://raw.githubusercontent.com/bungle/lua-resty-template/1f9a5c24fc7572dbf5be0b9f8168cc3984b03d24/lib/resty/template.lua
|
||||
-- only modification: remove / from HTML_ENTITIES to not escape it, and fix the appropriate regex.
|
||||
--[[
|
||||
Copyright (c) 2014 - 2017 Aapo Talvensaari
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the {organization} nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
--]]
|
||||
|
||||
local setmetatable = setmetatable
|
||||
local loadstring = loadstring
|
||||
local loadchunk
|
||||
local tostring = tostring
|
||||
local setfenv = setfenv
|
||||
local require = require
|
||||
local capture
|
||||
local concat = table.concat
|
||||
local assert = assert
|
||||
local prefix
|
||||
local write = io.write
|
||||
local pcall = pcall
|
||||
local phase
|
||||
local open = io.open
|
||||
local load = load
|
||||
local type = type
|
||||
local dump = string.dump
|
||||
local find = string.find
|
||||
local gsub = string.gsub
|
||||
local byte = string.byte
|
||||
local null
|
||||
local sub = string.sub
|
||||
local ngx = ngx
|
||||
local jit = jit
|
||||
local var
|
||||
|
||||
local _VERSION = _VERSION
|
||||
local _ENV = _ENV
|
||||
local _G = _G
|
||||
|
||||
local HTML_ENTITIES = {
|
||||
["&"] = "&",
|
||||
["<"] = "<",
|
||||
[">"] = ">",
|
||||
['"'] = """,
|
||||
["'"] = "'",
|
||||
}
|
||||
|
||||
local CODE_ENTITIES = {
|
||||
["{"] = "{",
|
||||
["}"] = "}",
|
||||
["&"] = "&",
|
||||
["<"] = "<",
|
||||
[">"] = ">",
|
||||
['"'] = """,
|
||||
["'"] = "'",
|
||||
["/"] = "/"
|
||||
}
|
||||
|
||||
local VAR_PHASES
|
||||
|
||||
local ok, newtab = pcall(require, "table.new")
|
||||
if not ok then newtab = function() return {} end end
|
||||
|
||||
local caching = true
|
||||
local template = newtab(0, 12)
|
||||
|
||||
template._VERSION = "1.9"
|
||||
template.cache = {}
|
||||
|
||||
local function enabled(val)
|
||||
if val == nil then return true end
|
||||
return val == true or (val == "1" or val == "true" or val == "on")
|
||||
end
|
||||
|
||||
local function trim(s)
|
||||
return gsub(gsub(s, "^%s+", ""), "%s+$", "")
|
||||
end
|
||||
|
||||
local function rpos(view, s)
|
||||
while s > 0 do
|
||||
local c = sub(view, s, s)
|
||||
if c == " " or c == "\t" or c == "\0" or c == "\x0B" then
|
||||
s = s - 1
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
local function escaped(view, s)
|
||||
if s > 1 and sub(view, s - 1, s - 1) == "\\" then
|
||||
if s > 2 and sub(view, s - 2, s - 2) == "\\" then
|
||||
return false, 1
|
||||
else
|
||||
return true, 1
|
||||
end
|
||||
end
|
||||
return false, 0
|
||||
end
|
||||
|
||||
local function readfile(path)
|
||||
local file = open(path, "rb")
|
||||
if not file then return nil end
|
||||
local content = file:read "*a"
|
||||
file:close()
|
||||
return content
|
||||
end
|
||||
|
||||
local function loadlua(path)
|
||||
return readfile(path) or path
|
||||
end
|
||||
|
||||
local function loadngx(path)
|
||||
local vars = VAR_PHASES[phase()]
|
||||
local file, location = path, vars and var.template_location
|
||||
if sub(file, 1) == "/" then file = sub(file, 2) end
|
||||
if location and location ~= "" then
|
||||
if sub(location, -1) == "/" then location = sub(location, 1, -2) end
|
||||
local res = capture(concat{ location, '/', file})
|
||||
if res.status == 200 then return res.body end
|
||||
end
|
||||
local root = vars and (var.template_root or var.document_root) or prefix
|
||||
if sub(root, -1) == "/" then root = sub(root, 1, -2) end
|
||||
return readfile(concat{ root, "/", file }) or path
|
||||
end
|
||||
|
||||
do
|
||||
if ngx then
|
||||
VAR_PHASES = {
|
||||
set = true,
|
||||
rewrite = true,
|
||||
access = true,
|
||||
content = true,
|
||||
header_filter = true,
|
||||
body_filter = true,
|
||||
log = true
|
||||
}
|
||||
template.print = ngx.print or write
|
||||
template.load = loadngx
|
||||
prefix, var, capture, null, phase = ngx.config.prefix(), ngx.var, ngx.location.capture, ngx.null, ngx.get_phase
|
||||
if VAR_PHASES[phase()] then
|
||||
caching = enabled(var.template_cache)
|
||||
end
|
||||
else
|
||||
template.print = write
|
||||
template.load = loadlua
|
||||
end
|
||||
if _VERSION == "Lua 5.1" then
|
||||
local context = { __index = function(t, k)
|
||||
return t.context[k] or t.template[k] or _G[k]
|
||||
end }
|
||||
if jit then
|
||||
loadchunk = function(view)
|
||||
return assert(load(view, nil, nil, setmetatable({ template = template }, context)))
|
||||
end
|
||||
else
|
||||
loadchunk = function(view)
|
||||
local func = assert(loadstring(view))
|
||||
setfenv(func, setmetatable({ template = template }, context))
|
||||
return func
|
||||
end
|
||||
end
|
||||
else
|
||||
local context = { __index = function(t, k)
|
||||
return t.context[k] or t.template[k] or _ENV[k]
|
||||
end }
|
||||
loadchunk = function(view)
|
||||
return assert(load(view, nil, nil, setmetatable({ template = template }, context)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function template.caching(enable)
|
||||
if enable ~= nil then caching = enable == true end
|
||||
return caching
|
||||
end
|
||||
|
||||
function template.output(s)
|
||||
if s == nil or s == null then return "" end
|
||||
if type(s) == "function" then return template.output(s()) end
|
||||
return tostring(s)
|
||||
end
|
||||
|
||||
function template.escape(s, c)
|
||||
if type(s) == "string" then
|
||||
if c then return gsub(s, "[}{\">/<'&]", CODE_ENTITIES) end
|
||||
return gsub(s, "[\"><'&]", HTML_ENTITIES)
|
||||
end
|
||||
return template.output(s)
|
||||
end
|
||||
|
||||
function template.new(view, layout)
|
||||
assert(view, "view was not provided for template.new(view, layout).")
|
||||
local render, compile = template.render, template.compile
|
||||
if layout then
|
||||
if type(layout) == "table" then
|
||||
return setmetatable({ render = function(self, context)
|
||||
local context = context or self
|
||||
context.blocks = context.blocks or {}
|
||||
context.view = compile(view)(context)
|
||||
layout.blocks = context.blocks or {}
|
||||
layout.view = context.view or ""
|
||||
return layout:render()
|
||||
end }, { __tostring = function(self)
|
||||
local context = self
|
||||
context.blocks = context.blocks or {}
|
||||
context.view = compile(view)(context)
|
||||
layout.blocks = context.blocks or {}
|
||||
layout.view = context.view
|
||||
return tostring(layout)
|
||||
end })
|
||||
else
|
||||
return setmetatable({ render = function(self, context)
|
||||
local context = context or self
|
||||
context.blocks = context.blocks or {}
|
||||
context.view = compile(view)(context)
|
||||
return render(layout, context)
|
||||
end }, { __tostring = function(self)
|
||||
local context = self
|
||||
context.blocks = context.blocks or {}
|
||||
context.view = compile(view)(context)
|
||||
return compile(layout)(context)
|
||||
end })
|
||||
end
|
||||
end
|
||||
return setmetatable({ render = function(self, context)
|
||||
return render(view, context or self)
|
||||
end }, { __tostring = function(self)
|
||||
return compile(view)(self)
|
||||
end })
|
||||
end
|
||||
|
||||
function template.precompile(view, path, strip)
|
||||
local chunk = dump(template.compile(view), strip ~= false)
|
||||
if path then
|
||||
local file = open(path, "wb")
|
||||
file:write(chunk)
|
||||
file:close()
|
||||
end
|
||||
return chunk
|
||||
end
|
||||
|
||||
function template.compile(view, key, plain)
|
||||
assert(view, "view was not provided for template.compile(view, key, plain).")
|
||||
if key == "no-cache" then
|
||||
return loadchunk(template.parse(view, plain)), false
|
||||
end
|
||||
key = key or view
|
||||
local cache = template.cache
|
||||
if cache[key] then return cache[key], true end
|
||||
local func = loadchunk(template.parse(view, plain))
|
||||
if caching then cache[key] = func end
|
||||
return func, false
|
||||
end
|
||||
|
||||
function template.parse(view, plain)
|
||||
assert(view, "view was not provided for template.parse(view, plain).")
|
||||
if not plain then
|
||||
view = template.load(view)
|
||||
if byte(view, 1, 1) == 27 then return view end
|
||||
end
|
||||
local j = 2
|
||||
local c = {[[
|
||||
context=... or {}
|
||||
local function include(v, c) return template.compile(v)(c or context) end
|
||||
local ___,blocks,layout={},blocks or {}
|
||||
]] }
|
||||
local i, s = 1, find(view, "{", 1, true)
|
||||
while s do
|
||||
local t, p = sub(view, s + 1, s + 1), s + 2
|
||||
if t == "{" then
|
||||
local e = find(view, "}}", p, true)
|
||||
if e then
|
||||
local z, w = escaped(view, s)
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = sub(view, i, s - 1 - w)
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
if z then
|
||||
i = s
|
||||
else
|
||||
c[j] = "___[#___+1]=template.escape("
|
||||
c[j+1] = trim(sub(view, p, e - 1))
|
||||
c[j+2] = ")\n"
|
||||
j=j+3
|
||||
s, i = e + 1, e + 2
|
||||
end
|
||||
end
|
||||
elseif t == "*" then
|
||||
local e = find(view, "*}", p, true)
|
||||
if e then
|
||||
local z, w = escaped(view, s)
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = sub(view, i, s - 1 - w)
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
if z then
|
||||
i = s
|
||||
else
|
||||
c[j] = "___[#___+1]=template.output("
|
||||
c[j+1] = trim(sub(view, p, e - 1))
|
||||
c[j+2] = ")\n"
|
||||
j=j+3
|
||||
s, i = e + 1, e + 2
|
||||
end
|
||||
end
|
||||
elseif t == "%" then
|
||||
local e = find(view, "%}", p, true)
|
||||
if e then
|
||||
local z, w = escaped(view, s)
|
||||
if z then
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = sub(view, i, s - 1 - w)
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
i = s
|
||||
else
|
||||
local n = e + 2
|
||||
if sub(view, n, n) == "\n" then
|
||||
n = n + 1
|
||||
end
|
||||
local r = rpos(view, s - 1)
|
||||
if i <= r then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = sub(view, i, r)
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
c[j] = trim(sub(view, p, e - 1))
|
||||
c[j+1] = "\n"
|
||||
j=j+2
|
||||
s, i = n - 1, n
|
||||
end
|
||||
end
|
||||
elseif t == "(" then
|
||||
local e = find(view, ")}", p, true)
|
||||
if e then
|
||||
local z, w = escaped(view, s)
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = sub(view, i, s - 1 - w)
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
if z then
|
||||
i = s
|
||||
else
|
||||
local f = sub(view, p, e - 1)
|
||||
local x = find(f, ",", 2, true)
|
||||
if x then
|
||||
c[j] = "___[#___+1]=include([=["
|
||||
c[j+1] = trim(sub(f, 1, x - 1))
|
||||
c[j+2] = "]=],"
|
||||
c[j+3] = trim(sub(f, x + 1))
|
||||
c[j+4] = ")\n"
|
||||
j=j+5
|
||||
else
|
||||
c[j] = "___[#___+1]=include([=["
|
||||
c[j+1] = trim(f)
|
||||
c[j+2] = "]=])\n"
|
||||
j=j+3
|
||||
end
|
||||
s, i = e + 1, e + 2
|
||||
end
|
||||
end
|
||||
elseif t == "[" then
|
||||
local e = find(view, "]}", p, true)
|
||||
if e then
|
||||
local z, w = escaped(view, s)
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = sub(view, i, s - 1 - w)
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
if z then
|
||||
i = s
|
||||
else
|
||||
c[j] = "___[#___+1]=include("
|
||||
c[j+1] = trim(sub(view, p, e - 1))
|
||||
c[j+2] = ")\n"
|
||||
j=j+3
|
||||
s, i = e + 1, e + 2
|
||||
end
|
||||
end
|
||||
elseif t == "-" then
|
||||
local e = find(view, "-}", p, true)
|
||||
if e then
|
||||
local x, y = find(view, sub(view, s, e + 1), e + 2, true)
|
||||
if x then
|
||||
local z, w = escaped(view, s)
|
||||
if z then
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = sub(view, i, s - 1 - w)
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
i = s
|
||||
else
|
||||
y = y + 1
|
||||
x = x - 1
|
||||
if sub(view, y, y) == "\n" then
|
||||
y = y + 1
|
||||
end
|
||||
local b = trim(sub(view, p, e - 1))
|
||||
if b == "verbatim" or b == "raw" then
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = sub(view, i, s - 1 - w)
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
c[j] = "___[#___+1]=[=["
|
||||
c[j+1] = sub(view, e + 2, x)
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
else
|
||||
if sub(view, x, x) == "\n" then
|
||||
x = x - 1
|
||||
end
|
||||
local r = rpos(view, s - 1)
|
||||
if i <= r then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = sub(view, i, r)
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
c[j] = 'blocks["'
|
||||
c[j+1] = b
|
||||
c[j+2] = '"]=include[=['
|
||||
c[j+3] = sub(view, e + 2, x)
|
||||
c[j+4] = "]=]\n"
|
||||
j=j+5
|
||||
end
|
||||
s, i = y - 1, y
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif t == "#" then
|
||||
local e = find(view, "#}", p, true)
|
||||
if e then
|
||||
local z, w = escaped(view, s)
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = sub(view, i, s - 1 - w)
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
if z then
|
||||
i = s
|
||||
else
|
||||
e = e + 2
|
||||
if sub(view, e, e) == "\n" then
|
||||
e = e + 1
|
||||
end
|
||||
s, i = e - 1, e
|
||||
end
|
||||
end
|
||||
end
|
||||
s = find(view, "{", s + 1, true)
|
||||
end
|
||||
s = sub(view, i)
|
||||
if s and s ~= "" then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = s
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
c[j] = "return layout and include(layout,setmetatable({view=table.concat(___),blocks=blocks},{__index=context})) or table.concat(___)"
|
||||
return concat(c)
|
||||
end
|
||||
|
||||
function template.render(view, context, key, plain)
|
||||
assert(view, "view was not provided for template.render(view, context, key, plain).")
|
||||
return template.print(template.compile(view, key, plain)(context))
|
||||
end
|
||||
|
||||
return template
|
|
@ -13,7 +13,7 @@
|
|||
# limitations under the License.
|
||||
|
||||
# 0.0.0 shouldn't clobber any released builds
|
||||
TAG ?= 0.50
|
||||
TAG ?= 0.58
|
||||
REGISTRY ?= quay.io/kubernetes-ingress-controller
|
||||
ARCH ?= $(shell go env GOARCH)
|
||||
DOCKER ?= docker
|
||||
|
@ -26,14 +26,14 @@ ifeq ($(GOHOSTOS),darwin)
|
|||
SED_I=sed -i ''
|
||||
endif
|
||||
|
||||
QEMUVERSION=v2.12.0
|
||||
QEMUVERSION=v2.12.0-1
|
||||
|
||||
IMGNAME = nginx
|
||||
IMAGE = $(REGISTRY)/$(IMGNAME)
|
||||
MULTI_ARCH_IMG = $(IMAGE)-$(ARCH)
|
||||
|
||||
# Set default base image dynamically for each arch
|
||||
BASEIMAGE?=gcr.io/google-containers/debian-base-$(ARCH):0.3
|
||||
BASEIMAGE?=quay.io/kubernetes-ingress-controller/debian-base-$(ARCH):0.1
|
||||
|
||||
ifeq ($(ARCH),arm)
|
||||
QEMUARCH=arm
|
||||
|
@ -67,7 +67,7 @@ all-push: $(addprefix sub-push-,$(ALL_ARCH))
|
|||
|
||||
container: .container-$(ARCH)
|
||||
.container-$(ARCH):
|
||||
cp ./* $(TEMP_DIR)
|
||||
cp -r ./rootfs/* $(TEMP_DIR)
|
||||
cd $(TEMP_DIR) && $(SED_I) 's|BASEIMAGE|$(BASEIMAGE)|g' Dockerfile
|
||||
cd $(TEMP_DIR) && $(SED_I) "s|ARCH|$(QEMUARCH)|g" Dockerfile
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
|
||||
nginx 1.13.x base image using [debian-base](https://github.com/kubernetes/kubernetes/tree/master/build/debian-base)
|
||||
nginx 1.15.x base image using [debian-base](https://github.com/kubernetes/kubernetes/tree/master/build/debian-base)
|
||||
|
||||
nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP proxy server.
|
||||
|
||||
This custom nginx image contains:
|
||||
|
||||
- [stream](http://nginx.org/en/docs/stream/ngx_stream_core_module.html) tcp support for upstreams
|
||||
- nginx stats [nginx-module-vts](https://github.com/vozlt/nginx-module-vts)
|
||||
- [Dynamic TLS record sizing](https://blog.cloudflare.com/optimizing-tls-over-tcp-to-reduce-latency/)
|
||||
- [ngx_devel_kit](https://github.com/simpl/ngx_devel_kit)
|
||||
- [set-misc-nginx-module](https://github.com/openresty/set-misc-nginx-module)
|
||||
|
@ -26,7 +25,7 @@ This image provides a default configuration file with no backend servers.
|
|||
*Using docker*
|
||||
|
||||
```console
|
||||
docker run -v /some/nginx.con:/etc/nginx/nginx.conf:ro quay.io/kubernetes-ingress-controller/nginx:0.30
|
||||
docker run -v /some/nginx.con:/etc/nginx/nginx.conf:ro quay.io/kubernetes-ingress-controller/nginx:0.56
|
||||
```
|
||||
|
||||
*Creating a replication controller*
|
||||
|
|
|
@ -28,10 +28,10 @@ spec:
|
|||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
name: frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: quay.io/kubernetes-ingress-controller/nginx:0.30
|
||||
image: quay.io/kubernetes-ingress-controller/nginx:0.56
|
||||
ports:
|
||||
- containerPort: 80
|
||||
- containerPort: 443
|
||||
|
|
|
@ -17,7 +17,7 @@ FROM BASEIMAGE
|
|||
|
||||
CROSS_BUILD_COPY qemu-ARCH-static /usr/bin/
|
||||
|
||||
COPY build.sh install_lua_resty_waf.sh /
|
||||
COPY . /
|
||||
|
||||
RUN clean-install bash
|
||||
|
||||
|
@ -30,4 +30,6 @@ RUN ln -sf /dev/stderr /var/log/nginx/error.log
|
|||
|
||||
EXPOSE 80 443
|
||||
|
||||
ENTRYPOINT [ "/entrypoint.sh" ]
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
|
@ -19,23 +19,24 @@ set -o errexit
|
|||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
export NGINX_VERSION=1.13.12
|
||||
export NDK_VERSION=0.3.0
|
||||
export VTS_VERSION=0.1.16
|
||||
export SETMISC_VERSION=0.31
|
||||
export NGINX_VERSION=1.15.2
|
||||
export NDK_VERSION=0.3.1rc1
|
||||
export SETMISC_VERSION=0.32
|
||||
export STICKY_SESSIONS_VERSION=08a395c66e42
|
||||
export MORE_HEADERS_VERSION=0.33
|
||||
export NGINX_DIGEST_AUTH=274490cec649e7300fea97fed13d84e596bbc0ce
|
||||
export NGINX_SUBSTITUTIONS=bc58cb11844bc42735bbaef7085ea86ace46d05b
|
||||
export NGINX_OPENTRACING_VERSION=0.3.0
|
||||
export OPENTRACING_CPP_VERSION=1.4.0
|
||||
export ZIPKIN_CPP_VERSION=0.3.1
|
||||
export JAEGER_VERSION=0.4.1
|
||||
export MODSECURITY_VERSION=1.0.0
|
||||
export LUA_NGX_VERSION=0.10.13
|
||||
export NGINX_OPENTRACING_VERSION=0.6.0
|
||||
export OPENTRACING_CPP_VERSION=1.5.0
|
||||
export ZIPKIN_CPP_VERSION=0.5.1
|
||||
export JAEGER_VERSION=ba0fa3fa6dbb01995d996f988a897e272100bf95
|
||||
export MODSECURITY_VERSION=37b76e88df4bce8a9846345c27271d7e6ce1acfb
|
||||
export LUA_NGX_VERSION=e94f2e5d64daa45ff396e262d8dab8e56f5f10e0
|
||||
export LUA_UPSTREAM_VERSION=0.07
|
||||
export COOKIE_FLAG_VERSION=1.1.0
|
||||
export NGINX_INFLUXDB_VERSION=f8732268d44aea706ecf8d9c6036e9b6dacc99b2
|
||||
export NGINX_INFLUXDB_VERSION=f20cfb2458c338f162132f5a21eb021e2cbe6383
|
||||
export GEOIP2_VERSION=2.0
|
||||
export NGINX_AJP_VERSION=bf6cd93f2098b59260de8d494f0f4b1f11a84627
|
||||
|
||||
export BUILD_PATH=/tmp/build
|
||||
|
||||
|
@ -80,29 +81,34 @@ clean-install \
|
|||
util-linux \
|
||||
lua5.1 liblua5.1-0 liblua5.1-dev \
|
||||
lmdb-utils \
|
||||
libjemalloc1 libjemalloc-dev \
|
||||
wget \
|
||||
libcurl4-openssl-dev \
|
||||
libprotobuf-dev protobuf-compiler \
|
||||
libz-dev \
|
||||
procps \
|
||||
git g++ pkgconf flex bison doxygen libyajl-dev liblmdb-dev libtool dh-autoreconf libxml2 libpcre++-dev libxml2-dev \
|
||||
lua-cjson \
|
||||
python \
|
||||
luarocks \
|
||||
libmaxminddb-dev \
|
||||
authbind \
|
||||
dumb-init \
|
||||
gdb \
|
||||
|| exit 1
|
||||
|
||||
if [[ ${ARCH} == "x86_64" ]]; then
|
||||
ln -s /usr/lib/x86_64-linux-gnu/liblua5.1.so /usr/lib/liblua.so
|
||||
ln -s /usr/lib/x86_64-linux-gnu /usr/lib/lua-platform-path
|
||||
ln -s /usr/lib/x86_64-linux-gnu /usr/lib/lua-platform-path
|
||||
fi
|
||||
|
||||
if [[ ${ARCH} == "armv7l" ]]; then
|
||||
ln -s /usr/lib/arm-linux-gnueabihf/liblua5.1.so /usr/lib/liblua.so
|
||||
ln -s /usr/lib/arm-linux-gnueabihf /usr/lib/lua-platform-path
|
||||
ln -s /usr/lib/arm-linux-gnueabihf /usr/lib/lua-platform-path
|
||||
fi
|
||||
|
||||
if [[ ${ARCH} == "aarch64" ]]; then
|
||||
ln -s /usr/lib/aarch64-linux-gnu/liblua5.1.so /usr/lib/liblua.so
|
||||
ln -s /usr/lib/aarch64-linux-gnu /usr/lib/lua-platform-path
|
||||
ln -s /usr/lib/aarch64-linux-gnu /usr/lib/lua-platform-path
|
||||
fi
|
||||
|
||||
if [[ ${ARCH} == "ppc64le" ]]; then
|
||||
|
@ -127,26 +133,26 @@ function geoip_get {
|
|||
wget -O $GEOIP_FOLDER/$1 $2 || { echo "Could not download $1, exiting." ; exit 1; }
|
||||
gunzip $GEOIP_FOLDER/$1
|
||||
}
|
||||
geoip_get "GeoIP.dat.gz" "https://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz"
|
||||
geoip_get "GeoLiteCity.dat.gz" "https://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz"
|
||||
geoip_get "GeoIPASNum.dat.gz" "http://download.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz"
|
||||
|
||||
geoip_get "GeoIPASNum.dat.gz" "http://download.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz"
|
||||
geoip_get "GeoIP.dat.gz" "https://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz"
|
||||
geoip_get "GeoLite2-City.mmdb.gz" "http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz"
|
||||
geoip_get "GeoLite2-ASN.mmdb.gz" "http://geolite.maxmind.com/download/geoip/database/GeoLite2-ASN.tar.gz"
|
||||
geoip_get "GeoLiteCity.dat.gz" "https://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz"
|
||||
|
||||
mkdir --verbose -p "$BUILD_PATH"
|
||||
cd "$BUILD_PATH"
|
||||
|
||||
# download, verify and extract the source files
|
||||
get_src fb92f5602cdb8d3ab1ad47dbeca151b185d62eedb67d347bbe9d79c1438c85de \
|
||||
get_src eeba09aecfbe8277ac33a5a2486ec2d6731739f3c1c701b42a0c3784af67ad90 \
|
||||
"http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz"
|
||||
|
||||
get_src 88e05a99a8a7419066f5ae75966fb1efc409bad4522d14986da074554ae61619 \
|
||||
get_src 49f50d4cd62b166bc1aaf712febec5e028d9f187cedbc27a610dfd01bdde2d36 \
|
||||
"https://github.com/simpl/ngx_devel_kit/archive/v$NDK_VERSION.tar.gz"
|
||||
|
||||
get_src 97946a68937b50ab8637e1a90a13198fe376d801dc3e7447052e43c28e9ee7de \
|
||||
get_src f1ad2459c4ee6a61771aa84f77871f4bfe42943a4aa4c30c62ba3f981f52c201 \
|
||||
"https://github.com/openresty/set-misc-nginx-module/archive/v$SETMISC_VERSION.tar.gz"
|
||||
|
||||
get_src c668d0ed38afbba12f0224cb8cf5d70dcb9388723766dfb40d00539f887186fa \
|
||||
"https://github.com/vozlt/nginx-module-vts/archive/v$VTS_VERSION.tar.gz"
|
||||
|
||||
get_src a3dcbab117a9c103bc1ea5200fc00a7b7d2af97ff7fd525f16f8ac2632e30fbf \
|
||||
"https://github.com/openresty/headers-more-nginx-module/archive/v$MORE_HEADERS_VERSION.tar.gz"
|
||||
|
||||
|
@ -159,26 +165,26 @@ get_src ede0ad490cb9dd69da348bdea2a60a4c45284c9777b2f13fa48394b6b8e7671c \
|
|||
get_src 618551948ab14cac51d6e4ad00452312c7b09938f59ebff4f93875013be31f2d \
|
||||
"https://github.com/yaoweibin/ngx_http_substitutions_filter_module/archive/$NGINX_SUBSTITUTIONS.tar.gz"
|
||||
|
||||
get_src 2d2b8784a09c7bb4ae7f8a76ab679c54a683b8dda26db2f948982de0ad44c7a5 \
|
||||
get_src b6a6eecb0b18b15398b7d6ed0a2db4cfd7a9015c1e26f9da4160acc588b82b6f \
|
||||
"https://github.com/opentracing-contrib/nginx-opentracing/archive/v$NGINX_OPENTRACING_VERSION.tar.gz"
|
||||
|
||||
get_src 2eb0a4a7dc62bc8cbf12872080197b41d53b4c04966c860774a6b11fd59fad55 \
|
||||
get_src 4455ca507936bc4b658ded10a90d8ebbbd61c58f06207be565a4ffdc885687b5 \
|
||||
"https://github.com/opentracing/opentracing-cpp/archive/v$OPENTRACING_CPP_VERSION.tar.gz"
|
||||
|
||||
get_src f16a6f1eed494ca3c2607d7ad671cb134bd7eb320c5969c8281c10922a146589 \
|
||||
get_src f65cbb1de638f5b7bb4a7a3e0b4a6ecef7870e119f85652e3bd5fe4ea2f15d3f \
|
||||
"https://github.com/rnburn/zipkin-cpp-opentracing/archive/v$ZIPKIN_CPP_VERSION.tar.gz"
|
||||
|
||||
get_src 8deee6d6f7128f58bd6ba2893bd69c1fdbc8a3ad2797ba45ef94b977255d181c \
|
||||
"https://github.com/SpiderLabs/ModSecurity-nginx/archive/v$MODSECURITY_VERSION.tar.gz"
|
||||
get_src fe7d3188e097d68f1942d46c4adba262d9ddcf433409ebc15bb5355bfb001a4a \
|
||||
"https://github.com/SpiderLabs/ModSecurity-nginx/archive/$MODSECURITY_VERSION.tar.gz"
|
||||
|
||||
get_src 35b5a96ceb0aec68abdf25cdb9fe43cce09b2ab7bf52fb32d77038f21fef75ac \
|
||||
"https://github.com/jaegertracing/jaeger-client-cpp/archive/v$JAEGER_VERSION.tar.gz"
|
||||
get_src b68286966f292fb552511b71bd8bc11af8f12c8aa760372d1437ac8760cb2f25 \
|
||||
"https://github.com/jaegertracing/jaeger-client-cpp/archive/$JAEGER_VERSION.tar.gz"
|
||||
|
||||
get_src 9915ad1cf0734cc5b357b0d9ea92fec94764b4bf22f4dce185cbd65feda30ec1 \
|
||||
"https://github.com/AirisX/nginx_cookie_flag_module/archive/v$COOKIE_FLAG_VERSION.tar.gz"
|
||||
|
||||
get_src ecea8c3d7f69dd48c6132498ddefb5d83ba9f387fa3d4da14e2abeacdfc8a3ee \
|
||||
"https://github.com/openresty/lua-nginx-module/archive/v$LUA_NGX_VERSION.tar.gz"
|
||||
get_src 027a1f1ddb35164c720451869fc5ea9095abaf70af02a1b17f59e0772c0cfec0 \
|
||||
"https://github.com/openresty/lua-nginx-module/archive/$LUA_NGX_VERSION.tar.gz"
|
||||
|
||||
get_src 2a69815e4ae01aa8b170941a8e1a10b6f6a9aab699dee485d58f021dd933829a \
|
||||
"https://github.com/openresty/lua-upstream-nginx-module/archive/v$LUA_UPSTREAM_VERSION.tar.gz"
|
||||
|
@ -213,9 +219,14 @@ get_src d81b33129c6fb5203b571fa4d8394823bf473d8872c0357a1d0f14420b1483bd \
|
|||
get_src 76d8638a350a0484b3d6658e329ba38bb831d407eaa6dce2a084a27a22063133 \
|
||||
"https://github.com/openresty/luajit2/archive/v2.1-20180420.tar.gz"
|
||||
|
||||
get_src e41589bd88953276c16c4817ab9b4faba1aca21d9bb70a8c1714505176c16ae4 \
|
||||
get_src 1897d7677d99c1cedeb95b2eb00652a4a7e8e604304c3053a93bd3ba7dd82884 \
|
||||
"https://github.com/influxdata/nginx-influxdb-module/archive/$NGINX_INFLUXDB_VERSION.tar.gz"
|
||||
|
||||
get_src ebb4652c4f9a2e1ee31fddefc4c93ff78e651a4b2727d3453d026bccbd708d99 \
|
||||
"https://github.com/leev/ngx_http_geoip2_module/archive/$GEOIP2_VERSION.tar.gz"
|
||||
|
||||
get_src 5f629a50ba22347c441421091da70fdc2ac14586619934534e5a0f8a1390a950 \
|
||||
"https://github.com/yaoweibin/nginx_ajp_module/archive/$NGINX_AJP_VERSION.tar.gz"
|
||||
|
||||
# improve compilation times
|
||||
CORES=$(($(grep -c ^processor /proc/cpuinfo) - 0))
|
||||
|
@ -275,29 +286,66 @@ fi
|
|||
cd "$BUILD_PATH/opentracing-cpp-$OPENTRACING_CPP_VERSION"
|
||||
mkdir .build
|
||||
cd .build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF ..
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_CXX_FLAGS="-fPIC" \
|
||||
-DBUILD_TESTING=OFF \
|
||||
-DBUILD_MOCKTRACER=OFF \
|
||||
..
|
||||
|
||||
make
|
||||
make install
|
||||
|
||||
# build zipkin lib
|
||||
# build jaeger lib
|
||||
cd "$BUILD_PATH/jaeger-client-cpp-$JAEGER_VERSION"
|
||||
sed -i 's/-Werror//' CMakeLists.txt
|
||||
sed -i 's/-Werror/-Wno-psabi/' CMakeLists.txt
|
||||
|
||||
cat <<EOF > export.map
|
||||
{
|
||||
global:
|
||||
OpenTracingMakeTracerFactory;
|
||||
local: *;
|
||||
};
|
||||
EOF
|
||||
|
||||
mkdir .build
|
||||
cd .build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=1 -DBUILD_TESTING=OFF -DJAEGERTRACING_WITH_YAML_CPP=OFF -DJAEGERTRACING_BUILD_EXAMPLES=OFF ..
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_TESTING=OFF \
|
||||
-DJAEGERTRACING_BUILD_EXAMPLES=OFF \
|
||||
-DJAEGERTRACING_BUILD_CROSSDOCK=OFF \
|
||||
-DJAEGERTRACING_COVERAGE=OFF \
|
||||
-DJAEGERTRACING_PLUGIN=ON \
|
||||
-DHUNTER_CONFIGURATION_TYPES=Release \
|
||||
-DJAEGERTRACING_WITH_YAML_CPP=ON ..
|
||||
|
||||
make
|
||||
make install
|
||||
|
||||
export HUNTER_INSTALL_DIR=$(cat _3rdParty/Hunter/install-root-dir)
|
||||
echo "HUNTER_INSTALL_DIR: ${HUNTER_INSTALL_DIR}"
|
||||
cp $HUNTER_INSTALL_DIR/lib/libthrift* /usr/local/lib
|
||||
rm /usr/local/lib/libthrift*.a
|
||||
export HUNTER_INSTALL_DIR=$(cat _3rdParty/Hunter/install-root-dir) \
|
||||
|
||||
mv libjaegertracing_plugin.so /usr/local/lib/libjaegertracing_plugin.so
|
||||
|
||||
# build zipkin lib
|
||||
cd "$BUILD_PATH/zipkin-cpp-opentracing-$ZIPKIN_CPP_VERSION"
|
||||
|
||||
cat <<EOF > export.map
|
||||
{
|
||||
global:
|
||||
OpenTracingMakeTracerFactory;
|
||||
local: *;
|
||||
};
|
||||
EOF
|
||||
|
||||
mkdir .build
|
||||
cd .build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=1 -DBUILD_TESTING=OFF ..
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DBUILD_PLUGIN=ON \
|
||||
-DBUILD_TESTING=OFF ..
|
||||
|
||||
make
|
||||
make install
|
||||
|
||||
|
@ -312,8 +360,9 @@ git submodule update
|
|||
cd "$BUILD_PATH"
|
||||
git clone -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity
|
||||
cd ModSecurity/
|
||||
# checkout v3.0.2
|
||||
git checkout 8d0f51beda5c031e38741c27f29b67f0266352bb
|
||||
# TODO: use a tag once 3.0.3 is released
|
||||
# checkout v3.0.3
|
||||
# git checkout
|
||||
git submodule init
|
||||
git submodule update
|
||||
sh build.sh
|
||||
|
@ -373,6 +422,7 @@ Include /etc/nginx/owasp-modsecurity-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTE
|
|||
cd "$BUILD_PATH/nginx-$NGINX_VERSION"
|
||||
|
||||
WITH_FLAGS="--with-debug \
|
||||
--with-compat \
|
||||
--with-pcre-jit \
|
||||
--with-http_ssl_module \
|
||||
--with-http_stub_status_module \
|
||||
|
@ -396,8 +446,19 @@ fi
|
|||
|
||||
# "Combining -flto with -g is currently experimental and expected to produce unexpected results."
|
||||
# https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
|
||||
CC_OPT="-g -Og -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wno-deprecated-declarations --param=ssp-buffer-size=4 -DTCP_FASTOPEN=23 -Wno-error=strict-aliasing -fPIC -I$HUNTER_INSTALL_DIR/include"
|
||||
LD_OPT="-ljemalloc -fPIE -fPIC -pie -Wl,-z,relro -Wl,-z,now -L$HUNTER_INSTALL_DIR/lib"
|
||||
CC_OPT="-g -Og -fPIE -fstack-protector-strong \
|
||||
-Wformat \
|
||||
-Werror=format-security \
|
||||
-Wno-deprecated-declarations \
|
||||
-fno-strict-aliasing \
|
||||
-D_FORTIFY_SOURCE=2 \
|
||||
--param=ssp-buffer-size=4 \
|
||||
-DTCP_FASTOPEN=23 \
|
||||
-fPIC \
|
||||
-I$HUNTER_INSTALL_DIR/include \
|
||||
-Wno-cast-function-type"
|
||||
|
||||
LD_OPT="-fPIE -fPIC -pie -Wl,-z,relro -Wl,-z,now -L$HUNTER_INSTALL_DIR/lib"
|
||||
|
||||
if [[ ${ARCH} == "x86_64" ]]; then
|
||||
CC_OPT+=' -m64 -mtune=native'
|
||||
|
@ -405,7 +466,6 @@ fi
|
|||
|
||||
WITH_MODULES="--add-module=$BUILD_PATH/ngx_devel_kit-$NDK_VERSION \
|
||||
--add-module=$BUILD_PATH/set-misc-nginx-module-$SETMISC_VERSION \
|
||||
--add-module=$BUILD_PATH/nginx-module-vts-$VTS_VERSION \
|
||||
--add-module=$BUILD_PATH/headers-more-nginx-module-$MORE_HEADERS_VERSION \
|
||||
--add-module=$BUILD_PATH/nginx-goodies-nginx-sticky-module-ng-$STICKY_SESSIONS_VERSION \
|
||||
--add-module=$BUILD_PATH/nginx-http-auth-digest-$NGINX_DIGEST_AUTH \
|
||||
|
@ -415,9 +475,9 @@ WITH_MODULES="--add-module=$BUILD_PATH/ngx_devel_kit-$NDK_VERSION \
|
|||
--add-module=$BUILD_PATH/nginx_cookie_flag_module-$COOKIE_FLAG_VERSION \
|
||||
--add-module=$BUILD_PATH/nginx-influxdb-module-$NGINX_INFLUXDB_VERSION \
|
||||
--add-dynamic-module=$BUILD_PATH/nginx-opentracing-$NGINX_OPENTRACING_VERSION/opentracing \
|
||||
--add-dynamic-module=$BUILD_PATH/nginx-opentracing-$NGINX_OPENTRACING_VERSION/jaeger \
|
||||
--add-dynamic-module=$BUILD_PATH/nginx-opentracing-$NGINX_OPENTRACING_VERSION/zipkin \
|
||||
--add-dynamic-module=$BUILD_PATH/ModSecurity-nginx-$MODSECURITY_VERSION \
|
||||
--add-dynamic-module=$BUILD_PATH/ngx_http_geoip2_module-${GEOIP2_VERSION} \
|
||||
--add-module=$BUILD_PATH/nginx_ajp_module-${NGINX_AJP_VERSION} \
|
||||
--add-module=$BUILD_PATH/ngx_brotli"
|
||||
|
||||
./configure \
|
||||
|
@ -441,14 +501,19 @@ WITH_MODULES="--add-module=$BUILD_PATH/ngx_devel_kit-$NDK_VERSION \
|
|||
--without-http_scgi_module \
|
||||
--with-cc-opt="${CC_OPT}" \
|
||||
--with-ld-opt="${LD_OPT}" \
|
||||
${WITH_MODULES} \
|
||||
&& make || exit 1 \
|
||||
&& make install || exit 1
|
||||
--user=www-data \
|
||||
--group=www-data \
|
||||
${WITH_MODULES}
|
||||
|
||||
make || exit 1
|
||||
make install || exit 1
|
||||
|
||||
echo "Cleaning..."
|
||||
|
||||
cd /
|
||||
|
||||
mv /usr/share/nginx/sbin/nginx /usr/sbin
|
||||
|
||||
apt-mark unmarkauto \
|
||||
bash \
|
||||
curl ca-certificates \
|
||||
|
@ -456,7 +521,7 @@ apt-mark unmarkauto \
|
|||
libpcre3 \
|
||||
zlib1g \
|
||||
libaio1 \
|
||||
xz-utils \
|
||||
gdb \
|
||||
geoip-bin \
|
||||
libyajl2 liblmdb0 libxml2 libpcre++ \
|
||||
gzip \
|
||||
|
@ -464,8 +529,6 @@ apt-mark unmarkauto \
|
|||
|
||||
apt-get remove -y --purge \
|
||||
build-essential \
|
||||
gcc-6 \
|
||||
cpp-6 \
|
||||
libgeoip-dev \
|
||||
libpcre3-dev \
|
||||
libssl-dev \
|
||||
|
@ -474,14 +537,14 @@ apt-get remove -y --purge \
|
|||
linux-libc-dev \
|
||||
cmake \
|
||||
wget \
|
||||
patch \
|
||||
protobuf-compiler \
|
||||
python \
|
||||
xz-utils \
|
||||
git g++ pkgconf flex bison doxygen libyajl-dev liblmdb-dev libgeoip-dev libtool dh-autoreconf libpcre++-dev libxml2-dev
|
||||
|
||||
apt-get autoremove -y
|
||||
|
||||
mkdir -p /var/lib/nginx/body /usr/share/nginx/html
|
||||
|
||||
mv /usr/share/nginx/sbin/nginx /usr/sbin
|
||||
|
||||
rm -rf "$BUILD_PATH"
|
||||
rm -Rf /usr/share/man /usr/share/doc
|
||||
rm -rf /tmp/* /var/tmp/*
|
||||
|
@ -491,7 +554,29 @@ rm -rf /usr/local/modsecurity/bin
|
|||
rm -rf /usr/local/modsecurity/include
|
||||
rm -rf /usr/local/modsecurity/lib/libmodsecurity.a
|
||||
|
||||
rm -rf /root/.cache
|
||||
|
||||
rm -rf /etc/nginx/owasp-modsecurity-crs/.git
|
||||
rm -rf /etc/nginx/owasp-modsecurity-crs/util/regression-tests
|
||||
|
||||
rm -rf $HOME/.hunter
|
||||
|
||||
# update image permissions
|
||||
writeDirs=( \
|
||||
/etc/nginx \
|
||||
/var/lib/nginx \
|
||||
/var/log/nginx \
|
||||
/opt/modsecurity/var/log \
|
||||
/opt/modsecurity/var/upload \
|
||||
/opt/modsecurity/var/audit \
|
||||
);
|
||||
|
||||
for dir in "${writeDirs[@]}"; do
|
||||
mkdir -p ${dir};
|
||||
chown -R www-data.www-data ${dir};
|
||||
done
|
||||
|
||||
chmod 755 /etc/authbind/byuid/33
|
||||
chown www-data /etc/authbind/byuid/33
|
||||
chmod 755 /etc/authbind/byport/*
|
||||
chown www-data /etc/authbind/byport/*
|
14
images/echoheaders/Dockerfile → images/nginx/rootfs/entrypoint.sh
Normal file → Executable file
|
@ -1,4 +1,6 @@
|
|||
# Copyright 2017 The Kubernetes Authors. All rights reserved.
|
||||
#!/usr/bin/dumb-init /bin/bash
|
||||
|
||||
# Copyright 2018 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.
|
||||
|
@ -12,12 +14,6 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
FROM BASEIMAGE
|
||||
|
||||
ADD nginx.conf /etc/nginx/nginx.conf
|
||||
ADD template.lua /usr/local/share/lua/5.1/
|
||||
ADD README.md README.md
|
||||
ADD run.sh /usr/local/bin/run.sh
|
||||
RUN chmod +x /usr/local/bin/run.sh
|
||||
ENTRYPOINT ["/usr/local/bin/run.sh"]
|
||||
set -e
|
||||
|
||||
authbind --deep $@
|
0
images/nginx/rootfs/etc/authbind/byport/443
Normal file
0
images/nginx/rootfs/etc/authbind/byport/80
Normal file
4
images/nginx/rootfs/etc/authbind/byuid/33
Normal file
|
@ -0,0 +1,4 @@
|
|||
0.0.0.0:1-1023
|
||||
0.0.0.0:1-1023
|
||||
::0:1-1023
|
||||
::0:1-1023
|
|
@ -33,6 +33,9 @@ if [[ ${ARCH} != "x86_64" ]]; then
|
|||
luarocks install lrexlib-pcre 2.7.2-1 PCRE_LIBDIR=${PCRE_LIBDIR}
|
||||
fi
|
||||
|
||||
curl -o 96b0a04ce62dd01b6c6c8a8c97df7ce9916d173e.patch -sSL https://github.com/p0pr0ck5/lua-resty-waf/commit/96b0a04ce62dd01b6c6c8a8c97df7ce9916d173e.patch
|
||||
patch -p1 < 96b0a04ce62dd01b6c6c8a8c97df7ce9916d173e.patch
|
||||
|
||||
make
|
||||
make install-check
|
||||
|
|
@ -25,6 +25,12 @@ import (
|
|||
"k8s.io/kubernetes/pkg/util/filesystem"
|
||||
)
|
||||
|
||||
// ReadWriteByUser defines linux permission to read and write files for the owner user
|
||||
const ReadWriteByUser = 0660
|
||||
|
||||
// ReadByUserGroup defines linux permission to read files by the user and group owner/s
|
||||
const ReadByUserGroup = 0640
|
||||
|
||||
// Filesystem is an interface that we can use to mock various filesystem operations
|
||||
type Filesystem interface {
|
||||
filesystem.Filesystem
|
||||
|
@ -35,7 +41,7 @@ func NewLocalFS() (Filesystem, error) {
|
|||
fs := filesystem.DefaultFs{}
|
||||
|
||||
for _, directory := range directories {
|
||||
err := fs.MkdirAll(directory, 0655)
|
||||
err := fs.MkdirAll(directory, ReadWriteByUser)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -97,12 +103,5 @@ func NewFakeFS() (Filesystem, error) {
|
|||
}
|
||||
}
|
||||
|
||||
fakeFs.MkdirAll("/run", 0655)
|
||||
fakeFs.MkdirAll("/proc", 0655)
|
||||
fakeFs.MkdirAll("/etc/nginx/template", 0655)
|
||||
|
||||
fakeFs.MkdirAll(DefaultSSLDirectory, 0655)
|
||||
fakeFs.MkdirAll(AuthDirectory, 0655)
|
||||
|
||||
return fakeFs, nil
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import (
|
|||
"k8s.io/ingress-nginx/internal/ingress/annotations/auth"
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/authreq"
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/authtls"
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/backendprotocol"
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/clientbodybuffersize"
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/connection"
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/cors"
|
||||
|
@ -54,7 +55,6 @@ import (
|
|||
"k8s.io/ingress-nginx/internal/ingress/annotations/sslpassthrough"
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/upstreamhashby"
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/upstreamvhost"
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/vtsfilterkey"
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/xforwardedprefix"
|
||||
"k8s.io/ingress-nginx/internal/ingress/errors"
|
||||
"k8s.io/ingress-nginx/internal/ingress/resolver"
|
||||
|
@ -66,6 +66,7 @@ const DeniedKeyName = "Denied"
|
|||
// Ingress defines the valid annotations present in one NGINX Ingress rule
|
||||
type Ingress struct {
|
||||
metav1.ObjectMeta
|
||||
BackendProtocol string
|
||||
Alias string
|
||||
BasicDigestAuth auth.Config
|
||||
CertificateAuth authtls.Config
|
||||
|
@ -90,7 +91,6 @@ type Ingress struct {
|
|||
UpstreamHashBy string
|
||||
LoadBalancing string
|
||||
UpstreamVhost string
|
||||
VtsFilterKey string
|
||||
Whitelist ipwhitelist.SourceRange
|
||||
XForwardedPrefix bool
|
||||
SSLCiphers string
|
||||
|
@ -132,7 +132,6 @@ func NewAnnotationExtractor(cfg resolver.Resolver) Extractor {
|
|||
"UpstreamHashBy": upstreamhashby.NewParser(cfg),
|
||||
"LoadBalancing": loadbalancing.NewParser(cfg),
|
||||
"UpstreamVhost": upstreamvhost.NewParser(cfg),
|
||||
"VtsFilterKey": vtsfilterkey.NewParser(cfg),
|
||||
"Whitelist": ipwhitelist.NewParser(cfg),
|
||||
"XForwardedPrefix": xforwardedprefix.NewParser(cfg),
|
||||
"SSLCiphers": sslcipher.NewParser(cfg),
|
||||
|
@ -140,6 +139,7 @@ func NewAnnotationExtractor(cfg resolver.Resolver) Extractor {
|
|||
"GRPC": grpc.NewParser(cfg),
|
||||
"LuaRestyWAF": luarestywaf.NewParser(cfg),
|
||||
"InfluxDB": influxdb.NewParser(cfg),
|
||||
"BackendProtocol": backendprotocol.NewParser(cfg),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@ package auth
|
|||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
@ -86,17 +84,6 @@ type auth struct {
|
|||
|
||||
// NewParser creates a new authentication annotation parser
|
||||
func NewParser(authDirectory string, r resolver.Resolver) parser.IngressAnnotation {
|
||||
os.MkdirAll(authDirectory, 0755)
|
||||
|
||||
currPath := authDirectory
|
||||
for currPath != "/" {
|
||||
currPath = path.Dir(currPath)
|
||||
err := os.Chmod(currPath, 0755)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return auth{r, authDirectory}
|
||||
}
|
||||
|
||||
|
@ -157,8 +144,7 @@ func dumpSecret(filename string, secret *api.Secret) error {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: check permissions required
|
||||
err := ioutil.WriteFile(filename, val, 0777)
|
||||
err := ioutil.WriteFile(filename, val, file.ReadWriteByUser)
|
||||
if err != nil {
|
||||
return ing_errors.LocationDenied{
|
||||
Reason: errors.Wrap(err, "unexpected error creating password file"),
|
||||
|
|
62
internal/ingress/annotations/backendprotocol/main.go
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
Copyright 2018 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.
|
||||
*/
|
||||
|
||||
package backendprotocol
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
|
||||
"k8s.io/ingress-nginx/internal/ingress/resolver"
|
||||
)
|
||||
|
||||
var (
|
||||
validProtocols = regexp.MustCompile(`^(HTTP|HTTPS|AJP|GRPC|GRPCS)$`)
|
||||
)
|
||||
|
||||
type backendProtocol struct {
|
||||
r resolver.Resolver
|
||||
}
|
||||
|
||||
// NewParser creates a new backend protocol annotation parser
|
||||
func NewParser(r resolver.Resolver) parser.IngressAnnotation {
|
||||
return backendProtocol{r}
|
||||
}
|
||||
|
||||
// ParseAnnotations parses the annotations contained in the ingress
|
||||
// rule used to indicate the backend protocol.
|
||||
func (a backendProtocol) Parse(ing *extensions.Ingress) (interface{}, error) {
|
||||
if ing.GetAnnotations() == nil {
|
||||
return "HTTP", nil
|
||||
}
|
||||
|
||||
proto, err := parser.GetStringAnnotation("backend-protocol", ing)
|
||||
if err != nil {
|
||||
return "HTTP", nil
|
||||
}
|
||||
|
||||
proto = strings.TrimSpace(strings.ToUpper(proto))
|
||||
if !validProtocols.MatchString(proto) {
|
||||
glog.Warningf("Protocol %v is not a valid value for the backend-protocol annotation. Using HTTP as protocol", proto)
|
||||
return "HTTP", nil
|
||||
}
|
||||
|
||||
return proto, nil
|
||||
}
|
68
internal/ingress/annotations/backendprotocol/main_test.go
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
Copyright 2018 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.
|
||||
*/
|
||||
|
||||
package backendprotocol
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
api "k8s.io/api/core/v1"
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
|
||||
"k8s.io/ingress-nginx/internal/ingress/resolver"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
|
||||
func buildIngress() *extensions.Ingress {
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
Spec: extensions.IngressSpec{
|
||||
Backend: &extensions.IngressBackend{
|
||||
ServiceName: "default-backend",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseAnnotations(t *testing.T) {
|
||||
ing := buildIngress()
|
||||
|
||||
_, err := NewParser(&resolver.Mock{}).Parse(ing)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
data := map[string]string{}
|
||||
data[parser.GetAnnotationWithPrefix("backend-protocol")] = "HTTPS"
|
||||
ing.SetAnnotations(data)
|
||||
i, err := NewParser(&resolver.Mock{}).Parse(ing)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error parsing ingress with backend-protocol")
|
||||
}
|
||||
val, ok := i.(string)
|
||||
if !ok {
|
||||
t.Errorf("expected a string type")
|
||||
}
|
||||
if val != "HTTPS" {
|
||||
t.Errorf("expected HTTPS but %v returned", val)
|
||||
}
|
||||
}
|
|
@ -28,6 +28,8 @@ import (
|
|||
"k8s.io/ingress-nginx/internal/ingress/resolver"
|
||||
)
|
||||
|
||||
const defaultPermanentRedirectCode = http.StatusMovedPermanently
|
||||
|
||||
// Config returns the redirect configuration for an Ingress rule
|
||||
type Config struct {
|
||||
URL string `json:"url"`
|
||||
|
@ -48,7 +50,7 @@ func NewParser(r resolver.Resolver) parser.IngressAnnotation {
|
|||
// rule used to create a redirect in the paths defined in the rule.
|
||||
// If the Ingress contains both annotations the execution order is
|
||||
// temporal and then permanent
|
||||
func (a redirect) Parse(ing *extensions.Ingress) (interface{}, error) {
|
||||
func (r redirect) Parse(ing *extensions.Ingress) (interface{}, error) {
|
||||
r3w, _ := parser.GetBoolAnnotation("from-to-www-redirect", ing)
|
||||
|
||||
tr, err := parser.GetStringAnnotation("temporal-redirect", ing)
|
||||
|
@ -73,20 +75,19 @@ func (a redirect) Parse(ing *extensions.Ingress) (interface{}, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if pr != "" {
|
||||
if err := isValidURL(pr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Config{
|
||||
URL: pr,
|
||||
Code: http.StatusMovedPermanently,
|
||||
FromToWWW: r3w,
|
||||
}, nil
|
||||
prc, err := parser.GetIntAnnotation("permanent-redirect-code", ing)
|
||||
if err != nil && !errors.IsMissingAnnotations(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if r3w {
|
||||
if prc < http.StatusMultipleChoices || prc > http.StatusPermanentRedirect {
|
||||
prc = defaultPermanentRedirectCode
|
||||
}
|
||||
|
||||
if pr != "" || r3w {
|
||||
return &Config{
|
||||
URL: pr,
|
||||
Code: prc,
|
||||
FromToWWW: r3w,
|
||||
}, nil
|
||||
}
|
||||
|
|
101
internal/ingress/annotations/redirect/redirect_test.go
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
Copyright 2018 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.
|
||||
*/
|
||||
|
||||
package redirect
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
|
||||
"k8s.io/ingress-nginx/internal/ingress/resolver"
|
||||
)
|
||||
|
||||
const (
|
||||
defRedirectURL = "http://some-site.com"
|
||||
)
|
||||
|
||||
func TestPermanentRedirectWithDefaultCode(t *testing.T) {
|
||||
rp := NewParser(resolver.Mock{})
|
||||
if rp == nil {
|
||||
t.Fatalf("Expected a parser.IngressAnnotation but returned nil")
|
||||
}
|
||||
|
||||
ing := new(extensions.Ingress)
|
||||
|
||||
data := make(map[string]string, 1)
|
||||
data[parser.GetAnnotationWithPrefix("permanent-redirect")] = defRedirectURL
|
||||
ing.SetAnnotations(data)
|
||||
|
||||
i, err := rp.Parse(ing)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error with ingress: %v", err)
|
||||
}
|
||||
redirect, ok := i.(*Config)
|
||||
if !ok {
|
||||
t.Errorf("Expected a Redirect type")
|
||||
}
|
||||
if redirect.URL != defRedirectURL {
|
||||
t.Errorf("Expected %v as redirect but returned %s", defRedirectURL, redirect.URL)
|
||||
}
|
||||
if redirect.Code != defaultPermanentRedirectCode {
|
||||
t.Errorf("Expected %v as redirect to have a code %d but had %d", defRedirectURL, defaultPermanentRedirectCode, redirect.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPermanentRedirectWithCustomCode(t *testing.T) {
|
||||
rp := NewParser(resolver.Mock{})
|
||||
if rp == nil {
|
||||
t.Fatalf("Expected a parser.IngressAnnotation but returned nil")
|
||||
}
|
||||
|
||||
testCases := map[string]struct {
|
||||
input int
|
||||
expectOutput int
|
||||
}{
|
||||
"valid code": {http.StatusPermanentRedirect, http.StatusPermanentRedirect},
|
||||
"invalid code": {http.StatusTeapot, defaultPermanentRedirectCode},
|
||||
}
|
||||
|
||||
for n, tc := range testCases {
|
||||
t.Run(n, func(t *testing.T) {
|
||||
ing := new(extensions.Ingress)
|
||||
|
||||
data := make(map[string]string, 2)
|
||||
data[parser.GetAnnotationWithPrefix("permanent-redirect")] = defRedirectURL
|
||||
data[parser.GetAnnotationWithPrefix("permanent-redirect-code")] = strconv.Itoa(tc.input)
|
||||
ing.SetAnnotations(data)
|
||||
|
||||
i, err := rp.Parse(ing)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error with ingress: %v", err)
|
||||
}
|
||||
redirect, ok := i.(*Config)
|
||||
if !ok {
|
||||
t.Errorf("Expected a redirect Config type")
|
||||
}
|
||||
if redirect.URL != defRedirectURL {
|
||||
t.Errorf("Expected %v as redirect but returned %s", defRedirectURL, redirect.URL)
|
||||
}
|
||||
if redirect.Code != tc.expectOutput {
|
||||
t.Errorf("Expected %v as redirect to have a code %d but had %d", defRedirectURL, tc.expectOutput, redirect.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
package vtsfilterkey
|
||||
|
||||
import (
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
|
||||
"k8s.io/ingress-nginx/internal/ingress/resolver"
|
||||
)
|
||||
|
||||
type vtsFilterKey struct {
|
||||
r resolver.Resolver
|
||||
}
|
||||
|
||||
// NewParser creates a new vts filter key annotation parser
|
||||
func NewParser(r resolver.Resolver) parser.IngressAnnotation {
|
||||
return vtsFilterKey{r}
|
||||
}
|
||||
|
||||
// Parse parses the annotations contained in the ingress rule
|
||||
// used to indicate if the location/s contains a fragment of
|
||||
// configuration to be included inside the paths of the rules
|
||||
func (a vtsFilterKey) Parse(ing *extensions.Ingress) (interface{}, error) {
|
||||
return parser.GetStringAnnotation("vts-filter-key", ing)
|
||||
}
|
|
@ -26,6 +26,8 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const nginxPID = "/tmp/nginx.pid"
|
||||
|
||||
// Name returns the healthcheck name
|
||||
func (n NGINXController) Name() string {
|
||||
return "nginx-ingress-controller"
|
||||
|
@ -33,7 +35,7 @@ func (n NGINXController) Name() string {
|
|||
|
||||
// Check returns if the nginx healthz endpoint is returning ok (status code 200)
|
||||
func (n *NGINXController) Check(_ *http.Request) error {
|
||||
res, err := http.Get(fmt.Sprintf("http://0.0.0.0:%v%v", n.cfg.ListenPorts.Status, ngxHealthPath))
|
||||
res, err := http.Get(fmt.Sprintf("http://127.0.0.1:%v%v", n.cfg.ListenPorts.Status, ngxHealthPath))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -43,7 +45,7 @@ func (n *NGINXController) Check(_ *http.Request) error {
|
|||
}
|
||||
|
||||
if n.cfg.DynamicConfigurationEnabled {
|
||||
res, err := http.Get(fmt.Sprintf("http://0.0.0.0:%v/is-dynamic-lb-initialized", n.cfg.ListenPorts.Status))
|
||||
res, err := http.Get(fmt.Sprintf("http://127.0.0.1:%v/is-dynamic-lb-initialized", n.cfg.ListenPorts.Status))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -58,13 +60,13 @@ func (n *NGINXController) Check(_ *http.Request) error {
|
|||
if err != nil {
|
||||
return errors.Wrap(err, "unexpected error reading /proc directory")
|
||||
}
|
||||
f, err := n.fileSystem.ReadFile("/run/nginx.pid")
|
||||
f, err := n.fileSystem.ReadFile(nginxPID)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unexpected error reading /run/nginx.pid")
|
||||
return errors.Wrapf(err, "unexpected error reading %v", nginxPID)
|
||||
}
|
||||
pid, err := strconv.Atoi(strings.TrimRight(string(f), "\r\n"))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unexpected error reading the PID from /run/nginx.pid")
|
||||
return errors.Wrapf(err, "unexpected error reading the nginx PID from %v", nginxPID)
|
||||
}
|
||||
_, err = fs.NewProc(pid)
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
"k8s.io/apiserver/pkg/server/healthz"
|
||||
"k8s.io/kubernetes/pkg/util/filesystem"
|
||||
|
||||
"k8s.io/ingress-nginx/internal/file"
|
||||
ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config"
|
||||
)
|
||||
|
||||
|
@ -60,8 +61,8 @@ func TestNginxCheck(t *testing.T) {
|
|||
})
|
||||
|
||||
// create pid file
|
||||
fs.MkdirAll("/run", 0655)
|
||||
pidFile, err := fs.Create("/run/nginx.pid")
|
||||
fs.MkdirAll("/tmp", file.ReadWriteByUser)
|
||||
pidFile, err := fs.Create(nginxPID)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ const (
|
|||
sslSessionCacheSize = "10m"
|
||||
|
||||
// Default setting for load balancer algorithm
|
||||
defaultLoadBalancerAlgorithm = "least_conn"
|
||||
defaultLoadBalancerAlgorithm = ""
|
||||
|
||||
// Parameters for a shared memory zone that will keep states for various keys.
|
||||
// http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn_zone
|
||||
|
@ -161,31 +161,6 @@ type Configuration struct {
|
|||
// By default this is enabled
|
||||
IgnoreInvalidHeaders bool `json:"ignore-invalid-headers"`
|
||||
|
||||
// EnableVtsStatus allows the replacement of the default status page with a third party module named
|
||||
// nginx-module-vts - https://github.com/vozlt/nginx-module-vts
|
||||
// By default this is disabled
|
||||
EnableVtsStatus bool `json:"enable-vts-status,omitempty"`
|
||||
|
||||
// Vts config on http level
|
||||
// Description: Sets parameters for a shared memory zone that will keep states for various keys. The cache is shared between all worker processe
|
||||
// https://github.com/vozlt/nginx-module-vts#vhost_traffic_status_zone
|
||||
// Default value is 10m
|
||||
VtsStatusZoneSize string `json:"vts-status-zone-size,omitempty"`
|
||||
|
||||
// Vts config on http level
|
||||
// Description: Enables the keys by user defined variable. The key is a key string to calculate traffic.
|
||||
// The name is a group string to calculate traffic. The key and name can contain variables such as $host,
|
||||
// $server_name. The name's group belongs to filterZones if specified. The key's group belongs to serverZones
|
||||
// if not specified second argument name. The example with geoip module is as follows:
|
||||
// https://github.com/vozlt/nginx-module-vts#vhost_traffic_status_filter_by_set_key
|
||||
// Default value is $geoip_country_code country::*
|
||||
VtsDefaultFilterKey string `json:"vts-default-filter-key,omitempty"`
|
||||
|
||||
// Description: Sets sum key used by vts json output, and the sum label in prometheus output.
|
||||
// These indicate metrics values for all server zones combined, rather than for a specific one.
|
||||
// Default value is *
|
||||
VtsSumKey string `json:"vts-sum-key,omitempty"`
|
||||
|
||||
// RetryNonIdempotent since 1.9.13 NGINX will not retry non-idempotent requests (POST, LOCK, PATCH)
|
||||
// in case of an error. The previous behavior can be restored using the value true
|
||||
RetryNonIdempotent bool `json:"retry-non-idempotent"`
|
||||
|
@ -247,6 +222,12 @@ type Configuration struct {
|
|||
// http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format
|
||||
LogFormatStream string `json:"log-format-stream,omitempty"`
|
||||
|
||||
// If disabled, a worker process will accept one new connection at a time.
|
||||
// Otherwise, a worker process will accept all new connections at a time.
|
||||
// http://nginx.org/en/docs/ngx_core_module.html#multi_accept
|
||||
// Default: true
|
||||
EnableMultiAccept bool `json:"enable-multi-accept,omitempty"`
|
||||
|
||||
// Maximum number of simultaneous connections that can be opened by each worker process
|
||||
// http://nginx.org/en/docs/ngx_core_module.html#worker_connections
|
||||
MaxWorkerConnections int `json:"max-worker-connections,omitempty"`
|
||||
|
@ -328,7 +309,7 @@ type Configuration struct {
|
|||
// Sets the secret key used to encrypt and decrypt TLS session tickets.
|
||||
// http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_tickets
|
||||
// By default, a randomly generated key is used.
|
||||
// Example: openssl rand 80 | base64 -w0
|
||||
// Example: openssl rand 80 | openssl enc -A -base64
|
||||
SSLSessionTicketKey string `json:"ssl-session-ticket-key,omitempty"`
|
||||
|
||||
// Time during which a client may reuse the session parameters stored in a cache.
|
||||
|
@ -375,6 +356,9 @@ type Configuration struct {
|
|||
// Default: true
|
||||
UseHTTP2 bool `json:"use-http2,omitempty"`
|
||||
|
||||
// gzip Compression Level that will be used
|
||||
GzipLevel int `json:"gzip-level,omitempty"`
|
||||
|
||||
// MIME types in addition to "text/html" to compress. The special value “*” matches any MIME type.
|
||||
// Responses with the “text/html” type are always compressed if UseGzip is enabled
|
||||
GzipTypes string `json:"gzip-types,omitempty"`
|
||||
|
@ -461,6 +445,10 @@ type Configuration struct {
|
|||
// Default: nginx
|
||||
ZipkinServiceName string `json:"zipkin-service-name"`
|
||||
|
||||
// ZipkinSampleRate specifies sampling rate for traces
|
||||
// Default: 1.0
|
||||
ZipkinSampleRate float32 `json:"zipkin-sample-rate"`
|
||||
|
||||
// JaegerCollectorHost specifies the host to use when uploading traces
|
||||
JaegerCollectorHost string `json:"jaeger-collector-host"`
|
||||
|
||||
|
@ -480,6 +468,9 @@ type Configuration struct {
|
|||
// Default: 1
|
||||
JaegerSamplerParam string `json:"jaeger-sampler-param"`
|
||||
|
||||
// MainSnippet adds custom configuration to the main section of the nginx configuration
|
||||
MainSnippet string `json:"main-snippet"`
|
||||
|
||||
// HTTPSnippet adds custom configuration to the http section of the nginx configuration
|
||||
HTTPSnippet string `json:"http-snippet"`
|
||||
|
||||
|
@ -497,8 +488,7 @@ type Configuration struct {
|
|||
// ReusePort instructs NGINX to create an individual listening socket for
|
||||
// each worker process (using the SO_REUSEPORT socket option), allowing a
|
||||
// kernel to distribute incoming connections between worker processes
|
||||
// Default: false
|
||||
// Reason for the default: https://trac.nginx.org/nginx/ticket/1300
|
||||
// Default: true
|
||||
ReusePort bool `json:"reuse-port"`
|
||||
|
||||
// HideHeaders sets additional header that will not be passed from the upstream
|
||||
|
@ -534,6 +524,9 @@ type Configuration struct {
|
|||
// http://github.com/influxdata/nginx-influxdb-module/
|
||||
// By default this is disabled
|
||||
EnableInfluxDB bool `json:"enable-influxdb"`
|
||||
|
||||
// Checksum contains a checksum of the configmap configuration
|
||||
Checksum string `json:"-"`
|
||||
}
|
||||
|
||||
// NewDefault returns the default nginx configuration
|
||||
|
@ -575,6 +568,7 @@ func NewDefault() Configuration {
|
|||
HSTSMaxAge: hstsMaxAge,
|
||||
HSTSPreload: false,
|
||||
IgnoreInvalidHeaders: true,
|
||||
GzipLevel: 5,
|
||||
GzipTypes: gzipTypes,
|
||||
KeepAlive: 75,
|
||||
KeepAliveRequests: 100,
|
||||
|
@ -582,6 +576,7 @@ func NewDefault() Configuration {
|
|||
LogFormatEscapeJSON: false,
|
||||
LogFormatStream: logFormatStream,
|
||||
LogFormatUpstream: logFormatUpstream,
|
||||
EnableMultiAccept: true,
|
||||
MaxWorkerConnections: 16384,
|
||||
MapHashBucketSize: 64,
|
||||
NginxStatusIpv4Whitelist: defNginxStatusIpv4Whitelist,
|
||||
|
@ -592,6 +587,7 @@ func NewDefault() Configuration {
|
|||
ProxyHeadersHashMaxSize: 512,
|
||||
ProxyHeadersHashBucketSize: 64,
|
||||
ProxyStreamResponses: 1,
|
||||
ReusePort: true,
|
||||
ShowServerTokens: true,
|
||||
SSLBufferSize: sslBufferSize,
|
||||
SSLCiphers: sslCiphers,
|
||||
|
@ -607,9 +603,6 @@ func NewDefault() Configuration {
|
|||
WorkerProcesses: strconv.Itoa(runtime.NumCPU()),
|
||||
WorkerShutdownTimeout: "10s",
|
||||
LoadBalanceAlgorithm: defaultLoadBalancerAlgorithm,
|
||||
VtsStatusZoneSize: "10m",
|
||||
VtsDefaultFilterKey: "$geoip_country_code country::*",
|
||||
VtsSumKey: "*",
|
||||
VariablesHashBucketSize: 128,
|
||||
VariablesHashMaxSize: 2048,
|
||||
UseHTTP2: true,
|
||||
|
@ -641,6 +634,7 @@ func NewDefault() Configuration {
|
|||
BindAddressIpv6: defBindAddress,
|
||||
ZipkinCollectorPort: 9411,
|
||||
ZipkinServiceName: "nginx",
|
||||
ZipkinSampleRate: 1.0,
|
||||
JaegerCollectorPort: 6831,
|
||||
JaegerServiceName: "nginx",
|
||||
JaegerSamplerType: "const",
|
||||
|
|