LoginSignup
0
1

More than 1 year has passed since last update.

OpenShift Service Meshを使ったマイクロサービスのトラブルシューティング入門

Posted at

はじめに

OpenShiftでは、開発や運用を支援する様々なツールの導入・管理機能をOperatorとして提供しています。今回はこのOperatorとIstioのサンプルアプリであるBookinfoを使って、Service Mesh環境におけるObservabilityの確保とトラブルシューティングについてまとめていきます。

前提条件

今回利用する環境とバージョンは以下の通りです。各ツールのインストール方法は後述の手順内にて説明します。

  • OpenShift Container Platform : 4.10.24
  • Red Hat OpenShift Service Mesh Operator : 2.2.1-0
  • OpenShift Elasticsearch Operator : 5.4.4
  • Red Hat OpenShift distributed tracing platform Operator : 1.34.1-5
  • Kiali Operator : 1.48.2
  • Prometheus Operator : 0.56.3
  • Red Hat OpenShift Logging Operator : 5.4.4

その他の前提条件は以下の通りです。

  • AWS環境
    • AdministratorAccessロールを持つIAMユーザー
  • 踏み台兼Dokcerビルド用EC2インスタンス(以下、bastion)
    • AMI: Amazon Linux 2
    • Type: m6i.xlarge

手順

OpenShiftインストール

bastionで以下の手順を実施します。

aws configure
 → AdministratorAccessのIAMユーザーのCredentialsを入力
curl -O https://mirror.openshift.com/pub/openshift-v4/clients/ocp/4.10.24/openshift-install-linux-4.10.24.tar.gz
curl -O https://mirror.openshift.com/pub/openshift-v4/clients/ocp/4.10.24/openshift-client-linux-4.10.24.tar.gz
tar xvzf openshift-install-linux-4.10.24.tar.gz
tar xvzf openshift-client-linux-4.10.24.tar.gz
sudo mv oc kubectl /usr/local/bin

次にmasterノードにSSHする際に使うキーを生成します。ここではパスワードなしで作成しています。

ssh-keygen -t ed25519 -f ~/.ssh/openshift-master -N "" <<<y

OpenShiftのインストール時に使うpull-secretを取得します。後ほどコマンド実行時に中身をペーストするので、ここではCopy pull secretを選択しましょう。

Red Hat OpenShift Cluster Management
https://console.redhat.com/openshift/install/gcp/installer-provisioned

install-config.yamlを作成します。

./openshift-install create install-config

デフォルトで作成されるinstall-configではWorkerノードのタイプがm6i.largeになります。これでは少しスペックが足りないので、以下のように追記してWorkerノードのタイプをm6i.xlargerにします。

install-config.yaml
apiVersion: v1
baseDomain: xxx.com
compute:
- architecture: amd64
  hyperthreading: Enabled
  name: worker
  platform:
    aws:                   #追記
      type: m6i.xlarge     #追記
  replicas: 3
...省略...

クラスターを作成します。

./openshift-install create cluster

しばらくして作成が完了すると、コンソールログにapiのURLとkubeadminのパスワードが表示されるので、それを使ってCLIでログインしておきます。

oc login -u kubeadmin -p <パスワード> https://api.aws-cluster.xxx.com:6443

最後にデフォルトのRouteに対して証明書を設定します。後ほどローカルでビルドしたイメージをOpenShiftの内部レジストリにPushするにあたり必要になります。
今回はacme.shを使って無償のSSL証明書を発行し、OpenShiftのdefault-routerにセットします。

まずacme.shをインストールします。アドレスは任意の値を設定ください。

curl https://get.acme.sh | sh -s email=sample@example.com

次に以下のシェルスクリプトを作成して実行します。

openshift-router-cert.sh
#!/bin/bash

export CERTDIR=$HOME/certificates
export AWS_ACCESS_KEY_ID=$(aws configure get aws_access_key_id)
export AWS_SECRET_ACCESS_KEY=$(aws configure get aws_secret_access_key)
export LE_API=$(oc whoami --show-server | cut -f 2 -d ':' | cut -f 3 -d '/' | sed 's/-api././')
export LE_WILDCARD=$(oc get ingresscontroller default -n openshift-ingress-operator -o jsonpath='{.status.domain}')

.acme.sh/acme.sh --issue --dns dns_aws -d ${LE_API} -d *.${LE_WILDCARD}
mkdir -p ${CERTDIR}
.acme.sh/acme.sh --install-cert -d ${LE_API} -d *.${LE_WILDCARD} --cert-file ${CERTDIR}/cert.pem --key-file ${CERTDIR}/key.pem --fullchain-file ${CERTDIR}/fullchain.pem --ca-file ${CERTDIR}/ca.cer

