분산 트레이싱

분산 트레이싱 (Distributed Tracing)

분산 트레이싱은 마이크로서비스 전반에서 요청을 추적하고 연관시키는 방법이에요. Consul은 각 애플리케이션에서 먼저 트레이싱이 구현되어야 하며, 구현된 후 사이드카 프록시를 요청 경로의 스팬(span)으로 추가해요. 이 문서에서 트레이싱 구성 방법과 고려 사항을 설명할게요.

출처: 문서

본문

분산 트레이싱은 마이크로서비스 전반에서 요청을 추적하고 연관시키는 방법입니다. 분산 트레이싱은 먼저 각 애플리케이션에서 구현되어야 하며, Consul이 추가할 수 없습니다. 애플리케이션에서 구현되면 Consul에 분산 트레이싱을 추가하면 사이드카 프록시가 요청 경로의 스팬으로 추가됩니다.

애플리케이션 변경 (Application Changes)

Consul 단독으로는 애플리케이션에 분산 트레이싱을 구현할 수 없습니다. 각 애플리케이션은 필요한 헤더를 전파해야 합니다. 일반적으로 다음과 같은 트레이싱 라이브러리를 사용해 수행합니다:

구성 (Configuration)

애플리케이션이 트레이싱 라이브러리로 계측되면 트레이스에 사이드카 프록시 스팬을 추가하도록 Consul을 구성할 준비가 됩니다. 최종 구성은 다음과 비슷할 것입니다:

HCL

Kubernetes YAML

JSON

Kind = "proxy-defaults"
Name = "global"
Config {
  protocol           = "http"
  envoy_tracing_json = <<EOF
{
  "http":{
    "name":"envoy.tracers.zipkin",
    "typedConfig":{
      "@type":"type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
      "collector_cluster":"collector_cluster_name",
      "collector_endpoint_version":"HTTP_JSON",
      "collector_endpoint":"/api/v2/spans",
      "shared_span_context":false
    }
  }
}
EOF

  envoy_extra_static_clusters_json = <<EOF
{
  "connect_timeout":"3.000s",
  "dns_lookup_family":"V4_ONLY",
  "lb_policy":"ROUND_ROBIN",
  "load_assignment":{
    "cluster_name":"collector_cluster_name",
    "endpoints":[
      {
        "lb_endpoints":[
          {
            "endpoint":{
              "address":{
                "socket_address":{
                  "address":"collector-url",
                  "port_value":9411,
                  "protocol":"TCP"
                }
              }
            }
          }
        ]
      }
    ]
  },
  "name":"collector_cluster_name",
  "type":"STRICT_DNS"
}
EOF
}
apiVersion: consul.hashicorp.com/v1alpha1
kind: ProxyDefaults
metadata:
  name: global
spec:
  config:
    protocol: http
    envoy_tracing_json: |
      {
        "http":{
          "name":"envoy.tracers.zipkin",
          "typedConfig":{
            "@type":"type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
            "collector_cluster":"collector_cluster_name",
            "collector_endpoint_version":"HTTP_JSON",
            "collector_endpoint":"/api/v2/spans",
            "shared_span_context":false
          }
        }
      }
    envoy_extra_static_clusters_json: |
      {
        "connect_timeout":"3.000s",
        "dns_lookup_family":"V4_ONLY",
        "lb_policy":"ROUND_ROBIN",
        "load_assignment":{
          "cluster_name":"collector_cluster_name",
          "endpoints":[
            {
              "lb_endpoints":[
                {
                  "endpoint":{
                    "address":{
                      "socket_address":{
                        "address":"collector-url",
                        "port_value":9411,
                        "protocol":"TCP"
                      }
                    }
                  }
                }
              ]
            }
          ]
        },
        "name":"collector_cluster_name",
        "type":"STRICT_DNS"
      }
{
  "Kind": "ProxyDefaults",
  "Name": "global",
  "Config": {
    "protocol": "http",
    "envoy_tracing_json": "{\"http\":{\"name\":\"envoy.tracers.zipkin\",\"typedConfig\":{\"@type\":\"type.googleapis.com/envoy.config.trace.v3.ZipkinConfig\",\"collector_cluster\":\"collector_cluster_name\",\"collector_endpoint_version\":\"HTTP_JSON\",\"collector_endpoint\":\"/api/v2/spans\",\"shared_span_context\":false}}}",
    "envoy_extra_static_clusters_json": "{\"connect_timeout\":\"3.000s\",\"dns_lookup_family\":\"V4_ONLY\",\"lb_policy\":\"ROUND_ROBIN\",\"load_assignment\":{\"cluster_name\":\"collector_cluster_name\",\"endpoints\":[{\"lb_endpoints\":[{\"endpoint\":{\"address\":{\"socket_address\":{\"address\":\"collector-url\",\"port_value\":9411,\"protocol\":\"TCP\"}}}}]}]},\"name\":\"collector_cluster_name\",\"type\":\"STRICT_DNS\"}"
  }
}

