KUBERNETES

17. 로깅 시스템 구축 – 로키

1. 쿠버네티스 환경의 기본 애플리케이션 로그 설정과 Stern 도구 사용

로그는 시스템 장애 처리, 성능 문제 해결 및 보안 모니터링에 있어 필수적인 역할을 합니다. 이번 장에서는 쿠버네티스 환경에서 애플리케이션 로그를 효과적으로 관리하는 방법에 대해 살펴보겠습니다.

먼저 애플리케이션 로그 설정입니다. 

‘12-Factor App’ 가이드에 따르면 컨테이너 환경의 로그는 표준 출력(stdout)과 표준 에러(stderr)로 보내는 것을 권고합니다. 쿠버네티스에서 애플리케이션 로깅의 가장 기본적인 원칙입니다. 이 방식은 다음과 같은 이유로 권장됩니다:

  • 간소화된 로그 관리
    파일 시스템에 로그를 기록하는 대신 stdout과 stderr로 로그를 보내면, 쿠버네티스 시스템이 자동으로 로그를 캡처하고 관리할 수 있습니다.
  • 효율적인 로그 수집
    쿠버네티스는 stdout과 stderr에서 로그를 수집하여 Pod 별로 로그 파일을 생성합니다. 이는 로그 수집 솔루션(예: 로키,  Fluentd, Logstash)을 통해 중앙화된 로깅 시스템으로 전송될 수 있습니다.
  • 확장성 및 유지보수
    애플리케이션이 확장됨에 따라 로그 관리의 복잡성이 증가하지 않습니다. 개별 애플리케이션 별 별도 로그 파일 지정 등이 필요하지 않아 여러 컨테이너와 파드 간에 일관된 로깅 경험을 제공합니다.

대부분의 현대 애플리케이션과 로깅 프레임워크는 로그를 stdout과 stderr로 보낼 수 있도록 구성할 수 있어 특별한 어려움 없이 설정할 수 있습니다. 로깅 설정을 조정하여 로그 출력을 콘솔로 리디렉션할 수 있습니다.

해당 설정에 따라 작성된 컨테이너 애플리케이션의 로그는 해당 파드에 접속하지 않아도 원격에서 간편하게 ‘k logs’ 명령어로 애플리케이션 종류에 상관없이 단일 명령어로 조회할 수 있습니다. 기존 VM 환경은 애플리케이션마다 로그 파일 위치가 달라 해당 파일 이름을 기억해서 직접 VM에 접속하여 해당 로그를 조회해야하는 어려움이 있었습니다. 

‘kubectl logs’ 명령어는 쿠버네티스(Kubernetes) 클러스터에서 실행 중인 특정 파드의 로그를 조회하는 데 사용되는 기본 명령어입니다. 이 명령어는 간단하고 직관적으로 특정 파드의 로그를 쉽게 확인할 수 있게 해줍니다.

주로 ‘k logs -f’ 옵션을 추가하여 로그를 실시간으로 스트리밍하는(–follow) 방법으로 많이 사용합니다. 하지만 하나의 파드 로그만 조회 가능한 불편한 점이 있습니다.

‘kubectl stern’은 쿠버네티스 클러스터 내 여러 파드의 로그를 실시간으로 동시에 병렬적으로 조회할 수 있는 도구입니다. ‘stern’은 파드 이름이나 레이블 셀렉터를 통해 다중 파드의 로그를 한 번에 조회할 수 있습니다. 예를 들어 레이블 셀렉터를 사용하여 특정 서비스나 애플리케이션에 속하는 모든 파드의 로그를 쉽게 확인할 수 있습니다.

그리고 로그 출력 시 각 파드의 로그를 다른 색상으로 표시하여, 어떤 로그가 어느 파드에서 나왔는지 쉽게 구별할 수 있게 해줍니다. 파드 이름이나 컨테이너 이름은 정규 표현식을 사용하여 필터링할 수 있습니다. 이는 보다 정교한 로그 조회를 가능하게 합니다.

예를 들어 Ingress 설정 후 ALB가 정상으로 설정이 안되어 있으면 aws-load-balancer-controller 로그를 확인합니다. 그런데 파드가 아래와 같이 2개가 실행 중 입니다.

(jerry-test:kube-system)~$ k get pod --selector app.kubernetes.io/name=aws-load-balancer-controller
NAME                                            READY   STATUS    RESTARTS   AGE
aws-load-balancer-controller-677cdb6b5c-7jz2f   1/1     Running   0          24d
aws-load-balancer-controller-677cdb6b5c-dzs7c   1/1     Running   0          24d

