GKE에서 Elastic Stack 설정


이 튜토리얼에서는 Kubernetes 기반 Elastic Cloud(ECK) 연산자를 사용하여 GKE에서 Elastic Stack을 실행하는 방법을 보여줍니다.

Elastic Stack은 실시간으로 데이터를 로깅, 모니터링, 분석하는 데 사용되는 대중적인 오픈소스 솔루션입니다. GKE에서 Elastic Stack을 사용하면 GKE Autopilot과 강력한 Elastic Stack 기능을 통해 확장성과 안정성을 확보할 수 있습니다.

이 튜토리얼은 Kubernetes 관리자 또는 사이트 안정성 엔지니어를 대상으로 합니다.

목표

  • GKE 클러스터 만들기
  • ECK 연산자 배포
  • ECK 연산자를 사용하여 Elasticsearch 클러스터 및 Kibana 구성
  • ECK 연산자를 사용하여 완전한 Elastic Stack 배포
  • Elasticsearch 클러스터의 자동 확장 및 Elastic Stack 배포 업그레이드
  • Elastic Stack을 사용하여 Kubernetes 환경 모니터링

비용

이 문서에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.

프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요. Google Cloud를 처음 사용하는 사용자는 무료 체험판을 사용할 수 있습니다.

이 문서에 설명된 태스크를 완료했으면 만든 리소스를 삭제하여 청구가 계속되는 것을 방지할 수 있습니다. 자세한 내용은 삭제를 참조하세요.

시작하기 전에

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.
  3. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  5. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  6. Enable the GKE API:

    gcloud services enable container.googleapis.com
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

    gcloud init
  9. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  10. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  11. Enable the GKE API:

    gcloud services enable container.googleapis.com
  12. Google 계정에 역할을 부여합니다. 다음 각 IAM 역할에 대해 다음 명령어를 한 번씩 실행합니다. roles/container.clusterAdmin

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:EMAIL_ADDRESS" --role=ROLE
    • PROJECT_ID를 프로젝트 ID로 바꿉니다.
    • EMAIL_ADDRESS를 이메일 주소로 바꿉니다.
    • ROLE을 각 개별 역할로 바꿉니다.
  • 소유 도메인 이름이 있어야 합니다. 도메인 이름은 63자(영문 기준) 이하여야 합니다. Cloud Domains 또는 다른 등록기관을 이용할 수 있습니다.

환경 준비

이 튜토리얼에서는 Cloud Shell을 사용하여 Google Cloud에서 호스팅되는 리소스를 관리합니다. Cloud Shell에는 kubectl, Helm, gcloud CLI 등 이 튜토리얼에서 필요한 소프트웨어가 사전 설치되어 있습니다.

Cloud Shell로 환경을 설정하려면 다음 단계를 따르세요.

  1. Google Cloud 콘솔에서 Cloud Shell 활성화 아이콘Cloud Shell 활성화를 클릭하여 Google Cloud 콘솔에서 Cloud Shell 세션을 시작합니다. 그러면 Google Cloud 콘솔 하단 창에서 세션이 시작됩니다.

  2. Helm 차트 저장소를 추가한 후 업데이트합니다.

    helm repo add elastic https://helm.elastic.co
    helm repo update
    
  3. GitHub 저장소를 클론합니다.

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
    
  4. 작업 디렉터리로 변경합니다.

    cd kubernetes-engine-samples/observability/elastic-stack-tutorial
    

GKE 클러스터 만들기

컨트롤 플레인 측정항목 수집이 사용 설정된 GKE 클러스터를 만듭니다.

gcloud container clusters create-auto elk-stack \
    --location="us-central1" \
    --monitoring="SYSTEM,WORKLOAD,API_SERVER,SCHEDULER,CONTROLLER_MANAGER"

ECK 연산자 배포

Elastic Cloud on Kubernetes(ECK)는 Kubernetes 클러스터에서 Elastic Stack을 배포 및 관리하기 위한 플랫폼입니다.

ECK는 Elastic Stack 클러스터의 배포 및 관리를 자동화하여 Kubernetes에서 Elastic Stack을 설정하고 유지보수하는 프로세스를 간소화합니다. Kubernetes에서 Elasticsearch, Kibana, 애플리케이션 성능 관리 서버, 기타 Elastic Stack 구성요소를 만들고 구성하는 데 사용할 수 있는 Kubernetes 커스텀 리소스 집합을 제공합니다. 이를 통해 개발자와 DevOps팀은 Elastic Stack 클러스터를 대규모로 구성하고 관리할 수 있습니다.