oc delete secret router-certs -n openshift-ingress
oc create secret tls router-certs --cert=${CERTDIR}/fullchain.pem --key=${CERTDIR}/key.pem -n openshift-ingress

oc patch ingresscontroller default -n openshift-ingress-operator --type=merge --patch='{"spec": {"defaultCertificate": { "name": "router-certs" }}}'
chmod +x openshift-router-cert.sh
./openshift-router-cert.sh

しばらくしてrouterが再起動し、Webコンソールアクセスして適切に証明書が適用されているか確認します。

サービスメッシュ環境の構築

次にサービスメッシュを構成する各種Operatorをインストールしていきます。

  • OpenShift Elasticsearch Operator
  • Kiali Operator
  • Red Hat OpenShift distributed tracing platform
  • Red Hat OpenShift Service Mesh

以下のファイルを作成してapplyします。
事前にElasticsearch Operatorをデプロイするためのopenshift-operators-redhatプロジェクトも作成しておきます。

servicemesh-operators.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: openshift-operators-redhat
  annotations:
    openshift.io/node-selector: ""
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  labels:
  name: elasticsearch-operator
  namespace: openshift-operators-redhat
spec:
  channel: stable
  installPlanApproval: Automatic
  name: elasticsearch-operator
  source: redhat-operators
  sourceNamespace: openshift-marketplace
  startingCSV: elasticsearch-operator.5.4.4
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: jaeger-product
  namespace: openshift-operators
spec:
  channel: stable
  installPlanApproval: Automatic
  name: jaeger-product
  source: redhat-operators
  sourceNamespace: openshift-marketplace
  startingCSV: jaeger-operator.v1.34.1-5
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: kiali-ossm
  namespace: openshift-operators
spec:
  channel: stable
  installPlanApproval: Automatic
  name: kiali-ossm
  source: redhat-operators
  sourceNamespace: openshift-marketplace
  startingCSV: kiali-operator.v1.48.2
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: servicemeshoperator
  namespace: openshift-operators
spec:
  channel: stable
  installPlanApproval: Automatic
  name: servicemeshoperator
  source: redhat-operators
  sourceNamespace: openshift-marketplace
  startingCSV: servicemeshoperator.v2.2.1
oc apply -f servicemesh-operators.yaml

Operatorがデプロイされました。

oc get operator --all-namespaces

NAME                                                AGE
elasticsearch-operator.openshift-operators-redhat   8m34s
jaeger-product.openshift-operators                  8m7s
kiali-ossm.openshift-operators                      7m58s
servicemeshoperator.openshift-operators             7m47s

ではサービスメッシュを構成するコンポーネントをデプロイしていきます。
まずはNamespaceの作成です。今回はIstioのコントロールプレーンを配置するIstio-systemとBookinfoアプリをデプロイするbookinfoを準備します。

oc new-project istio-system
oc new-project bookinfo

次にIstioのコントロールプレーンを作成します。OpenShiftのService Mesh OperatorはOSSのIstioとは異なり、同じクラスターで複数のコントロールプレーンが持てたり、Observabilityに必要なコンポーネントをプリセットでデプロイしてくれます。詳細はOpenShiftの公式ドキュメントを参照ください。
ではCRDのyamlファイルを作成してapplyします。

servicemeshcontrolplane.yaml
kind: ServiceMeshControlPlane
apiVersion: maistra.io/v2
metadata:
  name: basic
  namespace: istio-system
spec:
  version: v2.1
  tracing:
    type: Jaeger
    sampling: 10000
  policy:
    type: Istiod
  telemetry:
    type: Istiod
  addons:
    jaeger:
      install:
        storage:
          type: Memory
    prometheus:
      enabled: true
    kiali:
      enabled: true
    grafana:
      enabled: true
oc apply -f servicemeshcontrolplane.yaml

Jaegerのストレージには商用の永続ストレージとしてElasticsearchが選択可能ですが、今回はデモのため一時的なストレージで対応しています。Elasticsearchを使う場合はこちらのページを参照ください。

しばらく待つと、istio-systemプロジェクトにIstioをはじめ、Prometheus、Jaeger、Elasticsearch、GrafanaのPodが生成されます。

oc get pods -n istio-system