이 때 ‘k stern’ 명령어를 사용하면 간단하게 파드 이름의 앞부분, ‘aws-load’만 입력하면 2개의 파드 로그를 모두 간편하게 조회할 수 있습니다.

(jerry-test:kube-system)~$ k stern aws-load
+ aws-load-balancer-controller-677cdb6b5c-dzs7c > aws-load-balancer-controller
+ aws-load-balancer-controller-677cdb6b5c-7jz2f > aws-load-balancer-controller
aws-load-balancer-controller-677cdb6b5c-7jz2f aws-load-balancer-controller {"level":"info","ts":"2023-12-24T16:43:27Z","logger":"controllers.ingress","msg":"Auto Create SG","LB SGs":[{"$ref":"#/resources/AWS::EC2::SecurityGroup/ManagedLBSecurityGroup/status/groupID"},"sg-05575a71e55ab5c89"],"backend SG":"sg-05575a71e55ab5c89"}

설치는 k krew를 이용하여 편리합니다.

(jerry-test:kube-system)~$ k krew install stern

2. 쿠버네티스 로그 조회 시스템 : ELK 스택에 비교하여 로키의 장점

전통적으로 ELK 스택(Elasticsearch, Logstash, Kibana)이 로그 수집 및 분석을 위한 강력한 솔루션으로 널리 사용되어 왔습니다. 그러나 쿠버네티스 환경에서는 최근 Grafana의 로키(Loki)가 주목을 받고 있습니다. Loki는 쿠버네티스와의 통합, 설정의 용이성, 자원 사용 효율성 면에서 주목할 만한 장점을 제공합니다.

국내에도 우아한 형제 등 많은 기업에서 도입하고 있습니다.

간단히 ELK를 알아보면, ELK 스택의 Elasticsearch는 분산 검색 및 데이터 분석 엔진이며, Logstash는 다양한 소스에서 로그를 수집하고 변환하는 서버사이드 데이터 처리 파이프라인입니다. Kibana는 Elasticsearch 데이터를 시각화하고 탐색하는 사용자 인터페이스를 제공합니다.

이에 반하여 Loki는 Grafana Labs에서 개발한 로그 수집 시스템으로, 특히 쿠버네티스와의 긴밀한 통합으로 인기를 얻고 있습니다. Loki는 Prometheus의 데이터 모델에 영감을 받아 설계되었으며, 간소화된 아키텍처를 가지고 있습니다.

로키의 주요 특징입니다.

  • 설치 및 설정의 용이성

Loki는 ELK 스택에 비해 설치 및 설정이 훨씬 간단합니다. 쿠버네티스 환경에서 헬름 차트로 별다른 설정 변경없이 Loki를 배포할 수 있습니다. 이는 시스템 관리자와 개발자 모두에게 시간 절약과 효율성을 의미합니다.

  • 낮은 자원 사용
    Loki는 Elasticsearch에 비해 상대적으로 낮은 CPU 및 메모리 자원을 사용합니다. 이는 비용 절감 차원에서 매우 큰 장점입니다. Loki는 인덱싱을 최소화하고 로그 데이터 자체를 압축하여 저장함으로써 효율적인 자원 사용을 달성합니다. 많은 사례에서 공유하듯이 기존 ELK 스택에 비하여 약 30% 이상 비용을 절약할 수 있습니다.

  •  S3 호환 스토리지 사용
    Loki는 Amazon S3, Google Cloud Storage, Microsoft Azure Storage와 같은 S3 호환 오브젝트 스토리지를 사용하여 로그 데이터를 저장할 수 있습니다. S3는 EBS 등에 비하여 비용이 저렴합니다. 그리고 S3는 미리 용량을 지정하지 않을 수 있어 넉넉하게 용량을 설정하는 ELK에 비하여 스토리지 비용을 절감할 수 있습니다. 

물론 S3 스토리지를 사용하여 성능이 떨어질 수 있습니다. 하지만 적절한 성능 튜닝으로 많은 부분 해결 할 수 있습니다. 쿠버네티스 환경에서 로그 관리 시스템을 선택할 때, Loki는 간소화된 설치 및 설정, 낮은 자원 사용으로 비용 절감, S3 호환 스토리지의 효율적 사용 등의 장점을 가지고 있습니다. ELK 스택이 제공하는 강력한 기능과 광범위한 사용 사례에도 불구하고, Loki는 특히 쿠버네티스 환경에서 더 나은 선택이 될 수 있습니다. 

