학습 과정: 확장 가능한 애플리케이션 - Prometheus로 모니터링


이 튜토리얼 모음은 Google Kubernetes Engine(GKE) Enterprise 버전에서 실행되는 최신 애플리케이션 환경을 배포, 실행, 관리하려는 IT 관리자와 운영자를 대상으로 합니다. 이 튜토리얼 모음을 진행하면서 Cymbal Bank 샘플 마이크로서비스 애플리케이션을 사용하여 모니터링 및 알림을 구성하고, 워크로드를 확장하며, 장애를 시뮬레이션하는 방법을 알아봅니다.

  1. 클러스터 만들기 및 샘플 애플리케이션 배포
  2. Google Cloud Managed Service for Prometheus로 모니터링(이 튜토리얼)
  3. 워크로드 확장
  4. 장애 시뮬레이션
  5. 중앙 집중식 변경 관리

개요 및 목표

이 튜토리얼 모음에서 사용된 Cymbal Bank 샘플 애플리케이션은 모두 GKE 클러스터에서 실행되는 여러 마이크로서비스로 구성됩니다. 이러한 서비스에 문제가 있으면 은행 애플리케이션에 액세스할 수 없는 등 은행 고객이 좋지 않은 경험을 할 수 있습니다. 서비스 관련 문제를 가능한 한 빨리 알게 되면 문제 해결을 신속하게 시작할 수 있습니다.

이 튜토리얼에서는 Google Cloud Managed Service for Prometheus 및 Cloud Monitoring을 사용하여 GKE 클러스터의 워크로드를 모니터링하는 방법을 알아봅니다. 다음 작업을 완료하는 방법을 알아봅니다.

  • Alertmanager용 Slack 웹훅을 만듭니다.

  • 샘플 마이크로서비스 기반 애플리케이션의 상태를 모니터링하도록 Prometheus를 구성합니다.

  • 서비스 중단을 시뮬레이션하고 Slack 웹훅을 사용하여 전송된 알림을 검토합니다.

비용

이 튜토리얼 시리즈에서 GKE Enterprise를 사용 설정하고 Cymbal Bank 샘플 애플리케이션을 배포하면 GKE Enterprise를 사용 중지하거나 프로젝트를 삭제할 때까지 가격 책정 페이지에 나열된 대로 Google Cloud에서 GKE Enterprise에 대해 클러스터별 요금이 발생합니다.

Compute Engine VM 및 Cloud Monitoring 요금과 같이 Cymbal Bank 샘플 애플리케이션을 실행하는 동안 발생하는 기타 Google Cloud 비용도 사용자가 부담합니다.

시작하기 전에

워크로드를 모니터링하는 방법을 알아보려면 Autopilot을 사용하는 GKE 클러스터를 만들고 Cymbal Bank 샘플 마이크로서비스 기반 애플리케이션을 배포하는 첫 번째 튜토리얼을 완료해야 합니다.

Cymbal Bank에 대한 이 튜토리얼 모음을 순서대로 완료하는 것이 좋습니다. 튜토리얼 모음을 진행하면서 새로운 기술을 배우고 추가적인 Google Cloud 제품 및 서비스를 사용하게 됩니다.

GKE Autopilot 클러스터가 Google Cloud Managed Service for Prometheus를 사용하여 커뮤니케이션 플랫폼에 메시지를 생성하는 방법의 예시를 보여주기 위해 이 튜토리얼에서는 Slack을 사용합니다. 자체 프로덕션 배포에서는 GKE 클러스터에 문제가 발생할 때 조직의 선호하는 커뮤니케이션 도구를 사용하여 메시지를 처리하고 전송할 수 있습니다.

  • 이메일로 등록하거나 작업공간 관리자가 보낸 초대를 사용하여 Slack 작업공간에 가입합니다.

Slack 애플리케이션 만들기

모니터링 설정에서 중요한 부분은 서비스 중단과 같은 실행 가능한 이벤트가 발생할 때 알림을 받는 것입니다. 이를 위한 일반적인 패턴은 이 튜토리얼에서 사용하는 Slack과 같은 커뮤니케이션 도구로 알림을 전송하는 것입니다. Slack은 프로덕션 배포와 같은 외부 애플리케이션에서 메시지를 생성할 수 있는 웹훅 기능을 제공합니다. GKE 클러스터에 문제가 발생하면 조직의 다른 커뮤니케이션 도구를 사용하여 메시지를 처리하고 전송할 수 있습니다.

