1
2
Production Kubernetes Online Study (=PKOS)는 쿠버네티스 실무 실습 스터디입니다.
CloudNet@ Gasida(가시다)님이 진행하시며, 책 "24단계 실습으로 정복하는 쿠버네티스"을 기반으로 진행하고 있습니다.

스터디 4주차 시간에는 쿠버네티스 모니터링과 로깅 시스템을 구축하여 기능들을 살펴보았다. 이번 블로그 글에서는 모니터링 시스템에 대해 심화 학습한 내용들을 공유하고자 한다.

모니터링은 어떤 대상을 감시, 감찰한다는 뜻으로 모니터링의 목적은 지속적인 감시, 감찰을 통해 대상의 상태나 가용성, 변화 등을 확인하고 대비하는 것이다. 모니터링의 개념처럼 쿠버네티스 모니터링도 똑같다. 쿠버네티스에서 특정 기간에 측정한 일련의 숫자(메트릭)에 대해 감시와 감찰을 통해 대상의 상태나 가용성 변화를 확인하고 대비한다고 보면 되겠다. 쿠버네티스 모니터링 시스템으로는 Prometheus, InfluxDB, DataDog, 클라우드 프로바이더 등이 있으나 이번 블로그 글에서는 오픈소스 모니터링 시스템인 Prometheus와 기능 확장 시스템인 Thanos를 다루겠다.


Prometheus

오픈 소스 모니터링 시스템이다. 시계열 데이터 수집, 저장 및 쿼리 기능을 제공하고 다양한 경고 기능을 제공한다. 오픈소스 진영에서 가장 많이 사용하는 모니터링 시스템으로 사실상 거의 표준처럼 사용하고 있다. 아키텍처는 다음과 같다. (공식문서)

<a href="https://prometheus.io/docs/introduction/overview/">https://prometheus.io/docs/introduction/overview/</a>

https://prometheus.io/docs/introduction/overview/

빨간 네모로 표시된 것이 프로메테우스 구성 컴포넌트이다.

  • Prometheus Server : Prometheus 서버는 메트릭 수집, 저장, 처리 및 쿼리 기능을 수행한다. 메트릭 수집 방식으로 Pull 방식을 기본적으로 사용한다. 해당 서버가 대상 서비스로부터 메트릭을 주기적으로 수집하고, 시계열 데이터베이스(TSDB, HDD/SDD)에 저장한다. 데이터베이스에 저장한 데이터는 쿼리 언어 PromQL을 통해 데이터를 필터링, 집계 시각화하는데 사용한다.
  • Pushgateway : Pushgateway는 Push 방식을 사용하는 일부 유형의 메트릭을 Prometheus에서 수집하기 위한 중간 서버이다. 주로 일회성 작업(예: 배치 작업)으로부터 메트릭을 수집하는 데 사용된다. 작업이 종료되더라도 메트릭이 보존되어 Prometheus 서버가 해당 메트릭을 수집할 수 있게 한다.
  • Alertmanager: Alertmanager는 Prometheus 서버에서 발생한 경고를 관리하고, 사용자에게 알림을 전달하는 컴포넌트이다.
  • Prometheus UI : 내장된 웹 인터페이스로, 사용자가 Prometheus 서버에서 메트릭을 쿼리하고, 시각화된 그래프를 확인할 수 있다. 사용자는 PromQL을 사용하여 원하는 메트릭을 검색하고 분석할 수 있으며, 기본적인 대시보드 및 경고 설정을 관리할 수 있다.

