측정항목을 기준으로 포드 자동 확장 최적화

이 튜토리얼에서는 Cloud Monitoring에서 사용할 수 있는 측정항목을 기준으로 Google Kubernetes Engine (GKE) 워크로드를 자동으로 확장하는 방법을 보여줍니다.

이 튜토리얼에서는 다음 측정항목 중 하나를 기준으로 자동 확장을 설정할 수 있습니다.

Pub/Sub

Pub/Sub 백로그

Pub/Sub 구독에 남아 있는 확인되지 않은 메시지 수를 보고하는 외부 측정항목을 기준으로 확장합니다. 이렇게 하면 문제가 발생하기 전에 지연 시간을 효과적으로 줄일 수 있지만, CPU 사용률에 따라 자동 확장보다 리소스를 상대적으로 많이 사용할 수 있습니다.

커스텀 측정항목

커스텀 Prometheus 측정항목

Google 관리형 Prometheus를 통해 Prometheus 형식으로 내보낸 커스텀 사용자 정의 측정항목을 기준으로 확장합니다. Prometheus 측정항목은 Gauge 유형이어야 합니다.

자동 확장은 기본적으로 비용과 지연 시간 사이에서 허용되는 균형을 찾는 것입니다. 이러한 측정항목 및 기타 측정항목의 조합을 실험하여 자신에게 맞는 정책을 찾을 수 있습니다.

커스텀 측정항목 어댑터 배포

커스텀 측정항목 어댑터를 사용하면 클러스터에서 Cloud Monitoring을 통해 측정항목을 보내고 받을 수 있습니다.

Pub/Sub

GKE용 워크로드 아이덴티티 제휴를 사용 설정한 클러스터와 사용 중지한 클러스터는 커스텀 측정항목 어댑터를 설치하는 절차가 서로 다릅니다. 클러스터를 만들 때 선택한 설정과 일치하는 옵션을 선택합니다.

워크로드 아이덴티티

사용자에게 필수 승인 역할을 만들 수 있는 권한을 부여합니다.

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole cluster-admin --user "$(gcloud config get-value account)"

클러스터에 커스텀 측정항목 어댑터를 배포합니다.

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml

어댑터는 custom-metrics 네임스페이스에서 custom-metrics-stackdriver-adapter Kubernetes 서비스 계정을 사용합니다. Monitoring 뷰어 역할을 할당하여 이 서비스 계정이 Cloud Monitoring 측정항목을 읽을 수 있게 합니다.

gcloud projects add-iam-policy-binding projects/$PROJECT_ID \
  --role roles/monitoring.viewer \
  --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapter

기존 인증

사용자에게 필수 승인 역할을 만들 수 있는 권한을 부여합니다.

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole cluster-admin --user "$(gcloud config get-value account)"

클러스터에 커스텀 측정항목 어댑터를 배포합니다.

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml

커스텀 측정항목

GKE용 워크로드 아이덴티티 제휴를 사용 설정한 클러스터와 사용 중지한 클러스터는 커스텀 측정항목 어댑터를 설치하는 절차가 서로 다릅니다. 클러스터를 만들 때 선택한 설정과 일치하는 옵션을 선택합니다.

워크로드 아이덴티티

사용자에게 필수 승인 역할을 만들 수 있는 권한을 부여합니다.

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole cluster-admin --user "$(gcloud config get-value account)"

클러스터에 커스텀 측정항목 어댑터를 배포합니다.

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml

어댑터는 custom-metrics 네임스페이스에서 custom-metrics-stackdriver-adapter Kubernetes 서비스 계정을 사용합니다. Monitoring 뷰어 역할을 할당하여 이 서비스 계정이 Cloud Monitoring 측정항목을 읽을 수 있게 합니다.

gcloud projects add-iam-policy-binding projects/$PROJECT_ID \
  --role roles/monitoring.viewer \
  --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapter

기존 인증

사용자에게 필수 승인 역할을 만들 수 있는 권한을 부여합니다.

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole cluster-admin --user "$(gcloud config get-value account)"

클러스터에 커스텀 측정항목 어댑터를 배포합니다.

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml

측정항목으로 애플리케이션 배포

이 튜토리얼의 애플리케이션 코드가 포함된 저장소를 다운로드합니다.

Pub/Sub

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
cd kubernetes-engine-samples/databases/cloud-pubsub