NAME                                    READY   STATUS    RESTARTS   AGE
grafana-869946b4fc-6sm9r                2/2     Running   0          109s
istio-egressgateway-684b45584f-zk5mh    1/1     Running   0          109s
istio-ingressgateway-5964cc866b-6ng74   1/1     Running   0          109s
istiod-basic-7cff65cb5b-wfbtm           1/1     Running   0          119s
jaeger-d67c849c8-9hh9x                  2/2     Running   0          106s
kiali-67bdff5b46-kwz8b                  1/1     Running   0          80s
prometheus-668d558d98-mlnb7      	2/2     Running   0          114s
wasm-cacher-basic-d9dbcc97b-6zmz8	1/1     Running   0          101s

次にCRDのServicemeshMemberRollを作成します。こちらはspec.membersにNamespace名を入力することでそのNamespaceをサービスメッシュに参加させることができます。

servicemeshmemberroll.yaml
kind: ServiceMeshMemberRoll
apiVersion: maistra.io/v1
metadata:
  name: default
  namespace: istio-system
spec:
  members:
    - bookinfo
oc apply -f servicemeshmemberroll.yaml

これでアプリケーションをデプロイするための下準備が完了しました。

Bookinfoアプリケーションのビルド・デプロイ

Bookinfoのデプロイにあたり、デフォルトのソースコードに対して少しだけ修正を加えます。コンテナが出力するログにリクエストIDを表示させます。

git clone https://github.com/istio/istio.git && cd istio/samples/bookinfo
vi src/reviews/reviews-application/src/main/java/application/rest/LibertyRestEndpoint.java
LibertyRestEndpoint.java
()...
167         } else {
168           System.out.println("[" + requestHeaders.getHeaderString("x-request-id") + "] Error    : unable to contact " + ratings_service + " got status of " + statusCode);   //エラーログの先頭に”x-request-id”ヘッダーを追記
169           return null;
170         }
()...
vi src/ratings/ratings.js
ratings.js
()...
199           if (unavailable) {
200               getLocalReviewsServiceUnavailable(res)
201               console.log("error: 'Service unavailable'" + ' ' + JSON.stringify(req.headers))  //行追記
202           } else {

()...

コード修正が完了したらイメージのビルド&プッシュを行います。
今回はbastionでイメージをビルドしOpenshiftの内部レジストリにプッシュします。しかしOpenShiftの内部レジストリはデフォルトでは外部からのアクセスができないため、先にレジストリへのアクセスパスを作成します。

oc patch configs.imageregistry.operator.openshift.io/cluster --patch '{"spec":{"defaultRoute":true}}' --type=merge

しばらくするとdefault-routerが作成されます。

oc get route -n openshift-image-registry

NAME            HOST/PORT                                                                           PATH   SERVICES         PORT    TERMINATION   WILDCARD
default-route   default-route-openshift-image-registry.apps.aws-cluster.xxx.com          image-registry   <all>   reencrypt     None

dockerをインストールして内部レジストリにログインします。

sudo yum install -y docker 
sudo gpasswd -a $USER docker
sudo systemctl restart docker
HOST=$(oc get route default-route -n openshift-image-registry --template='{{ .spec.host }}')
docker login -u kubeadmin -p $(oc whoami -t) $HOST

ログインできたらイメージをプッシュします。

./build_push_update_images.sh v0.1 --prefix=${HOST}/bookinfo

しばらくして、イメージがプッシュされていることを確認します。

oc get is -n bookinfo

NAME                                       IMAGE REPOSITORY                                                                                                                      TAGS          UPDATED
examples-bookinfo-details-v1               default-route-openshift-image-registry.apps.aws-cluster.xxx.com/bookinfo/examples-bookinfo-details-v1               latest,v0.1   3 minutes ago
examples-bookinfo-details-v2               default-route-openshift-image-registry.apps.aws-cluster.xxx.com/bookinfo/examples-bookinfo-details-v2               latest,v0.1   3 minutes ago
...(略)...

デプロイの前に、Bookinfoは特定のユーザーIDで動作しますが、OpenShiftではそのIDが許可されていないため、事前に許可設定を入れておきます。

oc project bookinfo
oc adm policy add-scc-to-user anyuid -z bookinfo-details
oc adm policy add-scc-to-user anyuid -z bookinfo-productpage
oc adm policy add-scc-to-user anyuid -z bookinfo-ratings
oc adm policy add-scc-to-user anyuid -z bookinfo-reviews

ではデプロイしていきます。

oc apply -f platform/kube/bookinfo.yaml -n bookinfo -f networking/bookinfo-gateway.yaml

実はこのままデプロイしただけではサイドカーコンテナが起動しません。OSSのIstioとは違い、OpenShiftのIstioではdeploymentに明示的にannotationsを付与しないとサイドカーコンテナが立ち上がらない仕様になっています。
そのため、annotationsを付与してPodを再起動します。

oc patch deploy details-v1 productpage-v1 ratings-v1 reviews-v1 reviews-v2 reviews-v3 -n bookinfo --type=merge --patch='{"spec": {"template": { "metadata": { "annotations": { "sidecar.istio.io/inject": "true" }}}}}'
oc rollout restart -n bookinfo deploy details-v1 productpage-v1 ratings-v1 reviews-v1 reviews-v2 reviews-v3

Podを確認すると、全てのPodでサイドカーコンテナが立ち上がっていることを確認できます。

oc get pods -n bookinfo

NAME                              READY   STATUS        RESTARTS   AGE
details-v1-76b9bff7cd-5b6x2	  2/2     Running	0          40s
productpage-v1-79cd499988-frj9m   2/2     Running	0          40s
ratings-v1-5dcfcc5b6-tp28z        2/2     Running	0          39s
reviews-v1-5d9b67ddcd-5d8vp	  2/2     Running	0          39s
reviews-v2-6888fb4c96-kfw7t	  2/2     Running	0          39s
reviews-v3-7447bbd598-j25wd	  2/2     Running	0          39s

reviewsにおいてはv1,v2,v3の3つがデプロイされますが、デフォルトだとランダムに振り分けられます。ここではratingsにアクセスする必要があるため、全てのリクエストをreviews-v2に向けるようにVirtualServiceをデプロイします。

cat networking/virtual-service-reviews-test-v2.yaml | sed -e s/"subset: v1"/"subset: v2"/g | oc apply -f - -n bookinfo

最後にDestinationRuleをデプロイします。

oc apply -f networking/destination-rule-all.yaml

では以下のコマンドでURLを取得してブラウザでアクセスしてみましょう。

export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath='{.spec.host}')
echo "http://$GATEWAY_URL/productpage"