아키텍처를 살펴보았는데 프로메테우스는 단일 노드 시스템으로 설계되어 있어 클러스터링 구조를 직접 지원하지 않는다. 이로인해 확장성과 고가용성에 일부 보완이 필요하다.

  • 확장성 문제
    • 단일 노드에서 모든 메트릭을 처리하려 할 때 노드의 자원이 고갈되어 성능 저하를 초래할 수 있다.
    • 대규모 인프라에서 많은 수의 메트릭을 수집하고 처리하는 데 있어 성능 저하와 저장소 부족 문제가 발생할 수 있다. 외부 스토리지 연결이 필요하다.
  • 고가용성 문제
    • 단일 노드에서 발생하는 장애나 다운타임이 생겨 프로메테우스 서버가 내려가면 그 시간 동안에는 메트릭을 수집할 수 없다.
    • 볼륨이 AWS EBS 를 사용해도 단일 노드에서만 연결이 가능하다. 연결 노드에 다운 타임이 발생하면 메트릭을 가져올 수 없다.

이러한 문제를 해결하기 위한 도구로 Thanos를 사용할 것이다.

Thanos

프로메테우스의 확장성과 고가용성을 개선하기 위한 시스템이다. 사이트 정문에 대놓고 프로메테우스를 저격하고 있다. 타노스 아키텍처를 통해 어떻게 개선할 수 있는 확인해보겠다.

<a href="https://thanos.io/v0.6/thanos/getting-started.md/">https://thanos.io/v0.6/thanos/getting-started.md/</a>

https://thanos.io/v0.6/thanos/getting-started.md/

파란 네모가 타노스 구성 컴포넌트이다. 설계 디자인은 공식 문서에서도 참고가 가능하다.

  • Thanos Sidecar : Prometheus에 연결되어 메트릭 데이터를 쿼리하고 클라우드 스토리지에 업로드한다. 노드마다 사이드카가 연결되며 외부 스토리지 저장을 통해 확장성을 개선시키는 역할의 컴포넌트이다.
  • Thanos Store Gateway : 외부 스토리지에 메트릭 데이터를 읽어 Thanos Query로 전달한다. 해당 컴포넌트를 통해 외부 스토리지에서 과거 데이터도 쿼리할 수 있게 된다.
  • Thanos Query : 사용자 쿼리를 요청 처리하며 짧은 시간의 데이터는 타노스 사이드카에서 가져오며, 오래된 데이터는 스토어 게이트웨이를 통해 외부 스토리지에서 가져온다. Prometheus Query API를 구현하여 사용자가 기존의 Prometheus 쿼리를 그대로 사용할 수 있게 한다.

프로메테우스단에서 고가용성을 제공해주는 컴포넌트이다. 통합 데이터간의 중복 제거 (de-duplication) 기능을 기본으로 제공하여 여러 프로메테우스 및 원격 스토리지의 메트릭 데이터를 통합하여 쿼리할 수 있게 해준다. 한 가지 주의할 점은 Thanos query 도 고가용성을 보장해줘야 한다. 공식 문서에 따르면 타노스 구성 파드들은 샤딩 수단을 제공하지 않아, 모두 수평적 확장이 가능하다. 타노스 배포시 쿼리 파드 개수를 2개 이상으로 조절하여 가용성을 보장시키자.

<a href="https://observability.thomasriley.co.uk/prometheus/using-thanos/high-availability/">https://observability.thomasriley.co.uk/prometheus/using-thanos/high-availability/</a>

https://observability.thomasriley.co.uk/prometheus/using-thanos/high-availability/

<a href="https://thanos.io/tip/thanos/design.md/#metric-sources">https://thanos.io/tip/thanos/design.md/#metric-sources</a>

https://thanos.io/tip/thanos/design.md/#metric-sources

  • Thanos Compactor : 타노스 쿼리와는 별개의 프로세스로, 객체 스토리지 버킷만 가리키며 여러 개의 작은 블록을 더 큰 블록으로 지속적으로 통합시켜주는 컴포넌트이다. 블록을 통합시키면 데이터가 압축하게 되므로 버킷의 총 스토리지 크기, 스토어 노드의 로드 및 버킷에서 쿼리 데이터를 가져오는 데 필요한 요청 수가 크게 줄어든다.
  • Thanos Ruler : 프로메테우스 인스턴스들로부터 알림 규칙 정보를 가져와 통합하고, 프로메테우스와 함께 작동하는 외부 알림 시스템에게 알림을 전송하는 역할의 컴포넌트이다.

