Merge pull request #4732 from willthames/enable-opentracing-annotation
Allow enabling/disabling opentracing for ingresses
This commit is contained in:
commit
b286c2a336
9 changed files with 218 additions and 0 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -47,3 +47,7 @@ bin
|
||||||
test/e2e-image/wait-for-nginx.sh
|
test/e2e-image/wait-for-nginx.sh
|
||||||
.cache
|
.cache
|
||||||
cover.out
|
cover.out
|
||||||
|
|
||||||
|
# secret terraform variables
|
||||||
|
build/images/nginx/aws.tfvars
|
||||||
|
build/images/nginx/env.tfvars
|
||||||
|
|
|
@ -98,6 +98,7 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz
|
||||||
|[nginx.ingress.kubernetes.io/ssl-ciphers](#ssl-ciphers)|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/connection-proxy-header](#connection-proxy-header)|string|
|
||||||
|[nginx.ingress.kubernetes.io/enable-access-log](#enable-access-log)|"true" or "false"|
|
|[nginx.ingress.kubernetes.io/enable-access-log](#enable-access-log)|"true" or "false"|
|
||||||
|
|[nginx.ingress.kubernetes.io/enable-opentracing](#enable-opentracing)|"true" or "false"|
|
||||||
|[nginx.ingress.kubernetes.io/lua-resty-waf](#lua-resty-waf)|string|
|
|[nginx.ingress.kubernetes.io/lua-resty-waf](#lua-resty-waf)|string|
|
||||||
|[nginx.ingress.kubernetes.io/lua-resty-waf-debug](#lua-resty-waf)|"true" or "false"|
|
|[nginx.ingress.kubernetes.io/lua-resty-waf-debug](#lua-resty-waf)|"true" or "false"|
|
||||||
|[nginx.ingress.kubernetes.io/lua-resty-waf-ignore-rulesets](#lua-resty-waf)|string|
|
|[nginx.ingress.kubernetes.io/lua-resty-waf-ignore-rulesets](#lua-resty-waf)|string|
|
||||||
|
@ -669,6 +670,15 @@ Note that rewrite logs are sent to the error_log file at the notice level. To en
|
||||||
nginx.ingress.kubernetes.io/enable-rewrite-log: "true"
|
nginx.ingress.kubernetes.io/enable-rewrite-log: "true"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Enable Opentracing
|
||||||
|
|
||||||
|
Opentracing can be enabled or disabled globally through the ConfigMap but this will sometimes need to be overridden
|
||||||
|
to enable it or disable it for a specific ingress (e.g. to turn off tracing of external health check endpoints)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
nginx.ingress.kubernetes.io/enable-opentracing: "true"
|
||||||
|
```
|
||||||
|
|
||||||
### X-Forwarded-Prefix Header
|
### X-Forwarded-Prefix Header
|
||||||
To add the non-standard `X-Forwarded-Prefix` header to the upstream request with a string value, the following annotation can be used:
|
To add the non-standard `X-Forwarded-Prefix` header to the upstream request with a string value, the following annotation can be used:
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,15 @@ data:
|
||||||
enable-opentracing: "true"
|
enable-opentracing: "true"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To enable or disable instrumentation for a single Ingress, use
|
||||||
|
the `enable-opentracing` annotation:
|
||||||
|
```
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
nginx.ingress.kubernetes.io/enable-opentracing: "true"
|
||||||
|
```
|
||||||
|
|
||||||
We must also set the host to use when uploading traces:
|
We must also set the host to use when uploading traces:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -47,6 +47,7 @@ import (
|
||||||
"k8s.io/ingress-nginx/internal/ingress/annotations/log"
|
"k8s.io/ingress-nginx/internal/ingress/annotations/log"
|
||||||
"k8s.io/ingress-nginx/internal/ingress/annotations/luarestywaf"
|
"k8s.io/ingress-nginx/internal/ingress/annotations/luarestywaf"
|
||||||
"k8s.io/ingress-nginx/internal/ingress/annotations/mirror"
|
"k8s.io/ingress-nginx/internal/ingress/annotations/mirror"
|
||||||
|
"k8s.io/ingress-nginx/internal/ingress/annotations/opentracing"
|
||||||
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
|
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
|
||||||
"k8s.io/ingress-nginx/internal/ingress/annotations/portinredirect"
|
"k8s.io/ingress-nginx/internal/ingress/annotations/portinredirect"
|
||||||
"k8s.io/ingress-nginx/internal/ingress/annotations/proxy"
|
"k8s.io/ingress-nginx/internal/ingress/annotations/proxy"
|
||||||
|
@ -90,6 +91,7 @@ type Ingress struct {
|
||||||
ExternalAuth authreq.Config
|
ExternalAuth authreq.Config
|
||||||
EnableGlobalAuth bool
|
EnableGlobalAuth bool
|
||||||
HTTP2PushPreload bool
|
HTTP2PushPreload bool
|
||||||
|
Opentracing opentracing.Config
|
||||||
Proxy proxy.Config
|
Proxy proxy.Config
|
||||||
ProxySSL proxyssl.Config
|
ProxySSL proxyssl.Config
|
||||||
RateLimit ratelimit.Config
|
RateLimit ratelimit.Config
|
||||||
|
@ -138,6 +140,7 @@ func NewAnnotationExtractor(cfg resolver.Resolver) Extractor {
|
||||||
"ExternalAuth": authreq.NewParser(cfg),
|
"ExternalAuth": authreq.NewParser(cfg),
|
||||||
"EnableGlobalAuth": authreqglobal.NewParser(cfg),
|
"EnableGlobalAuth": authreqglobal.NewParser(cfg),
|
||||||
"HTTP2PushPreload": http2pushpreload.NewParser(cfg),
|
"HTTP2PushPreload": http2pushpreload.NewParser(cfg),
|
||||||
|
"Opentracing": opentracing.NewParser(cfg),
|
||||||
"Proxy": proxy.NewParser(cfg),
|
"Proxy": proxy.NewParser(cfg),
|
||||||
"ProxySSL": proxyssl.NewParser(cfg),
|
"ProxySSL": proxyssl.NewParser(cfg),
|
||||||
"RateLimit": ratelimit.NewParser(cfg),
|
"RateLimit": ratelimit.NewParser(cfg),
|
||||||
|
|
57
internal/ingress/annotations/opentracing/main.go
Normal file
57
internal/ingress/annotations/opentracing/main.go
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019 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 opentracing
|
||||||
|
|
||||||
|
import (
|
||||||
|
networking "k8s.io/api/networking/v1beta1"
|
||||||
|
|
||||||
|
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
|
||||||
|
"k8s.io/ingress-nginx/internal/ingress/resolver"
|
||||||
|
)
|
||||||
|
|
||||||
|
type opentracing struct {
|
||||||
|
r resolver.Resolver
|
||||||
|
}
|
||||||
|
|
||||||
|
// Config contains the configuration to be used in the Ingress
|
||||||
|
type Config struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
Set bool `json:"set"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal tests for equality between two Config types
|
||||||
|
func (bd1 *Config) Equal(bd2 *Config) bool {
|
||||||
|
if bd1.Set != bd2.Set {
|
||||||
|
return false
|
||||||
|
} else if bd1.Enabled != bd2.Enabled {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewParser creates a new serviceUpstream annotation parser
|
||||||
|
func NewParser(r resolver.Resolver) parser.IngressAnnotation {
|
||||||
|
return opentracing{r}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s opentracing) Parse(ing *networking.Ingress) (interface{}, error) {
|
||||||
|
enabled, err := parser.GetBoolAnnotation("enable-opentracing", ing)
|
||||||
|
if err != nil {
|
||||||
|
return &Config{Set: false, Enabled: false}, nil
|
||||||
|
}
|
||||||
|
return &Config{Set: true, Enabled: enabled}, nil
|
||||||
|
}
|
121
internal/ingress/annotations/opentracing/main_test.go
Normal file
121
internal/ingress/annotations/opentracing/main_test.go
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019 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 opentracing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
api "k8s.io/api/core/v1"
|
||||||
|
networking "k8s.io/api/networking/v1beta1"
|
||||||
|
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
|
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
|
||||||
|
"k8s.io/ingress-nginx/internal/ingress/resolver"
|
||||||
|
)
|
||||||
|
|
||||||
|
func buildIngress() *networking.Ingress {
|
||||||
|
defaultBackend := networking.IngressBackend{
|
||||||
|
ServiceName: "default-backend",
|
||||||
|
ServicePort: intstr.FromInt(80),
|
||||||
|
}
|
||||||
|
|
||||||
|
return &networking.Ingress{
|
||||||
|
ObjectMeta: meta_v1.ObjectMeta{
|
||||||
|
Name: "foo",
|
||||||
|
Namespace: api.NamespaceDefault,
|
||||||
|
},
|
||||||
|
Spec: networking.IngressSpec{
|
||||||
|
Backend: &networking.IngressBackend{
|
||||||
|
ServiceName: "default-backend",
|
||||||
|
ServicePort: intstr.FromInt(80),
|
||||||
|
},
|
||||||
|
Rules: []networking.IngressRule{
|
||||||
|
{
|
||||||
|
Host: "foo.bar.com",
|
||||||
|
IngressRuleValue: networking.IngressRuleValue{
|
||||||
|
HTTP: &networking.HTTPIngressRuleValue{
|
||||||
|
Paths: []networking.HTTPIngressPath{
|
||||||
|
{
|
||||||
|
Path: "/foo",
|
||||||
|
Backend: defaultBackend,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIngressAnnotationOpentracingSetTrue(t *testing.T) {
|
||||||
|
ing := buildIngress()
|
||||||
|
|
||||||
|
data := map[string]string{}
|
||||||
|
data[parser.GetAnnotationWithPrefix("enable-opentracing")] = "true"
|
||||||
|
ing.SetAnnotations(data)
|
||||||
|
|
||||||
|
val, _ := NewParser(&resolver.Mock{}).Parse(ing)
|
||||||
|
openTracing, ok := val.(*Config)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("expected a Config type")
|
||||||
|
}
|
||||||
|
if !openTracing.Set {
|
||||||
|
t.Errorf("expected annotation value to be set")
|
||||||
|
}
|
||||||
|
if !openTracing.Enabled {
|
||||||
|
t.Errorf("expected annotation value to be true, got false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIngressAnnotationOpentracingSetFalse(t *testing.T) {
|
||||||
|
ing := buildIngress()
|
||||||
|
|
||||||
|
// Test with explicitly set to false
|
||||||
|
data := map[string]string{}
|
||||||
|
data[parser.GetAnnotationWithPrefix("enable-opentracing")] = "false"
|
||||||
|
ing.SetAnnotations(data)
|
||||||
|
|
||||||
|
val, _ := NewParser(&resolver.Mock{}).Parse(ing)
|
||||||
|
openTracing, ok := val.(*Config)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("expected a Config type")
|
||||||
|
}
|
||||||
|
if !openTracing.Set {
|
||||||
|
t.Errorf("expected annotation value to be set")
|
||||||
|
}
|
||||||
|
if openTracing.Enabled {
|
||||||
|
t.Errorf("expected annotation value to be false, got true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIngressAnnotationOpentracingUnset(t *testing.T) {
|
||||||
|
ing := buildIngress()
|
||||||
|
|
||||||
|
// Test with no annotation specified
|
||||||
|
data := map[string]string{}
|
||||||
|
ing.SetAnnotations(data)
|
||||||
|
|
||||||
|
val, _ := NewParser(&resolver.Mock{}).Parse(ing)
|
||||||
|
openTracing, ok := val.(*Config)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("expected a Config type")
|
||||||
|
}
|
||||||
|
if openTracing.Set {
|
||||||
|
t.Errorf("expected annotation value to be unset")
|
||||||
|
}
|
||||||
|
}
|
|
@ -1165,6 +1165,7 @@ func locationApplyAnnotations(loc *ingress.Location, anns *annotations.Ingress)
|
||||||
loc.ExternalAuth = anns.ExternalAuth
|
loc.ExternalAuth = anns.ExternalAuth
|
||||||
loc.EnableGlobalAuth = anns.EnableGlobalAuth
|
loc.EnableGlobalAuth = anns.EnableGlobalAuth
|
||||||
loc.HTTP2PushPreload = anns.HTTP2PushPreload
|
loc.HTTP2PushPreload = anns.HTTP2PushPreload
|
||||||
|
loc.Opentracing = anns.Opentracing
|
||||||
loc.Proxy = anns.Proxy
|
loc.Proxy = anns.Proxy
|
||||||
loc.ProxySSL = anns.ProxySSL
|
loc.ProxySSL = anns.ProxySSL
|
||||||
loc.RateLimit = anns.RateLimit
|
loc.RateLimit = anns.RateLimit
|
||||||
|
|
|
@ -34,6 +34,7 @@ import (
|
||||||
"k8s.io/ingress-nginx/internal/ingress/annotations/luarestywaf"
|
"k8s.io/ingress-nginx/internal/ingress/annotations/luarestywaf"
|
||||||
"k8s.io/ingress-nginx/internal/ingress/annotations/mirror"
|
"k8s.io/ingress-nginx/internal/ingress/annotations/mirror"
|
||||||
"k8s.io/ingress-nginx/internal/ingress/annotations/modsecurity"
|
"k8s.io/ingress-nginx/internal/ingress/annotations/modsecurity"
|
||||||
|
"k8s.io/ingress-nginx/internal/ingress/annotations/opentracing"
|
||||||
"k8s.io/ingress-nginx/internal/ingress/annotations/proxy"
|
"k8s.io/ingress-nginx/internal/ingress/annotations/proxy"
|
||||||
"k8s.io/ingress-nginx/internal/ingress/annotations/proxyssl"
|
"k8s.io/ingress-nginx/internal/ingress/annotations/proxyssl"
|
||||||
"k8s.io/ingress-nginx/internal/ingress/annotations/ratelimit"
|
"k8s.io/ingress-nginx/internal/ingress/annotations/ratelimit"
|
||||||
|
@ -329,6 +330,9 @@ type Location struct {
|
||||||
// Mirror allows you to mirror traffic to a "test" backend
|
// Mirror allows you to mirror traffic to a "test" backend
|
||||||
// +optional
|
// +optional
|
||||||
Mirror mirror.Config `json:"mirror,omitempty"`
|
Mirror mirror.Config `json:"mirror,omitempty"`
|
||||||
|
// Opentracing allows the global opentracing setting to be overridden for a location
|
||||||
|
// +optional
|
||||||
|
Opentracing opentracing.Config `json:"opentracing"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SSLPassthroughBackend describes a SSL upstream server configured
|
// SSLPassthroughBackend describes a SSL upstream server configured
|
||||||
|
|
|
@ -966,8 +966,17 @@ stream {
|
||||||
set $location_path {{ $location.Path | escapeLiteralDollar | quote }};
|
set $location_path {{ $location.Path | escapeLiteralDollar | quote }};
|
||||||
|
|
||||||
{{ if $all.Cfg.EnableOpentracing }}
|
{{ if $all.Cfg.EnableOpentracing }}
|
||||||
|
{{ if and $location.Opentracing.Set (not $location.Opentracing.Enabled) }}
|
||||||
|
opentracing off;
|
||||||
|
{{ else }}
|
||||||
{{ opentracingPropagateContext $location }};
|
{{ opentracingPropagateContext $location }};
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
{{ else }}
|
||||||
|
{{ if and $location.Opentracing.Set $location.Opentracing.Enabled }}
|
||||||
|
opentracing on;
|
||||||
|
{{ opentracingPropagateContext $location }};
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
{{ if $location.Mirror.URI }}
|
{{ if $location.Mirror.URI }}
|
||||||
mirror {{ $location.Mirror.URI }};
|
mirror {{ $location.Mirror.URI }};
|
||||||
|
|
Loading…
Reference in a new issue