ECK는 여러 Elasticsearch 노드, 자동 애플리케이션 장애 조치, 원활한 업그레이드, SSL 암호화를 지원합니다. ECK에는 Elasticsearch 성능을 모니터링하고 문제를 해결할 수 있는 기능도 포함되어 있습니다.

  1. ECK Helm 차트를 설치합니다.

    helm upgrade --install "elastic-operator" "elastic/eck-operator" \
        --version="2.8.0" \
        --create-namespace \
        --namespace="elastic-system" \
        --set="resources.limits.cpu=250m" \
        --set="resources.limits.memory=512Mi" \
        --set="resources.limits.ephemeral-storage=1Gi" \
        --set="resources.requests.cpu=250m" \
        --set="resources.requests.memory=512Mi" \
        --set="resources.requests.ephemeral-storage=1Gi"
    
  2. 다음과 같이 연산자가 준비될 때까지 기다립니다.

    watch kubectl get pods -n elastic-system
    

    출력은 다음과 비슷합니다.

    NAME                 READY   STATUS    RESTARTS   AGE
    elastic-operator-0   1/1     Running   0          31s    
    

    연산자 STATUS이(가) Running이면 Ctrl+C을(를) 눌러 명령줄로 돌아갑니다.

ECK에서 Elastic Stack 구성

Elasticsearch, Kibana, Fleet 모드로 작동하는 Elastic 에이전트를 사용하면 Kibana를 통해 데이터를 관리하고 시각화할 수 있는 강력하고 확장 가능한 완전 관리형 솔루션을 설정할 수 있습니다.

Kibana는 Elasticsearch에서 데이터를 검색, 분석, 시각화하도록 하는 오픈소스 데이터 분석 및 시각화 도구입니다.

Elastic 에이전트는 로그 또는 측정항목과 같은 다양한 소스에서 데이터를 수집하여 Elasticsearch로 자동 전송하는 간단한 데이터 전송자입니다.

Elastic Fleet은 Elastic 에이전트가 중앙의 Fleet 서버에 보고하고 서버에서 구성 및 관리를 처리하는 작업 모드입니다. Fleet 서버는 Elastic 에이전트의 배포, 구성, 확장을 간소화하므로 대규모의 복잡한 배포를 보다 쉽게 관리할 수 있습니다.

Elasticsearch 자동 확장은 운영자 정의 정책에 따라 추가 리소스가 필요할 때 보고할 수 있는 자체 모니터링 기능입니다. 예를 들어 정책을 통해 가용 디스크 공간을 기반으로 특정 등급을 확장하도록 지정할 수 있습니다. Elasticsearch는 디스크 공간을 모니터링하고 용량 부족이 예측되는 경우 확장을 제안할 수는 있지만 필요한 리소스를 추가하는 것은 여전히 운영자의 책임입니다. Elasticsearch 자동 확장에 관한 자세한 내용은 Elasticsearch 문서의 자동 확장을 참조하세요.

Elasticsearch 클러스터 구성

Elasticsearch는 대량의 데이터를 빠르고 효율적으로 저장하고 검색할 수 있도록 설계된 분산형 RESTful 검색 및 분석 엔진을 제공합니다.

