この記事はニフクラ 等を提供している、富士通クラウドテクノロジーズ Advent Calendar 2022 の 8 日目の記事です。
前日は@yusayoshi さんの playwrightとGitlab CI/CDでE2Eテストを自動化してみた でした。
時間が掛かる作業であるテストを自動化して工数を削減しつつ、テストが失敗したときはログだけでなく動画付きで教えてくて、至れり尽くせりで素晴らしいと感じました。
本日はIstioのカスタムメトリクスの取得の仕方について説明したいと思います。
実は私は10月にHatobaチームに配属されたばかりで、k8sについて絶賛勉強中です。
その勉強した内容の一部を共有したいと思います。
k8s環境があれば、Istio初心者でも手を動かしながら試せる内容を心がけています。
Istioとは
概要
Istioとはマイクロサービスのサービスメッシュを構築・管理するためのOSSです。
最近のサービスはマイクロ化が進み、一つのサービスに対して複数のアプリケーションが複雑に連携して動作しています。
そのアプリケーション間の通信を管理し、またアップデートを行っていくことはとても労力のかかる行為となります。
その網目のように張り巡らされたアプリケーションの通信網(サービスメッシュ)の管理をIstioが行ってくれます。
Istioでできること
公式サイトによると次のような機能が紹介されています。
-
サービス間の通信の暗号化
-
ロードバランシング機能(HTTP, gRPC, WebSocket, TCP)
-
サービス間のトラフィック管理(ルーティング, リトライ, フェイルオーバー, フォールトインジェクション)
-
メトリクスやログ、トレースを用いたサービス内のトラフィックの自動監視
Istioを使う利点
Istioの大きな特徴の一つとしては既存のコードを変更しなくても導入することができるという点が挙げられます。
各アプリケーションのサイドカーとしてプロキシを注入し、アプリケーションの双方向の通信をproxy経由で行います。
アプリケーション側からはproxyを意識せずに通信を行うことができ、Istioは各proxyによって通信の制御や監視を実現します。
監視について
システムを運用、開発していく上で監視は重要です。
システムが正しく動いているかを確認する手段として必要なものです。
それ以上にシステムの状態を把握し、システムの正しい状態とは何か、必要なものは何かを知ることができます。
監視の要素としてログ、メトリクス、トレースの3つがあります。
- ログ
- 文字でシステムの状態や動作を記録する
- そのため、データ量は巨大で解析にも時間が掛かる
- メトリクス
- 数値でシステムの状態や動作を記録する
- 状態の時間変化を確認できる
- トレース
- アプリケーション間の通信とその経路を記録する
- アプリケーションの連携を確認できる
本記事はこの中のうち、メトリクスのみを対象としています。
カスタムメトリクスの取得
Istioのインストール
本記事では下記のような環境で検証を行っています。
version | |
---|---|
Kubernetes | v1.24.3 |
Istio | v1.15.2 |
Istio公式ドキュメントを参考にIstioの環境構築を行っていきます。
まず、Istioctlのインストールを行います。
$ curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.15.2 TARGET_ARCH=x86_64 sh -
$ cp -p istio-1.15.2/bin/istioctl /usr/local/bin
$ istioctl version
no running Istio pods in "istio-system"
1.15.2
次にプロファイルを利用してIstioのインストールを行います。
$ istioctl install --set profile=demo -y
✔ Istio core installed
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete Making this installation the default for injection and validation.
デプロイが成功しているかを確認します。
$ kubectl get all -n istio-system
NAME READY STATUS RESTARTS AGE
pod/istio-egressgateway-789bbc8b8b-zpr5s 1/1 Running 0 17m
pod/istio-ingressgateway-5474bb49b8-6q8nj 1/1 Running 0 2m8s
pod/istiod-6dcd646fc9-fs48q 1/1 Running 0 17m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/istio-egressgateway ClusterIP 10.99.96.227 <none> 80/TCP,443/TCP 17m
service/istio-ingressgateway LoadBalancer 10.107.127.207 111.64.92.157 15021:30817/TCP,80:32633/TCP,443:30004/TCP 17m
service/istiod ClusterIP 10.108.217.159 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 17m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/istio-egressgateway 1/1 1 1 17m
deployment.apps/istio-ingressgateway 1/1 1 1 17m
deployment.apps/istiod 1/1 1 1 17m
NAME DESIRED CURRENT READY AGE
replicaset.apps/istio-egressgateway-789bbc8b8b 1 1 1 17m
replicaset.apps/istio-ingressgateway-5474bb49b8 1 1 1 17m
replicaset.apps/istiod-6dcd646fc9 1 1 1 17m
サイドカーを自動的にデプロイするように設定します。
$ kubectl label namespace default istio-injection=enabled
namespace/default labeled
サンプルのサービスとしてhttpbinをデプロイします。
$ kubectl apply -f istio-1.15.2/samples/httpbin/httpbin.yaml
serviceaccount/httpbin created
service/httpbin created
deployment.apps/httpbin created
$ kubectl apply -f istio-1.15.2/samples/httpbin/httpbin-gateway.yaml
gateway.networking.istio.io/httpbin-gateway created
virtualservice.networking.istio.io/httpbin created
デプロイが成功しているか確認します
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/httpbin-847f64cc8d-ft5cj 2/2 Running 0 4s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/httpbin ClusterIP 10.105.123.149 <none> 8000/TCP 3m3s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 132m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/httpbin 1/1 1 1 3m3s
NAME DESIRED CURRENT READY AGE
replicaset.apps/httpbin-847f64cc8d 1 1 1 3m3s
curlコマンドでアクセスをしてみます。
IPアドレスとPortは環境によって異なるため、公式ドキュメントを参考に取得してください。
自分の環境の場合は次のようにして取得しています。
$ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
$ curl http://$INGRESS_HOST:$INGRESS_PORT/get
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "xxx.xxx.xxx.xxx",
"User-Agent": "curl/7.68.0",
"X-B3-Parentspanid": "fe58d5ff194cc300",
"X-B3-Sampled": "1",
"X-B3-Spanid": "85a24cab8430ae49",
"X-B3-Traceid": "afcfbec3b49a33e1fe58d5ff194cc300",
"X-Envoy-Attempt-Count": "1",
"X-Envoy-External-Address": "xxx.xxx.xxx.xxx",
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Has......."
},
"origin": "xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx",
"url": "http://xxx.xxx.xxx.xxx/get"
}
httpbinからの応答が返ってくれば成功です。
メトリクス取得
次にIstioでデフォルトで公開されているメトリクスを確認していきます。
今回はprometheusを用いてメトリクスを確認します。
prometheusは次のようにインストールすることができます。
$ kubectl apply -f istio-1.15.2/samples/addons/prometheus.yaml
erviceaccount/prometheus created
configmap/prometheus created
clusterrole.rbac.authorization.k8s.io/prometheus created
clusterrolebinding.rbac.authorization.k8s.io/prometheus created
service/prometheus created
deployment.apps/prometheus created
prometheusのダッシュボードを確認してみます。
$ kubectl -n istio-system port-forward service/prometheus 9090:9090
ブラウザでhttp://localhost:9090
にアクセスするとダッシュボードが確認できます。
expressionにistio_request_total
と入力し、Executeするとメトリクスが確認できます。
先ほどのcurlコマンドを繰り返し実行し、prometheusのグラフ表示をすると次のようにリクエスト数が増えていることが分かります。
istio_request_total
以外にも次のようなメトリクスがIstioではデフォルトで公開されます。
ラベル追加
では、本題のカスタムメトリクスに移っていきます。本記事ではメトリクスへのラベルの追加を行います。
以下の公式ドキュメントを参考にしました。
例えば、istio_request_totalメトリクスには、appラベルやresponse_codeラベルなどが既に存在しています。
Istioではこれらのラベル以外に追加可能な値が存在しています。
追加可能な変数の一覧は次のサイトに掲載されています。
この中の、destination.portとrequest.methodをラベルとして追加してみます。
IstioOperatorにラベルの設定を追加します。
次のようなmetrics.yaml
ファイルを作成します。
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
profile: demo
meshConfig:
defaultConfig:
extraStatTags:
- destination_port
- request_method
values:
telemetry:
v2:
prometheus:
configOverride:
inboundSidecar:
metrics:
- name: requests_total
dimensions:
destination_port: string(destination.port)
request_method: request.method
設定を適用します。
$ istioctl install -f metrics.yaml -y
次にhttpbinのpodのサイドカーにも設定を追加します。
httpbin.yaml
をコピーして設定を追加します。
$ cp istio-1.15.2/samples/httpbin/httpbin.yaml httpbin_metrics.yaml
httpbin_metrics.yaml
のannotationsにsidecar.istio.io/extraStatTags
の設定を追加します。
...省略...
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
annotations:
sidecar.istio.io/extraStatTags: destination_port, request_method
...省略...
設定変更を適用し、podを再起動します。
$ kubectl apply -f httpbin_metrics.yaml
$ kubectl delete pods --all
prometheusの起動コマンドを再度実行して確認すると、ラベルが追加されていることが分かります。
まとめ
今回はIstioのカスタムメトリクスの取得する方法を紹介させていただきました。
Istioを使えば簡単にメトリクスを取得することができるので、ぜび皆さんも試してみてください!
この記事は富士通クラウドテクノロジーズ Advent Calendar 2022 の 8 日目の記事でした。
明日は @nori3636 さんの「WSLでminikubeの環境構築をしてみる」です。
偶然ですが連続してk8sに関連した内容となりました。
自分はまだminikubeで色々試したことが無いため、どんなことをするのか楽しみです。
参考文献