スクリーンショット 2022-08-12 3.18.09.png

アラートの設定

サービスメッシュ環境とサンプルアプリがデプロイできたので、これからトラブルシューティングに向けた設定を行います。
まずはアラートの設定です。OpenShift Service MeshではプリセットでPrometheusやGrafanaがデプロイされますが、アラート設定用のコンポーネントは提供されておりません。そのため、自分で設定変更を行い環境準備が必要です。

今回はプリセットのPrometheusでアラートルールを設定し、別途デプロイするAlertmanagerでSlackに通知を飛ばします。

まず以下のyamlファイルを作成します。ファイル名はこのまま設定してください。istio全体のリクエストの内、500番台以外のステータスコードの割合が95%を下回るとアラートを発出するルールです。

alerting_rules.yml
groups:
- name: alert sample
  rules:
  - alert: IstioHigh5xxErrorRate
    expr: sum(rate(istio_requests_total{reporter="source", response_code!~"5.*"}[5m])) / sum(rate(istio_requests_total{reporter="source"}[5m])) * 100 < 95
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: Istio high 5xx error rate
      description: "Global Success Rate (non-5xx responses) < 95% .\n  VALUE = {{ $value }} %"

このファイルを使ってConfigMapを作成します。

oc create configmap alert-rule --from-file=./alerting_rules.yml -n istio-system

次にPrometheusにこのアラートルールを設定するよう、PrometheusのDeploymentを編集します。
先ほどのConfigMapの設定ファイルを/etc/config配下にマウントします。

oc edit deploy/prometheus -n istio-system
...(略)...
180         volumeMounts:
181         - mountPath: /etc/prometheus
182           name: config-volume
183         - mountPath: /etc/config    #追記
184           name: alert-volume        #追記
...(略)...
218       - configMap:
219           defaultMode: 420
220           name: prometheus
221         name: config-volume
222       - configMap:                  #追記
223           defaultMode: 420          #追記
224           name: alert-rule          #追記
225         name: alert-volume          #追記
...(略)...

Podが再起動したら、以下のコマンドでPrometheusのURLを取得してブラウザでアクセスします。

oc get route prometheus -n istio-system --template='{{ .spec.host }}'

Alertタブを選択すると、alerting_rules.ymlの設定内容が反映されていることを確認できます。
スクリーンショット 2022-08-12 3.40.34.png