Kubernetes에 Elastic Stack을 배포할 때는 VM 설정, 특히 Elasticsearch에 필요한 vm.max_map_count setting을(를) 관리해야 합니다. vm.max_map_count은(는) 프로세스에서 파일에 할당할 수 있는 메모리 영역의 수를 지정합니다. Elasticsearch가 최적으로 실행되려면 이 값을 262144 이상으로 설정해야 합니다. 자세한 내용은 ECK 문서의 가상 메모리를 참조하세요.

  1. 다음 매니페스트를 검토합니다.

    apiVersion: scheduling.k8s.io/v1
    kind: PriorityClass
    metadata:
      name: user-daemonset-priority
    value: 999999999
    preemptionPolicy: PreemptLowerPriority
    globalDefault: false
    description: "User DaemonSet priority"

    이 매니페스트는 호스트에서 직접 커널 설정을 구성하는 DaemonSet를 설명합니다. 이 매니페스트는 Autopilot 모드로 실행되는 허용 목록에 있습니다. 컨테이너 이미지를 포함하여 이 매니페스트를 수정하지 마세요.

  2. 이 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f max-map-count-setter-ds.yaml
    
  3. 다음 매니페스트를 검토합니다.

    apiVersion: elasticsearch.k8s.elastic.co/v1
    kind: Elasticsearch
    metadata:
      name: elasticsearch
      namespace: elastic-system
    spec:
      version: "8.9.0"
      volumeClaimDeletePolicy: DeleteOnScaledownOnly
      podDisruptionBudget:
        spec:
          minAvailable: 2
          selector:
            matchLabels:
              elasticsearch.k8s.elastic.co/cluster-name: elasticsearch
      nodeSets:
        - name: default
          config:
            node.roles: ["master", "data", "ingest", "ml", "remote_cluster_client"]
          podTemplate:
            metadata:
              labels:
                app.kubernetes.io/name: elasticsearch
                app.kubernetes.io/version: "8.9.0"
                app.kubernetes.io/component: "elasticsearch"
                app.kubernetes.io/part-of: "elk"
            spec:
              nodeSelector:
                cloud.google.com/compute-class: "Balanced"
              initContainers:
                - name: max-map-count-check
                  command:
                    - sh
                    - -c
                    - while true; do mmc=$(cat /proc/sys/vm/max_map_count); if test ${mmc} -eq 262144; then exit 0; fi; sleep 1; done
                  resources:
                    requests:
                      cpu: 10m
                      memory: 16Mi
                      ephemeral-storage: 16Mi
                    limits:
                      cpu: 10m
                      memory: 16Mi
                      ephemeral-storage: 16Mi
              containers:
                - name: elasticsearch
                  resources:
                    requests:
                      cpu: 990m
                      memory: 4080Mi
                      ephemeral-storage: 1008Mi
                    limits:
                      cpu: 1000m
                      memory: 4080Mi
                      ephemeral-storage: 1008Mi
                  env:
                    - name: ES_JAVA_OPTS
                      value: "-Xms2g -Xmx2g"
          count: 3
          volumeClaimTemplates:
            - metadata:
                name: elasticsearch-data # Do not change this name unless you set up a volume mount for the data path.
              spec:
                accessModes:
                  - ReadWriteOnce
                resources:
                  requests:
                    storage: 2Gi
                storageClassName: standard-rwo

    이 매니페스트는 다음 필드를 사용하여 Elasticsearch 클러스터를 정의합니다.

    • initContainers: 가상 메모리 호스트의 커널 설정이 변경될 때까지 기다립니다.
    • podDisruptionBudget: 포드의 디스크 조각 모음 프로세스 중에 클러스터가 폐기되지 않도록 지정합니다.
    • config.node.roles: Elasticsearch 노드 역할 구성입니다. 노드 역할에 대한 자세한 내용은 Elasticsearch 문서의 노드를 참조하세요.
  4. 이 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f elasticsearch.yaml
    
  5. Elasticsearch 클러스터가 준비될 때까지 기다립니다.

    watch kubectl --namespace elastic-system get elasticsearches.elasticsearch.k8s.elastic.co
    

    출력은 다음과 비슷합니다.

    NAME            HEALTH   NODES   VERSION   PHASE   AGE
    elasticsearch   green    3       8.8.0     Ready   5m3s
    

    Elasticsearch 클러스터 HEALTH이(가) green, PHASE이(가) Ready(으)로 되면 Ctrl+C을(를) 눌러 명령줄로 돌아갑니다.