Autopilot을 사용하는 GKE 클러스터에는 Google Cloud Managed Service for Prometheus 인스턴스가 포함됩니다. 이 인스턴스는 애플리케이션에 문제가 발생할 때 알림을 생성할 수 있습니다. 그런 다음 이러한 알림은 Slack 웹훅을 사용하여 Slack 작업공간에 메시지를 보낼 수 있으므로 문제가 발생하면 프롬프트 알림을 받을 수 있습니다.

Prometheus에서 생성된 알림을 기반으로 Slack 알림을 설정하려면 Slack 애플리케이션을 만들고 이 애플리케이션에 대한 수신 웹훅을 활성화한 다음 Slack 작업공간에 애플리케이션을 설치해야 합니다.

  1. 작업공간 이름과 Slack 계정 사용자 인증 정보를 사용하여 Slack에 로그인합니다.

  2. 새 Slack 앱 만들기

    1. Create an app(앱 만들기) 대화상자에서 From scratch(처음부터)를 클릭합니다.
    2. App Name(앱 이름)을 지정하고 Slack 작업공간을 선택합니다.
    3. Create App을 클릭합니다.
    4. Add features and functionality(특징 및 기능 추가)에서 Incoming Webhooks(수신 웹훅)를 클릭합니다.
    5. Activate Incoming Webhooks(수신 웹훅 활성화) 전환 버튼을 클릭합니다.
    6. Webhook URLs for Your Workspace(작업공간의 웹훅 URL) 섹션에서 Add New Webhook to Workspace(작업공간에 새 웹훅 추가)를 클릭합니다.
    7. 승인 페이지가 열리면 알림을 수신할 채널을 선택합니다.
    8. 허용을 클릭합니다.
    9. Slack 애플리케이션의 웹훅이 Webhook URLs for Your Workspace(작업공간의 웹훅 URL) 섹션에 표시됩니다. 나중을 위해 이 URL을 저장합니다.

Alertmanager 구성

Prometheus에서 Alertmanager는 배포로 생성되는 모니터링 이벤트를 처리합니다. Alertmanager는 중복 이벤트를 건너뛰고, 관련 이벤트를 그룹화하며, Slack 웹훅을 사용하는 것과 같이 알림을 전송할 수 있습니다. 이 섹션에서는 새 Slack 웹훅을 사용하도록 Alertmanager를 구성하는 방법을 보여줍니다. Alertmanager가 전송할 이벤트를 처리하는 방법을 지정하는 것은 이 튜토리얼의 다음 섹션인 Prometheus 구성에서 설명합니다.

Slack 웹훅을 사용하도록 Alertmanager를 구성하려면 다음 단계를 완료합니다.

  1. 디렉터리를 이전 튜토리얼의 Cymbal Bank용 모든 샘플 매니페스트가 포함된 Git 저장소로 변경합니다.

    cd ~/bank-of-anthos/
    

    필요한 경우 디렉터리 위치를 이전에 저장소를 클론한 위치로 변경합니다.

  2. Slack 애플리케이션의 웹훅 URL로 Alertmanager 샘플 YAML 매니페스트를 업데이트합니다.

    sed -i "s@SLACK_WEBHOOK_URL@SLACK_WEBHOOK_URL@g" "extras/prometheus/gmp/alertmanager.yaml"
    

    SLACK_WEBHOOK_URL을 이전 섹션의 웹훅 URL로 바꿉니다.

  3. 애플리케이션 코드를 변경하지 않고 고유한 Slack 웹훅 URL을 동적으로 사용하려면 Kubernetes 보안 비밀을 사용하면 됩니다. 애플리케이션 코드는 이 보안 비밀의 값을 읽습니다. 더 복잡한 애플리케이션에서는 이 기능으로 보안 또는 규정 준수를 위해 값을 변경 또는 순환할 수 있습니다.

    Slack 웹훅 URL이 포함된 샘플 YAML 매니페스트를 사용하여 Alertmanager의 Kubernetes 보안 비밀을 만듭니다.

    kubectl create secret generic alertmanager \
      -n gmp-public \
      --from-file=extras/prometheus/gmp/alertmanager.yaml
    
  4. Prometheus는 내보내기 도구를 사용하여 코드 변경 없이 애플리케이션에서 측정항목을 가져올 수 있습니다. Prometheus 블랙박스 내보내기 도구를 사용하면 HTTP 또는 HTTPS와 같은 엔드포인트를 프로브할 수 있습니다. 이 내보내기 도구는 애플리케이션의 내부 작업을 Prometheus에 노출하고 싶지 않거나 노출하지 못할 때 잘 작동합니다. Prometheus 블랙박스 내보내기 도구는 애플리케이션 코드를 변경하지 않고도 작동하여 측정항목을 Prometheus에 노출할 수 있습니다.

    Prometheus 블랙박스 내보내기 도구를 클러스터에 배포합니다.

    kubectl apply -f extras/prometheus/gmp/blackbox-exporter.yaml
    