최근에 비용 절감 요구 사항이 높아지면서 로키의 도입이 더욱 많아졌습니다.

3. S3를 이용한 Loki와 Promtail 설치 가이드

이번 절에서는 Amazon S3를 이용한 Loki의 설치 및 설정 방법과 Promtail, Loki의 로그 수집 에이전트, 설치 방법을 안내합니다. 크게 3가지 부분으로 나누어집니다. 로그 저장 용도로 S3를 사용하므로 사전에 S3를 설치하는 과정이 필요합니다.

  1. 로키 로그 저장용 S3 버킷 설정
  2. S3 스토리지 사용을 위한 IRSA 설정
  3. 헬름 차트를 이용한 로키 및 Promtail 설치

먼저 S3 버킷 설정입니다. S3와 같이 AWS 자원은 테라폼을 이용하는 것이 향후 재사용성과 재현 측면에서 유리합니다. 필자의 S3 테라폼 코드입니다. 아래 코드는 필자의 깃헙 링크에서 확인할 수 있습니다.

  • s3.tf
resource "aws_s3_bucket" "this" {
  bucket = "${var.s3_bucket_name}-${var.codename}"
}

resource "aws_s3_bucket_public_access_block" "this" {
  bucket = aws_s3_bucket.this.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}
  • variables.tf
variable "codename" {
  type    = string
  default = "jerry-test"
}

variable "s3_bucket_name" {
  type    = string
  default = "loki-s3"
}

codename, 버킷 이름 등은 임의로 변경하실 수 있습니다.

다음은 S3 스토리지를 사용하기 위해서 iam policy와 iam role을 생성합니다. 역시 테라폼을 이용합니다. (깃헙 링크) S3에 데이터를 쓰고 조회하는 권한 등이 필요합니다.

resource "aws_iam_policy" "AWSS3EksLokiAccess" {
  name        = "AWSS3EksLokiAccess"
  path        = "/"
  description = "AWSS3EksLokiAccess"

  # Terraform's "jsonencode" function converts a
  # Terraform expression result to valid JSON syntax.
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "s3:ListBucket",
          "s3:PutObject",
          "s3:GetObject",
          "s3:DeleteObject",
        ]
        Effect = "Allow"
        Resource = [
          "arn:aws:s3:::*",
          "arn:aws:s3:::*/*"
        ]
      },
    ]
  })
}

resource "aws_iam_role" "loki_s3" {
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow",
        Principal = {
          Federated = "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/oidc.eks.ap-northeast-2.amazonaws.com/id/${ENDPOINT_URL}"
        },
        Action = "sts:AssumeRoleWithWebIdentity"
        Condition = {
          StringEquals = {
            "oidc.eks.ap-northeast-2.amazonaws.com/id/${ENDPOINT_URL}:aud" = "sts.amazonaws.com"
            "oidc.eks.ap-northeast-2.amazonaws.com/id/${ENDPOINT_URL}:sub" = "system:serviceaccount:monitoring:loki"
          }
        }
      },
    ]
  })
  description           = "loki role for loki-jerry-test eks"
  force_detach_policies = false
  managed_policy_arns   = ["arn:aws:iam::${ACCOUNT_ID}:policy/AWSS3EksLokiAccess"]
  max_session_duration  = 3600
  name                  = "loki-jerry-test"
  path                  = "/"
}

위 테라폼 파일을 기준으로 AWS 자원을 생성합니다.

(jerry-test:monitoring)loki-s3$ tf init
(jerry-test:monitoring)loki-s3$ tf plan -out planfile
(jerry-test:monitoring)loki-s3$ tf apply planfile

테라폼 코드를 실행하면 아래와 같이 로키 관련 버킷과 IAM Role을 확인할 수 있습니다.

S3 Bucket

IAM Role

이제 로키 헬름 차트를 설치하기 위한 AWS 자원 설정을 테라폼을 이용하여 완료하였습니다. 헬름을 이용하여 로키를 설치합니다.

$helm repo add grafana https://grafana.github.io/helm-charts

설치에 사용한 헬름 Values 파일니다. (깃허브 링크)