Kibana 구성

  1. 다음 매니페스트를 검토합니다.

    apiVersion: kibana.k8s.elastic.co/v1
    kind: Kibana
    metadata:
      name: kibana
      namespace: elastic-system
    spec:
      version: "8.9.0"
      count: 1
      elasticsearchRef:
        name: elasticsearch
        namespace: elastic-system
      http:
        tls:
          selfSignedCertificate:
            disabled: true
      config:
        server.publicBaseUrl: https://elk.BASE_DOMAIN
        xpack.reporting.kibanaServer.port: 5601
        xpack.reporting.kibanaServer.protocol: http
        xpack.reporting.kibanaServer.hostname: kibana-kb-http.elastic-system.svc
        xpack.fleet.agents.elasticsearch.hosts: ["https://elasticsearch-es-http.elastic-system.svc:9200"]
        xpack.fleet.agents.fleet_server.hosts: ["https://fleet-server-agent-http.elastic-system.svc:8220"]
        xpack.fleet.packages:
        - name: system
          version: latest
        - name: elastic_agent
          version: latest
        - name: fleet_server
          version: latest
        - name: kubernetes
          version: latest
        xpack.fleet.agentPolicies:
        - name: Fleet Server on ECK policy
          id: eck-fleet-server
          namespace: default
          monitoring_enabled:
          - logs
          - metrics
          unenroll_timeout: 900
          package_policies:
          - name: fleet_server-1
            id: fleet_server-1
            package:
              name: fleet_server
        - name: Elastic Agent on ECK policy
          id: eck-agent
          namespace: default
          monitoring_enabled:
          - logs
          - metrics
          unenroll_timeout: 900
          package_policies:
          - package:
              name: system
            name: system-1
          - package:
              name: kubernetes
            name: kubernetes-1
      podTemplate:
        metadata:
          labels:
            app.kubernetes.io/name: kibana
            app.kubernetes.io/version: "8.9.0"
            app.kubernetes.io/component: "ui"
            app.kubernetes.io/part-of: "elk"
        spec:
          containers:
          - name: kibana
            resources:
              requests:
                memory: 1Gi
                cpu: 500m
                ephemeral-storage: 1Gi
              limits:
                memory: 1Gi
                cpu: 500m
                ephemeral-storage: 1Gi

    이 매니페스트는 Fleet 서버와 에이전트에 대한 에이전트 정책을 구성하는 Kibana 커스텀 리소스를 설명합니다.

  2. 이 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f kibana.yaml
    
  3. 포드가 준비될 때까지 기다립니다.

    watch kubectl --namespace elastic-system get kibanas.kibana.k8s.elastic.co
    

    출력은 다음과 비슷합니다.

    NAME     HEALTH   NODES   VERSION   AGE
    kibana   green    1       8.8.0     6m47s
    

    포드 HEALTH이(가) green(으)로 되면 Ctrl+C을(를) 눌러 명령줄로 돌아갑니다.

Kibana에 액세스하도록 부하 분산기 구성

Kibana에 액세스하려면 Kubernetes 인그레스 객체, Google 관리형 인증서, 전역 IP 주소, DNS 영역을 만듭니다.

  1. 전역 외부 IP 주소를 만듭니다.

    gcloud compute addresses create "elastic-stack" --global
    
  2. Cloud DNS에서 관리형 영역 및 레코드 세트를 만듭니다.

    gcloud dns managed-zones create "elk" \
        --description="DNS Zone for Airflow" \
        --dns-name="elk.BASE_DOMAIN" \
        --visibility="public"
    
    gcloud dns record-sets create "elk.BASE_DOMAIN" \
        --rrdatas="$(gcloud compute addresses describe "elastic-stack" --global --format="value(address)")" \
        --ttl="300" \
        --type="A" \
        --zone="elk"
    
  3. 네임서버 목록으로 NS 레코드 세트를 만들어 DNS 영역을 기본 도메인의 하위 도메인으로 지정합니다. 다음 명령어를 사용하여 네임서버 목록을 가져올 수 있습니다.

    gcloud dns record-sets describe elk.BASE_DOMAIN \
        --type="NS" \
        --zone="elk" \
        --format="value(DATA)"
    
  4. 다음 매니페스트를 검토합니다.

    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: elastic-stack
      namespace: elastic-system
    spec:
      domains:
        - elk.BASE_DOMAIN

    이 매니페스트는 TLS 연결을 설정하기 위해 SSL 인증서를 프로비저닝하는 ManagedCertificate를 설명합니다.

  5. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f ingress.yaml
    

