cloudwithbass

[Terraform] Terraform 연습하기 9: Prometheus, Grafana, PV와 PVC, Route53 본문

Terraform

[Terraform] Terraform 연습하기 9: Prometheus, Grafana, PV와 PVC, Route53

여영클 2024. 9. 21. 13:37

이전 포스팅까지의 인프라 구성도입니다.

이전 포스팅에선 aws-loadbalancer-controller의 helm chart를 이용해 ALB를 구성했습니다.

이번 포스팅의 목표는 두 가지입니다.

  1. 대표적인 모니터링 도구인 Prometheus와 Grafana를 helm chart로 배포합니다.
  2. Route53을 이용해 호스팅 영역 별로 Prometheus와 Grafna로 접속하는 도메인을 생성합니다. (예시: prometheus.example.com과 grafana.example.com)

모든 소스코드는 아래 주소에서 확인하실 수 있습니다.

https://github.com/Dminus251/practice-terraform/tree/main/demo09-monitoring

목차


     

    1. Prometheus 구성하기

    helm.tf

    resource "helm_release" "prometheus"{
      depends_on = [module.eks-cluster, module.addon-aws-ebs-csi-driver, module.node_group]
      repository = "https://prometheus-community.github.io/helm-charts"
      name = "practice-prometheus" #release name
      chart = "prometheus" # chart name
      namespace = "monitoring"
      create_namespace = true
      set {
        name = "server.persistentVolume.storageClass"
        value = "gp2"
      }
      set {
        name  = "alertmanager.persistence.storageClass"
        value = "gp2"
      }
    }

    Prometheus의 Artifact HubAWS 문서를 참조해서 repository와 chart명을 사용합니다.

     

    에러가 발생할 수 있는 사항들

    1.  depends_onmodule.node_group module.addon-aws-ebs-csi-driver를 추가해야 합니다.

    • 노드 그룹보다 prometheus가 먼저 생성되면, no available node 에러가 발생합니다.
    • ebs-csi-driver에 대한 내용은 2번 항목에서 설명하겠습니다.

    2.  server.persistentVolume.storageClassaltertmanager.persistence.storageClassgp2로 설정해야 합니다. 그 이유는 addon-aws-ebs-csi-driver에서 설명하겠습니다.

    • 여기서 조금 헤맸던 게, 아래 사진처럼 prometheus의 artifact hub에서 default values를 보면 altertmanager.persistence.storageClass라는 변수는 존재하지 않습니다.
    • 존재하지 않음에도.. 이 변수를 gp2로 설정하지 않으면 에러가 발생했습니다.
    • 저는 aws 문서에서 helm cli를 통해 이 변수를 gp2로 설정하는 것을 보고 따라했습니다.


    2. aws-ebs-csi-drvier 구성하기

    main.tf

    module "addon-aws-ebs-csi-driver"{
      source = "./modules/t-aws-eks/addon/"
      addon-cluster_name = module.eks-cluster.cluster-name
      addon-name = "aws-ebs-csi-driver"
      addon-role = module.role-ecd-sa.arn
      depends_on = [module.node_group]
    }

     

    • addon-aws-ebs-csi-driver는 eks 클러스터가 AWS 리소스인 Amazon EBS(Elastic Block Store)를 사용할 수 있게 해주는 기능입니다.
    • 이 기능을 추가하면 Service Account를 자동으로 생성해 줍니다.
    • role은 AWS 문서의 aws-ebs-csi-driver에서 요구하는 정책을 연결했습니다.
    • policy와 role에 대한 내용은 위 AWS 문서를 참고해도 되고, 전체 role 코드는 아래 git을 참고해주세요.

    https://github.com/Dminus251/practice-terraform/tree/main/demo09-monitoring/modules/t-aws-eks/role/ebs-csi-driver

     

    참고로 콘솔에서는 아래 사진과 같이 클러스터 → 추가 기능에 들어가 구성할 수 있습니다.

     


     

    aws-ebs-csi-driver가 필요한 이유

    • 아시다시피, pod는 실행 중 언제든 다운될 수 있습니다.
    • 만약 데이터를 pod에 저장한다면 pod가 다운될 때 중요한 데이터들도 함께 사라질 것입니다.
    • 이런 상황을 예방하기 위해 데이터를 클러스터 EBS에 데이터를 저장해야 하고, 이러한 이유로 aws-ebs-csi-driver가 필요합니다.
    • 이 애드온을 통해 사용하는 EBS는 쿠버네티스에서 PVPVC 리소스에 의해 관리됩니다.
    • 이 애드온을 설치하지 않으면 prometheus의 alrertmanager와 server POD가 Pending 상태가 됩니다. (ebs를 사용할 수 없으므로)

    PV와 PVC

    PV (Persistent Volume)

    • 데이터를 저장할 EBS, NFS 등 물리적인 저장소를 정의합니다.
    • storage, storageClass를 정의해서 저장소를 클러스터 내에서 사용하도록 합니다.

    PVC (Persistent Volume Claim):

    • storageClass를 지정하고, 그 저장소에서 원하는 만큼 storage를 요청할 때 사용합니다.

    ebs-aws-csi-driver 애드온을 연결하면, pv, pvc, storageClass가 자동으로 생성되므로 관련 소스 코드는 보지 않겠습니다.


    3. Grafana 구성하기

    helm.tf

    resource "helm_release" "grafana"{
      depends_on = [module.eks-cluster, module.addon-aws-ebs-csi-driver]
      repository = "https://grafana.github.io/helm-charts"
      name = "practice-grafana"
      chart = "grafana"
      namespace = "monitoring"
      create_namespace = true
       set {
        name  = "adminPassword"
        value = "admin"
      }
      set {
        name  = "persistence.enabled"
        value = "true"
      }
      set {
        name  = "persistence.storageClassName"
        value = "gp2"
      }
    }

    Artifact hub의 grafana 문서를 참조합니다.

    prometheus와 마찬가지로 네임 스페이스는 monitoring으로 지정했습니다.

    grafana도 데이터를 저장해야 하기 때문에 EBS의 유형 중 하나인 gp2 볼륨을 사용해야 합니다. 


    4. Service, Ingress 정의하기

    중괄호가 많아서 코드가 100줄이 넘기 때문에 아래 git을 참고해주세요.

     

    단순히 grafana와 prometheus의 service, ingress를 테라폼 리소스로 표현한 것입니다.

    https://github.com/Dminus251/practice-terraform/blob/main/demo09-monitoring/kubernetes-main.tf

     

    몇 가지 설명할 접을 꼽자면

    1. prometheus는 '/graph' 경로를 통해 헬스 체크를 하고, grafana는 '/api/health'경로를 통해 헬스 체크를 합니다. 따라서 이를 annotations에 정의해야 합니다.
    2. 이 포스팅의 목적대로 프로메테우스, 그라파나의 도메인을 구분했습니다.  따라서 각 ingress의 spec.rule.host를 'prometheus.${var.DOMAIN}', 'grafana.${var.DOMAIN}'으로 설정합니다.

    5. Route53 구성하기

    이제 모든 리소스를 구성했으니 Route 53만 구성하면 됩니다.


    5-1. 도메인 구매하기

    • Amazon Route 53을 사용하기 위해선 도메인을 구매해야 합니다.
    • 저는 이전에 가비아에서 구매했던 도메인을 사용했습니다.

    5-2. Route53에서 호스팅 영역 생성

    • 이 설정 또한 테라폼 코드를 이용해서 하면 좋겠지만, 호스팅 영역을 생성할 때마다 네임서버가 바뀝니다.
    • 이를 일일이 가비아에서 다시 설정하는 것은 번거로우며, 네임 서버가 전파되기 까지 몇 시간씩 소요되기도 합니다.
    • 따라서 월에 0.5달러를 내야 하지만 호스팅 영역을 생성하겠습니다.


    Route53에 들어가 호스팅 영역을 생성하면 아래 사진처럼 두 개의 레코드가 보일 것입니다.

    그 중 NS 유형을 누르면 우측 모자이크한 값이 4개 나오는데요, 각각 복사해서 가비아의 My 가비아 → 도메인 관리에 들어가서 아래 사진처럼 1차 ~ 4차 호스트명에 기입합니다.

     

    이때 NS 값은 맨 마지막에 '.'이 있을텐데 마지막 '.'은 빼고 기입해야 합니다.

    가비아 네임서버 설정


    다시 Route53으로 돌아가 레코드 생성을 누릅니다.

    총 두 개를 생성할 것인데, 레코드 이름은 각각 prometheus와 grafana로 설정합니다.

    유형은 A 유형, 대상은 ALB에 대한 별칭을 선택하고,  ingress에 의해 프로비저닝된 ALB를 선택하면 됩니다.


    네임 서버를 등록하고, 최대 72시간을 기다려야 전파가 완료됩니다. (제 경우 늦어봐야 3~4시간 정도 소요됐습니다.)

    ubuntu에서 다음 명령으로 전파가 됐는지 확인할 수 있습니다.

    dig <DNS 이름>

     

    예를 들어 아래와 같은 식으로 답이 반환되는데요

    status에 NOERROR가 나오고, AUTHORITY SECTION 부분에, ROUTE53의 NS 유형에 있던 값이 보인다면 정상적으로 전파가 된 것입니다.

    하지만 dig 명령어가 DNS 전파를 100% 보장하진 않으니 아래 주소에서도 확인해보시길 바랍니다.

    https://www.whatsmydns.net/


    정상적으로 전파가 됐다면 웹 브라우저에서 prometheus.example.com, grafana.example.com에 접속합니다.

    이때 당연히 example.com은 자신이 구매하고 route53에 등록한 도메인이여야 합니다.

     

    만약 아래 사진과 같은 메시지가 나온다면 '사이트로 이동' 버튼을 클릭하면 됩니다.

    http 프로토콜을 사용했기 때문에 발생하는 메시지입니다.

    인증서를 발급받아 https를 이용할 수 있겠지만, 이전에 한 번 해보기도 했고, 왠지 모를 이유로 과금됐던 기억이 있기 때문에 이번 포스팅에 패스하겠습니다

     

    정상적으로 접속된 promehteus

     

    정상적으로 접속된 grafana


    6. Grafana 모니터링 환경 구성

    이제 DNS로 grafana에 접속할 수 있으니 모니터링 환경을 구성해보겠습니다.

     

    먼저 모니터링할 데이터 소스를 추가합니다.

    Connection에는 pormetheus의 DNS를 입력하면 됩니다.

    DNS가 없다면 http://localhost:포트 번호 등의 프로메테우스를 호스트 중인 URL을 입력합니다.


     

    다음으로 Grafana labs에서 원하는 대시보드 템플릿을 선택 후, Copy ID to clipboard 버튼을 클릭합니다.

     

     

    Grafana의 Connections -> Data sources에 들어가 Import dashboard 선택 후, 복사헀던 ID를 붙여넣습니다.

     

    이후 추가했던 데이터 소스인 프로메테우스를 선택합니다.

     

    이제 대시 보드에서 아래와 같이 모니터링을 진행할 수 있습니다.

    pod를 누르니 제 클러스터의 monitoring namespace에서 실행 중인 pod들을 확인할 수 있습니다.


    7. 그 외 알게 된 점

    1. 네임 서버는 하나만 사용하기

    저는 이 실습을 진행하며 기존 CloudFlare의 네임 서버를 이용하고 있던 도메인을 사용했습니다.

    이 도메인에 CloudFlare와 Route53의 네임서버를 입력했더니 정상적으로 라우팅되지 않는 에러가 발생했습니다.

    하나의 네임 서버에서 ip를 찾지 못하면 다른 네임 서버를 참조할 것이라고 생각했는데, 제 생각이 잘못됐습니다.

     

    2. 경로 사용 불가? (확실하지 않음)

    이 실습에선 프로메테우스와 그라파나에 각각 prometheus.example.com과 grafana.example.com을 통해 접속했는데요, 사실 초기 계획에선 example.com/prometheus와 example.com/grafana를 통해 접속하길 원했습니다.

     

    helm의 value 중 prefixURL도 사용해봤고, aws-loadbalacner-controller에서 지원하지 않는 redirect 기능을 위해 nginx-loadbalancer-contoller도 사용해봤고, S3 버킷에서 로드 밸런서를 로깅도 해봤지만 결국 경로를 통해 프로메테우스와 그라파나에 접속하려던 목표를 이루진 못했습니다.

    사실 이유를 대충은 알 것 같지만 아직도 완벽하게 이해가 되진 않습니다.

     

    저번 포스팅과 이번 포스팅의 간격이 10일인데, 그 10일 중 4일 정도를 이 부분에서 허비했던 것 같습니다..