Introduce Tracing Annotations (#3481)

* Add the tracing environment variables to the proxy spec
* Add tracing event
* Remove unnecessary CLI change
* Update log message
* Handle single segment service name
* Use default service account if not provided

The injector doesn't read the defaults from the values.yaml

* Remove references to conf.workload.ownerRef in log messages

This nested field isn't always set.

Signed-off-by: Ivan Sim <ivan@buoyant.io>
This commit is contained in:
Ivan Sim 2019-09-26 16:07:30 -07:00 committed by GitHub
parent 8f83a56431
commit 9f21c8b481
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 108 additions and 2 deletions

View File

@ -74,6 +74,9 @@ Proxy:
Memory:
Limit: ""
Request: ""
Trace:
CollectorSvcAddr: ""
CollectorSvcAccount: default
UID: 2102
# proxy-init configuration

View File

@ -68,6 +68,14 @@ env:
- name: LINKERD2_PROXY_TAP_SVC_NAME
value: linkerd-tap.$(_l5d_ns).serviceaccount.identity.$(_l5d_ns).$(_l5d_trustdomain)
{{ end -}}
{{ if .Proxy.Trace -}}
{{ if .Proxy.Trace.CollectorSvcAddr -}}
- name: LINKERD2_PROXY_TRACE_COLLECTOR_SVC_ADDR
value: {{ .Proxy.Trace.CollectorSvcAddr }}
- name: LINKERD2_PROXY_TRACE_COLLECTOR_SVC_NAME
value: {{ .Proxy.Trace.CollectorSvcAccount }}.serviceaccount.identity.$(_l5d_ns).$(_l5d_trustdomain)
{{ end -}}
{{ end -}}
image: {{.Proxy.Image.Name}}:{{.Proxy.Image.Version}}
imagePullPolicy: {{.Proxy.Image.PullPolicy}}
livenessProbe:

View File

@ -20,6 +20,7 @@ import (
const (
eventTypeSkipped = "InjectionSkipped"
eventTypeInjected = "Injected"
eventTypeTracing = "Tracing"
)
// Inject returns an AdmissionResponse containing the patch, if any, to apply
@ -108,6 +109,9 @@ func Inject(api *k8s.API,
if parent != nil {
recorder.Event(*parent, v1.EventTypeNormal, eventTypeInjected, "Linkerd sidecar proxy injected")
if report.TracingEnabled {
recorder.Event(*parent, v1.EventTypeNormal, eventTypeTracing, "Tracing Enabled")
}
}
log.Infof("patch generated for: %s", report.ResName())
log.Debugf("patch: %s", patchJSON)

View File

@ -85,6 +85,7 @@ type (
SAMountPath *SAMountPath
Ports *Ports
Resources *Resources
Trace *Trace
UID int64
}
@ -181,6 +182,12 @@ type (
TLS struct {
KeyPEM, CrtPEM string
}
// Trace has all the tracing-related Helm variables
Trace struct {
CollectorSvcAddr string
CollectorSvcAccount string
}
)
// NewValues returns a new instance of the Values type.

View File

@ -85,6 +85,10 @@ func TestNewValues(t *testing.T) {
Request: "",
},
},
Trace: &Trace{
CollectorSvcAddr: "",
CollectorSvcAccount: "default",
},
UID: 2102,
},

View File

@ -2,6 +2,7 @@ package inject
import (
"encoding/json"
"fmt"
"regexp"
"sort"
"strconv"
@ -27,6 +28,8 @@ const (
proxyInitResourceRequestMemory = "10Mi"
proxyInitResourceLimitCPU = "100m"
proxyInitResourceLimitMemory = "50Mi"
traceDefaultSvcAccount = "default"
)
var (
@ -55,6 +58,7 @@ var (
k8s.ProxyVersionOverrideAnnotation,
k8s.ProxyIgnoreInboundPortsAnnotation,
k8s.ProxyIgnoreOutboundPortsAnnotation,
k8s.ProxyTraceCollectorSvcAddr,
}
)
@ -497,6 +501,11 @@ func (conf *ResourceConfig) injectPodSpec(values *patch) {
}
values.AddRootVolumes = len(conf.pod.spec.Volumes) == 0
if trace := conf.trace(); trace != nil {
log.Infof("tracing enabled: remote service=%s, service account=%s", trace.CollectorSvcAddr, trace.CollectorSvcAccount)
values.Proxy.Trace = trace
}
}
func (conf *ResourceConfig) injectProxyInit(values *patch) {
@ -539,6 +548,36 @@ func (conf *ResourceConfig) serviceAccountVolumeMount() *corev1.VolumeMount {
return nil
}
func (conf *ResourceConfig) trace() *charts.Trace {
var (
svcAddr = conf.getOverride(k8s.ProxyTraceCollectorSvcAddr)
svcAccount = conf.getOverride(k8s.ProxyTraceCollectorSvcAccount)
)
if svcAddr == "" {
return nil
}
if svcAccount == "" {
svcAccount = traceDefaultSvcAccount
}
hostAndPort := strings.Split(svcAddr, ":")
hostname := strings.Split(hostAndPort[0], ".")
var ns string
if len(hostname) == 1 {
ns = conf.workload.Meta.Namespace
} else {
ns = hostname[1]
}
return &charts.Trace{
CollectorSvcAddr: svcAddr,
CollectorSvcAccount: fmt.Sprintf("%s.%s", svcAccount, ns),
}
}
// Given a ObjectMeta, update ObjectMeta in place with the new labels and
// annotations.
func (conf *ResourceConfig) injectObjectMeta(values *patch) {

View File

@ -31,6 +31,7 @@ type expectedProxyConfigs struct {
initVersion string
inboundSkipPorts string
outboundSkipPorts string
trace *charts.Trace
}
func TestConfigAccessors(t *testing.T) {
@ -103,7 +104,10 @@ func TestConfigAccessors(t *testing.T) {
k8s.ProxyUIDAnnotation: "8500",
k8s.ProxyLogLevelAnnotation: "debug,linkerd2_proxy=debug",
k8s.ProxyEnableExternalProfilesAnnotation: "false",
k8s.ProxyVersionOverrideAnnotation: proxyVersionOverride},
k8s.ProxyVersionOverrideAnnotation: proxyVersionOverride,
k8s.ProxyTraceCollectorSvcAddr: "oc-collector.tracing:55678",
k8s.ProxyTraceCollectorSvcAccount: "default",
},
},
Spec: corev1.PodSpec{},
},
@ -133,6 +137,10 @@ func TestConfigAccessors(t *testing.T) {
initVersion: version.ProxyInitVersion,
inboundSkipPorts: "4222,6222",
outboundSkipPorts: "8079,8080",
trace: &charts.Trace{
CollectorSvcAddr: "oc-collector.tracing:55678",
CollectorSvcAccount: "default.tracing",
},
},
},
{id: "use defaults",
@ -189,7 +197,10 @@ func TestConfigAccessors(t *testing.T) {
k8s.ProxyUIDAnnotation: "8500",
k8s.ProxyLogLevelAnnotation: "debug,linkerd2_proxy=debug",
k8s.ProxyEnableExternalProfilesAnnotation: "false",
k8s.ProxyVersionOverrideAnnotation: proxyVersionOverride},
k8s.ProxyVersionOverrideAnnotation: proxyVersionOverride,
k8s.ProxyTraceCollectorSvcAddr: "oc-collector.tracing:55678",
k8s.ProxyTraceCollectorSvcAccount: "default",
},
spec: appsv1.DeploymentSpec{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{},
@ -220,6 +231,10 @@ func TestConfigAccessors(t *testing.T) {
initVersion: version.ProxyInitVersion,
inboundSkipPorts: "4222,6222",
outboundSkipPorts: "8079,8080",
trace: &charts.Trace{
CollectorSvcAddr: "oc-collector.tracing:55678",
CollectorSvcAccount: "default.tracing",
},
},
},
}
@ -348,6 +363,20 @@ func TestConfigAccessors(t *testing.T) {
t.Errorf("Expected: %v Actual: %v", expected, actual)
}
})
t.Run("proxyTraceCollectorService", func(t *testing.T) {
var expected *charts.Trace
if testCase.expected.trace != nil {
expected = &charts.Trace{
CollectorSvcAddr: testCase.expected.trace.CollectorSvcAddr,
CollectorSvcAccount: testCase.expected.trace.CollectorSvcAccount,
}
}
if actual := resourceConfig.trace(); !reflect.DeepEqual(expected, actual) {
t.Errorf("Expected: %+v Actual: %+v", expected, actual)
}
})
})
}
}