serviceAccount:
  annotations:
    "eks.amazonaws.com/role-arn": arn:aws:iam::${ACCOUNT_ID}:role/loki-jerry-test

loki:
  auth_enabled: false

  limits_config:
    retention_period: 5d
    enforce_metric_name: false

  querier:
    max_concurrent: 10
    query_timeout: 30m 
    engine:
      timeout: 30m

  server:
    http_listen_port: 3100

  storage:
    type: "s3"
    s3:
      region: ap-northeast-2
    bucketNames:
      chunks: loki-s3-jerry-test
      ruler: loki-s3-jerry-test
      admin: loki-s3-jerry-test

주요 설정입니다.

serviceAccount.annotations
앞에서 생성한 Role ARN 정보를 입력합니다. 로키가 외부 AWS S3 리소스를 사용하기 위한 권한을 지정합니다.

loki.limits_config.retention_period: 5d
로그를 보관할 기간을 지정합니다. 테스트 서비스라 5일로 지정하였고 개별 설정에 따라 1개월 혹은 6개월 등으로 변경할 수 있습니다.

querier 관련 설정
max_concurrent: 동시에 처리할 수 있는 쿼리의 최대 수를 정의합니다.
query_timeout: 쿼리 실행에 대한 타임아웃을 설정합니다.
engine: 쿼리 엔진의 설정으로, 여기서는 타임아웃을 30분으로 설정합니다.

storage 관련 설정
type: 사용할 스토리지 유형을 설정합니다. 여기서는 AWS의 S3를 사용합니다.
s3.region: S3 스토리지의 설정으로, AWS 리전을 지정합니다.
bucketNames: 다양한 Loki 구성 요소에 사용될 S3 버킷 이름을 지정합니다. 앞에서 생성한 버킷 이름을 사용합니다.

준비된 헬름 Values 파일을 이용하여 로키를 설치합니다.

$ helm install --values ci/jerry-test-values.yaml loki grafana/loki --version 5.36.3 -n monitoring
NAME: loki
LAST DEPLOYED: Fri Dec  8 14:31:35 2023
NAMESPACE: monitoring
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
***********************************************************************
 Welcome to Grafana Loki
 Chart version: 5.36.3
 Loki version: 2.9.2
***********************************************************************

Installed components:
* gateway
* read
* write
* backend

설치가 완료되면 로키 관련 파드를 확인할 수 있습니다.

$ k get pod --selector app.kubernetes.io/instance=loki
NAME                            READY   STATUS    RESTARTS   AGE
loki-backend-0                  2/2     Running   0          4d22h
loki-backend-1                  2/2     Running   0          4d22h
loki-backend-2                  2/2     Running   0          4d23h
loki-gateway-5c6c8479c9-47drn   1/1     Running   0          4d23h
loki-read-688c4b6867-8t5wz      1/1     Running   0          4d23h
loki-read-688c4b6867-pmrtq      1/1     Running   0          4d23h
loki-read-688c4b6867-wh47r      1/1     Running   0          4d23h
loki-write-0                    1/1     Running   0          4d23h
loki-write-1                    1/1     Running   0          4d23h
loki-write-2                    1/1     Running   0          4d23h

다음으로 Promtail을 헬름으로 설치합니다. Promtail은 Grafana Loki에 로그를 전송하는 에이전트로, Kubernetes 클러스터 내에서 실행되는 컨테이너들의 로그를 수집하는 데 사용됩니다

헬름을 이용한 설치 방법은 기존과 동일하게 헬름 차트를 로컬에 내려 받고 설치하는 방법 혹은 인터넷에 공개된 헬름 차트를 이용하여 설치할 수 있습니다.

아래는 로컬에 내려받아 설치하는 방법입니다.

$ helm pull grafana/promtail --version 6.15.3
$ tar xvfz promtail-6.15.3.tgz 

$ rm -rf promtail-6.15.3.tgz 
$ mv promtail/ promtail-6.15.3

Values.yaml 파일은 아래와 같이 수정합니다. (깃허브 링크)

# helm upgrade --install promtail grafana/promtail --version 6.15.3 -n monitoring --values values.yaml
priorityClassName: system-node-critical

# -- Default volumes that are mounted into pods. In most cases, these should not be changed.
# Use `extraVolumes`/`extraVolumeMounts` for additional custom volumes.
# @default -- See `values.yaml`
defaultVolumes:
  - name: run
    hostPath:
      path: /run/promtail
  - name: containers
    hostPath:
      path: /var/lib/docker/containers
  - name: pods
    hostPath:
      path: /var/log/pods

