Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Navigating the Distributed Systems Execution Ma...

Kasten
November 14, 2018

Navigating the Distributed Systems Execution Maze With OpenTracing

As distributed systems have become commonplace, the need for organized, easy to parse debugging information from these systems has become a necessity. However, adding tracing in distributed systems presents unique challenges such as associating related trace information across processes and services, making minimally intrusive changes to add tracing infrastructure, and deciding when enough tracing has been added.

This talk discusses the adventures and resulting battlescars the engineers at Kasten obtained while adding OpenTracing and Jaeger to their Kubernetes system. By the end of this talk, listeners will know what results to expect from adding OpenTracing to Go projects, understand some of the gotchas associated with tracing, and learn some of the differences between tracing with services meshes only and using a tracing library.

Kasten

November 14, 2018
Tweet

More Decks by Kasten

Other Decks in Technology

Transcript

  1. Navigating the Distributed Systems Execution Maze with OpenTracing Ashlie Martinez,

    University of Washington PhD student, former intern Ilya Kislenko (on behalf of Julio López), Member of Technical Stuff @depohmel/[email protected]
  2. Our tracing journey... • Existing Kubernetes app • Microservices architecture

    is complex • Logging and Metrics are not enough • How to add tracing with minimal disruptions
  3. Sample App: Image Gallery Client Image Catalog DB Image Store

    Images Image Gallery API • 2 backend microservices • golang • Swagger generated HTTP/JSON APIs • https://github.com/kastenhq/demoapp
  4. Distributed Tracing High Level • Automatically aggregate traces • Highlights

    the execution path requests • Helps pinpoint where failures or slowness occur • Complements logs and metrics collection tools Image Catalog DB Image Store Images Image Gallery API Traces Tracing UI Request Developer
  5. Trace and Span what are they? Trace - is the

    complete processing of a request. The trace represents the whole journey of a request as it moves through all of the services or components of a distributed system. Span - is a single step in the total processing of the overall request. Spans are typically named and timed operations trace span1 span2 span3 spanN Application Distributed Tracing Search and analyze
  6. OpenTracing & Jaeger OpenTracing: • CNCF distributed tracing library for

    Go, C#, Java, and other languages • Instrument existing code with OpenTracing calls to collect tracing information Jaeger: • CNCF UI for visualizing and searching tracing data • Uses coalesced tracing data stored in a database like Cassandra • Deployable via helm chart and K8s yaml Other tracing options: Zipkin, Google OpenCensus
  7. OpenTracing Go SDK • Each trace collected by a single

    service is called a “span” ◦ Spans can be nested to show one service calling another • OpenTracing leverages Go’s Context object to carry info about traces ◦ Code being traced must propagate Context to be traced • Information like HTTP status codes or request IDs can be added to traces ◦ Allows developers to get more information about the state of the system for that trace ◦ Can help the developer associate a specific trace with other debug information like logs
  8. Instrumenting Image Gallery App: Part 1 Client Image Catalog DB

    Image Store Images Image Gallery API Add tracing for incoming requests
  9. Instrumenting Image Gallery App: Part 1 Image Catalog Incoming Request

    Middleware Application Code Use custom middleware to add tracing HTTP Client for outgoing requests Other Services
  10. Instrumenting Image Gallery App: Part 1 Add tracing to incoming

    requests for services with custom middleware func Middleware(next http.Handler) http.Handler { // requests that go through it. return nethttp.Middleware(opentracing. GlobalTracer (), next, nethttp. OperationNameFunc (func(r *http.Request) string { return "HTTP " + r.Method + " " + r.URL.String() })) }
  11. Instrumenting Image Gallery App: Part 2 Client Image Catalog DB

    Image Store Images Image Gallery API Add tracing for outgoing requests
  12. Instrumenting Image Gallery App: Part 2 Image Catalog Incoming Request

    Middleware Application Code Use custom HTTP transport to add tracing HTTP Client for outgoing requests Other Services
  13. Instrumenting Image Gallery App: Part 2 func (t *tracingTransport )

    RoundTrip (r *http.Request) (*http.Response, error) { ctx := r.Context() span, ctx2 := opentracing. StartSpanFromContext (ctx, "HTTP Request" ) defer span.Finish() r.WithContext (ctx2) carrier := opentracing. HTTPHeadersCarrier (r.Header) span.Tracer().Inject(span.Context(), opentracing.HTTPHeaders, carrier) resp, err := t.transport. RoundTrip(r) span.SetTag(string(ext.HTTPStatusCode), resp.StatusCode) return resp, err } Add tracing to incoming requests for services with custom HTTP transport
  14. Instrumenting Image Gallery App: Part 2 func (t *tracingTransport )

    RoundTrip (r *http.Request) (*http.Response, error) { ctx := r.Context() span, ctx2 := opentracing. StartSpanFromContext (ctx, "HTTP Request" ) defer span.Finish() r.WithContext (ctx2) carrier := opentracing. HTTPHeadersCarrier (r.Header) span.Tracer().Inject(span.Context(), opentracing.HTTPHeaders, carrier) resp, err := t.transport. RoundTrip(r) span.SetTag(string(ext.HTTPStatusCode), resp.StatusCode) return resp, err } Add tracing to incoming requests for services with custom HTTP transport
  15. Instrumenting Image Gallery App: Part 2 func (t *tracingTransport )

    RoundTrip (r *http.Request) (*http.Response, error) { ctx := r.Context() span, ctx2 := opentracing. StartSpanFromContext (ctx, "HTTP Request" ) defer span.Finish() r.WithContext (ctx2) carrier := opentracing. HTTPHeadersCarrier (r.Header) span.Tracer().Inject(span.Context(), opentracing.HTTPHeaders, carrier) resp, err := t.transport. RoundTrip(r) span.SetTag(string(ext.HTTPStatusCode), resp.StatusCode) return resp, err } Add tracing to incoming requests for services with custom HTTP transport
  16. Instrumenting Image Gallery App: Part 2 Now we can see

    that metadata is calling store service
  17. Instrumenting Image Gallery App: Part 2 Now we can see

    that metadata is calling store service
  18. Instrumenting Image Gallery App: Part 3 Client Image Catalog DB

    Image Store Images Image Gallery API Extra tracing in other functions
  19. Instrumenting Image Gallery App: Part 3 Image Catalog Incoming Request

    Middleware Application Code Add extra calls to OpenTracing HTTP Client for outgoing requests Other Services
  20. Instrumenting Image Gallery App: Part 3 Can we reuse the

    same HTTP transport from the last part?
  21. Instrumenting Image Gallery App: Part 3 Can we reuse the

    same HTTP transport from the last part? No, not all APIs have the same interface • K8s API does not take Context object • mgo does not use Go’s HTTP client • Official AWS and GCP GO APIs can use the same trick as part 2
  22. Instrumenting Image Gallery App: Part 3 func (s *Mongo) GetAllImages

    (ctx context.Context) (models.ImageList, error) { span, _ := opentracing. StartSpanFromContext (ctx, "GetAllImages request" ) defer span.Finish() addSpanTags (span) err := s.Ping() if err != nil { return models.ImageList{}, err } c := s.Conn.DB(dbName).C(collName) imgs := models.ImageList{} return imgs, c.Find(nil).All(&imgs) } Add extra code to functions to create OpenTracing spans
  23. Instrumenting Image Gallery App We saw 3 different ways to

    add tracing, which are good for different situations: • Incoming requests -> OpenTracing Middleware • Outgoing requests -> custom HTTP transport • Other parts of application -> manual calls to tracing functions
  24. Recap Today we discussed • Using OpenTracing Go SDK to

    add instrumentation microservices • Instrumenting calls to other services: DB, cloud provider, K8s API • Installing Jaeger tracing collector and UI in k8s cluster • Using Jaeger UI to visualize, analyze and dig into traces
  25. Pffff… my logging is amazing! • Pro: Good for collecting

    detailed information at a single point • Con: Hard to correlate and analyze logs across microservices • Use tracing to get overview and logging to get details in problem areas
  26. I’m getting sms from Nagios! • Pro: Use alerts to

    get automated notifications from your monitoring system • Cons: It shows you only service or 1 call, not a specifics. • When combined with tracing, request-scoped metrics can be avalible
  27. But my service mesh has it?! • Pro: No instrumentation

    or Context propagation required • Con: Only coarse-grained traces like part 1 of instrumenting our application • Can be combined with tracing frameworks for better data
  28. My cloud provider do it for me for “free” Tracing

    solutions from cloud providers: • GoogleCloud Stackdriver Trace • AWS X-Ray • Pro: Almost seamless integration when used in those environments • Con: Most of the time means you locked down to 1 provider
  29. Final Thoughts Tracing can give insights into system bottlenecks, but

    need to balance with time spent adding instrumentation Trade-offs: • Pro: Fine granularity and detailed request information • Con: Additional resource requirements. ◦ Request processing in each of the services, and additional network traffic ◦ Additional processing and storage requirements for the traces
  30. Attributes Go Gophers • https://github.com/ashleymcnamara/gophers/blob/master/LICENSE The Illustrated Children's Guide to

    Kubernetes • https://azure.microsoft.com/en-us/resources/videos/the-illustrated-children- s-guide-to-kubernetes/