블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 


쿠버네티스 #15

모니터링 3/3 구글 스택드라이버를 이용한 모니터링

조대협 (http://bcho.tistory.com)



구글 클라우드 쿠버네티스 스택드라이버 모니터링

쿠버네티스 모니터링 시스템을 구축하는 다른 방법으로는 클라우드 서비스를 사용하는 방법이 있다. 그중에서 구글 클라우드에서 제공하는 스택 드라이버 쿠버네티스 모니터링에 대해서 소개하고자한다.

https://cloud.google.com/monitoring/kubernetes-engine/


현재는 베타 상태로, 구글 클라우드 쿠버네티스 서비스 (GKE)에서만 지원이 되며, 쿠버네티스 버전 1.10.2 와 1.11.0 (또는 그 상위버전)에서만 지원이 되고, 모니터링 뿐 아니라, 쿠버네티스 서비스에 대한 로깅을 스택드라이버 로깅 서비스를 이용해서 함께 제공한다.


스택드라이버 쿠버네티스 모니터링을 설정하는 방법은 간단하다. 쿠버네티스 클러스터를 설정할때, 아래 그림과 같이 Additional features 항목에서 “Try the new Stackdriver beta monitoring and Logging experience” 항목을 체크하면 된다.



클러스터를 생성한 후에, 구글 클라우드 콘솔에서 Monitoring 메뉴를 선택한 후에



스택드라이버 메뉴에서 Resources 메뉴에서 아래 그림과 같이 Kubernetes 메뉴를 선택하면 쿠버네티스 모니터링 내용을 볼 수 있다.



모니터링 구조

스택드라이버 쿠버네티스 모니터링의 가장 큰 장점 중의 하나는 단순한 단일 뷰를 통해서 대부분의 리소스 모니터링 과 이벤트에 대한 모니터링이 가능하다는 것이다.

아래 그림이 스택드라이버 모니터링 화면인데, “2”라고 표시된 부분이 시간에 따른 이벤트이다. 장애등이 발생하였을 경우 아래 그림과 같이 붉은 색으로 표현되고, 3 부분을 보면, 여러가지 뷰 (계층 구조)로 각 자원들을 모니터링할 수 있다. 장애가 난 부분이 붉은 색으로 표시되는 것을 확인할 수 있다.



<출처 : https://cloud.google.com/monitoring/kubernetes-engine/observing >


Timeline에 Incident가 붉은 색으로 표시된 경우 상세 정보를 볼 수 있는데, Timeline에서 붉은 색으로 표시된 부분을 누르면 아래 그림과 같이 디테일 이벤트 카드가 나온다. 이 카드를 통해서 메모리,CPU 등 이벤트에 대한 상세 내용을 확인할 수 있다.



<출처 : https://cloud.google.com/monitoring/kubernetes-engine/observing >


반대로 정상적인 경우에는 아래 그림과 같이 이벤트 부분에 아무것도 나타나지 않고, 모든 자원이 녹색 동그라미로 표시되어 있는 것을 확인할 수 있다.


개념 구조

쿠버네티스 모니터링중에 어려운 점중의 하나는 어떤 계층 구조로 자원을 모니터링 하는가 인데, 이런점을 해결하기 위해서 구글 스택드라이버 쿠버네티스 모니터링은 3가지 계층 구조에 따른 모니터링을 지원한다. 모니터링 화면을 보면 아래와 같이 Infrastructure, Workloads, Services 와 같이 세가지 탭이 나오는 것을 볼 수 있다.



어떤 관점에서 클러스터링을 모니터링할것인가인데,

  • Infrastructure : 하드웨어 자원 즉, node를 기준으로 하는 뷰로,  Cluster > Node > Pod > Container 의 계층 구조로 모니터링을 제공한다.

  • Workloads : 워크로드, 즉 Deployment를 중심으로 하는 뷰로 Cluster > Namespace > Workload (Deployment) > Pod > Container 순서의 계층 구조로 모니터링을 제공한다.

  • Services : 애플리케이션 즉 Service 를 중심으로 하는 뷰로 Cluster > Namespace > Service > Pod > Container 계층 순서로 뷰를 제공한다.

Alert 에 대한 상세 정보

각 계층 뷰에서 리소스가 문제가 있을 경우에는 앞의 동그라미가 붉은색으로 표시가 되는데,  해당 버튼을 누르게 되면, Alert 에 대한 상세 정보 카드가 떠서, 아래 그림과 같이 이벤트에 대한 상세 정보를 확인할 수 있다.


<출처 : https://cloud.google.com/monitoring/kubernetes-engine/observing >

결론

지금까지 간단하게 쿠버네티스에 대한 모니터링과 로깅에 대해서 알아보았다. 프로메테우스나 그라파나와 같은 최신 기술을 써서 멋진 대쉬 보드를 만드는 것도 중요하지만 모니터링과 로깅은 시스템을 안정적으로 운영하고 장애전에 그 전조를 파악해서 대응하고, 장애 발생시에는 해결과 향후 예방을 위한 분석 및 개선 활동이 일어나야 한다. 이를 위해서 모니터링과 로깅은 어디까지나 도구일 뿐이고, 어떤 지표를 모니터링 할것인지 (SLI : Service Level Indicator), 지표의 어느값까지를 시스템 운영의 목표로 삼을 것인지 (SLO : Service Level Object)를 정하는 프렉틱스 관점이 더 중요하다.  이를 구글에서는 SRE (Site Reliability Engineering)이라고 하는데, 이에 대한 자세한 내용은 https://landing.google.com/sre/book.html 를 참고하기 바란다.

이런 프렉틱스를 구축하는데 목적을 두고, 모니터링을 위한 툴링등은 직접 구축하는 것보다는 클라우드에서 제공하는 스택 드라이버와 같은 솔루션이나 데이타독(Datadog)와 같은 전문화된 모니터링 툴로 구축을 해서 시간을 줄이고, 프렉틱스 자체에 시간과 인력을 더 투자하는 것을 권장한다.




쿠버네티스 #14

모니터링 2/3 Prometheus를 이용한 모니터링


조대협 (http://bcho.tistory.com)

프로메테우스

그동안 주요 모니터링 솔루션으로 사용되던 힙스터는 1.13 버전 이후로 deprecated 될 예정이고, 그 이후를 맏을 모니터링 솔루션으로 가장 많이 언급되는 모니터링 솔루션은 프로메테우스 (Prometheus)이다.


프로메테우스는 SoundCloud (http://soundcloud.com/)에서 개발된 모니터링 툴로, 2016년에 CNCF  (Cloud Native Computing Foundation)에 오픈소스 프로젝트로 기부되었다. 지표 수집을 통한 모니터링을 주요 기능으로 하고 있다.


쿠버네티스 모니터링뿐만 아니라 애플리케이션이나 서버, OS 등 다양한 대상으로 부터 지표를 수집하여 모니터링할 수 있는 범용 솔루션으로, 아래와 같은 구조를 가지고 있다.



<그림. 프로메테우스 모니터링 아키텍처>

데이타 수집 부분

기본적으로, 프로메테우스는 데이타 수집을 PULLING 모델을 사용한다. 모니터링 대상이 되는 자원이 지표 정보를 프로메테우스로 보내는 것이 아니라, 프로메테우스가 주기적으로 모니터링 대상에서 지표를 읽어 오는 모델을 사용한다.


모니터링 대상이 프로메테우스의 데이타 포맷을 지원할 경우 바로 읽어올 수 있고, 만약에 지원하지 않는다면 별도의 에이전트를 설치해서 지표를 읽어올 수 있는데, 이를 exporter라고 한다. exporter는 mysql,nginx,redis와 같은 패키지는 미리 개발된 export가 있어서 다양한 서비스의 지표까지 쉽게 읽어올 수 있다.

이런 패키지 애플리케이션이 아니라, java 나 node.js와 같은 사용자 애플리케이션의 경우에는 Exporter를 사용하는 방법 말고도, 프로메테우스 클라이언트 라이브러리를 사용하게 되면, 바로 지표를 프로메테우스 서버로 보낼 수 있다.

마지막으로, Push gateway를 사용하는 방법이 있는데, 배치나 스케쥴 작업 같은 서비스의 경우에는 항상 서비스가 떠 있는 것이 아니라, 필요한 경우에만 떠 있다가 작업이 끝나면 사라지는 경우가 있다. 그래서, 이런 서비스를 Pulling으로 지표를 얻어오기가 어려울 수 있는데, 이를 보완하기 위해서, 이런 서비스들이 Push 방식으로 Push gateway에 지표를 쏴주면, Push gateway가 지표를 보관하고 있다가 프로메테우스 서버가 Pulling 을 하면, 저장된 지표 정보를 리턴하도록 한다.

서비스 디스커버리

그러면 프로메테우스는 모니터링 대상을 어떻게 알 수 있을까? 당연히 모니터링 대상 목록을 유지하고 있고, 대상에 대한 IP나 기타 접속 정보를 설정 파일에 주면, 그 정보를 기반으로 프로메테우스 서버가 모니터링 정보를 읽어온다.

그러나 오토스케일링을 많이 사용하는 클라우드 환경이나 쿠버네티스와 같은 컨테이너 환경에서는 모니터링 대상의 IP가 동적으로 변경되는 경우가 많기 때문에 이를 일일이 설정파일에 넣는데 한계가 있다. 이러한 문제를 해결 하기 위해서 프로메테우스는 서비스 디스커버리 를 사용하는데, 모니터링 대상이 등록되어 있는 저장소에서 목록을 받아서 그 대상을 모니터링 하는 형태이다.


프로메테우스는 DNS나 Consul, etcd와 같은 다양한 서비스 디스커버리 서비스와 연동을 통해서 자동으로 모니터링 대상의 목록을 가지고 올 수 있다.

저장 및 시각화

이렇게 수집된 지표 정보들은 프로메테우스 내부의 시계열 데이타베이스에 저장이 되고, 프로메테우스 웹 콘솔을 이용하여 시각화 되거나 또는 API를 외부에 제공해서 Grafana와 같은 시각화 툴을 통해서 지표를 시작화 해서 볼 수 있다.

알림 서비스

부가 기능중의 하나로, alerting 컴포넌트는, 지표에 대한 규칙을 걸어놓고 그 규칙을 위반할 경우에는 알림을 보낼 수 있는 기능을 가지고 있다. 알림을 보내는 대상은 이메일이나 pagerduty와 같은 notification 서비스 등과 연동이 가능하다.

쿠버네티스 연동 아키텍처

그러면, 쿠버네티스와 프로메테우스는 어떻게 연동이 될까? 여기서 오해하지 말아야 하는 점은 Heapster,cAdvisor 스택과 같이 딱 정해진 아키텍쳐는 없다는 것이다. 프로메테우스는 범용 모니터링 솔루션으로 프로메테우스 서버가 지표정보를 읽어올 수 만 있다면 거의 모든 정보를 읽어올 수 있는 구조이기 때문에, 쿠버네티스 연동에 있어서도 자유도가 매우 높다


단 레퍼런스 할 수 있는 구성은 있는데, 다음과 같은 구조를 갖는다.


먼저 프로메테우스 서버가 모니터링할 리소스를 찾기 위해서 서비스 디스커버리 (Service discovery) 메카니즘이 필요한데, 이를 위해서 쿠버네티스 API를 호출해서, 자원들의 목록 (Pod,Node, Service,Ingress,Endpoint 등)의 목록을 라벨 셀렉터(label selector)를 이용하여 수집한다.

다음 수집된 모니터링 대상에 대해서 모니터링을 수행하는데, 쿠버네티스는 apiServer에서 /metric 이라는 URL을 통해서 기본적인 지표 정보를 리턴하기 때문에, 쿠버네티스 자원들에 대한 모니터링은 이 API를 통해서 수집하게 된다.


아랫단에 하드웨어 즉 node에 대한 정보는 API를 통해서 수집하기가 어렵기 때문에, node에 node exporter를 설치해서 하드웨어와 OS에 대한 정보를 수집한다. 컨테이너에 대한 정보는 node별로 배포되어 있는 cAdvisor가 이를 수집하여 프로메테우스에 제공한다.


컨테이너내에서 기동되는 애플리케이션에 대한 정보는 필요한 경우, 클라이언트 SDK나, 솔루션에 맞는 exporter를 이용해서 수집한다.

쿠버네티스 연동하기

그러면 실제로 프로메테우스를 설치해서 쿠버네티스 클러스터를 모니터링 해보자. 앞의 아키텍쳐에서 봤지만, alert server, exporter, prometheus server 등 설치해야 하는 서버들이 많아서, 일일이 설치하는 것이 쉽지 않다. 여러가지 설치 방법이 있지만 여기서는 쿠버네티스의 패키지 매니저인 Helm 을 이용해서 프로메테우스를 설치하도록 한다. Helm 은  Linux의 RPM이나, Node.js의 npm같이 소프트웨어 스택을 명령으로 손쉽게 설치할 수 있도록 해주는 패키지 매니져의 개념으로 쿠버네티스 버전의 npm 툴이라고 이해하면 된다.


참고로 여기서 설치는 로컬 PC의 minikube 환경을 이용해서 설치하였다. 클라우드 환경에서 제공되는 쿠버네티스 클러스터의 경우에는 다소 차이가 있을 수 있으니, 각 벤더에서 제공되는 가이드를 참고하기 바란다. 아울러 아래 설치 내용은 운영 환경에서 적용하기는 어렵고, 운영환경 적용을 위해서는 적절한 디스크 타입과 Pod의 사이즈등을 다시 클러스터 환경에 맞도록 설정해야하고 어디까지나, 테스트 용임을 인지하기 바란다.

Helm 인스톨

Helm은 클라이언트와 서버 두개의 모듈로 나뉘어 진다.

인스톨은 어렵지 않은데, 클라이언트 OS에 따라 약간씩 차이가 있다. 자세한 인스톨 방법은 https://docs.helm.sh/using_helm/ 문서를 참고하면 된다.

클라이언트 인스톨

맥에서 클라이언트 인스톨은 brew를 이용하면 쉽게할 수 있다.

%brew install kubernetes-helm

명령을 이용하면 Helm 클라이언트가 로컬 PC에 설치된다.

서버 인스톨

Helm 서버를 Tiller라고 하는데, Tiler 서버의 인스톨은 어렵지 않으나, 클라우드 벤더나 설치 환경에 따라서 약간씩의 차이가 있다.


Minikube  환경에서 인스톨

Minikube 환경에서 인스톨은 Helm 클라이언트를 인스톨 한 후에, 아래와 같이

%helm init

명령어를 실행하면 쿠버네티스 클러스터에 Tiller 서버가 자동으로 설치된다.


구글 클라우드 쿠버네티스 엔진 (GKE) 환경에서 인스톨

GKE 환경은 약간 설치 방법이 다른데, 보안적인 이슈로 인해서 계정에 대한 권한 컨트롤을 상대적으로 까다롭게 하기 때문이다.

(참고 : https://cloud.google.com/solutions/continuous-integration-helm-concourse )


아래 명령을 이용하면 kube-system 네임 스페이스에 tiller라는 이름으로 서비스 어카운트를 생성할 수 있다.

% kubectl create clusterrolebinding user-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)

% kubectl create serviceaccount tiller --namespace kube-system

% kubectl create clusterrolebinding tiller-admin-binding --clusterrole=cluster-admin --serviceaccount=kube-system:tiller


다음 Tiller를 생성할때, --service-account=tiller 옵션을 줘서 tiller 가 실행될때, 해당 서비스 어카운트의 권한을 가지고 실행되도록 한다.


헬름 서버 (Tieller) 인스톨

./helm init --service-account=tiller
./helm update


이렇게 설치 하지 않으면 Tiller 자체는 설치가 될 수 있지만, Tiller에 의해서 인스톨 되는 패키지들이 권한 오류로 인해서 제대로 설치되지 않을 수 있다

Helm Chart를 이용한 Prometheus 설치

Helm이 준비되었으면 프로메테우스 를 설치해보자


% git clone https://github.com/kubernetes/charts

명령을 이용하여 Helm chart를 다운 받는다. Helm chart는 npm 파일과 같이 인스톨 스크립트를 모아놓은 것으로 생각하면 된다. 프로메테우스외에도 다양한 설치 스크립트가 있다.


$ cd charts/stable/prometheus

를 이용해서 프로메테우스 디렉토리로 들어간 후에, 아래 명령을 이용하면 prometheus 네임스페이스에 프로메테우스가 설치된다.


$ helm install -f values.yaml stable/prometheus --name prometheus --namespace prometheus


설치가 끝났으면 이제 프로메테우스가 제대로 작동해서 지표를 수집하고 있는지 확인하자. 프로메테우스 서버는 디폴트로 9090 포트를 통해서 웹 인터페이스를 제공한다. 프로메테우스 서버를 외부 서비스로 expose 하지 않았기 때문에 포트 포워딩을 이용해서 프로메테우스 서버의 9090 포트를 포워딩 해보자


%kubectl get pod -n prometheus

명령을 이용해서 prometheus 네임스페이스에 있는 pod 목록을 다음과 같이 가지고 온다.



prometheus의 pod 명이 “prometheus-server-5695758946-gdxjx” 인것을 알았으면,localhost:9090을 이 pod의 9090포트로 포워딩하도록 설정한다.

%kubectl port-forward -n prometheus prometheus-server-5695758946-gdxjx 9090


포트 포워딩이 설정되었으면 localhost:9090으로 접속하여 프로메테우스의 웹 콘솔을 접속해보자

처음에는 아무것도 나오지 않을텐데, metric을 PQL (프로메테우스 쿼리)를 이용해서 선택하면 아래와 같이 해당 지표에 대한 값이 나오는것을 볼 수 있다. 아래는 node의 disk_io 정보를 살펴보는 쿼리이다.



이 메뉴에서 지표를 모니터링 하거나 또는 모니터링된 지표를 Graph 탭을 눌러서 그래프로 시각화 할 수 있다. 메뉴를 조금더 둘러보면 상단의 Status 메뉴에서 Service Discovery 메뉴를 눌러보면 다음과 같은 결과를 얻을 수 있다.


모니터링해야 하는 자원들의 목록으로 node, node-cadvisor, pods, services 등에 대한 정보를 모니터링할 수 있는 것을 확인할 수 있다.


Target 메뉴를 클릭하면 다음과 같은 정보가 나오는데,


어디로 부터 지표들을 수집해오는지 URL등을 확인할 수 있다. apiserver의 URL, node metric 정보 수집 URL node cAdvisor 수집 URL등을 확인할 수 있다.

Helm Chart를 이용한 Grafana 설치

프로메테우스를 설치했으면 이를 시각화 하기 위해서 Grafana를 설치해서 연동해보도록 하자.

Helm chart 디렉토리에서 stable/grafana 디렉토리에 values.yaml 파일이 있는데, 이 부분에서 adminPassword 부분을 찾아서 admin 사용자의 비밀 번호를 세팅하도록 하자.


adminUser: admin

adminPassword: mypassword


다음 Helm chart를 이용해서 Grafana를 설치한다.

stable/grafana 디렉토리에서 앞에서 수정한 values.yaml 파일을 이용한다.

%helm install -f values.yaml stable/grafana --name grafana --namespace grafana


설치가 종료되었으면 Grafana 콘솔에 접속해보자.

%kubectl get pod -n grafana 명령을 이용해서 grafana 서버의 pod 명을 알아낸다.


Grafana 서버는 외부 서비스로 Expose 되지 않았기 때문에, 포트 포워딩을 이용해서 해당 서버에 접속하도록 한다. Grafana는 3000번 포트로 웹 접속을 허용한다.


% kubectl port-forward -n grafana grafana-679cdd7676-zhwnf 3000

명령을 이용하면 localhost:3000을 Grafana 웹 서버로 포워딩 해준다.

localhost:3000에 접속해보면 다음과 같은 로그인 창이 나온다.


로그인창에서, 사용자명을 admin으로 입력하고, 비밀번호는 앞의 설정에서 입력한 비밀번호를 설정한다.

다음으로 프로메테우스 서버를 데이타 소스로 설정해야 하는데, grafana 메뉴에서 Configuration > Data source 메뉴를 선택한다.



Data source를 추가하기 위해서는 프로메테우스 서버의 URL 을 알아야 하는데, 프로메테우스 서버는 내부 IP를 가지고 있는 서비스로 Expose 되어 있다. 서비스명을 알기 위해서 다음 명령어를 실행한다.

%kubectl get svc -n prometheus

다음과 같이 서비스명이 prometheus-server이고 cluster-IP가 10.102.173.250 인것을 확인할 수 있다.




HTTP URL은 http://prometheus-server.prometheus.svc.cluster.local 게 된다.

그러면 이 정보를 Grafana datasource 쪽에 추가한다.



데이타소스 명은 Kuberentes로 지정하고, 타입은 Prometheus로 지정한다. 그리고 HTTP URL은 위의 http://prometheus-server.prometheus.svc.cluster.local 를 사용하고 Access 타입은 Server를 선택한다.


이 과정이 끝나면, 프로메테우스를 Grafana의 데이타 소스로 사용할 수 있다.

이 데이타 소스를 이용해서 대쉬 보드를 구성해야 하는데, 수동으로 일일이 구성할 수 도 있지만 Grafana 커뮤니티에는 이미 미리 구성되어 있는 대쉬보드 템플릿이 많다. 이 템플릿을 그대로 import 해서 사용해보도록 하겠다.

Grafana 메뉴에서 아래와 같이 Create > Import 메뉴를 선택한다.


다음 대쉬보드 설정 JSON을 넣을 수 있는데, 또는 Grafana.com에 등록된 대쉬보드 템플릿 번호를 넣을 수 도 있다. 여기서는 쿠버네티스 클러스터 모니터링 템플릿을 사용하도록 하겠다. 이 템플릿의 ID는 1621번이기 때문에 아래와 같이 템플릿 ID를 입력한다.

이 템플릿 이외에도, 노드 모니터링을 위한 템플릿등 여러 종류의 대쉬 보드 템플릿이 있기 때문에 용도에 맞게 선택해서 사용하면 된다.


템플릿 ID를 선택하면 다음 화면에서 데이타 소스를 선택해줘야 하는데, 아래 그림과 같이 Prometheus 부분을 앞에서 만든 데이타 소스 이름인 Kubernetes를 선택한다.


설정이 끝난후에 대쉬보드를 확인하면 아래와 같이 쿠버네티스에 대한 전반적인 모니터링 정보가 나오는 것을 확인할 수 있다.





쿠버네티스 #13

모니터링 1/2


조대협 (http://bcho.tistory.com)


시스템을 운영하는데 있어서 운영 관점에 있어서 가장 중요한 기능중의 하나는 시스템에 대한 모니터링이다. 시스템 자원의 사용량이나 에러등에 대한 모니터링을 통해서, 시스템을 안정적으로 운영하고 문제 발생시 원인 파악과 대응을 할 수 있다.

이번 글에서는 쿠버네티스 모니터링 시스템에 대한 개념과, 아키텍쳐 그리고 구축 방법에 대해서 소개하고자 한다.

쿠버네티스 모니터링 컨셉

쿠버네티스에 대한 모니터링을 보면 많은 툴과 지표들이 있어서 혼돈하기 쉬운데, 먼저 모니터링 컨셉에 대한 이해를 할 필요가 있다.

쿠버네티스 기반의 시스템을 모니터링하기 위해서는 크게 아래와 같이 4가지 계층을 모니터링해야 한다.



1. 호스트 (노드)

먼저 쿠버네티스 컨테이너를 실행하는 하드웨어 호스트 즉 노드에 대한 지표 모니터링이 필요하다. 노드의 CPU,메모리, 디스크, 네트워크 사용량과, 노드 OS와 커널에 대한 모니터링이 이에 해당한다.

2. 컨테이너

다음은 노드에서 기동되는 각각의 컨테이너에 대한 정보이다. 컨테이너의 CPU,메모리, 디스크, 네트워크 사용량등을 모니터링 한다.

3. 애플리케이션

컨테이너안에서 구동되는 개별 애플리케이션의 지표를 모니터링 한다. 예를 들어, 컨테이너에서 기동되는 node.js 기반의 애플리케이션의 응답시간, HTTP 에러 빈도등을 모니터링한다.

4. 쿠버네티스

마지막으로, 컨테이너를 컨트롤 하는 쿠버네티스 자체에 대한 모니터링을한다. 쿠버네티스의 자원인 서비스나 POD, 계정 정보등이 이에 해당한다.

쿠버네티스 기반의 시스템 모니터링에 대해서 혼돈이 오는 부분중의 하나가 모니터링이라는 개념이 포괄적이기 때문이다. 우리가 여기서 다루는 모니터링은 자원에 대한 지표 대한 모니터링이다. 포괄적인 의미의 모니터링은 로그와, 에러 모니터링등 다양한 내용을 포괄한다.  

쿠버네티스 로깅

지표 모니터링과 함께 중요한 모니터링 기능중 하나는 로그 수집 및 로그 모니터링이다.

로그 수집 및 로그 모니터링 방법은 여러가지 방법이 있지만, 오픈소스 로그 수집 및 모니터링 조합인 EFK (Elastic search + FluentD + Kibina) 스택을 이용하는 경우가 대표적이다.

Fluentd 에이전트를 이용하여, 각종 로그를 수집하여, Elastic search에 저장하고, 저장된 지표를 Kibana 대쉬 보들르 이용하여 시작화 해서 나타내는 방법이 있다.

이에 대한 자세한 설명을 생략한다.

쿠버네티스 모니터링 시스템 구축

그러면 이러한 모니터링 시스템을 어떻게 구축할 것인가?

쿠버네티스 모니터링은 버전업 과정에서 많은 변화를 겪고 있다. 기존 모니터링 시스템의 아키텍쳐는 cAdvisor,Heapster를 이용하는 구조였으나, 이 아키텍쳐는 곧 deprecated 될 예정이고, Prometheus등 다양한 모니터링 아키텍쳐가 후보로 고려 되고 있다.

아래 그래프를 보면 재미있는 통계 결과가 있는데, cAdvisor,Heapster,Promethus 를 이용하는 방법도 있지만, 클라우드의 경우에는 클라우드 벤더에서 제공하는 쿠버네티스 모니터링 솔루션을 그대로 사용하거나 (18%) 또는 데이타독이나 뉴렐릭 (Datadog, newRelic)과 같이 전문화된 모니터링 클라우드을 사용하는 비율 (26%) 도 꽤 높다.



<그림. 쿠버네티스 모니터링 솔루션 분포 >

출처 :  https://thenewstack.io/5-tools-monitoring-kubernetes-scale-production/


개인적인 의견으로는 직접 모니터링 솔루션을 구축해서 사용하는 것보다는 비용은 약간 들지만 클라우드 벤더에서 제공되는 모니터링 도구나 또는 데이타독과 같은 전문 모니터링 솔루션을 이용하는 것을 추천한다.


직접 모니터링 솔루션을 구축할 경우 구축과 운영에 드는 노력도 꽤 크고, 또한 어떠한 지표를 모니터링해야할지 등에 대한 추가적인 노하우가 필요하다. 또한 cAdvisor,Heapster,Promethues 조합은 호스트와 컨테이너 그리고 쿠버네티스에 대한 모니터링은 제공하지만 애플리케이션 지표에 대한 모니터링과 로깅 기능은 제공하지 않기 때문에 별도의 구축이 필요하다. 이런 노력을 들이는 것 보다는 모든 기능이 한번에 제공되고 운영을 대행해주는 데이타독이나 클라우드에서 제공해주는 모니터링 솔루션을 사용하는 것을 추천한다.

Heapster 기반 모니터링 아키텍처

이러한 모니터링 요건을 지원하기 위해서, 쿠버네티스는 자체적인 모니터링 컴포넌트를 가지고 있는데, 그 구조는 다음과 같다.



<그림. 쿠버네티스 모니터링 시스템 아키텍쳐>

출처 Source : https://www.datadoghq.com/blog/how-to-collect-and-graph-kubernetes-metrics/


cAdvisor

cAdvisor는 모니터링 에이전트로, 각 노드마다 설치되서 노드에 대한 정보와 컨테이너 (Pod)에 대한 지표를 수집하여, Kubelet으로 전달한다.

Heapster

cAdvisor에 의해 수집된 지표는 Heapster 라는 중앙 집중화된 지표 수집 시스템에 모이게 되고, Heapster는 수집된 지표를 스토리지 백앤드에 저장한다.

Storage backend

Heapster가 지표를 저장하는 데이타베이스를 스토리지 백앤드라고 하는데, Heapster는 확장성을 위해서 다양한 스토리지 백앤드를 플러그인 구조를 선택하여 연결할 수 있다.

현재 제공되는 대표적인 스토리지 백앤드는 구글 클라우드의 모니터링 시스템인 스택드라이버 (stackdriver), 오픈 소스 시계열 데이타베이스인 인플럭스 디비 (InfluxDB) 등을 지원한다.

그래프 대쉬 보드

이렇게 저장된 모니터링 지표는 그래프와 같은 형태로 시각화 될필요가 있는데, 스토리지 백앤드를 지원하는 다양한 시각화 도구를 사용할 수 있다. 구글의 모니터링 시스템인 스택드라이버의 경우에는 자체적인 대쉬보드 및 그래프 인터페이스가 있고, 인플럭스 디비나 프로메테우스의 경우에는 오픈소스 시각화 도구인 그라파나(Grafana)를 사용할 수 있다.


<그림. 그라파나와 프로메테우스를 연결하여, 지표 모니터링을 시각화 한 예제>


그러나 이 아키텍쳐는 deprecation 계획이 시작되서 1.13 버전 부터는 완전히 제거될 예정이다.

https://github.com/kubernetes/heapster/blob/master/docs/deprecation.md


쿠버네티스 대시보드

다른 방법으로는 쿠버네티스를 모니터링 하고 관리할 수 있는 쉬운 방법이 하나 있는데, 쿠버네티스 대시보드를 사용하는 방법이다. 쿠버네티스는 기본적으로 kubectl이라는 커맨드 라인 인터페이스 (이하 CLI : Command Line Interface)를 사용하지만, 추가적으로 웹 기반의 관리 콘솔을 제공한다. 이를 쿠버네티스 대시보드라고 한다. (https://github.com/kubernetes/dashboard)

대시 보드 설치

쿠버네티스 대시 보드 설치 방법은 간단하다. 아래와 같이 대시보드 설정 yaml 파일을 이용하면 간단하게 대시 보드를 쿠버네티스 클러스터에 설치할 수 있다.


% kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml


일반적인 경우에는 위의 스크립트로 설치가 가능하지만, 구글 클라우드 쿠버네티스 엔진의의 경우에는 설치 중에 권한 관련 에러가 나올 수 있는데, 구글 클라우드 쿠버네티스 엔진의 경우에는 보안을 이유로 일반적인 쿠버네티스보다 권한 설정 레벨이 높게 설정되어 있기 때문이다. 구글 클라우드 쿠버네티스 엔진에서 대시보드를 설치하고자할때에는 위의 스크립트를 실행하기 전에 먼저 아래 명령어를 이용해서, 현재 사용자 계정에 대해서 cluster-admin 롤을 부여해줘야 한다.  


%kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole cluster-admin --user $(gcloud config get-value account)

대시 보드 접속

대시보드 설치가 끝났으면, 대시보드를 접속해보자

대시보드는 외부 서비스로 제공되지 않고, 내부 IP로만 접속이 가능한데, 클러스터 외부에서 접근하려면 kubectl proxy를 이용하면, 간단하게 접근이 가능하다.

kubectl proxy는 로컬 머신 (예를 들어 노트북)과 쿠버네티스 클러스터간의 통신을 프록싱해줘서, 로컬 머신에서 쿠버네티스 클러스터내의 HTTP 서비스를 접근할 수 있도록 해준다.

사용 방법은 로컬 머신에서 간단하게

%kubectl proxy

명령을 실행해주면 localhost:8001 포트를 통해서 쿠버네티스 클러스터로 트래픽을 프록시 해준다.

위와 같이 proxy를 실행한후에,  아래 URL로 접근을 하면, 대시보드 콘솔에 접근할 수 있다.

http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/


URL에 접근하면 아래와 같이 로그인 창이 나타난다.



사용자 계정 및 토큰등에 대해서는 보안 부분에서 별도로 다루기로 하겠다.

대쉬보드를 사용하기 위해서는 사용자 인증이 필요한데, 간단하게 인증을 위한 토큰을 사용하는 방법을 이용하도록 하겠다.

토큰은 쿠버네티스 API 인증 메커니즘중의 하나로, 여기서는 admin-user라는 계정을 하나 만든후에, 그 계정에, 클러스터 관리자롤을 부여한 후에, 그 사용자의 토큰을 사용하는 방법을 사용하겠다.


먼저 아래 스크립트를 이용해서 admin-user 라는 사용자를 생성한다.

admin-user.yaml 파일

apiVersion: v1

kind: ServiceAccount

metadata:

 name: admin-user

 namespace: kube-system


다음 아래 스크립트를 이용해서 cluster-admin 롤을 앞에서 생성한 admin-user에 부여한다.

admin-rolebinding.yaml 파일

apiVersion: rbac.authorization.k8s.io/v1beta1

kind: ClusterRoleBinding

metadata:

 name: admin-user

roleRef:

 apiGroup: rbac.authorization.k8s.io

 kind: ClusterRole

 name: cluster-admin

subjects:

- kind: ServiceAccount

 name: admin-user

 namespace: kube-system


다음 아래 명령어를 이용하면 admin-user의 토큰 값을 알 수 있다.

% kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')


명령을 실행하면 아래와 같이 토큰이 출력된다.


이 토큰 값을 앞의 로그인 창에 입력하면, 대시보드에 로그인할 수 있다.

대시 보드에 로그인하면 아래와 같이 노드나, Pod, 서비스등 쿠버네티스의 자원의 대부분의 정보에 대한 모니터링이 가능하다.




또한 kubectl CLI 명령을 사용하지 않고도 손쉽게 Deployment 등 각종 자원을 생성할 수 있다.


로그 부분에 들어가면 아래와 같이 로그 정보를 볼 수 있다



재미있는 기능중 하나는 아래 그림과 같이 특정 Pod의 컨테이너를 선택하면, 웹콘솔상에서 해당 컨테이너로 SSH 로그인이 가능하다.



여기서 다룬 쿠버네티스 대시보드 설정 및 로그인 부분은 프록시 사용, 로그인을 토큰을 사용하는 등, 운영환경에는 적절하지 않은 방법이다. 개발환경이나 테스트 용도로만 사용하도록 하고, 운영 환경에서는 사용자 계정 시스템 생성과 적절한 권한 배정을 한 후에, 적절한 보안 인증 시스템을 마련한 후에 적용하도록 하자.



Stackdriver profiler

클라우드 컴퓨팅 & NoSQL/google cloud | 2018.04.08 21:44 | Posted by 조대협


Stack driver profiler


조대협 (http://bcho.tistory.com)


얼마전에 구글 클라우드의 모니터링 솔루션인 stack driver에서 profiler 기능이 발표되었다. (https://cloud.google.com/profiler) 

우리가 일반적으로 생각하는 성능 분석을 위한 profiling 도구로, 구글 클라우드 뿐만 아니라, 여러 서버에서 동작하는 Java/node.js/Go 애플리케이션의 성능을 모니터링할 수 있다.(파이썬은 곧 지원 예정)


장점은 코드 수정없이 간단하게 에이전트만 추가함으로써 프로파일러 사용이 가능하고, 프로파일링된 결과를 stackdriver 웹 콘솔에서 바로 확인이 가능하다는 것이다.


JDB등 전통적인 프로파일러가 있기는 하지만 보통 프로파일러가 적용되면, 애플리케이션의 성능이 극단적으로 느려지기 때문에, 운영환경에 적용이 불가능한데, Stack driver profiler의 경우에는 성능 저하가 미비하여 운영환경에도 적용이 가능하다.


"Stackdriver Profiler uses statistical techniques and extremely low-impact instrumentation that runs across all production application instances to provide a complete picture of an application’s performance without slowing it down."


아래는 자바 애플리케이션을 프로파일을 하기 위해서 프로파일러 바이너리를 agentPath에 추가한 형태이다


java \ -agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=user,-cprof_service_version=1.0.0 \ -jar ./User-0.0.1-SNAPSHOT.jar


아래는 자바 애플리케이션을 프로파일을 하기 위해서 프로파일러 바이너리를 agentPath에 추가한 형태이다

애플리케이션은 http://bcho.tistory.com/1247 에서 사용한 간단한 REST API를 사용하였다.

코드를 실행해서 프로파일링 데이타를 얻고 나면 아래와 같이 구글 클라우드 콘솔에서 프로파일링 결과를 확인할 수 있다.


위의 뷰는 WALL뷰로, 전체 프로그램이 수행되는 중에, 어느 코드가 시간을 얼마나 사용했는지를 프로파일링 해준결과이다.
이 외에도 CPU 시간으로 볼 수 도 있고, 메모리 사용률등 다양한 뷰
대규모 분산 서비스나 MSA 구조에 적합하도록 프로파일 결과를 볼 수 있는 범위를 선택이 가능한데, 상단의 메뉴를 보면 프로파일링 결과를 볼 서비스와, 프로파일 타입 (CPU,WALL:메서드별 실행시간, 메모리 사용률), 그리고 서비스가 배포된 클라우드 존, 서비스 버전 등에 따라서 선택이 가능하다. 아래는 언어별로 지원하는 프로파일 타입이다. 



Profiler의 뷰는 애플리케이션 타입에 상관이 없이 순수 프로그래밍 플랫폼에만 연관된 뷰로만 보여준다.
무슨이야기인가 하면, 보통 웹 애플리케이션은 멀티 쓰레드 타입으로 동작하고, REQUEST가 들어오면 쓰레드가 하나의 요청을 처리하고 빠지는 형태이기 때문에, 쓰레드별로 어떤 메서드가 순차적으로 실행되었는지등의 뷰를 선호하는데, JENNIFER나 오픈 소스 스카우터와 같은 APM (Application Peformance Monitoring)툴이 이러한 뷰를 제공한다. 

위의 샘플을 보더라도, 톰캣서버의 쓰레드들이 대부분 모니터링 될뿐 직접 코딩한 메서드들이 관측 되지는 않는다. (사용자 코드가 적고, 실행시 별로 크게 시간을 소요하지 않는 것도 원인이기는 하지만)

만약에 REQUEST에 대한 메서드별 소요 시간 모니터링 및 병목 구간 확인을 하려면, Stack driver profiler보다는 Stack driver trace를 사용하는 것이 적절하다. http://bcho.tistory.com/1245

그래서 Stack Driver는 성능 모니터링 (APM)제품군을 Trace, Profiler, Debugger 3가지로 묶고 있고, (Debugger는 나중에 시간이 되면 테스트하고 다루도록 하겠다.) 각기 다른 뷰로 상호 보완적인 관점에서 성능 모니터링이 가능하도록 하고 있다.



구글 스택드라이버를 이용한 애플리케이션 로그 모니터링

조대협 (http://bcho.tistory.com)

스택드라이버 소개

스택드라이버는 구글 클라우드에서 서비스로 제공되는 시스템 로그 및 모니터링 시스템이다. CPU,메모리사용량과 같은 하드웨어에 대한 정보에서 부터 웹서버나 OS와 같은 미들웨어 및 애플리케이션 로그를 수집, 검색 및 분석할 수 있으며, 여러 오픈 소스 (MongoDB, CouchDB, Redis - https://cloud.google.com/monitoring/agent/plugins/ )등에 대한 모니터링도 가능하다.

구글 클라우드 뿐 아니라, AWS에 대한 모니터링을 통합으로 지원하는 등, 상당히 많은 기능을 가지고 있다.

이 글에서는 스택드라이버를 이용하여 애플리케이션 로그를 수집하고 이를 분석하는 방법에 대해서 설명하고자 한다.

자바를 기반으로 애플리케이션 로깅을 설명한다. 자바 애플리케이션에서 스택드라이버로 로그를 남기는 방법은 여러가지가 있으나, 일반적으로 자바 프로그래밍 언어에서 많이 사용하는 로깅 프레임웍은 SL4J 를 이용한 로깅과, 스택드라이버 SDK를 이용하여 JSON 형태로 로그를 저장하는 방법에 대해서 알아보도록 한다.

API 인증

스택 드라이버를 사용하기 위해서는 로그 API에 대한 인증이 필요하다. 인증에는 여러가지 방법이 있는다. 사용이 쉬운 방법을 설명한다.

로컬 환경 또는 타 환경에서 인증

로컬 개발환경이나 클라우드에서 인증을 하는 방법은 서비스 어카운트 (Service Account)를 사용하는 방법이 있다. 서비스 어카운트는 구글 클라우드 콘솔에서  IAM 메뉴에서 생성할 수 있다. 서비스 어카운트 메뉴를 아래와 같이 선택한 다음.


상단 메뉴에서 Create Service Account  버튼을 누르고 서비스 어카운트 생성한다.


서비스 어카운트에는 서비스 어카운트의 권한을 설정할 수 있는데, Project Owner로 설정하면 모든 권한을 다 가질 수 있고, 여기서는 로깅 권한만을 줄것이기 때문에, Logs Writer 권한만을 지정한다.


계정 생성을 하면 json 파일이 다운로드 된다.

이 파일은 환경 변수 GOOGLE_APPLICATION_CREDENTIALS 에 파일 경로를 지정해주면 된다.

예시 $ export GOOGLE_APPLICATION_CREDENTIALS=/Users/terrycho/keys/terrycho-sandbox-projectowner.json




구글 클라우드 VM 내에서 인증

구글 클라우드 VM내에서 자바 코드를 실행할 경우 VM 자체에 API 접근 권한을 부여할 수 있다. 보통 운영환경에서는 이 방법이 권장된다.

아래와 같이 VM 생성시 “Identity and API access” 에서 API 접근 권한을 주면 된다. Set access for each API를 써서 Logging write 권한만을 줄 수 있고, 아니면 Allow full access to all Cloud APIs 를 이용해서 전체 API에 대한 권한을 줄 수 도 있다.




SL4J를 이용한 로깅

sl4j를 이용한 로깅은, 기존의 sl4j 로거를 그대로 사용하기 때문에 코드 변환이 거의 없고, 단지 maven 에서 라이브러리 의존성을 스택드라이버 로거로만 변경해주면 되기 때문에 별도의 학습이 필요없고 사용법이 단순하다는 장점이 있다. sl4j 로깅은 단순하다.

의존성 추가

먼저  pom.xml 에 아래와 같은 의존성을 추가 한다.

<dependency>
<groupId>com.google.cloud</groupId>       <artifactId>google-cloud-logging-logback</artifactId> <version>0.30.0-alpha</version>
</dependency>

logback.xml

다음 필요에 따라서 sl4j에 대한 설정을 위해서 logback.xml 을 추가 설정할 수 있다. 여기서 로깅 레벨등을 지정할 수 있으나, sl4j에 대한 내용이기 때문에 별도로 설명하지는 않는다.

자주 실수 하는 부분이 logback.xml은 클래스 패스의 경로내에 들어가 있어야 하는데 다른 방법으로는 자바 옵션으로 -Dlogback.configurationFile 으로 logback.xml 경로를 설정하면 된다.



코드

코드를 보자

package com.google.example.stackdriver;


import org.slf4j.Logger;

import org.slf4j.LoggerFactory;



public class App {

 private static final Logger logger = LoggerFactory.getLogger(App.class);

 

 public static void main(String[] args) {

   logger.info("My Hello Log4j");

 }

}


코드는 간단하다. logger를 선언한 후에, .info, .error, .warning 등의 메서드로 텍스트 문자열을 남기면 된다.


자바 로거 연동은 sl4j이외에도 java.util.logging 도 연동이 가능하다. 자세한 내용은 https://cloud.google.com/logging/docs/setup/java 를 참고하기 바란다.

Logger를 이용한 로깅

sl4j는 사용이 간편한 반면에 텍스트 문자열로 로깅이 되기 때문에, 구조화된 정보 (JSON)이나 여러 필드를 가지는 로그를 남기기가 쉽지 않다는 단점을 가지고 있다. 스택드라이버 전용 SDK를 사용하면, JSON등 다양한 포맷으로 로그를 쉽게 남길 수 있다. (sl4j의 경우에도 LoggingEnahncer를 사용하면 가능하기는 하다)


전체 코드는 다음과 같다.


package com.google.example.stackdriver;

import com.google.cloud.MonitoredResource;

import com.google.cloud.logging.LogEntry;

import com.google.cloud.logging.Logging;

import com.google.cloud.logging.LoggingOptions;

import com.google.cloud.logging.Payload.JsonPayload;

import com.google.cloud.logging.Payload.StringPayload;

import com.google.cloud.logging.Severity;

import java.util.Collections;

import java.util.HashMap;

import java.util.Map;


public class LogWithLabel {

 //https://cloud.google.com/logging/docs/reference/libraries

 final static String LOG_NAME="terry-tutorial";

 /** Expects a new or existing Stackdriver log name as the first argument.*/

 public static void main(String... args) throws Exception {


   // Instantiates a client

   Logging logging = LoggingOptions.getDefaultInstance().getService();


   // The data to write to the log

   String text = "Hello, world!";

   Map<String, Object> jsonMap = new HashMap<String, Object>();

   jsonMap.put("elapsedtime", 11);

   

   for(int i=0;i<1000;i++){

    jsonMap.put("count", i);

   LogEntry entry

    //= LogEntry.newBuilder(StringPayload.of(text))

    // 한페이로드만 사용이 가능함. 오버라이드됨.

    = LogEntry.newBuilder(JsonPayload.of(jsonMap))

.setSeverity(Severity.ERROR)

       .setLogName(LOG_NAME)

       .setResource(MonitoredResource.newBuilder("global").build())

       .addLabel("instancename", "instance-1")

       .build();

   // Writes the log entry asynchronously

   logging.write(Collections.singleton(entry));

   }


   System.out.printf("Logged: %s%n", text);

 }

}


먼저 Logging 객체를 가지고 와야 한다. 별도의 설정 없이 다음과 같이 설정하면 되고, 프로젝트 및 인증은 앞에서 설정한 Service Account 파일의 정보를 그대로 사용한다.

Logging logging = LoggingOptions.getDefaultInstance().getService();


이 예제는 JSON 포맷으로 데이타를 저장하는 방법인데, 단순하게 1 레이어의 JSON을 저장하도록 하였다. Map을 이용하여 jsonMap을 정의하고, put을 이용하여 key, value 값을 저장한다.


   String text = "Hello, world!";

   Map<String, Object> jsonMap = new HashMap<String, Object>();

   jsonMap.put("elapsedtime", 11);


다음 로그를 저장하기 위해서는 LogEntry 객체를 이용해야 하는데, LogEntry는 LogEntry.newBuilder(PayLoad)를 이용하여 생성한다. Text 로그를 저장하는 TextPayLoad를 사용하거나 다른 페이로드도 있지만 여기서는 JsonPayLoad를 사용하였다.

LogEntry.newBuilder(JsonPayload.of(jsonMap))


다음 로그 Serverity (INFO,ERROR,WARNING)는 setServerity로 정할 수 있다. 스택 드라이버 로그는 정보 구조에서 계층 구조를 가질 수 있는데, 다음과 같은 개념을 가지고 있다.

리소스

리소스는 이 로그가 어떤 자원에 속하는지를 정의한다. 예를 들어, VM, 빅쿼리와 같이 어떤 인프라에 속하는지를 정의할 수 있는데, 애플리케이션의 경우 일반적으로 “global” 리소스로 정의한다.

리소스 명은 setResource메서드를 이용해서 지정이 가능하다.

라벨

다음 로그에 라벨을 달 수 있다. 예를 들어 이 리소스가 VM인데, 어떤 VM인지 식별을 하기 위해서 키를 name, 값을 인스턴스명 등으로 지정할 수 있다. 또는 개발/운영 환경인지를 구별하기 위해서 env 라는 키를 이용해서 환경에 따라 값을 dev,qa,prod 등으로 달 수 있다. 하나의 로그에는 여러개의 라벨을 붙이는 것이 가능하다. 라벨은 키,밸류 형태로 .addLabel(키,값)으로 추가가 가능하다.

로그 이름

로그 이름은 로그를 그룹핑할 수 있는데, 애플리케이션 종류등으로 그룹핑을할 수 있다. 이 로그는 사용자 로그, 게임 로그 등으로 그룹핑이 가능하다. 그룹 명을 setLogName으로 지정이 가능하다.


아래는 리소스를 global, 로그 이름을 LOG_NAME, 라벨에 instancename을 키로, instance-1이라는 값을 지정한 코드 예제이다.

       .setLogName(LOG_NAME)

       .setResource(MonitoredResource.newBuilder("global").build())

       .addLabel("instancename", "instance-1")

로그 확인

로그는 구글 클라우드 콘솔에서 STACKDRIVER > Logs 항목에서 확인이 가능하다.


위 그림과 같이 메뉴로 진입한 후에, 로그를 볼 수 있다.


리스트 박스에서 첫번째 박스는 리소스를 선택하는 화면으로 애플리케이션 로그는 앞의 예제에서 리소스를 global로 선택하였기 때문에, global을 선택한다. 그리고 두번째는 로그 이름을 고르는 화면인데, 앞에 예제에서 terry-tutorial로 로그 이름을 지정하였기 때문에 terry-tutorial을 선택한다.

다음 위의 화면에서 버튼을 누르면 실시간으로 로그를 볼 수 있는데, 통상 1분이내의 딜레이가 소요된다고 보면 된다.

로그에서 각 항목을 펼쳐보면 디테일을 볼 수 있다. 아래는 하나의 디테일인데, 중요한 부분은 timestamp에서 시간이 기록되고, serverity에 에러 레벨이 기록된다. 그리고 앞에서 지정한 Json PayLoad가 jsonPayLoad 라는 항목으로 들어간다.  라벨은 labels라는 항목에 키/밸류 형식으로 지정이 되는 것을 볼 수 있다.


로그 검색 및 필터링

스택드라이버의 강력한 기능중 하나가 로그에 대한 검색과 필터링인데, 스택 드라이버 콘솔 상단 화면에서 필터링(검색) 조건을 넣으면 각 필드 값에 따라서 다양한 형태로 로그 검색이 가능하다.


이 조건은 resource가 global이고, 그중에서 jsonPayload.count 가 900 보다 큰 로그만을 추출하는 방법이다. (Advanced filter를 사용하엿음)

표현식이 어렵지 않으니, https://cloud.google.com/logging/docs/view/advanced_filters 를 참고하면 손쉽게 로그 검색이 가능하다.

EXPORT

스택 드라이버의 다른 장점 중의 하나는 저장된 로그를 다른 시스템으로 EXPORT할 수 있는데, 크게 다음 3가지로 EXPORT가 가능하다.

  • GCS (파일) : Google Cloud Storage에 파일로 로그를 저장이 가능하다.

  • Pub/Sub (실시간 스트리밍) : 실시간으로 로그를 Pub/Sub 큐로 저장이 가능하다. Pub/Sub 뒤에 컨슈머를 둬서 다양한 처리가 가능하고 (알럿등) Apache Beam (Dataflow)연동을 통해서 실시간으로 로그를 분석 하는 것이 가능하다

  • BigQuery (데이타 베이스) : 실시간으로 데이타를 대용량 데이타 베이스는 빅쿼리에 저장하여 다양한 쿼리 및 시각화가 가능하다.


로그 EXPORT는 상단 메뉴의 CREATE EXPORT 버튼을 이용하면 EXPORT 정의가 가능하다.


이때 흥미로운 점은 로그 EXPORT시 필터에 조건을 걸어놓으면, 필터에 맞는 조건에 있는 로그만 EXPORT가 된다. 즉 로그 레벨이 CRITICAL한 로그만 Pub/Sub으로 로깅해서 알럿을 보내는 것과 같은 작업이 가능하게 된다.

빅쿼리로 EXPORT

그럼 그중에서 빅쿼리로 로그를 EXPORT하는 방법에 대해서 알아보기로 한다.

빅쿼리로 EXPORT하기 위해서는 CREATE EXPORT를 누른 후에, 로그 SINK 명을 지정하고 데이타셋을 지정해야 하는데, 데이타셋을 새로 생성하면 된다.


이 예제에서는 필터를 추가하여 label에서 instancename이 “instance-1”인 로그만 빅쿼리로 저장하도록 EXPORT 설정을 하였다.


http://bigquery.google.com에 들어가면 앞에 지정한 이름으로 데이타셋이 생긴것을 확인할 수 있고, 테이블명은 앞에서 지정한 로그명인 terry_tutorial 로 지정된것을 확인할 수 있다.

다음은 로그 시간과, JsonPay로드의 elapsedtime과, count 값을 조회하는 쿼리와 결과 이다.



쿼리 결과




데이타 스튜디오를 이용한 로그 시각화

이렇게 빅쿼리에 저장된 데이타는 구글 데이타 스튜디오를 이용하여 손쉽게 시각화가 가능하다.

https://datastudio.google.com에 접속한 후에, Start New Report에서 Blank Report 만들기를 선택한다.

새로운 리포트 화면이 나오면 우측 하단의

를 선택하여 빅쿼리 테이블과 연결을 한다.


좌측 커넥터를 선택하는 화면에서 BigQuery를 선택한후


MY PROJECT에서 내 프로젝트를 고르고, 데이타셋과 테이블은 선택한다.


다음으로 상단의 CONNECT 버튼을 눌러서 테이블을 연결한다. 또는 프로젝트를 선택하는 대신 CUSTOM QUERY를 누르면, 직접 SQL을 써서 특정 필드만 조회할 수 있다.


여기서는 전체 테이블을 불러오는 것으로 진행하도록 한다.

다음 화면에서는 필드 선택 및 제거, 그리고 타입 설정등이 가능하다.


적절하게 사용할 필드를 선택하고, 타입을 지정한후, 우측 상단의 ADD TO REPORT를 선택한다.

타임 스탬프는 일반적으로 일단위로 컨버팅 되기 때문에, 세밀한 로그를 원하면 분단위 등으로 변경하거나 커스텀 쿼리를 이용해서 초단위 값으로 컨버팅하기를 권장한다.

다음 메뉴에서 그래프나 표를 선택하여 적절하게 그리고, X 축은 Deminsion에 설정한다. 아래는 Dimension을 timestamp로 선택하고, Y축은 Metric 값으로 jsonPayload.count를 준 예이다.



혹시 테이블을 그린후에 데이타가 나오지 않는 경우가 있는데, 이 경우는 대부분 DataStudio의 Time zone과 빅쿼리에 저장된 Time이 맞지 않아서, 쿼리 범위에서 제외되는 경우인데, 이 경우는 그래프의 Property에서 날짜 범위를 다음과 같이 조정해주면 된다.



이외에도 다양한 기능이 있는데, 다음 문서들을 참고하기 바란다.




Logentries를 인스톨하고 나니, 얼마후에 무료로 Community pack을 인스톨하라고 이메일이 왔다.

https://community.logentries.com/packs/heroku/





CPU,Memory와 같은 인프라 모니터링도 가능하고, 앱 모니터링도 가능한 플러그인이다.

설치 방법이 복잡해서 당장은 실행은 해보지는 않았지만 시간 날때 테스트할만한 가치는 있는듯


Heroku에서 newrelic을 이용한 node.js 애플리케이션 모니터링 (APM)


조대협 (http://bcho.tistory.com)


Heroku에서 node.js 애플리케이션에 대한 모니터링을 살펴보자. 애플리케이션의 모니터링은 모니터링 분야에서 APM (Application Performance Monitoring)이라는 분야로, 애플리케이션에서 어떤 API 들이 호출이 되었는지, 각 로직별 응답 시간등을 추적할 수 있다. 한국에서 유명한 APM으로는 제니퍼가 있다.

Heroku에서 사용할 수 있는 APM은 여러가지가 있지만 여기서는 newrelic이라는 제품을 소개한다.

Newrelicheroku 뿐 아니라, 모니터링 시장에서 매우 유명한 제품으로 APM 기능뿐만 아니라, 서버 인프라에 대한 모니터링등 상당히 많은 기능을 제공한다.

Heroku에는 그러한 기능을 제공하지는 않고 newrelicAPM 기능만을 제공한다.

 

newrelic add-on 설치


newrelic add-on부터 설치한다. 설치 명령어는 다음과 같다.


%heroku addons:create newrelic:{상품명}


상품명은 무료 상품을 사용할 예정이기 때문에, 상품명은 ‘wayne’를 선택한다. Heroku addons 명령어를 이용해서 다음과 같이 addons를 추가 한다.



Figure 7 newrelic addon 설치

 

상품 모델은 https://elements.heroku.com/addons/newrelic#plan_selector 를 참고하면 된다.

3 dyno 모니터링에 월 49$, 300 dyno에 월 4499% 까지 다양한 상품 모델이 있다. 가격은 다른 상품에 비해서 싼편은 아니지만, APM 쪽에서 그만큼 많은 기능을 제공한다.

 

newrelic 환경 변수 설정


다음으로 추가적인 환경 설정이 필요하다. 다음과 같이 heroku config 명령어를 이용해서 다음 환경변수들을 설정한다.

 

환경변수명

설정값

설명

NEW_RELIC_APP

‘helloherokuterry’

newrelic 을 적용한 heroku 애플리케이션 이름. 여기서는  helloherokuterry 앱을 사용하기 때문에, helloherokuterry 를 사용한다

NEW_RELIC_NO_CONFIG_FILE

‘true’

newrelicnode.js에서 사용하기 위해서 원래는 newrelic.js 에 환경변수를 설정하는데, herokunewrelic에서 이 옵션을 설정하면 newrelic.js 환경에서 환경변수를 읽는데, newrelic.js를 사용하지 않고, heroku config 를 이용하여 환경 변수를 설정할 경우, 이 옵션을 ‘true’로 세팅한다.

Figure 8 newrelic 환경 변수 목록

 

다음은 heroku config 명령을 이용해서 위의 두 환경 변수를 설정한 화면이다.



Figure 9 newrelic 환경 변수 설정 화면

 

node.js 애플리케이션에 에이전트 코드 삽입


환경 변수 설정이 끝났으면, newrelic 에서 node.js 애플리케이션의 실행 정보를 수집할 수 있도록 코드를 삽입해야 한다.

에이전트는 ‘newrelic’ node.js 모듈을 설치해서 app.js 에서 로딩 하면 된다.

package.json에서 다음과 같이 newrelic 모듈에 대한 의존성을 추가한다.


{

  "name": "helloheroku",

  "version": "0.0.0",

  "private": true,

  "scripts": {

    "start": "node ./bin/www"

  },

  "dependencies": {

    "body-parser": "~1.13.2",

    "cookie-parser": "~1.3.5",

    "debug": "~2.2.0",

    "ejs": "~2.3.3",

    "express": "~4.13.1",

    "morgan": "~1.6.1",

    "serve-favicon": "~2.3.0",

    "stylus": "0.42.3",

    "newrelic" : "~1.25.5"

  }

}

Figure 10 package.json  newrelic 의존성 추가

 

다음으로 이 모듈을 애플리케이션에서 로딩해야 하는데, app.js 맨 윗줄에 아래와 같이 require(‘newrelic’) 코드를 삽입한다.

 

require('newrelic');

 

var express = require('express');

var path = require('path');

var favicon = require('serve-favicon');

Figure 11 app.jsnewrelic 에이전트 로딩 코드를 삽입

 

코드가 수정되었으면 heroku에 배포한다.

 

Newrelic을 이용한 모니터링


이제 모든 준비가 끝났다. 애플리케이션을 기동하고 heroku 대쉬보드로 들어가 보자



Figure 12 애플리케이션 선택

 

그림과 같이 대쉬보드에서 애플리케이션을 선택하면, 다음과 같이 newrelic addon이 추가된것을 확인할 수 있다.



Figure 13 newrelic APM addon이 추가된 화면

 

newrelic을 클릭해보면, 설정이 제대로 되었다면 다음과 같은 화면이 나올것이다.



Figure 14 newrelic 첫번째 접속 화면

 

상단에서 APM화면을 눌러서 APM 화면으로 들어가면 아래와 같이 애플리케이션 리스트들이 나오고, 아까 등록한 helloherokuterry 애플리케이션이 나온다.



Figure 15 newrelic에서 애플리케이션 선택

 

해당 애플리케이션을 클릭하면 다음과 같이 애플리케이션에 대한 상세 정보가 나온다.



Figure 16 newrelic APM 모니터링 화면

 

전체 응답시간(Web transation time), 초당 처리량 (Throughput), 주로 호출되는 웹 트렌젝션 목록등을 볼 수 있다.

그이에도 각 인스턴스에 대한 디테일이나 개별 트렌젝션에 대한 추적, 에러등에 대해서도 추적이 가능하다.