tolerations:
  - effect: NoSchedule
    operator: Exists

priorityClassName: system-node-critical
이 설정은 Promtail 파드에 우선 순위 클래스를 할당합니다. 이는 해당 파드가 시스템 수준의 작업에 매우 중요하다는 것을 나타냅니다. 카펜터 환경에서 자원이 부족한 경우 Promtail 파드가 실행되지 못하는 경우를 막기 위하여 설정합니다. 일반적으로 각 노드에서 실행되어야 하는 중요한 시스템 서비스에 사용됩니다.

defaultVolumes
이 섹션은 Promtail 파드에 기본적으로 마운트되는 볼륨을 정의합니다. 

name: run
hostPath: /run/promtail로, 호스트 노드의 디렉토리를 컨테이너에 매핑합니다. 이는 Promtail의 런타임 데이터에 사용됩니다.

name: containers
hostPath: /var/lib/docker/containers로, Promtail이 Docker 컨테이너 로그에 접근할 수 있도록 합니다. Docker Runtime을 사용하지 않지만 기본 설정으로 추가하였습니다.

name: pods
hostPath: /var/log/pods로, Kubernetes 파드 로그에 접근할 수 있게 합니다. ContainerD Runtime 환경에서 클러스터 전반에 걸친 다양한 파드의 로그를 수집하는 데 필수 설정입니다.

tolerations
tolerations 섹션은 Promtail 파드가 특정한 테인트(taint)가 있는 노드에 스케줄될 수 있도록 합니다. 

여기서의 설정 (effect: NoSchedule, operator: Exists)은 Promtail 파드가 NoSchedule 효과를 가진 어떤 테인트도 용인할 수 있다는 것을 의미합니다. 즉, Promtail 파드는 적용된 테인트에 관계없이 모든 노드에 스케줄될 수 있어, 클러스터의 모든 부분에서 로그 수집이 가능합니다.

해당 설정으로 설치합니다.

$ helm install promtail -f ci/jerry-test-values.yaml .
NAME: promtail
LAST DEPLOYED: Fri Dec  8 17:39:25 2023
NAMESPACE: monitoring
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
***********************************************************************
 Welcome to Grafana Promtail
 Chart version: 6.15.3
 Promtail version: 2.9.2
***********************************************************************

Verify the application is working by running these commands:
* kubectl --namespace monitoring port-forward daemonset/promtail 3101
* curl http://127.0.0.1:3101/metrics

Promtail은 데몬셋으로 실행하는 모든 노드에 설치됩니다.

(jerry-test:monitoring)loki$ k get pod --selector app.kubernetes.io/name=promtail
NAME             READY   STATUS    RESTARTS   AGE
promtail-g7kz6   1/1     Running   0          9d
promtail-mxxkk   1/1     Running   0          9d
promtail-rnlrq   1/1     Running   0          9d
promtail-tvswz   1/1     Running   0          4d23h

이제 Loki, Prometail 설정이 완료되었습니다.

4. 그라파나 로키 로그 시스템 조회

로키에 저장되어 있는 로그는 그라파나를 이용하여 조회할 수 있습니다. 그라파나에서 로키를 이용하여 파드 로그를 조회할 수 있도록 그라파나 설정의 ‘Data Sources’에 로키를 추가합니다.

그라파나 화면 왼편의 메뉴 – ‘Connections’ 선택합니다.

이어지는 화면에서 ‘loki’를 입력합니다.

로키 데이터 소스 추가를 위하여 화면 오른편 ‘Create a loki data source’를 클릭합니다.

그라파나에서 로키 파드를 접속하여 로키의 데이터를 가져오는 설정입니다. 클러스터 내부 통신이고 같은 monitoring 네임스페이스에 있으므로 로키 gateway  서비스 이름을 사용하면 됩니다.

(jerry-test:monitoring)Documents$ k get svc loki-gateway
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
loki-gateway   ClusterIP   172.20.51.165   <none>        80/TCP    11d

로키 gateway 서비스 이름을 아래 스크린 캡쳐의 URL에 입력합니다.

그라파나에서 로키 연동이 완료되었습니다. 실제 파드 로그를 조회해 보겠습니다.

그라파나의 로키 로그 조회는 ‘Explore’ 메뉴를 사용합니다.

