Understanding the new Istio Telemetry API
v1.11 버전에 추가된 new Telemetry API를 소개하는 내용
목적: mesh wide수준을 넘어 namespace-scope, workload groups / individual workload 단위의 behavior scope도 지원하기 위해.
Telemetry Generation 으로 3 layer level을 지원함.
- istio service-level (service to service. low-level proxy metric 말고.)
- Tracespan generation / reporting (어디로 보낼지, 무엇을 보낼지)
- Access logging behavior
어떤 필드를 데이터에 넣을 것인지 (Data Content) / 어디로 보낼 것인지 (Destination) Control할 수 있도록 하는 것이 목표.
- 현재는 알파 단계
telemetry 옵션을 설정할 수 있는 방법이 중구난방이었음. coherent Fashion의 필요성
- meshConfig, proxyConfig, 환경변수, envoyFilter...
- 적용할 영역과 flow를 명확히 알아야 했음. Gateway? inbound Http Traffic..?
설정 적용 방법을 일관성 있게 맞추고, Dynamic Configuration을 지원하도록.
- Support Tailoring istio's one-size-fit-most approach.
- 사용자가 원하는 다양한 커스텀 요구사항 (cardinality)을 지원할 수 있도록
- Debug / Support Operations
- 특정 workload에 문제가 생겼으면, 그 workload에만 access log 설정을 활성화한다던가
- rebooting proxy 없이도 설정 변경할 수 있도록.
Config Flow
- Telemetry CR: namespace scope로 생성.
- MeshConfig: Provider Configuration
두 개의 옵션을 토대로 Istiod에서 Right Configuration 정보를 확인한 뒤, 적용할 옵션을 각 workload에 전달한다.
Telemetry API Overview
- 설정을 적용할 리소스를 Namespace 단위로 지정할 수 있음. mesh-wide 적용하려면 istio-system namespace를 쓰면 된다.
- label selector 사용해서 workloads 단위로 세분화해서 지정할 수 있다.
- per domain / per telemetry type 등 필요로 하는 configuration을 하위에 지정하면 됨.
- 예시의 경우 tracing 설정을 zipkins provider에게 전달. Sampling 단위는 10%.
metrics provider를 지정할 수 있다.
- 지금은 meshConfig에서 지원하는 (정의된) provider를 문자열로 입력해야 함. (name: prometheus)
- meshConfig에 default provider 정의된 게 있다면 여기에 굳이 쓰지 않아도 적용됨.
- domain-specific configuration 필드. overrides 하위 항목들이다. tracing에서 정의한 내용과 사뭇 다르다.
- 예시의 경우 every metrics we generate, add a new label 'request_method' by 'reqeust.method' value.
- response code 삭제 -> metrics에서 error code는 신경쓰지 않겠다는 의도
Providers
무슨 목적으로 어떤 데이터를 보내느냐에 따라 provider도 다름. telemetry api에서는 provider 선택 + 연결을 보다 쉽게 설정할 수 있도록 했음.
- metrics를 위해서는 prometheus / stackdriver 라거나
- tracing을 위해서는 zipkins / jaeger 라거나
기존의 Authorization policy에서 적용한 extension provider와 유사한 방식으로 설정할 수 있도록 만들어뒀다. 내부적으로는 동일한 meshConfig API를 사용함.
istio가 제공하는 built-in provider (envoy / prometheus) 가 아니라면, extension provider 정보를 meshConfig에 정의해야 함.
- Unique name / specific type 필요
meshConfig resource에 extension provider를 정의하는 방법.
- zipkins 서비스, port, 그 외 specific attribute를 정의하면 됨.
- istiolog의 경우 envoyFileAccessLog 관련 설정을 Customize함.
provider 정의하는 것 자체엔 제약사항이 없다.
- 중요한 건, 여기 정의하기만 한다고 telemetry가 바로 동작하는 게 아니라는 점.
- 이건 설정을 입력한 거고, attach해야 적용된다.
default provider 설정하기.
default provider 값을 토대로 meshConfig 값을 설정하고, 사용자가 특정 namespace나 mesh-wide 설정을 따로 입력할 경우 override하는 구조.
- override 범위는 telemetry domain type. prometheus 설정을 바꾸고 싶으면 prometheus 관련 필드만 사용자가 정의하면 된다는 뜻. (무관한 jaeger 설정같은 걸 건드릴 필요가 없다)
발표자의 의견: 이게 list 형태로 입력을 받고 Append하는 구조이기 때문에, 입력 서순을 신경써야 한다.
- least specific overrides -> 위쪽에
- most specific matches -> 아래쪽에
Demo
Metric Customize
시연에 사용한 istio 버전: 1.13.3
- istiod / ingressgateway가 설치됨
- httpbin과 sleep pod가 Istio sidecar injected 상태로 running
sleep pod에서 httpbin으로 curl get 요청을 보냄.
httpbin pod의 envoy admin (localhost:15000) 에서 log를 확인해보면 envoy access log가 만들어진 것을 확인할 수 있다.
envoy log을 Customize하기 위한 yaml 예시 파일은 아래와 같다.
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
name: namespace-metrics
namespace: default
spec:
# no selector specified, applied to all workloads in the namespace
metrics:
- providers:
- name: prometheus
- tagOverrides: # 두 개의 custom label을 추가. label의 값은 values에 정의한 해당 필드의 값.
request_method:
value: "request.method"
request_host:
value: "request.host"
telemetry yaml을 적용한 뒤 다시 request를 보내고 Envoy access log를 확인하면
- istio_request_total은 2로 증가했다. 커스텀하기 전 request 1 + 커스텀한 후 request 1이니까 2가 되었음
- request_method___GET___istio_request_total 이라는 metric이 새로 만들어졌고, count가 1로 만들어졌다.
이런 식으로 prometheus에서 Metric 수집하는 이유?
- istio를 설치할 때, default envoy filer가 자동으로 설정된다.
kubectl get envoyfilter -A
: 기본으로 설치된 Envoy filter 리스트 확인kubectl get envoyfilter -n istio-system stats-filter-<istio-version>
특정 filter가 실제로 어떻게 만들어졌는지 확인하는 방법. 예시의 경우 stats-filter- stats-filter의 예시 중 하나인 istio.stats 필터 (wasm filter)
custom metric을 정의하면, filter 관련 정보가 바뀐다. httpbin pod의 istio listener가 어떤 envoyfilter를 추가했는지 확인하기 위해 아래 명령어를 수행한다.
istioctl proxyconfig listeners deploy/httpbin -o json | less
- filterChain에 적용된 필터가 두 개인 것을 확인할 수 있다. istio.stats
따라서 이렇게 커스텀을 수행할 경우, istio로 설치한 기본 envoyfiler를 지워야 double metric 상황을 방지할 수 있다.
삭제한 뒤 istio proxyconfig 정보를 확인해보면, istio.stats라는 이름의 필터는 하나만 생성된 걸 볼 수 있다.
- configurations 항목의 values를 보면, telemetry CR에서 커스텀한 필드가 들어가 있다.
metric이 어떻게 생성되는지 확인하기 위해 다시 httpbin에 curl 요청을 보내고, envoy admin으로 로그를 확인해보면 아래와 같이 나온다.
- istio_request_total은 istio에서 기본으로 설치된 envoyfilter가 수집하는 metric. filter를 삭제했으므로 request_total 값이 2로, 증가하지 않았다.
- request_method___GET___istio_request_total 필드의 counter는 1 증가했다.
metric 이름이 request_method___GET___ 처럼 기괴해진 이유는
- Wasm filter가 돌아가는 Envoy에서 new filter를 생성할 경우 boostrap configuration을 반드시 수정해야 함. + 커스텀한 Label이 regex match 통과하는지 검증이 필요함.
- 요건 coming release에서 보완해야 할 점 중 하나다.
- httpbin.yaml에서 annotation을 커스텀한 예시
- annotation에 sidecar.istio.io/extraStatTags: request_method 라는 key-value 추가함.
커스텀한 httpbin을 배포하고, curl 요청을 보낸 뒤 envoy admin으로 로그를 확인한 결과는 아래와 같다.
- pod가 새로 떴으므로, istio proxy가 저장하고 있던 로그는 삭제된다.
- 수집된 로그에 request_method:"GET" 이라는 필드가 추가됐다.
- istio에서 request_host 라는 필드는 내장되어 있으므로 별다른 annotation 설정 없이도 수집이 되지만, request_method는 Istio 기본 metric에 정의되어 있지 않으므로 Annotation을 추가해줬다고 함.
따라서, 만약 customizing label을 적용한 metric 수집을 하고 싶다면
- disable installing default envoy filter. 설치할 때 환경변수로 disable 설정할 수 있다고 함.
- 특정 필드를 추가하려면, statsTag attribute가 있어야 한다. 정황상 httpbin pod에서 설정한 annotation을 의미하는 듯.
Customizing Access log
Metric Customizing과는 다른 환경, 다른 발표자가 진행함.
access log service를 meshConfig에 등록한 모습.
default 설정은 위와 같이 구성한다.
- response code가 400 이상인 경우에만 로그 기록
envoy-als 로그를 확인해보면, 두 개의 로그가 확인됨.
- Client side (sleep pod) 에서의 로그
- Server side (httpbin pod) 에서의 로그
여기서 httpbin 서비스에 문제가 생겨서 응답이 좋지 않다고 가정해보자. 예컨대 특정 header가 들어오면 응답이 이상한 상황
- Cloud provider에 쌓이는 거 말고, 내 local에서도 에러 로그를 확인할 수 있어야 함.
- default filter 옵션에 아래 값을 override
- expression으로 response code 400 + request에 특정 header (x-log) 가 있을 경우 로그 기록
- provider로 builtin 서비스인 envoy 추가.
- envoy local logger를 의미함.
cf. 시연 영상에서는 Warning : multiple providers is not currently supported 에러가 뜨는데, 이제는 지원된다고 함. 버전 몇부터 정확히 되는 건지는 확인 필요함.
변경한 옵션을 적용하고 아래 명령어를 수행한 결과는 다음과 같다.
kubectl exec deploy/sleep -- curl httpbin:8000/status/200 -H "x-log:1 " -s -o /dev/null
Envoy local에서 로그가 확인된다. or 조건으로 filter를 걸어뒀으므로, response code가 200이어도 x-log 라는 header가 있으므로 envoy local에 기록됨.
envoy als에는 200 로그가 찍히지 않는다. 즉 mesh-default 설정은 건드리지 않은 채 특정 조건만 추가해서 커스텀이 가능함.