次にAlertmanagerをデプロイしてSlackへの通知設定を行います。
まずPrometheus Operatorをインストールします。
以下のファイルを作成して、applyします。

prometheus-operator.yaml
---
apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
  name: istio-system-operatorgroup
  namespace: istio-system
spec:
  targetNamespaces:
  - istio-system
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: prometheus
  namespace: istio-system
spec:
  channel: beta
  installPlanApproval: Automatic
  name: prometheus
  source: community-operators
  sourceNamespace: openshift-marketplace
  startingCSV: prometheusoperator.0.56.3
oc apply -f prometheus-operator.yaml -n istio-system

次にAlertmanagerの通知先の設定ファイルを作成します。
slackの通知先情報(URLやチャンネル名)を記載します。

alertmanager.yaml
global:
  resolve_timeout: 1m
  slack_api_url: >-
    https://hooks.slack.com/services/XXXXX/XXXXX/XXXXX
receivers:
  - name: test-slack
    slack_configs:
      - channel: istio-alert
        title: "{{ range .Alerts }}{{ .Annotations.summary }}\n{{ end }}"
        text: "{{ range .Alerts }}{{ .Annotations.description }}\n{{ end }}"
route:
  receiver: test-slack

設定ファイルをSecretとしてデプロイします。

oc create secret generic alertmanager --from-file=./alertmanager.yaml -n istio-system

次にAlertmanagerをデプロイするためにAlertmanagerCRDをデプロイします。

alertmanager.yaml
apiVersion: monitoring.coreos.com/v1
kind: Alertmanager
metadata:
  name: alertmanager-main
  namespace: istio-system
spec:
  alertmanagerConfigSelector: {}
  replicas: 1
  configSecret: alertmanager
oc apply -f alertmanager.yaml

しばらくするとAlertmanagerのStatefulSetsが立ち上がります。
このコンテナに対して、Prometheusからアラートを飛ばします。
Prometheusの設定ファイル(ConfigMap)を編集して、Alertmanager向けにアラート情報を連携するように設定します。

oc edit cm prometheus -n istio-system
...(略)...
  7   prometheus.yml: |-
  8     global:
  9       evaluation_interval: 1m
 10       scrape_interval: 15s
 11       scrape_timeout: 10s
 12     alerting:                                                            # 追記 
 13       alertmanagers:                                                     # 追記
 14       - static_configs:                                                  # 追記
 15         - targets:                                                       # 追記
 16           - alertmanager-operated.istio-system.svc.cluster.local:9093    # 追記
 17     rule_files:
 18     - /etc/config/recording_rules.yml
 19     - /etc/config/alerting_rules.yml
 20     - /etc/config/rules
 21     - /etc/config/alerts
...(略)...

変更内容を反映させます。

oc rollout restart deploy/prometheus -n istio-system

これでサービスの通信の不具合が発生した際、アラートがSlackに飛ぶよう設定できました。

OpenShift Loggingのインストール

最後に、コンテナのログを収集する環境を導入します。
まずopenshift-loggingプロジェクトを作成します。

oc new-project openshift-logging

次に以下のyamlファイルでOpenshift Logging Operatorをインストールします。

logging-operator.yaml
---
apiVersion: v1
kind: Namespace
metadata:
  name: openshift-logging
  annotations:
    openshift.io/node-selector: ""
---
apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
  name: openshift-logging
  namespace: openshift-logging
spec:
  targetNamespaces:
  - openshift-logging
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: cluster-logging
  namespace: openshift-logging
spec:
  channel: stable
  installPlanApproval: Automatic
  name: cluster-logging
  source: redhat-operators
  sourceNamespace: openshift-marketplace
  startingCSV: cluster-logging.5.4.4
oc apply -f logging-operator.yaml

次にClusterLoggingCRDでロギングスタックをデプロイします。

cluster-logging.yaml
kind: ClusterLogging
apiVersion: logging.openshift.io/v1
metadata:
  name: instance
  namespace: openshift-logging
spec:
  managementState: Managed
  logStore:
    type: elasticsearch
    elasticsearch:
      nodeCount: 3
      redundancyPolicy: SingleRedundancy
      storage:
        storageClassName: gp2
        size: 200G
      resources:
        requests:
          memory: "8Gi"
    retentionPolicy:
      application:
        maxAge: 7d
  visualization:
    type: kibana
    kibana:
      replicas: 1
  collection:
    logs:
      type: fluentd
      fluentd: {}
oc apply -f cluster-logging.yaml

これでロギング環境が作成できました。

トラブルシューティング