커스텀 측정항목

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
cd kubernetes-engine-samples/observability/custom-metrics-autoscaling/google-managed-prometheus

저장소에는 Cloud Monitoring으로 측정항목을 내보내는 코드가 포함되어 있습니다.

Pub/Sub

이 애플리케이션은 새 메시지의 Pub/Sub 구독을 폴링하여 메시지가 도착하면 이를 확인합니다. Pub/Sub 구독 측정항목은 Cloud Monitoring에서 자동으로 수집됩니다.

from google import auth
from google.cloud import pubsub_v1


def main():
    """Continuously pull messages from subsciption"""

    # read default project ID
    _, project_id = auth.default()
    subscription_id = 'echo-read'

    subscriber = pubsub_v1.SubscriberClient()
    subscription_path = subscriber.subscription_path(
        project_id, subscription_id)

    def callback(message: pubsub_v1.subscriber.message.Message) -> None:
        """Process received message"""
        print(f"Received message: ID={message.message_id} Data={message.data}")
        print(f"[{datetime.datetime.now()}] Processing: {message.message_id}")
        time.sleep(3)
        print(f"[{datetime.datetime.now()}] Processed: {message.message_id}")
        message.ack()

    streaming_pull_future = subscriber.subscribe(
        subscription_path, callback=callback)
    print(f"Pulling messages from {subscription_path}...")

    with subscriber:
        try:
            streaming_pull_future.result()
        except Exception as e:
            print(e)

커스텀 측정항목

이 애플리케이션은 /metrics 경로에 대한 모든 웹 요청에 대해 Prometheus 형식을 사용하여 상수 값 측정항목으로 응답합니다.

metric := prometheus.NewGauge(
	prometheus.GaugeOpts{
		Name: *metricName,
		Help: "Custom metric",
	},
)
prometheus.MustRegister(metric)
metric.Set(float64(*metricValue))

http.Handle("/metrics", promhttp.Handler())
log.Printf("Starting to listen on :%d", *port)
err := http.ListenAndServe(fmt.Sprintf(":%d", *port), nil)

저장소에는 애플리케이션을 클러스터에 배포하기 위한 Kubernetes 매니페스트도 포함됩니다. 배포는 클러스터에서 노드 간에 배포되는 여러 포드 복제본을 실행할 수 있는 Kubernetes API 객체입니다.

Pub/Sub

GKE용 워크로드 아이덴티티 제휴를 사용 설정한 클러스터와 사용 중지한 클러스터는 매니페스트가 서로 다릅니다. 클러스터를 만들 때 선택한 설정과 일치하는 옵션을 선택합니다.

워크로드 아이덴티티

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pubsub
spec:
  selector:
    matchLabels:
      app: pubsub
  template:
    metadata:
      labels:
        app: pubsub
    spec:
      serviceAccountName: pubsub-sa
      containers:
      - name: subscriber
        image: us-docker.pkg.dev/google-samples/containers/gke/pubsub-sample:v2

기존 인증

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pubsub
spec:
  selector:
    matchLabels:
      app: pubsub
  template:
    metadata:
      labels:
        app: pubsub
    spec:
      volumes:
      - name: google-cloud-key
        secret:
          secretName: pubsub-key
      containers:
      - name: subscriber
        image: us-docker.pkg.dev/google-samples/containers/gke/pubsub-sample:v2
        volumeMounts:
        - name: google-cloud-key
          mountPath: /var/secrets/google
        env:
        - name: GOOGLE_APPLICATION_CREDENTIALS
          value: /var/secrets/google/key.json

커스텀 측정항목

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: custom-metrics-gmp
  name: custom-metrics-gmp
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      run: custom-metrics-gmp
  template:
    metadata:
      labels:
        run: custom-metrics-gmp
    spec:
      containers:
      # sample container generating custom metrics
      - name: prometheus-dummy-exporter
        image: us-docker.pkg.dev/google-samples/containers/gke/prometheus-dummy-exporter:v0.2.0
        command: ["./prometheus-dummy-exporter"]
        args:
        - --metric-name=custom_prometheus
        - --metric-value=40
        - --port=8080

Google Cloud Managed Service for Prometheus에서는 PodMonitoring 리소스를 사용하여 Prometheus 측정항목을 Cloud Monitoring으로 내보냅니다.

apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
  name: "custom-metrics-exporter"