Prometheus 구성

Slack 웹훅을 사용하도록 Alertmanager를 구성한 후에는 Cymbal Bank에서 모니터링할 대상과 Alertmanager가 Slack 웹훅 사용에 대해 알림을 표시할 이벤트 종류를 Prometheus에 알려야 합니다.

이 튜토리얼에서 사용하는 Cymbal Bank 샘플 애플리케이션에는 GKE 클러스터에서 실행되는 다양한 마이크로서비스가 있습니다. Cymbal Bank 서비스 중 하나가 요청에 정상적으로 응답하지 않아 고객이 애플리케이션에 액세스할 수 없는 경우 가능한 한 빨리 알고 싶을 수 있습니다. 조직 정책에 따라 이벤트에 응답하도록 Prometheus를 구성할 수 있습니다.

프로브

모니터링할 리소스에 대해 Prometheus 프로브를 구성할 수 있습니다. 이러한 프로브는 프로브가 수신하는 응답을 기반으로 알림을 생성할 수 있습니다. Cymbal Bank 샘플 애플리케이션에서는 서비스의 200 수준 응답 코드를 확인하는 HTTP 프로브를 사용할 수 있습니다. HTTP 200 수준 응답은 서비스가 올바르게 실행 중이고 요청에 응답할 수 있음을 나타냅니다. 문제가 있고 프로브가 예상 응답을 수신하지 못하면 Alertmanager가 추가 작업을 처리하고 수행할 알림을 생성하는 Prometheus 규칙을 정의할 수 있습니다.

  1. Cymbal Bank 샘플 애플리케이션의 다양한 마이크로서비스의 HTTP 상태를 모니터링하기 위해 몇 가지 Prometheus 프로브를 만듭니다. 다음 샘플 매니페스트를 검토합니다.

    # Copyright 2023 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    ---
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: frontend-probe
      labels:
        app.kubernetes.io/name: frontend-probe
    spec:
      selector:
        matchLabels:
          app: blackbox-exporter
      endpoints:
      - port: metrics
        path: /probe
        params:
          target: [frontend:80]
          module: [http_2xx]
        timeout: 30s
        interval: 60s
    ---
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: userservice-probe
      labels:
        app.kubernetes.io/name: userservice-probe
    spec:
      selector:
        matchLabels:
          app: blackbox-exporter
      endpoints:
      - port: metrics
        path: /probe
        params:
          target: [userservice:8080/ready]
          module: [http_2xx]
        timeout: 30s
        interval: 60s
    ---
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: balancereader-probe
      labels:
        app.kubernetes.io/name: balancereader-probe
    spec:
      selector:
        matchLabels:
          app: blackbox-exporter
      endpoints:
      - port: metrics
        path: /probe
        params:
          target: [balancereader:8080/ready]
          module: [http_2xx]
        timeout: 30s
        interval: 60s
    ---
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: contacts-probe
      labels:
        app.kubernetes.io/name: contacts-probe
    spec:
      selector:
        matchLabels:
          app: blackbox-exporter
      endpoints:
      - port: metrics
        path: /probe
        params:
          target: [contacts:8080/ready]
          module: [http_2xx]
        timeout: 30s
        interval: 60s
    ---
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: ledgerwriter-probe
      labels:
        app.kubernetes.io/name: ledgerwriter-probe
    spec:
      selector:
        matchLabels:
          app: blackbox-exporter
      endpoints:
      - port: metrics
        path: /probe
        params:
          target: [ledgerwriter:8080/ready]
          module: [http_2xx]
        timeout: 30s
        interval: 60s
    ---
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: transactionhistory-probe
      labels:
        app.kubernetes.io/name: transactionhistory-probe
    spec:
      selector:
        matchLabels:
          app: blackbox-exporter
      endpoints:
      - port: metrics
        path: /probe
        params:
          target: [transactionhistory:8080/ready]
          module: [http_2xx]
        timeout: 30s
        interval: 60s
    

    이 매니페스트 파일에서 볼 수 있듯이 각 PodMonitoring Prometheus 활성 프로브에서 각 배포를 개별적으로 모니터링하는 것이 좋습니다.

  2. Prometheus 활성 프로브를 만들려면 클러스터에 매니페스트를 적용합니다.

    kubectl apply -f extras/prometheus/gmp/probes.yaml
    

