왜?
- 기존에는 CPU, Memory기반에 HPA를 적용했었는데, presto에서 Memory 사용은 테이블 사용후에 반환되지가 않아서 계속 높고, CPU는 많이 필요로 하지 않는지 thresh-hold를 30%로 해도 query가 들어올때 잠시 늘어났다가 0%로 돌아가기 때문에 scale-out 되었다고 해도 다시 minimum resource로 돌아가기 때문에, 실제로 많이 사용하는 시간에도 scale-out된 효과를 보기가 어려워서 다른 적당한 metrics를 찾는 과정에서 custom metrics를 이용한 HPA를 찾아보게 되었습니다.
- 결론적으로는 HPA보다 Schuduler를 사용해, 시간대별로 resource를 지정하는 방식을 적용하기는 했지만 custom metrics수집에 대해서 적용해볼수 있는 시간이 되었습니다.
custom metrics란?
- 기존 HPA에서 metrics type : Resource(CPU, Memory) 를 제외한 user가 생성한 metrics
- kubernetes API 는 custom과 external이 있는데 지금은 custom metrics만 다루기로 하겠습니다.
- 참조
- custom metrics : https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/custom-metrics-api.md
- external metrics https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/external-metrics-api.md
- https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/
Presto 의 monitoring정보를 kubernetes의 custom metrics에 전달하려면?
- kubernetes custom metrics hpa 로 검색하면 여러가지가 나오는데,
- https://cloud.google.com/kubernetes-engine/docs/tutorials/custom-metrics-autoscaling?hl=ko 에 나오는 stackDriver 는 GCP에 제공하는 solution으로 AWS에서는 적용이 어려울듯 합니다.
- https://www.ibm.com/support/knowledgecenter/ko/SSBS6K_2.1.0.3/manage_cluster/hpa.html 등에서 많이 다루고 있는 prometheus 로 수집된 정보를 custom metrics로 사용하는 방식으로 이 방법을 통해서 custom metrics를 통한 HPA를 개발해보도록 하겠습니다.
Presto 에서의 prometheus
- presto는 prometheus를 바로 제공하지는 않지만, presto와 같이 JVM을 사용하는 solution들은 /v1/JMX를 제공(presto-server/v1/JMX) 하고 있고 JMX를 prometheus로 형태로 제공하는 library(jmx-exporter)가 있어 해당 방법을 사용하도록 하겠습니다.
- 이번 단락에서는 Prometheus에서 presto의 metrics를 확인할수 있는 단계까지 다루도록 하겠습니다.
- presto docker image에 해당library추가하고, 사용할 presto를 새로 build합니다.
- 사용된 project : https://github.com/prometheus/jmx_exporter
- presto Dockerfile
RUN ..기존내용\
yum -y -q install wget && \
RUN wget https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.12.0/jmx_prometheus_javaagent-0.12.0.jar -P /usr/lib/presto/
- presto coordinator에서 사용할 jvm관련 및 jmx_exporter관련한 configMap을 생성하도록 하겠습니다.
- presto coordinator 서버를 위한 configMap에서 jvm.config에는 jmx-exporter 를 추가하고, jmx-export에서 활용할 설정파일명은 presto.yml로 정하고 어떤 metrics를 prometheus로 보내서 수집할것인지에 대해 설정합니다.
- presto.yml - 어떤 JMX metrics를 presto로 변환할지에 대한 설정입니다. 어떤 metrics를 수집할지에 대해서는 https://github.com/prestodb/presto/wiki/Monitoring 등을 참조를 했으며, QueryManager(최근1/5/15분 쿼리실행수 등), ClusterMemoryPool(AssignedQueries, FreeDistributedBytes, Nodes, ReservedDistributedBytes, TotalDistributedBytes 등), ClusterMemoryManager(ClusterMemoryBytes, ClusterTotalMemoryReservation, TotalAvailableProcessors 등) 정보를 수집하기로 하고 다음과 같이 설정파일을 만들었습니다.
- jvm.config - java jvm 관련 option이며 jmx-expoter library 사용하기 위한 설정을 추가합니다. 8081 port로 prometheus metrics service됨 (8080으로 하면 좋은데 기존 presto port와 충돌이 납니다)
- kubernetes configMap for presto coordinator
presto.yml: | rules: - pattern: "presto.memory<name=ClusterMemoryManager><>(.+): (.*)" name: "presto_clustermemorymanager_$1" help: "Presto: ClusterMemoryManager $1" type: GAUGE - pattern: "presto.memory<type=ClusterMemoryPool, name=(.*)><>(.+): (.*)" name: "presto_clustermemorypool_$1_$2" help: "Presto ClusterMemoryPool: $1 $2" type: GAUGE - pattern: "presto.execution<name=QueryManager><>(.+): (.*)" name: "presto_execution_querymanager_$1" help: "Presto Execution QueryManager: $1" type: GAUGE jvm.config: | ... -javaagent:/usr/lib/presto/jmx_prometheus_javaagent-0.12.0.jar=8081:/usr/lib/presto/etc/presto.yml
- prometheus 수집을 위한 설정
- prometheus가 presto의 metrics를 읽을수 있도록 설정해야하는데, 다른 문서에서는 이부분이 당연히 안다고 생각하는지 빠져있는 경우가 있습니다. 본인의 경우 helm을 통해서 prometheus를 설치했지만 설정은 어떻게 설치해도 비슷할것이라고 생각은 하고 helm 설치의 경우 관련한 chart에서 내용을 확인할수 있습니다. https://github.com/helm/charts/blob/master/stable/prometheus/values.yaml
- values.yaml에서 다음과 같은 내용이 있는데,
# Example scrape config for pods # # The relabeling allows the actual pod scrape endpoint to be configured via the # following annotations: # # * `prometheus.io/scrape`: Only scrape pods that have a value of `true` # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. # * `prometheus.io/port`: Scrape the pod on the indicated port instead of the default of `9102`.
- prometheus에서 pod를 모니터링해서 metrics를 수집하게 하기위해서는 pod annotation에 prometheus.io/scrape=true 와 추가적인 설정을 추가해야함을 알수 있습니다.
-
annotations: prometheus.io/scrape: "true" prometheus.io/port: "8081"
- presto coordinator pod에 annotation을 설정하게 되면 prometheus 관리화면에서 확인이 가능합니다.
- Status > Service Discovery 메뉴에서 annotation이 추가되면 kubernetes-pods의 active targets가 변하는걸 확인할 수 있고, 아래 "show more" 버튼으로 presto-coordinator 가 추가된것도 볼수 있습니다.
설정부분이 너무 길어져서 HPA적용은 다음 글에서 다루도록 하겠습니다. - kubernetes에서 presto 의 custom value HPA(Horizontal Pod Autoscaler) 2/2 - 적용