데이터 소스로 기본 설정(default) ‘Prometheus’가 아닌 ‘Loki’를 선택합니다.

이제 조회하고 싶은 파드를 지정하여 로그를 확인할 수 있습니다.  로키 메뉴의 화면 오른편 ‘Builder or Code’를 선택합니다.

Builder or Code

  • Builder : 로그 Label Filter 선택 메뉴를 drop down 형식으로 선택할 수 있습니다. 메뉴 중에서 선택할 수 있어 좀 더 쉽게 사용할 수 있습니다.
  • Code : 메뉴 선택이 아니라 직접 필요한 레이블을 입력하여 로그를 조회합니다. 메뉴를 선택할 수 없으나 자동 완성 기능을 지원합니다.

Builder 또는 Code 2가지 방법 중에서 편한 것을 선택합니다.

로키 로그 조회 LogQL은 Prometheus Query와 유사하게 레이블과 로그 텍스트 조회 2가지로 나누어 집니다.

예를 들어 앞 부문 {job=”karpenter/karpenter”} 은 레이블 기준이고 뒷부분  |=”INFO”은 상세 로그 내용을 기준으로 검색합니다.

앞 레이블은 로키가 자동으로 추가하는 쿠버네티스의 각종 레이블에서 선택하는 내용으로 namespace, pod 이름 등 다양한 레이블에서 내가 원하는 레이블만 필터링 할 수 있습니다.

필자는 네임스페이스와 Deployment, Statefulset 등 워크로드 이름으로 선택이 가능한 ‘job’을 디폴트로 사용합니다. 독자 여러분도 ‘job’을 사용하면 효율적입니다. 

레이블을 선택하고 이제 상세 로그 내용은 정규 표현식을 포함한 다양한 필터링 기준으로 검색할 수 있습니다. 

정규 표현식 등을 포함하여 필요한 로그 내용을 필터링할 수 있습니다.

필자의 {job=”karpenter/karpenter”} |=”INFO” 예시는 카펜터 로그에서 ‘INFO’를 포함한 로그를 검색하는 예제입니다. 각자 필요한 조건에 따라  조합하면 어렵지 않게 사용할 수 있습니다.

로그를 조회하다 보면 성능이 떨어진다라고 느끼는 경우가 종종 있습니다. 자세한 성능을 확인하고 싶으면 메뉴의 ‘Inspector’를 선택하면 상세한 성능 정보를 조회할 수 있습니다.

5. 그라파나 로그 대시보드 및 로그 알람 설정

기존 대시보드에 아래와 같이 해당 파드의 로그를 포함한 대시보드를 포함할 수 있습니다. 예를 들어 CPU, Memory 등의 사용량이 높은 경우 해당 시간대의 로그를 하나의 대시보드에서 같이 조회할 수 있어 편리합니다. 또한 로그를 기준으로 알람 설정도 가능합니다.

먼저, 로그 대시보드를 추가하는 방법입니다. 기존 대시보드 혹은 새로운 대시보드 생성을 선택하고 화면의 오른편 메뉴 ‘Add’ – ‘Visualization’를 추가합니다.

이어지는 화면에서 ‘Data Source’에서 기존의 Prometheus가 아닌 Loki를 선택합니다.

그리고 그래프 타입을 기본 ‘Time Series’가 아닌 ‘Logs’를 선택합니다.

이렇게 2가지 설정, Data Sources – Loki, Visualization 방식을 Logs를 선택합니다. 이제 기존과 동일하게 검색하려는 로그의 파드를 레이블을 선택하면 대시보드에 로그 검색 패널을 추가할 수 있습니다.

다음으로 로그 알람 설정을 위한 Count 설정입니다. 알람을 설정하기 위해서는 텍스트가 아닌 숫자로 변경해야 합니다. 특정 로그 패턴이 발생하는 로그를 숫자로 카운트하여 임계값을 초과하는 상황 발생 시 그라파나 알람 기능을 이용하여 알람을 전송할 수 있습니다. 

먼저 기존 로그 대시보드를 복제(‘Duplicate’)합니다.

대시보드 오른편의 ‘Edit’ 메뉴를 선택하여 상세한 설정을 변경합니다. 2가지 설정이 필요합니다. 먼저, 로그에서 알럿을 보내기 원하는 패턴(ex. error 등)을 지정합니다. 아래 예시는 로그에서 대소문자 구분없이 ‘info’ 문자열을 포함한 로그를 필터링합니다. 그리고 해당 로그 발생 빈도를 ‘Count over time’ 함수로 확인합니다. 발생 간격은 ‘$__interval’로 지정하면 그라파나에서 자동으로 발생 간격을 할당합니다.

