쿠버네티스를 사용하다보면 컨테이너 내부에서 발생하는 표준 출력 로그에 대한 모니터링이 필요할 때가 있습니다.
이번에는 로그를 수집하는 Promtail, 수집된 로그를 저장하는 Loki, 저장된 로그를 시각화하는 Grafana를 이용하여 컨테이너 로그 모니터링 시스템을 구축해보도록 하겠습니다.
요건
- 웹 서버(nginx,apache 등) 컨테이너에서 발생하는 access 로그를 모니터링 합니다.
환경
- Kubernetes Cluster - 1개 이상의 Control plane, 1개 이상의 Worker Node(+Public IP)
Process
- 환경 준비
- helm chart를 이용하여 Loki, Promtail 설치
- helm chart를 이용하여 Grafana 설치
- nginx 배포 및 접속확인
- Grafana 설정 및 nginx access log 모니터링
- nginx access log를 Grafana에서 바로 확인할 수 있는 이유?
주의 사항
- 별도의 Ingress 없이 Service의 NodePort를 이용하여 Worker Node에 직접 접속하여 확인하므로 공인 아이피 및 ACG 설정이 필요합니다.
1. 환경 준비
NCP 관리형 쿠버네티스 서비스를 이용하거나 수동으로 쿠버네티스 클러스터를 구축합니다.
이번에는 NCP 관리형 쿠버네티스 서비스를 사용하여 환경을 구축하였으며 NCP 공식 다큐먼트를 통해 생성 방법을 확인할 수 있습니다.
https://guide.ncloud-docs.com/docs/k8s-k8sstart
쿠버네티스 클러스터 생성 이후 쿠버네티스를 remote로 제어하기 위해 서버 한대를 추가로 생성하였으며 kubeconfig 파일 생성 및 iam 등록을 진행합니다.
https://guide.ncloud-docs.com/docs/k8s-iam-auth-ncp-iam-authenticator
마지막으로 kubectl 명령어를 사용하기 위해 설치를 진행합니다.
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
Loki,Promtail,Grafana의 경우 별도의 네임스페이스에 생성할 예정이므로 kubectl 명령어로 네임스페이스를 생성합니다.
kubectl --kubeconfig=/root/kubeconfig.yaml create namespace monitoring
*kubeconfig 위치의 경우 생성한 config 파일 위치로 설정합니다.
2. helm chart를 이용하여 Loki, Promtail 설치
helm이란 쿠버네티스 패키지 매니저로 원하는 패키지를 쿠버네티스에 쉽게 설치할 수 있게 해줍니다.
먼저 helm 설치를 진행합니다.
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
loki, promtail, grafana 설치를 위해 grafana 저장소를 추가하고 업데이트 합니다.
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
loki-stack을 설치하기 위해 helm 명령어를 이용하여 관련 yaml을 출력하고 수정합니다.
(loki와 promtail을 제외하고 나머지 내용은 삭제합니다.)
helm show values grafana/loki-stack > loki-stack-values.yaml
loki:
enabled: true
persistence:
enabled: true
size: 1Gi
promtail:
enabled: true
수정한 내용을 yaml을 이용하여 loki와 promtail을 설치합니다.
helm --kubeconfig=/root/kubeconfig.yaml install loki-stack grafana/loki-stack --values loki-stack-values.yaml -n monitoring
*helm으로 패키지를 설치할때도 kubeconfig 옵션을 사용하여 kubeconfig.yaml 파일을 참조해야 합니다.
loki와 promtail이 잘 설치된 것을 확인할 수 있습니다.
3. helm chart를 이용하여 Grafana 설치
helm chart를 이용하여 grafana를 바로 설치할 수 있지만, Admin Password 변경과 NodePort 설정을 하기 위해 몇가지 수정을 진행해야 합니다.
먼저 git clone을 통해 grafana 패키지를 다운로드 합니다.
git clone https://github.com/grafana/helm-charts.git
cd helm-charts/charts/grafana
value.yaml 파일의 내용을 수정하여 admin Password와 NodePort 설정을 진행합니다.
vi value.yaml
...
# Administrator credentials when not using an existing secret (see below)
adminUser: admin
adminPassword: {설정할 패스워드}
...
vi value.yaml
...
service:
enabled: true
# type: ClusterIP
type: NodePort
port: 80
targetPort: 3000
nodePort: 31000
...
수정한 파일을 지정하여 grafana를 설치합니다.
helm --kubeconfig=/root/kubeconfig.yaml install grafana grafana/grafana -f values.yaml --namespace monitoring
다음과 같이 Loki, promtail, grafana가 정상적으로 설치된 것을 확인할 수 있습니다.
[워커노드IP]:31000 으로 접속하여 grafana에 접속하여 admin/설정한 비밀번호를 입력합니다.
그라파나에 정상적으로 접속되는 것을 확인할 수 있습니다.
4.nginx 배포 및 접속 확인
nginx 배포를 위해 deployment와 service를 작성합니다.
vi nginx_deploymnet.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 2
selector:
matchLabels:
type: nginx
version: v1
template:
metadata:
labels:
type: nginx
version: v1
spec:
containers:
- name: nginx-01
image: nginx:latest
ports:
- containerPort: 80
vi nginx_service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
type: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
type: NodePort
생성된 두개의 파일을 쿠버네티스 클러스터에 배포합니다.
kubectl --kubeconfig=/root/kubeconfig.yaml apply -f nginx_deployment.yaml
kubectl --kubeconfig=/root/kubeconfig.yaml apply -f nginx_service.yaml
[워커노드IP]:30080을 통해 nginx 홈페이지에 접속할 수 있습니다.
5. Grafana 설정 및 nginx access log 모니터링
Grafana에서 Loki 데이터를 확인하기 위해 Data Source 지정이 필요합니다.
Configuration > Data Source를 클릭합니다.
Loki를 검색 후 클릭한 다음 설정을 진행하고 save&test로 저장합니다.
URL : http://loki-stack:3100
메뉴바에서 Explorer로 이동한 다음 Label filters에서 Container, nginx-01을 클릭합니다.
Run query를 누르기에 앞서 nginx 웹피이지([워커노드IP]:30080)를 새로고침을 통해 여러번 접속합니다.
이후 Run query를 클릭하면 nginx access log를 정상적으로 확인할 수 있습니다.
6.nginx access log를 Grafana에서 바로 확인할 수 있는 이유?
해당 글을 시작할때 promtail에서 로그를 수집하고 loki에서 로그를 저장하며 Grafana에서 저장된 로그를 시각화한다고 말씀 드렸는데요, 조금 더 자세히 살펴보도록 하겠습니다.
로그를 수집하는 promtail의 경우 노드마다 설치되는 daemonset 타입으로 배포가 되게 됩니다. 그 이유는 kubectl edit 명령어를 통해 확인할 수 있습니다.
kubectl --kubeconfig=/root/kubeconfig.yaml edit daemonset.apps/loki-stack-promtail -n monitoring
loki-stack-promtail.yaml의 내용을 쭉 보다보면 마지막 부분에 volume과 관련된 내용을 확인할 수 있습니다.
hostPath로 설정된 것중 /var/log/pods가 있는데, 이는 해당 데몬 셋으로 생성된 해당 컨테이너가 워커노드의 해당 경로를 공유하여 사용하겠다는 의미입니다.
그렇다면 워커노드의 /var/log/pods에는 무엇이 있을까요?
아래 이미지를 보면 파드명을 가진 디렉터리들이 있으며 해당 디렉터리에는 "표준 출력" 형식의 로그들이 있음을 알 수 있습니다.
배포한 nginx pod의 디렉터리에서 0.log의 내용을 tail로 확인하면 방금전 우리가 Grafana에서 확인했던 로그의 내용을 볼 수 있습니다.
즉, Promtail이 DaemonSet형식으로 배포되는 이유는 각 워커노드의 /var/log/pods의 로그를 수집하기 위함이고 초기 배포만 진행해도 해당 로그에 표준 출력으로 나오는 로그의 내용을 수집하여 Loki -> Grafana로 보낼 수 있게 되는 것입니다.
이러한 초기 설정 말고도 promtail의 config를 수정하는 것으로 다양한 로그 수집 방법을 구성할 수 있으며 상황에 맞게 선택하여 사용하시면 좋을 것 같습니다.