OpenTelemetry

OpenTelemetry (OpenTelemetry)

이 작업은 OpenTelemetry 수집기로 액세스 로그를 보내도록 Envoy 프록시를 구성하는 방법을 보여드려요. 프록시가 OpenTelemetry 형식으로 액세스 로그를 내보내도록 설정할 수 있어요.

출처: Istio 문서

본문

Envoy 프록시를 구성해서 액세스 로그를 OpenTelemetry 형식으로 내보낼 수 있어요. 이 예시에서는 프록시가 OpenTelemetry 수집기로 액세스 로그를 보내고, 수집기가 로그를 표준 출력으로 출력하도록 구성돼요. 그러면 kubectl logs 명령으로 OpenTelemetry 수집기의 표준 출력에 접근할 수 있어요.

시작하기 전에 (Before you begin)

  • 설치 가이드의 지침을 따라 Istio를 설정하세요.

[!note] demo 구성 프로필을 설치하면 egress 게이트웨이와 액세스 로깅이 활성화돼요.

  • 요청을 보낼 테스트 소스로 사용할 curl 샘플 앱을 배포하세요. 자동 사이드카 주입이 활성화되어 있으면 다음 명령으로 샘플 앱을 배포하세요.
$ kubectl apply -f @samples/curl/curl.yaml@

그렇지 않으면 curl 애플리케이션을 배포하기 전에 다음 명령으로 사이드카를 수동으로 주입하세요.

$ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@)

[!note] curl이 설치된 어떤 파드라도 테스트 소스로 사용할 수 있어요.

  • SOURCE_POD 환경 변수를 소스 파드의 이름으로 설정하세요.
$ export SOURCE_POD=$(kubectl get pod -l app=curl -o jsonpath={.items..metadata.name})
  • httpbin 샘플을 시작하세요. 자동 사이드카 주입이 활성화되어 있으면 httpbin 서비스를 배포하세요.
$ kubectl apply -f @samples/httpbin/httpbin.yaml@

그렇지 않으면 httpbin 애플리케이션을 배포하기 전에 사이드카를 수동으로 주입해야 해요.

$ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@)

OpenTelemetry 수집기용 네임스페이스를 만드세요.

$ kubectl create namespace observability

OpenTelemetry 수집기를 배포하세요. 다음 예시 구성을 시작점으로 사용할 수 있어요.

$ kubectl apply -f @samples/open-telemetry/otel.yaml@ -n observability