규칙

이전 단계에서 만든 프로브가 수신하는 응답을 기반으로 Prometheus가 수행할 작업을 알아야 합니다. Prometheus 규칙을 사용하여 이 응답을 정의합니다.

이 튜토리얼에서는 활성 프로브에 대한 응답에 따라 알림을 생성하도록 Prometheus 규칙을 만듭니다. 그런 다음 Alertmanager는 이러한 규칙의 출력을 처리하여 Slack 웹훅을 사용하여 알림을 생성합니다.

  1. 활성 프로브에 대한 응답을 기반으로 이벤트를 생성하는 규칙을 만듭니다. 다음 샘플 매니페스트를 검토합니다.

    # Copyright 2023 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    ---
    apiVersion: monitoring.googleapis.com/v1
    kind: Rules
    metadata:
      name: uptime-rule
    spec:
      groups:
      - name: Micro services uptime
        interval: 60s
        rules:
        - alert: BalancereaderUnavailable
          expr: probe_success{job="balancereader-probe"} == 0
          for: 1m
          annotations:
            summary: Balance Reader Service is unavailable
            description: Check Balance Reader pods and its logs
          labels:
            severity: 'critical'
        - alert: ContactsUnavailable
          expr: probe_success{job="contacts-probe"} == 0
          for: 1m
          annotations:
            summary: Contacts Service is unavailable
            description: Check Contacts pods and its logs
          labels:
            severity: 'warning'
        - alert: FrontendUnavailable
          expr: probe_success{job="frontend-probe"} == 0
          for: 1m
          annotations:
            summary: Frontend Service is unavailable
            description: Check Frontend pods and its logs
          labels:
            severity: 'critical'
        - alert: LedgerwriterUnavailable
          expr: probe_success{job="ledgerwriter-probe"} == 0
          for: 1m
          annotations:
            summary: Ledger Writer Service is unavailable
            description: Check Ledger Writer pods and its logs
          labels:
            severity: 'critical'
        - alert: TransactionhistoryUnavailable
          expr: probe_success{job="transactionhistory-probe"} == 0
          for: 1m
          annotations:
            summary: Transaction History Service is unavailable
            description: Check Transaction History pods and its logs
          labels:
            severity: 'critical'
        - alert: UserserviceUnavailable
          expr: probe_success{job="userservice-probe"} == 0
          for: 1m
          annotations:
            summary: User Service is unavailable
            description: Check User Service pods and its logs
          labels:
            severity: 'critical'
    

    이 매니페스트는 PrometheusRule을 설명하며 다음 필드를 포함합니다.

    • spec.groups.[*].name: 규칙 그룹의 이름입니다.
    • spec.groups.[*].interval: 그룹의 규칙이 평가되는 빈도입니다.
    • spec.groups.[*].rules[*].alert: 알림의 이름입니다.
    • spec.groups.[*].rules[*].expr: 평가할 PromQL 표현식입니다.
    • spec.groups.[*].rules[*].for: 알림이 실행되는 것으로 간주되기 전에 반환되어야 하는 시간입니다.
    • spec.groups.[*].rules[*].annotations: 각 알림에 추가할 주석 목록입니다. 이는 알림 규칙에만 유효합니다.
    • spec.groups.[*].rules[*].labels: 추가하거나 덮어쓸 라벨입니다.
  2. 규칙을 만들려면 클러스터에 매니페스트를 적용합니다.

    kubectl apply -f extras/prometheus/gmp/rules.yaml
    