View File

@ -42,6 +42,7 @@ type Report struct {
InjectDisabled bool
InjectDisabledReason string
InjectAnnotationAt string
TracingEnabled bool
// Uninjected consists of two boolean flags to indicate if a proxy and
// proxy-init containers have been uninjected in this report
@ -77,6 +78,7 @@ func newReport(conf *ResourceConfig) *Report {
report.HostNetwork = conf.pod.spec.HostNetwork
report.Sidecar = healthcheck.HasExistingSidecars(conf.pod.spec)
report.UDP = checkUDPPorts(conf.pod.spec)
report.TracingEnabled = conf.pod.meta.Annotations[k8s.ProxyTraceCollectorSvcAddr] != "" || conf.nsAnnotations[k8s.ProxyTraceCollectorSvcAddr] != ""
} else {
report.UnsupportedResource = true
}

View File

@ -169,6 +169,16 @@ const (
// injected.
ProxyEnableDebugAnnotation = ProxyConfigAnnotationsPrefix + "/enable-debug-sidecar"
// ProxyTraceCollectorSvcAddr can be used to enable tracing on a proxy.
// It takes the collector service name (e.g. oc-collector.tracing:55678) as
// its value.
ProxyTraceCollectorSvcAddr = ProxyConfigAnnotationsPrefix + "/trace-collector"
// ProxyTraceCollectorSvcAccount is used to specify the service account
// associated with the trace collector. It is used to create the service's
// mTLS identity.
ProxyTraceCollectorSvcAccount = "config.alpha.linkerd.io/trace-collector-service-account"
// IdentityModeDefault is assigned to IdentityModeAnnotation to
// use the control plane's default identity scheme.
IdentityModeDefault = "default"