Envoy 액세스 로그 활성화하기 (Enable Envoy's access logging)

액세스 로깅을 활성화하려면 Telemetry API를 사용하세요. MeshConfig를 편집해서 otel이라는 이름의 OpenTelemetry 프로바이더를 추가하세요. 여기에는 확장 프로바이더 스탠자를 추가하는 작업이 포함돼요.

extensionProviders:
- name: otel
  envoyOtelAls:
    service: opentelemetry-collector.observability.svc.cluster.local
    port: 4317

최종 구성은 대략 다음과 같아야 해요.

apiVersion: v1
kind: ConfigMap
metadata:
  name: istio
  namespace: istio-system
data:
  mesh: |-
    accessLogFile: /dev/stdout
    defaultConfig:
      discoveryAddress: istiod.istio-system.svc:15012
      proxyMetadata: {}
      tracing:
        zipkin:
          address: zipkin.istio-system:9411
    enablePrometheusMerge: true
    extensionProviders:
    - name: otel
      envoyOtelAls:
        service: opentelemetry-collector.observability.svc.cluster.local
        port: 4317
    rootNamespace: istio-system
    trustDomain: cluster.local
  meshNetworks: 'networks: {}'

다음으로, Istio가 액세스 로그를 OpenTelemetry 수집기로 보내도록 지시하는 Telemetry 리소스를 추가하세요.

$ cat <<EOF | kubectl apply -n default -f -
apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
  name: curl-logging
spec:
  selector:
    matchLabels:
      app: curl
  accessLogging:
    - providers:
      - name: otel
EOF

위 예시는 otel 액세스 로그 프로바이더를 사용하며, 기본 설정 외에 아무것도 구성하지 않아요. 비슷한 구성을 개별 네임스페이스나 개별 워크로드에 적용해서 더 세밀한 수준으로 로깅을 제어할 수도 있어요. Telemetry API 사용에 대한 자세한 내용은 Telemetry API 개요를 참고하세요.

Mesh Config 사용하기

IstioOperator 구성을 사용해서 Istio를 설치했다면, 구성에 다음 필드를 추가하세요.

spec:
  meshConfig:
    accessLogFile: /dev/stdout
    extensionProviders:
    - name: otel
      envoyOtelAls:
        service: opentelemetry-collector.observability.svc.cluster.local
        port: 4317
    defaultProviders:
      accessLogging:
      - envoy
      - otel

그렇지 않으면 원래 istioctl install 명령에 동등한 설정을 추가하세요. 예를 들어:

$ istioctl install -f <your-istio-operator-config-file>

기본 액세스 로그 형식 (Default access log format)

accessLogFormat이 지정되지 않은 경우 Istio는 다음 기본 액세스 로그 형식을 사용해요.

[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" %RESPONSE_CODE% %RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS% %CONNECTION_TERMINATION_DETAILS%
\"%UPSTREAM_TRANSPORT_FAILURE_REASON%\" %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% \"%REQ(X-FORWARDED-FOR)%\" \"%REQ(USER-AGENT)%\" \"%REQ(X-REQUEST-ID)%\"
\"%REQ(:AUTHORITY)%\" \"%UPSTREAM_HOST%\" %UPSTREAM_CLUSTER% %UPSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_REMOTE_ADDRESS% %REQUESTED_SERVER_NAME% %ROUTE_NAME%\n

다음 표는 curl에서 httpbin으로 보낸 요청에 기본 액세스 로그 형식을 사용한 예시를 보여줘요. | Log operator | access log in curl | access log in httpbin | | [%START_TIME%] | [2020-11-25T21:26:18.409Z] | [2020-11-25T21:26:18.409Z] | | \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" | "GET /status/418 HTTP/1.1" | "GET /status/418 HTTP/1.1" | | %RESPONSE_CODE% | 418 | 418 | | %RESPONSE_FLAGS% | - | - | | %RESPONSE_CODE_DETAILS% | via_upstream | via_upstream | | %CONNECTION_TERMINATION_DETAILS% | - | - | | \"%UPSTREAM_TRANSPORT_FAILURE_REASON%\" | "-" | "-" | | %BYTES_RECEIVED% | 0 | 0 | | %BYTES_SENT% | 135 | 135 | | %DURATION% | 4 | 3 | | %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% | 4 | 1 | | \"%REQ(X-FORWARDED-FOR)%\" | "-" | "-" | | \"%REQ(USER-AGENT)%\" | "curl/7.73.0-DEV" | "curl/7.73.0-DEV" | | \"%REQ(X-REQUEST-ID)%\" | "84961386-6d84-929d-98bd-c5aee93b5c88" | "84961386-6d84-929d-98bd-c5aee93b5c88" | | \"%REQ(:AUTHORITY)%\" | "httpbin:8000" | "httpbin:8000" | | \"%UPSTREAM_HOST%\" | "10.44.1.27:80" | "127.0.0.1:80" | | %UPSTREAM_CLUSTER% | outbound|8000||httpbin.foo.svc.cluster.local | inbound|8000|| | | %UPSTREAM_LOCAL_ADDRESS% | 10.44.1.23:37652 | 127.0.0.1:41854 | | %DOWNSTREAM_LOCAL_ADDRESS% | 10.0.45.184:8000 | 10.44.1.27:80 | | %DOWNSTREAM_REMOTE_ADDRESS% | 10.44.1.23:46520 | 10.44.1.23:37652 | | %REQUESTED_SERVER_NAME% | - | outbound_.8000_._.httpbin.foo.svc.cluster.local | | %ROUTE_NAME% | default | default |

액세스 로그 테스트 (Test the access log)

  1. curl에서 httpbin으로 요청을 보내세요.
$ kubectl exec "$SOURCE_POD" -c curl -- curl -sS -v httpbin:8000/status/418
...
< HTTP/1.1 418 Unknown
...
< server: envoy
...
I'm a teapot!
...
  1. otel-collector의 로그를 확인하세요.
$ kubectl logs -l app=opentelemetry-collector -n observability
[2020-11-25T21:26:18.409Z] "GET /status/418 HTTP/1.1" 418 - via_upstream - "-" 0 135 3 1 "-" "curl/7.73.0-DEV" "84961386-6d84-929d-98bd-c5aee93b5c88" "httpbin:8000" "127.0.0.1:80" inbound|8000|| 127.0.0.1:41854 10.44.1.27:80 10.44.1.23:37652 outbound_.8000_._.httpbin.foo.svc.cluster.local default

요청에 해당하는 메시지가 소스와 대상의 Istio 프록시 로그(각각 curl과 httpbin)에 모두 나타나는 것을 확인할 수 있어요. 로그에서 HTTP 동사(GET), HTTP 경로(/status/418), 응답 코드(418) 및 기타 요청 관련 정보를 볼 수 있어요.

정리 (Cleanup)

curl과 httpbin 서비스를 종료하세요.

$ kubectl delete telemetry curl-logging
$ kubectl delete -f @samples/curl/curl.yaml@
$ kubectl delete -f @samples/httpbin/httpbin.yaml@
$ kubectl delete -f @samples/open-telemetry/otel.yaml@ -n istio-system
$ kubectl delete namespace observability

Envoy 액세스 로그 비활성화하기

Istio 설치 구성에서 meshConfig.extensionProviders와 meshConfig.defaultProviders 설정을 제거하거나 ""로 설정하세요.

[!note] 아래 예시에서 default는 Istio 설치 시 사용한 프로필 이름으로 바꾸세요.

$ istioctl install --set profile=default
✔ Istio core installed
✔ Istiod installed
✔ Ingress gateways installed
✔ Installation complete

더 알아보기 (Learn more)

  • Telemetry API 개요에서 액세스 로그 프로바이더를 구성하는 방법을 더 알아보세요.
  • OpenTelemetry 프로토콜과 수집기 설정에 대해서는 OpenTelemetry 공식 문서를 참고하세요.