Service Mesh (ASM) は、Container Service for Kubernetes (ACK) クラスターおよびContainer Compute Service (ACS) クラスターのテレメトリデータを非侵入的な方法で収集します。 このテレメトリ機能により、サービスの動作が観察可能になり、O&Mスタッフがメンテナンスコストを増加させることなく、アプリケーションのトラブルシューティング、保守、最適化に役立ちます。 遅延、トラフィック、エラー、および飽和を含む4つの主要なメトリックに基づいて、ASMは、管理するサービスの一連のメトリックを生成します。 このトピックでは、ASMメトリックを使用してワークロードの自動スケーリングを実装する方法について説明します。
前提条件
ACKクラスターまたはACSクラスターが作成されます。 詳細については、「ACK管理クラスターの作成」または「ACSクラスターの作成」をご参照ください。
ASMインスタンスが作成されます。 詳細については、「ASMインスタンスの作成」をご参照ください。
PrometheusインスタンスとGrafanaインスタンスがクラスターにデプロイされます。 詳細については、「オープンソースのPrometheusを使用したACKクラスターのモニタリング」をご参照ください。
ASMインスタンスを監視するためにPrometheusインスタンスがデプロイされています。 詳細については、「自己管理型Prometheusインスタンスを使用したASMインスタンスの監視」をご参照ください。
背景
ASMは、管理するサービスの一連のメトリックを生成します。 詳細については、「Istio Standard Metrics」をご参照ください。
自動スケーリングは、リソース使用量に基づいてワークロードを自動的にスケールアップまたはスケールダウンするために使用されるアプローチです。 Kubernetesでは、2つのオートスケーラーを使用してオートスケーリングを実装します。
クラスターオートスケーラー (CA): CAは、クラスター内のノード数を増減するために使用されます。
水平ポッドオートスケーラー (HPA): HPAは、アプリケーションのデプロイに使用されるポッドの数を増減するために使用されます。
Kubernetesの集約レイヤーを使用すると、サードパーティのアプリケーションは、APIアドオンとして登録することでKubernetes APIを拡張できます。 これらのアドオンを使用して、カスタムメトリクスAPIを実装し、HPAが任意のメトリクスを照会できるようにすることができます。 HPAは、リソースメトリクスAPIを使用して、CPU使用率やメモリ使用量などのコアメトリクスを定期的にクエリします。 さらに、HPAはカスタムメトリクスAPIを使用して、ASMによって提供される可観測性メトリクスなどのアプリケーション固有のメトリクスを照会します。
手順1: ASMインスタンスのPrometheusモニタリングを有効にする
詳細については、「PrometheusのManaged Serviceへのメトリックの収集」をご参照ください。
手順2: カスタムメトリクスAPIのアダプターのデプロイ
次のコマンドを実行して、アダプタのインストールパッケージをダウンロードします。 次に、カスタムメトリクスAPIのアダプターをクラスターにインストールしてデプロイします。
詳細については、kube-metrics-adapterをご参照ください。
## Use Helm 3. helm -n kube-system install asm-custom-metrics ./kube-metrics-adapter --set prometheus.url=http://prometheus.istio-system.svc:9090
インストールが完了したら、次のコマンドを実行してkube-metrics-adapterが有効かどうかを確認します。
次のコマンドを実行して、
autoscaling/v2beta
が存在することを確認します。kubectl api-versions |grep "autoscaling/v2beta"
期待される出力:
autoscaling/v2beta
次のコマンドを実行して、kube-metrics-adapterのポッドのステータスを確認します。
kubectl get po -n kube-system |grep metrics-adapter
期待される出力:
asm-custom-metrics-kube-metrics-adapter-85c6d5d865-2**** 1/1 Running 0 19s
次のコマンドを実行して、kube-metrics-adapterによって提供されるカスタムメトリクスを照会します。
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1" | jq .
期待される出力:
{ "kind": "APIResourceList", "apiVersion": "v1", "groupVersion": "external.metrics.k8s.io/v1beta1", "resources": [] }
手順3: サンプルアプリケーションのデプロイ
testという名前の名前空間を作成します。 詳細については、「名前空間とリソースクォータの管理」をご参照ください。
自動サイドカープロキシ注入を有効にします。 詳細については、「自動サイドカープロキシ注入の有効化」をご参照ください。
サンプルアプリケーションを展開します。
podinfo.yamlという名前のファイルを作成し、次のコンテンツをファイルにコピーします。
apiVersion: apps/v1 kind: Deployment metadata: name: podinfo namespace: test labels: app: podinfo spec: minReadySeconds: 5 strategy: rollingUpdate: maxUnavailable: 0 type: RollingUpdate selector: matchLabels: app: podinfo template: metadata: annotations: prometheus.io/scrape: "true" labels: app: podinfo spec: containers: - name: podinfod image: stefanprodan/podinfo:latest imagePullPolicy: IfNotPresent ports: - containerPort: 9898 name: http protocol: TCP command: - ./podinfo - --port=9898 - --level=info livenessProbe: exec: command: - podcli - check - http - localhost:9898/healthz initialDelaySeconds: 5 timeoutSeconds: 5 readinessProbe: exec: command: - podcli - check - http - localhost:9898/readyz initialDelaySeconds: 5 timeoutSeconds: 5 resources: limits: cpu: 2000m memory: 512Mi requests: cpu: 100m memory: 64Mi --- apiVersion: v1 kind: Service metadata: name: podinfo namespace: test labels: app: podinfo spec: type: ClusterIP ports: - name: http port: 9898 targetPort: 9898 protocol: TCP selector: app: podinfo
次のコマンドを実行して、podinfoアプリケーションをデプロイします。
kubectl apply -n test -f podinfo.yaml
自動スケーリングをトリガーするには、リクエストをトリガーするためにテスト名前空間にロードテストサービスをデプロイする必要があります。
loadtester.yamlという名前のファイルを作成し、次の内容をファイルにコピーします。
apiVersion: apps/v1 kind: Deployment metadata: name: loadtester namespace: test labels: app: loadtester spec: selector: matchLabels: app: loadtester template: metadata: labels: app: loadtester annotations: prometheus.io/scrape: "true" spec: containers: - name: loadtester image: weaveworks/flagger-loadtester:0.18.0 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 8080 command: - ./loadtester - -port=8080 - -log-level=info - -timeout=1h livenessProbe: exec: command: - wget - --quiet - --tries=1 - --timeout=4 - --spider - http://localhost:8080/healthz timeoutSeconds: 5 readinessProbe: exec: command: - wget - --quiet - --tries=1 - --timeout=4 - --spider - http://localhost:8080/healthz timeoutSeconds: 5 resources: limits: memory: "512Mi" cpu: "1000m" requests: memory: "32Mi" cpu: "10m" securityContext: readOnlyRootFilesystem: true runAsUser: 10001 --- apiVersion: v1 kind: Service metadata: name: loadtester namespace: test labels: app: loadtester spec: type: ClusterIP selector: app: loadtester ports: - name: http port: 80 protocol: TCP targetPort: http
次のコマンドを実行して、ロードテストサービスをデプロイします。
kubectl apply -n test -f loadtester.yaml
サンプルアプリケーションとロードテストサービスがデプロイされているかどうかを確認します。
次のコマンドを実行して、ポッドのステータスを確認します。
kubectl get pod -n test
期待される出力:
NAME READY STATUS RESTARTS AGE loadtester-64df4846b9-nxhvv 2/2 Running 0 2m8s podinfo-6d845cc8fc-26xbq 2/2 Running 0 11m
次のコマンドを実行してロードテストのためにコンテナにログインし、heyコマンドを実行してロードを生成します。
export loadtester=$(kubectl -n test get pod -l "app=loadtester" -o jsonpath='{.items[0].metadata.name}') kubectl -n test exec -it ${loadtester} -c loadtester -- hey -z 5s -c 10 -q 2 http://podinfo.test:9898
サンプルアプリケーションとロードテストサービスがデプロイされていることを示すロードが生成されます。
ステップ4: ASMメトリックを使用してHPAを設定する
podinfoアプリケーションが1秒間に受信するリクエストの数に基づいて、podinfoアプリケーションのワークロードをスケーリングするHPAを定義します。 平均して1秒あたり10を超えるリクエストが受信されると、HPAはレプリカの数を増やします。
hpa.yamlという名前のファイルを作成し、次のコードをファイルにコピーします。
apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: podinfo namespace: test annotations: metric-config.external.prometheus-query.prometheus/processed-requests-per-second: | sum( rate( istio_requests_total{ destination_workload="podinfo", destination_workload_namespace="test", reporter="destination" }[1m] ) ) spec: maxReplicas: 10 minReplicas: 1 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: podinfo metrics: - type: External external: metric: name: prometheus-query selector: matchLabels: query-name: processed-requests-per-second target: type: AverageValue averageValue: "10"
次のコマンドを実行してHPAをデプロイします。
kubectl apply -f hpa.yaml
次のコマンドを実行して、HPAがデプロイされているかどうかを確認します。
次のコマンドを実行して、kube-metrics-adapterによって提供されるカスタムメトリクスを照会します。
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1" | jq .
期待される出力:
{ "kind": "APIResourceList", "apiVersion": "v1", "groupVersion": "external.metrics.k8s.io/v1beta1", "resources": [ { "name": "prometheus-query", "singularName": "", "namespaced": true, "kind": "ExternalMetricValueList", "verbs": [ "get" ] } ] }
出力には、HPAがデプロイされていることを示すカスタムASMメトリックのリストが含まれています。
自動スケーリングの確認
次のコマンドを実行してロードテストのためにコンテナにログインし、heyコマンドを実行してロードを生成します。
kubectl -n test exec -it ${loadtester} -c loadtester -- sh ~ $ hey -z 5m -c 10 -q 5 http://podinfo.test:9898
次のコマンドを実行して、自動スケーリングの効果を確認します。
説明メトリックは、デフォルトで30秒ごとに同期されます。 コンテナは3〜5分ごとに1回のみスケーリングできます。 このように、HPAは、競合戦略が実行される前に自動スケーリングのための時間を予約することができる。
watch kubectl -n test get hpa/podinfo
期待される出力:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE podinfo Deployment/podinfo 8308m/10 (avg) 1 10 6 124m
HPAは、1秒あたりのリクエスト数が指定されたしきい値を下回るまで、1分でワークロードのスケールアップを開始します。 ロードテストが完了すると、1秒あたりのリクエスト数はゼロになります。 その後、HPAはポッドの数を減らし始める。 数分後、レプリカの数は前の出力の値から1に減少します。