연계 배포

배포 환경 : kops 클러스터 (k8s 1.24), AWS Ubuntu 인스턴스

프로메테우스 & 타노스를 연계하여 배포한다. 배포를 위해 헬름 차트를 사용할 예정이며 프로메테우스 배포는 kube-prometheus-stack(그라파나, 추가 메트릭 자동 구성) 차트를 사용할 것이다. 또한 타노스는 bitnami/thanos 차트를 사용할 것이며 타노스 외부스토리지는 MinIO를 배포하여 연결할 것이다. 전체 배포 순서는 다음과 같다. 구성 차트는 필자의 깃허브에서 참고가 가능하다.

  1. MInIO 배포
  2. kube-promethes-statck 설정 & 배포
  3. 타노스 설정 & 배포
  4. 그라파나 설정 및 대시보드 확인

1. MinIO 배포

타노스 외부 스토리지로 MinIO를 설정할 것이다. 이를 위한 사전 작업으로 MinIO를 먼저 배포하겠다.

차트 가져오기

1
2
3
helm repo add minio https://charts.bitnami.com/bitnami
helm repo update
helm fetch minio/minio --untar --version 12.2.1

차트 설정

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# values-minio.yaml
mode: distributed

auth:
  rootUser: admin
  rootPassword: "admin1234"

statefulset:
  replicaCount: 4
  zones: 1
  drivesPerNode: 1

provisioning:
  config: 
    - name: region
      options:
        name: ap-northeast-2