spec:
  selector:
    matchLabels:
      run: custom-metrics-gmp
  endpoints:
  - port: 8080
    path: /metrics
    interval: 15s

GKE Standard 버전 1.27 또는 GKE Autopilot 버전 1.25부터는 Google Cloud Managed Service for Prometheus가 사용 설정됩니다. 이전 버전에서 클러스터의 Google Cloud Managed Service for Prometheus를 사용 설정하려면 관리형 수집 사용 설정을 참조하세요.

애플리케이션을 클러스터에 배포합니다.

Pub/Sub

GKE용 워크로드 아이덴티티 제휴를 사용 설정한 클러스터와 사용 중지한 클러스터는 애플리케이션을 배포하는 절차가 서로 다릅니다. 클러스터를 만들 때 선택한 설정과 일치하는 옵션을 선택합니다.

워크로드 아이덴티티

  1. 프로젝트에서 Pub/Sub API를 사용 설정합니다.

    gcloud services enable cloudresourcemanager.googleapis.com pubsub.googleapis.com
    
  2. Pub/Sub 주제 및 구독을 만듭니다.

    gcloud pubsub topics create echo
    gcloud pubsub subscriptions create echo-read --topic=echo
    
  3. 애플리케이션을 클러스터에 배포합니다.

    kubectl apply -f deployment/pubsub-with-workload-identity.yaml
    
  4. 이 애플리케이션은 pubsub-sa Kubernetes 서비스 계정을 정의합니다. 애플리케이션에서 메시지를 Pub/Sub 주제에 게시할 수 있도록 Pub/Sub 구독자 역할을 애플리케이션에 할당합니다.

    gcloud projects add-iam-policy-binding projects/$PROJECT_ID \
      --role=roles/pubsub.subscriber \
      --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID.svc.id.goog/subject/ns/default/sa/pubsub-sa
    

    위 명령어는 IAM이 Kubernetes 서비스 계정을 직접 참조하도록 주 구성원 식별자를 사용합니다.

    권장사항:

    주 구성원 식별자를 사용하되 대체 방법 설명에 나오는 제한사항을 고려해야 합니다.

기존 인증

  1. 프로젝트에서 Pub/Sub API를 사용 설정합니다.

    gcloud services enable cloudresourcemanager.googleapis.com pubsub.googleapis.com
    
  2. Pub/Sub 주제 및 구독을 만듭니다.

    gcloud pubsub topics create echo
    gcloud pubsub subscriptions create echo-read --topic=echo
    
  3. Pub/Sub에 액세스할 수 있는 서비스 계정을 만듭니다.

    gcloud iam service-accounts create autoscaling-pubsub-sa
    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member "serviceAccount:autoscaling-pubsub-sa@$PROJECT_ID.iam.gserviceaccount.com" \
      --role "roles/pubsub.subscriber"
    
  4. 서비스 계정 키 파일을 다운로드합니다.

    gcloud iam service-accounts keys create key.json \
      --iam-account autoscaling-pubsub-sa@$PROJECT_ID.iam.gserviceaccount.com
    
  5. 서비스 계정 키를 클러스터에 보안 비밀로 가져옵니다.

    kubectl create secret generic pubsub-key --from-file=key.json=./key.json
    
  6. 애플리케이션을 클러스터에 배포합니다.

    kubectl apply -f deployment/pubsub-with-secret.yaml
    

커스텀 측정항목

kubectl apply -f custom-metrics-gmp.yaml

애플리케이션이 배포될 때까지 잠시 기다리면 모든 포드가 Ready 상태에 도달합니다.

Pub/Sub

kubectl get pods

출력:

NAME                     READY   STATUS    RESTARTS   AGE
pubsub-8cd995d7c-bdhqz   1/1     Running   0          58s

커스텀 측정항목

kubectl get pods

출력:

NAME                                  READY   STATUS    RESTARTS   AGE
custom-metrics-gmp-865dffdff9-x2cg9   1/1     Running   0          49s

Cloud Monitoring에서 측정항목 보기

애플리케이션이 실행되면 측정항목이 Cloud Monitoring에 기록됩니다.