ようやく環境の準備ができたので、この状態でratingsを別のイメージに切り替えてみます。

oc project bookinfo
oc set image deployment/ratings-v1 ratings=image-registry.openshift-image-registry.svc:5000/bookinfo/examples-bookinfo-ratings-v-unavailable:v0.1

新しいPodがデプロイできたら、watchコマンドでBookinfoにアクセスします。

watch -n 1 http://$GATEWAY_URL/productpage

しばらくすると、Slackにアラートが通知されます。
スクリーンショット 2022-08-12 8.52.23.png

状況を把握するために、Grafanaダッシュボードで異常な値が出ていないか確認します。以下のコマンドでGrafanaのURLを取得してブラウザでアクセスします。

oc get route grafana -n istio-system --template='{{ .spec.host }}'

アクセス後、Iatio Service Dashboardでratingsのサービスを確認するとClient Success Rateが著しく下がっていることが分かります。
grafana.png

次にKialiを使って、このratingsが使われているサービスがどのような構成になっているのかを確認します。
以下のコマンドでKialiのURLを取得しブラウザでアクセスします。

oc get route kiali -n istio-system --template='{{ .spec.host }}'

KialiのGraph.png

Kialiを見るとたしかにreviewsとratings間の通信でエラーが発生していることが分かります。
では次はトラフィックフローをリクエスト単位の視点で確認していきます。以下のコマンドでJaegerのURLを取得してブラウザでアクセスします。

oc get route jaeger -n istio-system --template='{{ .spec.host }}'

エラーリクエストのトレース情報(Jaeger).png

ここまで問題箇所が特定できれば、あとは実際にコンテナのログを確認しにいきます。Jaegerの画面でエラーとなったリクエストのID(x-request-id)が確認できましたので、Kibanaでコンテナのログを検索しエラーの詳細を解析します。
以下のコマンドでKibanaのURLを取得してブラウザでアクセスします。

oc get route kibana -n openshift-logging --template='{{ .spec.host }}'

アクセス後、インデックスを作成します。パターンにapp-*と入力して、Next Stepを選択します。
スクリーンショット 2022-08-12 9.13.03.png
Time Filter field nameで@timestampを選択して、インデックスを作成します。
スクリーンショット 2022-08-12 9.13.10.png

この状態でDiscover画面でmessage: “*<リクエストID>*”を検索すると、エラーとなったリクエスト関連のコンテナログを取得できます。検索したログを見ると、reviewsでratingsに対するアクセスが503エラーとなっていることや、ratingsでerror: ‘Service unavailable’というログが出力されていることが分かります。このように、ログの出力にリクエストIDを含めることで、ひとつのリクエストに起因したログの検索が可能になります。
図X リクエストIDに紐づくエラーログの表示(Kibana).png

このログをもとにratingsのソースコードを確認すると、先ほど挿入したエラーログが出力されていることが分かります。

view istio/samples/bookinfo/src/ratings/ratings.js

...(略)...
198       else if (process.env.SERVICE_VERSION === 'v-unavailable' || process.env.SERVICE_VERSION === 'v-unhealthy') {
199           if (unavailable) {
200               getLocalReviewsServiceUnavailable(res)
201               console.log("error: 'Service unavailable'" + ' ' + JSON.stringify(req.headers))
202           } else {
203               getLocalReviewsSuccessful(res, productId)
204           }
...(略)...

この部分は環境変数SERVICE_VERSIONが”v-unavailable”か”v-unhealthy”の場合に呼ばれるため、このコンテナにこれらの環境変数が含まれていることを確認してみます。

oc exec -it ratings-v1-76c754d45c-rz2rr -c ratings -- env | grep SERVICE_VERSION

SERVICE_VERSION=v-unavailable

たしかにコンテナに環境変数が設定されていました。今回のエラーは、この環境変数によって1分ごとに503エラーを返すプログラムが動作しているために発生しました。

ratings.js
()... 
25 if (process.env.SERVICE_VERSION === 'v-unavailable') {
 26     // make the service unavailable once in 60 seconds
 27     setInterval(function () {
 28         unavailable = !unavailable
 29     }, 60000);
 30 }
()...

おわりに

簡単ですが、OpenShiftのインストールからサービスメッシュ環境を構築し、サンプルアプリでのトラブルシューティングの内容をまとめてみました。今回の設定はデモ用途のため本番では適さない設定もありましたが、サービスメッシュ環境において各監視ツールを使い、どんなプロセスで解析するかのイメージはつけられるかと思います。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1