ingress:
  enabled: true 
  hostname: minio.hanhorang.link
  path: /*
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}, {"HTTPS":9090}]'
    alb.ingress.kubernetes.io/certificate-arn: "$ACM arn "

persistence:
  storageClass: "kops-csi-1-21"
  • 분산스토리지 모드로 설정
  • (테스트환경 노드 4개) 노드당 파드 하나를 할당
  • Ingress(네트워크) : AWS ALB 설정
  • persistence(볼륨) : AWS gp2 기본 스토리지 클래스 설정

배포

1
2
kubectl create ns minio
helm install minio minio/minio -f values-minio.yaml -n minio --version 12.2.1

버킷 생성 및 접근 키 발급

타노스에서 minio 버킷에 접근하기 위한 접근 키를 발급받자

minio 도메인 접속

minio1.png

어드민 계정은 차트에서 admin / admin1234 로 설정되어 있다. 로그인을 하자.

로그인이 완료되면 다음과 같은 화면을 확인할 수 있다.

minio2.png

버킷 생성 후 버킷 접근을 위한 액세스 키 발급이 필요하다. 왼쪽 메뉴 [Access Keys] 에서 키를 발급받자.

Minio3.png

Access Key 발급 후 MINIO 동작 권한을 등록해야 한다. 생성한 키를 클릭하면 정책 입력 칸이 나온다. 아래 정책을 입력하도록 하자.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "admin:*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "kms:*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::*"
            ]
        }
    ]
}

필자의 경우 접근 키는 다음과 같이 생성되었다.

access_key : aajl91wFPCRVmfWR

secret_key: SfP4woqjY3fcyh1cuwF1CNQFEe6hs4X6

발급받은 키를 기반으로 Secret을 생성하자.

1
2
3
4
5
6
7
#minio-key.yaml
type: s3
config:
  bucket: thanos
  endpoint: minio.hanhorang.link
  access_key: aajl91wFPCRVmfWR
  secret_key: SfP4woqjY3fcyh1cuwF1CNQFEe6hs4X6
1
2
kubectl create ns monitoring
kubectl create secret generic thanos-minio-secret -n monitoring --from-file=minio-key.yaml

2. kube-promethes-statck 설정 & 배포

프로메테우스 배포 및 사이드 카에 타노스 연동을 위한 설정을 진행하겠다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm fetch prometheus-community/kube-prometheus-stack --untar --version 45.7.1

# 사용 리전의 인증서 ARN 확인
CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`
echo "alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN"

KOPS_CLUSTER_NAME="hanhorang.link"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# values-kube-prometheus-stack.yaml

cat <<EOT > ./values-kube-prometheus-stack.yaml
alertmanager:
  enabled: false 

grafana:
  defaultDashboardsTimezone: Asia/Seoul
  adminPassword: admin1234

  ingress:
    enabled: true
    ingressClassName: alb

    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
      alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
      alb.ingress.kubernetes.io/success-codes: 200-399
      alb.ingress.kubernetes.io/group.name: "monitoring"

    hosts:
      - grafana.$KOPS_CLUSTER_NAME

    paths:
      - /*

prometheus:
   # 사이드카 노출 서비스 설정
  thanosService:
    enabled: true

  ingress:
    enabled: true
    ingressClassName: alb

    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
      alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
      alb.ingress.kubernetes.io/success-codes: 200-399
      alb.ingress.kubernetes.io/group.name: "monitoring"

    hosts:
      - prometheus.$KOPS_CLUSTER_NAME

    paths:
      - /*

  prometheusSpec:
    podMonitorSelectorNilUsesHelmValues: false
    serviceMonitorSelectorNilUsesHelmValues: false
    retention: 5d
    retentionSize: "10GiB"
    scrapeInterval: "15s"
    # alert 관련 설정으로 주석 처리 
    # evaluationInterval: 15s
    # 가용성 설정
    replicas: 3 
    # 타노스 설정
    thanos: 
      image: "quay.io/thanos/thanos:v0.27.0"
      objectStorageConfig:
        key: minio-key.yaml
        name: thanos-minio-secret
      version: v0.27.0
    # 볼륨 설정 
    storageSpec: {}
    ## Using PersistentVolumeClaim
    ##
    #  volumeClaimTemplate:
    #    spec:
    #      storageClassName: gluster
    #      accessModes: ["ReadWriteOnce"]
    #      resources:
    #        requests:
    #          storage: 50Gi
    #    selector: {}
EOT
  • 알람을 사용하지 않음으로 alertmanager false로 설정하였다.
  • 헬름 차트를 보면 prometheus.thanos 에 설정하는 부분이 있는데 여기서 설정하는 것이 아니다! 원격 스토리지 접근에 대한 오류가 발생하므로 prometheus.prometheusSpec.thanos 에 앞서 생성한 시크릿 키를 입력하자. (위에 차트 그대로 입력하면 문제없습니다.)
1
2
3
4
kubectl create ns monitoring

helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 45.7.1 \
-f values-kube-prometheus-stack.yaml --namespace monitoring

배포 이후 타노스 사이드카 연동을 확인하자.

1
kubectl describe pods prometheus-kube-prometheus-stack-prometheus-0  -n monitoring

thanos-success.png

성공이다!

3. 타노스 설정 & 배포

타노스 사이드카를 제외한 컴포넌트를 설치하고 thnaos query 가 프로메테우스 사이드카로, store gateway가 원격 스토리지인 minio 로 연동할 수 있도록 설정해야 한다. 차트부터 가져오도록 하자.

1
2
3
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm fetch bitnami/thanos --untar --version 12.3.2

타노스 연동을 위해 설정을 진행한다. 메트릭을 가져오기 위해 버킷 정보와 프로메테우스 배포시 같이 배포된 타노스 사이드카 서비스 주소를 입력한다.

thanos-service.png

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
objstoreConfig: |-
  type: s3
  config:
    bucket: monitoring
    endpoint: minio.minio.svc.cluster.local:9000
    access_key: aajl91wFPCRVmfWR
    secret_key: SfP4woqjY3fcyh1cuwF1CNQFEe6hs4X6
    insecure: true   
querier:
  stores:
    - kube-prometheus-stack-thanos-discovery.monitoring.svc.cluster.local:10901
    - thanos-storegateway.monitoring.svc.cluster.local:10901
  replicaCount: 2
  ingress:
    enabled: true 
    hostname: thanos.hanhorang.link
    ingressClassName: "alb"
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
      alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:955963799952:certificate/7569648c-bfd5-4860-b2c1-16ef02acbb58
      alb.ingress.kubernetes.io/success-codes: 200-399
      alb.ingress.kubernetes.io/group.name: "monitoring" 

    path : /*
bucketweb:
  enabled: true
compactor:
  enabled: true
storegateway:
  enabled: true
ruler:
  enabled: false
  • objstoreConfig.config.endpoint 를 서비스 DNS로 대체했다. ALB 도메인 입력시 Timeout 으로 파드가 올라가지 않기 때문이다.
  • querier.store 에 쿼리할 대상을 등록한다. 대상으로 타노스 사이드카의 서비스 주소와 스토어게이트웨이를 등록한다.

배포

1
2
3

helm install thanos bitnami/thanos --version 12.3.2 \
-f values-thanos.yaml --namespace monitoring

배포 완료 후 타노스 쿼리 호스트 도메인을 통해 접속하자. Store와 Status/Target를 확인하여 사이드카 연동을 확인한다.

thanos.png

thanos-target.png

타노스가 정상적으로 배포된 것을 확인하였다. 배포 이후에는 프로메테우스 서버를 2개 이상 띄어서 프로메테우스 서버가 고가용성을 갖도록 구성하자. (앞서 프로메테우스 배포시 프로메테우스 서버를 3개를 배포하였다)

proemtheus-ha.png

3개의 프로메테우스 서버가 서로 독립적으로 메트릭을 수집한다. 타노스 쿼리는 프로메테우스에 등록된 사이드카를 통해 메트릭을 통합 수집한다. 이 때 고가용성이 보장되는데 하나의 프로메테우스가 다운타임이 가진다한들 다른 프로메테우스 서버에서 메트릭 수집 및 집계를 수행할 수 있기때문이다. 물론 중복 중복된 메트릭에 대해선 타노스 내 Use Deduplication 기능을 통해 소거가 가능하다. 중복 메트릭 설정은 프로메테우스 라벨 설정을 통해 가능하나 자동으로 설정이 되어 생략하겠다.

query1.png

4. 그라파나 설정

그라파나는 시각화 대시보드이다. 앞서 구축한 모니터링 시스템을 기반으로 메트릭 수집 파이프라인을 구성하고 대시보드를 확인하겠다. 그라파나 도메인에 접속하여 로그인을 진행한다. (초기 아이디: admin, 비밀번호: admin1234)

먼저, 수집 메트릭 URL을 프로메테우스에서 타노스 쿼리로 수정할 것이다. 왼쪽 하단의 톱니바퀴 메뉴에서 Configuration에 들어간 다음 프로메테우스 설정 URL을 thanos-query:9090 으로 수정하자.

grafana.png

grafana2.png

바꾸고 나서 대시보드를 확인하면 정상적으로 작동하는 것을 확인할 수 있다.

dashboard.png

마치며

kube-prometheus-stack 자체적으로도 프로메테우스 고가용성을 보장한다. 하지만 이렇게 구성한 프로메테우스 HA는 여전히 중복 데이터와 쿼리 집계, 확장성에 대한 보완 요소가 있다. 이를 해결하기 위해 Thanos을 소개하였고 연동 방법과 구성 요소를 확인하였다.

참고

https://aws.amazon.com/ko/blogs/opensource/improving-ha-and-long-term-storage-for-prometheus-using-thanos-on-eks-with-s3/

https://velog.io/@seokbin/Kube-Prometheus-Thanos-구성#4-프로메테우스-ha-구성