참고: 이 예제는 모든 프록시에 적용되는 proxy defaults 구성 항목을 사용하지만, 서비스 구성의 proxy 블록에 구성을 적용할 수도 있습니다. 프록시 서비스 등록은 Kubernetes에서는 지원되지 않습니다.

구성에는 사용자 지정해야 하는 두 개의 키가 있습니다:

  1. envoy_tracing_json: 특정 트레이싱 유형에 대한 트레이싱 구성을 설정합니다. 특정 컬렉터의 구성은 Envoy tracer 문서를 참조하세요. 이 구성은 envoy_extra_static_clusters_json에 정의된 클러스터 이름을 참조합니다.
  2. envoy_extra_static_clusters_json: Envoy가 스팬을 보낼 트레이싱 컬렉터의 주소를 정의합니다. 이 예제에서 URL은 collector-url:9411입니다.

구성 적용 (Applying the configuration)

이 구성은 Envoy의 bootstrap 구성(시작 시에만 적용 가능)을 변경하므로 프록시가 재시작 될 때만 적용됩니다. 즉, 이 구성의 변경 사항을 적용하려면 모든 프록시를 재시작해야 합니다.

참고: Kubernetes에서는 배포를 재시작하는 문제입니다(예: kubectl rollout restart deploy/deploy-name).

고려 사항 (Considerations)

  1. 분산 트레이싱은 HTTP와 gRPC 서비스에서만 지원됩니다. 프로토콜을 전역적으로(proxy defaults 구성 항목을 통해) 지정해야 합니다:

    HCL

    Kubernetes YAML

    JSON

    Kind      = "proxy-defaults"
    Name      = "global"
    Config {
      protocol = "http"
    }
    
    apiVersion: consul.hashicorp.com/v1alpha1
    kind: ProxyDefaults
    metadata:
      name: global
    spec:
      config:
        protocol: http
    
    {
      "Kind": "proxy-defaults",
      "Name": "global",
      "Config": {
        "protocol": "http"
      }
    }
    

    또는 각 서비스에 대해 service defaults 구성 항목으로 지정합니다:

    HCL

    Kubernetes YAML

    JSON

    Kind      = "service-defaults"
    Name      = "service-name"
    Protocol  = "http"
    
    apiVersion: consul.hashicorp.com/v1alpha1
    kind: ServiceDefaults
    metadata:
      name: service-name
    spec:
      protocol: http
    
    {
      "Kind": "service-defaults",
      "Name": "service-name",
      "Protocol": "http"
    }
    
  2. 인그레스 게이트웨이를 통한 요청은 x-client-trace-id: 1 헤더가 설정되지 않으면 추적되지 않습니다(hashicorp/consul#6645 참조).

  3. Consul의 프록시는 현재 OpenTelemetry 스팬을 지원하지 않습니다. Envoy가 완전히 구현하지 않았기 때문입니다. 대신 애플리케이션에 OpenTelemetry 라이브러리를 추가해 Envoy가 지원하는 다른 트레이싱 프로토콜(예: Zipkin 또는 Jaeger)에 대한 스팬을 방출할 수 있습니다.

  4. 트레이싱은 Envoy 프록시에서만 지원되며 내장(built-in) 프록시에서는 지원되지 않습니다.

  5. envoy_tracing_json에서 Zipkin tracer를 구성할 때 애플리케이션이 128비트 트레이스 ID를 생성하도록 구성된 경우 trace_id_128bit를 true로 설정하세요. 예를 들어:

    {
      "http": {
        "name": "envoy.tracers.zipkin",
        "typedConfig": {
          "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
          "collector_cluster": "zipkin",
          "collector_endpoint_version": "HTTP_JSON",
          "collector_endpoint": "/api/v2/spans",
          "shared_span_context": false,
          "trace_id_128bit": true
        }
      }
    }
    

더 알아보기 (Learn more)