측정항목 탐색기를 사용하여 모니터링 리소스의 측정항목을 확인하려면 다음을 수행하세요.

  1. Google Cloud 콘솔에서  측정항목 탐색기 페이지로 이동합니다.

    측정항목 탐색기로 이동

    검색창을 사용하여 이 페이지를 찾은 경우 부제목이 Monitoring인 결과를 선택합니다.

  2. 측정항목 요소에서 측정항목 선택 메뉴를 확장한 후 리소스 유형 및 측정항목 유형을 선택합니다. 예를 들어 가상 머신의 CPU 사용률을 차트로 표시하려면 다음 안내를 따르세요.
    1. (선택사항) 메뉴의 옵션을 줄이려면 필터 표시줄에서 측정항목 이름의 일부를 입력합니다. 이 예시에서는 utilization을 입력합니다.
    2. 활성 리소스 메뉴에서 VM 인스턴스를 선택합니다.
    3. 활성 측정항목 카테고리 메뉴에서 인스턴스를 선택합니다.
    4. 활성 측정항목 메뉴에서 CPU 사용량을 선택한 후 적용을 클릭합니다.
  3. 표시할 시계열을 필터링하려면 필터 요소를 사용합니다.

  4. 시계열을 조합하려면 집계 요소의 메뉴를 사용합니다. 예를 들어 VM의 CPU 사용률을 영역에 따라 표시하려면 첫 번째 메뉴를 평균으로, 두 번째 메뉴를 영역으로 설정합니다.

    집계 요소의 첫 번째 메뉴가 집계되지 않음으로 설정되면 모든 시계열이 표시됩니다. 집계 요소 기본 설정은 선택한 측정항목 유형에 따라 결정됩니다.

리소스 유형과 측정항목은 다음과 같습니다.

Pub/Sub

측정항목 탐색기

리소스 유형: pubsub_subscription

측정항목: pubsub.googleapis.com/subscription/num_undelivered_messages

커스텀 측정항목

측정항목 탐색기

리소스 유형: prometheus_target

측정항목: prometheus.googleapis.com/custom_prometheus/gauge

측정항목에 따라 Cloud Monitoring 측정항목 탐색기에 많은 활동이 아직 표시되지 않을 수 있습니다. 측정항목이 업데이트되지 않아도 놀라지 마세요.

HorizontalPodAutoscaler 객체 만들기

Cloud Monitoring에 측정항목이 표시되면 HorizontalPodAutoscaler를 배포하여 측정항목에 따라 배포 크기를 조절할 수 있습니다.

Pub/Sub

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: pubsub
spec:
  minReplicas: 1
  maxReplicas: 5
  metrics:
  - external:
      metric:
       name: pubsub.googleapis.com|subscription|num_undelivered_messages
       selector:
         matchLabels:
           resource.labels.subscription_id: echo-read
      target:
        type: AverageValue
        averageValue: 2
    type: External
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: pubsub

커스텀 측정항목

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: custom-metrics-gmp-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: custom-metrics-gmp
  minReplicas: 1
  maxReplicas: 5
  metrics:
  - type: Pods
    pods:
      metric:
        name: prometheus.googleapis.com|custom_prometheus|gauge
      target:
        type: AverageValue
        averageValue: 20

HorizontalPodAutoscaler를 클러스터에 배포합니다.

Pub/Sub

kubectl apply -f deployment/pubsub-hpa.yaml

커스텀 측정항목

kubectl apply -f custom-metrics-gmp-hpa.yaml

부하 생성

일부 측정항목의 경우 자동 확장을 보기 위해 부하를 생성해야 할 수 있습니다.

Pub/Sub

Pub/Sub 주제에 메시지 200개를 게시합니다.

for i in {1..200}; do gcloud pubsub topics publish echo --message="Autoscaling #${i}"; done

커스텀 측정항목

해당 없음: 이 샘플에 사용된 코드는 커스텀 측정항목의 상수 값 40을 내보냅니다. HorizontalPodAutoscaler는 대상 값 20으로 설정되므로 배포를 자동으로 확장하려고 시도합니다.

HorizontalPodAutoscaler가 측정항목 변경에 응답할 때까지 몇 분 정도 기다려야 할 수 있습니다.

HorizontalPodAutoscaler 확장 관찰

다음 명령어를 실행하여 배포의 현재 복제본 수를 확인할 수 있습니다.

kubectl get deployments

측정항목이 전파될 때까지 약간의 시간이 지나면 배포에서 백로그를 처리할 수 있는 포드 5개가 생성됩니다.

다음 명령어를 실행하여 HorizontalPodAutoscaler의 상태와 최근 활동도 검사할 수 있습니다.

kubectl describe hpa