중단 시뮬레이션

Prometheus 프로브, 규칙, Alertmanager 구성이 올바른지 확인하려면 문제가 발생할 때 경고와 알림이 전송되는지 테스트해야 합니다. 이 흐름을 테스트하지 않으면 문제가 발생할 때 프로덕션 서비스가 중단된다는 사실을 인식하지 못할 수 있습니다.

  1. 마이크로서비스 중 하나의 중단을 시뮬레이션하려면 contacts 배포를 0으로 확장합니다. 서비스 인스턴스가 없으면 Cymbal Bank 샘플 애플리케이션은 고객의 연락처 정보를 읽을 수 없습니다.

    kubectl scale deployment contacts --replicas 0
    

    GKE에서 배포를 축소하는 데 최대 5분이 걸릴 수 있습니다.

  2. 클러스터에서 배포 상태를 확인하고 contacts 배포가 올바르게 축소되는지 확인합니다.

    kubectl get deployments
    

    다음 출력 예시에서 contacts 배포는 0 인스턴스로 성공적으로 축소되었습니다.

    NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
    balancereader        1/1     1            1           17m
    blackbox-exporter    1/1     1            1           5m7s
    contacts             0/0     0            0           17m
    frontend             1/1     1            1           17m
    ledgerwriter         1/1     1            1           17m
    loadgenerator        1/1     1            1           17m
    transactionhistory   1/1     1            1           17m
    userservice          1/1     1            1           17m
    
  3. contacts 배포가 0으로 축소되면 Prometheus 프로브가 HTTP 오류 코드를 보고합니다. 이 HTTP 오류는 Alertmanager가 처리할 알림을 생성합니다.

    Slack 작업공간 채널에서 다음 예시와 비슷한 텍스트가 포함된 중단 알림 메시지를 확인합니다.

    [FIRING:1] ContactsUnavailable
    Severity: Warning :warning:
    Summary: Contacts Service is unavailable
    Namespace: default
    Check Contacts pods and it's logs
    
  4. 실제 중단 시나리오에서는 Slack에서 알림을 받은 후 문제 해결 및 서비스 복원을 시작합니다. 이 튜토리얼에서는 이 프로세스를 시뮬레이션하고 복제본 수를 다시 확장하여 contacts 배포를 복원합니다.

    kubectl scale deployment contacts --replicas 1
    

    배포를 확장하고 Prometheus 프로브가 HTTP 200 응답을 수신하는 데 최대 5분이 걸릴 수 있습니다. kubectl get deployments 명령어를 사용하여 배포 상태를 확인합니다.

    Prometheus 프로브에 대한 정상 응답이 수신되면 Alertmanager가 이벤트를 삭제합니다. 다음 예시와 비슷한 Slack 작업공간 채널에 알림 해결 알림 메시지가 표시됩니다.

    [RESOLVED] ContactsUnavailable
    Severity: Warning :warning:
    Summary: Contacts Service is unavailable
    Namespace: default
    Check Contacts pods and it's logs
    

삭제

Cymbal Bank에 대한 이 튜토리얼 모음을 순서대로 완료하는 것이 좋습니다. 튜토리얼 모음을 진행하면서 새로운 기술을 배우고 추가적인 Google Cloud 제품 및 서비스를 사용하게 됩니다.

다음 튜토리얼로 이동하기 전에 잠시 멈추고 이 튜토리얼에서 사용한 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 생성한 프로젝트를 삭제하세요.

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

다음 단계

다음 튜토리얼에서 GKE Enterprise에서 배포를 확장하는 방법 알아보기