이후 그래프 타입을 ‘Logs’가 아닌 기본 ‘Time series’를 선택합니다. 그러면 그래프를 확인할 수 있습니다.

이제 해당 그래프를 기준으로 알람을 설정할 수 있습니다. 메뉴의 ‘Alert’을 선택합니다.

이어지는 화면에서 원하는 알람 기준을 지정할 수 있습니다. 예를 들어 지난 1시간 동안 ‘info’ 문구를 포함한 로그가 1번 이상 1분 간격으로 체크하여 5분간 발생하면 알람을 발생하도록 아래와 같이 지정하였습니다.

처음 얼럿을 설정하면 다소 혼란스러울 수 있으나 2 ~ 3번만 하다보면 익숙해집니다. 메뉴에 따른 반복 작업이라 경험만 쌓이면 크게 어렵지는 않습니다.

완료된 얼럿 관련 설정은 홈 화면의 ‘Alerting’ 메뉴에서 확인할 수 있습니다.

Custom 등록한 얼럿을 확인할 수 있습니다.

6. 정리

쿠버네티스에서 로그 관리는 운영의 효율성과 시스템의 안정성에 필수입니다. 이번 블로그 글을 통해 로키 로그 시스템의 중요성과 그 구현 방법을 살펴보았습니다.

쿠버네티스 클러스터의 파드 로그는 표준 출력, 표준 에러 형태로 저장됩니다. 사용자는 애플리케이션 종류에 상관없이 ‘k logs’ 동일 명령어로 파드의 로그를 조회할 수 있습니다. 로키는 오픈소스 로그 통합 시스템으로 로그 텍스트 전체를 인덱스하지 않고 메타데이터 레이블 정보만 인덱스하여 자원 소요량이 작은 것이 큰 장점입니다. ELK 스택에 비해 경량화되어 비용을 절감할 수 있습니다. 설치 및 유지보수의 용이함, Prometheus와의 통합 모니터링 기능은 로키를 쿠버네티스 환경에 이상적으로 만듭니다. 

로키와 Promtail의 설치 과정은 헬름을 이용하여 비교적 어렵지 않습니다. 그라파나를 통한 로그 조회와 LogQL 사용법은 로그 관리를 더욱 효과적으로 만듭니다. 로그 조회는 Prometheus 쿼리 사용법과 크게 다르지 않아 비교적 적응하기가 용이합니다. 마지막으로, 그라파나를 활용한 로그 대시보드 및 알람 설정을 알아보았습니다.

이 글을 통해 쿠버네티스 환경에서 로키를 효과적으로 활용하는 방법에 대한 이해가 깊어졌기를 바랍니다. 로키를 통해 쿠버네티스 로그 관리의 복잡성을 줄이고, 시스템의 성능과 안정성을 개선할 수 있는 기회를 얻었기를 바랍니다.

해당 기술 블로그에 질문이 있으시면 언제든지 문의해 주세요. 직접 답변해 드립니다.
k8sqna@jennifersoft.com

1.12-Factor App 개발 가이드, https://12factor.net/ 
2. 로키는 북유럽 신화에 등장하는 주로 장난을 좋아하는 신 입니다. 프로메테우스와 동일하게 신의 이름을 사용합니다.  https://en.wikipedia.org/wiki/Loki
3.우아한 형제 로커 도입 블로그, https://techblog.woowahan.com/14505/



Next

Contact Us

안녕하세요? 제니퍼소프트입니다.
기술 문의의 경우 질문자의 회사/이름/연락처를 본문에 기술해 주셔야만 원할한 지원이 가능합니다.
보내주신 문의 사항을 검토하여 빠른 시일 내에 답변해 드리겠습니다.

  • Chris
  • Irene

메일을 보냈습니다.

메일 전송이 완료되었습니다.
빠른 시일 내에 답변드리겠습니다.
감사합니다.
제니퍼소프트 웹사이트는 쿠키를 사용합니다. 쿠키에 대한 자세한 정보 및 삭제 방법은 제니퍼소프트의 개인정보처리방침을 참고하시기 바라며 본 사이트를 계속해서 이용하는 것은 제니퍼소프트의 쿠키 사용에 동의함을 의미합니다.