Elastic 에이전트 구성

  1. 다음 매니페스트를 검토합니다.

    apiVersion: agent.k8s.elastic.co/v1alpha1
    kind: Agent
    metadata:
      name: fleet-server
      namespace: elastic-system
    spec:
      version: 8.9.0
      kibanaRef:
        name: kibana
        namespace: elastic-system
      elasticsearchRefs:
        - name: elasticsearch
          namespace: elastic-system
      mode: fleet
      fleetServerEnabled: true
      policyID: eck-fleet-server
      deployment:
        replicas: 1
        podTemplate:
          metadata:
            labels:
              app.kubernetes.io/name: fleet-server
              app.kubernetes.io/version: "8.9.0"
              app.kubernetes.io/component: "agent"
              app.kubernetes.io/part-of: "elk"
          spec:
            containers:
              - name: agent
                resources:
                  requests:
                    memory: 512Mi
                    cpu: 250m
                    ephemeral-storage: 10Gi
                  limits:
                    memory: 512Mi
                    cpu: 250m
                    ephemeral-storage: 10Gi
            volumes:
              - name: "agent-data"
                ephemeral:
                  volumeClaimTemplate:
                    spec:
                      accessModes: ["ReadWriteOnce"]
                      storageClassName: "standard-rwo"
                      resources:
                        requests:
                          storage: 10Gi
            serviceAccountName: fleet-server
            automountServiceAccountToken: true
            securityContext:
              runAsUser: 0

    이 매니페스트는 ECK에서 Fleet 서버를 구성하는 Elastic 에이전트를 설명합니다.

  2. 이 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f fleet-server-and-agents.yaml
    
  3. 포드가 준비될 때까지 기다립니다.

    watch kubectl --namespace elastic-system get agents.agent.k8s.elastic.co
    

    출력은 다음과 비슷합니다.

    NAME            HEALTH   AVAILABLE   EXPECTED   VERSION   AGE
    elastic-agent   green    5           5          8.8.0     14m
    fleet-server    green    1           1          8.8.0     16m
    

    포드 HEALTH이(가) green(으)로 되면 Ctrl+C을(를) 눌러 명령줄로 돌아갑니다.

로깅 및 모니터링 구성

Elastic Stack은 kube-state-metrics 내보내기 도구를 사용하여 클러스터 수준 측정항목을 수집할 수 있습니다.

  1. kube-state-metrics를 설치합니다.

    helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
    helm repo update
    helm install kube-state-metrics prometheus-community/kube-state-metrics --namespace elastic-system
    
  2. 기본 Kibana elastic 사용자 인증 정보를 가져옵니다.

    kubectl get secret elasticsearch-es-elastic-user -o yaml -n elastic-system -o jsonpath='{.data.elastic}' | base64 -d
    
  3. 브라우저에서 https://elk.BASE_DOMAIN을(를) 열고 사용자 인증 정보를 사용하여 Kibana에 로그인합니다.

  4. 메뉴에서 분석에 이어 대시보드를 선택합니다.

  5. 검색 텍스트 입력란에 Kubernetes 개요를 입력하고 개요 대시보드를 선택하여 기본 측정항목을 확인합니다.

    GKE가 Kibana에서 클러스터 측정항목을 가져오는 데 사용하는 일부 제어 영역 엔드포인트에 대한 액세스를 제한하므로 일부 대시보드 패널에 데이터가 없거나 오류 메시지가 표시될 수 있습니다.

삭제

이 튜토리얼에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트를 유지하고 개별 리소스를 삭제하세요.

프로젝트 삭제

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

개별 리소스 삭제

기존 프로젝트를 사용한 경우 삭제하지 않으려면 개별 리소스를 삭제합니다.

  1. Elastic Stack 구성요소, ECK 연산자, kube-state-metrics를 삭제합니다.

    kubectl --namespace elastic-system delete ingresses.networking.k8s.io elastic-stack
    kubectl --namespace elastic-system delete managedcertificates.networking.gke.io elastic-stack
    kubectl --namespace elastic-system delete frontendconfigs.networking.gke.io elastic-stack
    kubectl --namespace elastic-system delete agents.agent.k8s.elastic.co elastic-agent
    kubectl --namespace elastic-system delete agents.agent.k8s.elastic.co fleet-server
    kubectl --namespace elastic-system delete kibanas.kibana.k8s.elastic.co kibana
    kubectl --namespace elastic-system delete elasticsearches.elasticsearch.k8s.elastic.co elasticsearch
    kubectl --namespace elastic-system delete daemonsets.apps max-map-count-setter
    kubectl --namespace elastic-system delete pvc --selector='elasticsearch.k8s.elastic.co/cluster-name=elasticsearch'
    helm --namespace elastic-system uninstall kube-state-metrics
    helm --namespace elastic-system uninstall elastic-operator
    
  2. DNS 레코드 세트, IP 주소, DNS 관리형 영역, GKE 클러스터를 삭제합니다.

    gcloud dns record-sets delete "elk.BASE_DOMAIN" \
        --type="A" \
        --zone="elk" \
        --quiet
    
    gcloud compute addresses delete "elastic-stack" \
        --global \
        --quiet
    
    gcloud dns managed-zones delete "elk" --quiet
    
    gcloud container clusters delete "elk-stack" \
        --location="us-central1" \
        --quiet
    

다음 단계

  • Google Cloud에 대한 참조 아키텍처, 다이어그램, 권장사항 살펴보기. Cloud 아키텍처 센터 살펴보기