背景
こちらの記事は以下の記事の続きとなりますので、背景は以下の記事をご参照ください。
OpenShiftでProgressive Deliveryやってみた!(Argo Rollouts基礎編-CLI)
OpenShiftでProgressive Deliveryやってみた!(Argo Rollouts基本編-GUI)
OpenShiftでProgressive Deliveryやってみた!(Argo Rollouts応用編-Prometheusのメトリクスと連携)
シナリオ
今回の検証で実施するProgressive Deliveryのシナリオは以下のとおりです。
- Rolloutのコンテナ・イメージを新しいバージョンに更新
- 新しいバージョンはアクセスすると500 InternalServerErrorが発生する
- Argo Rolloutsによりトラフィックの50%がCanaryに割り当てた後一時停止
- アプリケーションの検証実施
- 50%の確率でCanaryに割り当てられるのでInternalServerErrorが応答される
- Argo Rolloutsで一時停止しているRolloutを再開(Promote)
- Argo Rolloutsの分析が実行される
- Canaryのサービスへのトラフィック上で過去5分の間の500 InternalServerErrorの回数をPrometheusから取得
- 5回以下の場合はRolloutが継続し完了する
- 5回より多く出力されている場合はRolloutがロールバックされる
- Canaryのサービスへのトラフィック上で過去5分の間の500 InternalServerErrorの回数をPrometheusから取得
構成手順
サンプルアプリケーションの拡張
OpenShift v4.6のマニュアル内でも使用されている以下のサンプルアプリケーションで500 InternalServerErrorが出力される新しいバージョンを作成します。
- 前述したリポジトリをFORKして以下の箇所を編集
- コンテキストルート(/)へのアクセスを200 正常応答から500 InternalServerErrorに変更
- コンテナ・イメージをビルドするためOpenShiftでアプリケーションを作成
PS D:\git> oc new-app --as-deployment-config --name prometheus-example-app golang~https://github.com/strada501/prometheus-example-app.git
--> Found image ca0cba7 (11 months old) in image stream "openshift/golang" under tag "1.13.4-ubi8" for "golang"
Go 1.13.4
---------
Go Toolset available as a container is a base platform for building and running various Go applications and frameworks. Go is an easy to learn, powerful, statically typed language in the C/C++ tradition with garbage collection, concurrent programming support, and memory safety features.
Tags: builder, golang, golang113, rh-golang113, go
* A source build using source code from https://github.com/strada501/prometheus-example-app.git will be created
* The resulting image will be pushed to image stream tag "prometheus-example-app:latest"
* Use 'oc start-build' to trigger a new build
* This image will be deployed in deployment config "prometheus-example-app"
* The image does not expose any ports - if you want to load balance or send traffic to this component
you will need to create a service with 'oc expose dc/prometheus-example-app --port=[port]' later
--> Creating resources ...
imagestream.image.openshift.io "prometheus-example-app" created
buildconfig.build.openshift.io "prometheus-example-app" created
deploymentconfig.apps.openshift.io "prometheus-example-app" created
--> Success
Build scheduled, use 'oc logs -f buildconfig/prometheus-example-app' to track its progress.
Run 'oc status' to view your app.
- ビルド・ログを確認し、
Push successful
を確認
PS D:\git> oc logs -f buildconfig/prometheus-example-app
Cloning "https://github.com/strada501/prometheus-example-app.git" ...
Commit: c65b7cdbd27e27ad4e3c22c1e94de67c83a8a4fa (Update main.go)
Author: Yasuyuki Kubota <strada@jp.ibm.com>
Date: Thu Jul 15 14:13:08 2021 +0900
Caching blobs under "/var/cache/blobs".
Getting image source signatures
Copying blob sha256:47db82df7f3f4393c1f19c362a2db2c47ca049b6fb20bef041dfc9bdb12a4504
Copying blob sha256:71391dc11a78542160544b68e45bc123ff55a2e84aeb6fa99b672d75765bc2f8
Copying blob sha256:6cc5487eb078291c64e0539c6d57546606b3936b71eabc7eec7960d069927ba4
Copying blob sha256:77c58f19bd6e67185938abb6bbb6ec229e07a5e607453904294d982de141d2f0
Copying blob sha256:0b1d2fb42752674d5c08548ef22a1c25885dd8588c0df75278a6a17fa1362e80
Warning: Pull failed, retrying in 5s ...
Getting image source signatures
Copying blob sha256:47db82df7f3f4393c1f19c362a2db2c47ca049b6fb20bef041dfc9bdb12a4504
Copying blob sha256:0b1d2fb42752674d5c08548ef22a1c25885dd8588c0df75278a6a17fa1362e80
Copying blob sha256:71391dc11a78542160544b68e45bc123ff55a2e84aeb6fa99b672d75765bc2f8
Copying blob sha256:77c58f19bd6e67185938abb6bbb6ec229e07a5e607453904294d982de141d2f0
Copying blob sha256:6cc5487eb078291c64e0539c6d57546606b3936b71eabc7eec7960d069927ba4
Copying config sha256:ca0cba75b144d9ec831c913b2146a6e9746c6cf43a4f6314047915f934c0b2f0
Writing manifest to image destination
Storing signatures
Generating dockerfile with builder image image-registry.openshift-image-registry.svc:5000/openshift/golang@sha256:ff3b2217e9a0bbb05536713606bdf49d0c9ef7754bd323482c41317a896c5bf2
STEP 1: FROM image-registry.openshift-image-registry.svc:5000/openshift/golang@sha256:ff3b2217e9a0bbb05536713606bdf49d0c9ef7754bd323482c41317a896c5bf2
STEP 2: LABEL "io.openshift.build.commit.id"="c65b7cdbd27e27ad4e3c22c1e94de67c83a8a4fa" "io.openshift.build.commit.ref"="master" "io.openshift.build.commit.message"="Update main.go" "io.openshift.build.source-location"="https://github.com/strada501/prometheus-example-app.git" "io.openshift.build.image"="image-registry.openshift-image-registry.svc:5000/openshift/golang@sha256:ff3b2217e9a0bbb05536713606bdf49d0c9ef7754bd323482c41317a896c5bf2" "io.openshift.build.commit.author"="Yasuyuki Kubota <strada@jp.ibm.com>" "io.openshift.build.commit.date"="Thu Jul 15 14:13:08 2021 +0900"
STEP 3: ENV OPENSHIFT_BUILD_NAME="prometheus-example-app-1" OPENSHIFT_BUILD_NAMESPACE="kubota-test" OPENSHIFT_BUILD_SOURCE="https://github.com/strada501/prometheus-example-app.git" OPENSHIFT_BUILD_COMMIT="c65b7cdbd27e27ad4e3c22c1e94de67c83a8a4fa"
STEP 4: USER root
STEP 5: COPY upload/src /tmp/src
STEP 6: RUN chown -R 1001:0 /tmp/src
STEP 7: USER 1001
STEP 8: RUN /usr/libexec/s2i/assemble
/tmp/src ~
go: downloading github.com/prometheus/client_golang v1.3.0
go: extracting github.com/prometheus/client_golang v1.3.0
go: downloading github.com/prometheus/common v0.7.0
go: downloading github.com/prometheus/client_model v0.1.0
go: downloading github.com/beorn7/perks v1.0.1
go: downloading github.com/cespare/xxhash/v2 v2.1.1
go: downloading github.com/golang/protobuf v1.3.2
go: downloading github.com/prometheus/procfs v0.0.8
go: extracting github.com/prometheus/client_model v0.1.0
go: extracting github.com/beorn7/perks v1.0.1
go: extracting github.com/cespare/xxhash/v2 v2.1.1
go: extracting github.com/prometheus/common v0.7.0
go: extracting github.com/prometheus/procfs v0.0.8
go: extracting github.com/golang/protobuf v1.3.2
go: downloading github.com/matttproud/golang_protobuf_extensions v1.0.1
go: extracting github.com/matttproud/golang_protobuf_extensions v1.0.1
go: finding github.com/prometheus/client_golang v1.3.0
go: finding github.com/prometheus/client_model v0.1.0
go: finding github.com/beorn7/perks v1.0.1
go: finding github.com/cespare/xxhash/v2 v2.1.1
go: finding github.com/prometheus/common v0.7.0
go: finding github.com/golang/protobuf v1.3.2
go: finding github.com/matttproud/golang_protobuf_extensions v1.0.1
go: finding github.com/prometheus/procfs v0.0.8
~
STEP 9: CMD /usr/libexec/s2i/run
STEP 10: COMMIT temp.builder.openshift.io/kubota-test/prometheus-example-app-1:1b4719fa
Getting image source signatures
Copying blob sha256:226bfaae015f1d5712cfced3b5b628206618eaacf72f4a44d0e4084071996319
Copying blob sha256:70056249a0e202adae10aa45fef56ac4cc6497619767753515022bc9c1278251
Copying blob sha256:0bfe5b62a1ad05827328d7629f8a9a7e16642fd14f40070a395fcd16917eb4f7
Copying blob sha256:7fbe9fcfa2da3fadd05c2e7caabc3da06c1a7fc36c14f5b6dddedc5ffb42be11
Copying blob sha256:1ee5a618948c954f5939610cdea18abc9b4ea49837b2284dfcc704c107e8fdd8
Copying blob sha256:a5e344f477e23a8dcafc25df603a178a9470835a1524867bfd1db3e3de38f41c
Copying config sha256:fda5edea5118eeb68890239e18a706f07cee81550e4029540c9cfaa8834a5ee5
Writing manifest to image destination
Storing signatures
--> fda5edea511
fda5edea5118eeb68890239e18a706f07cee81550e4029540c9cfaa8834a5ee5
Pushing image image-registry.openshift-image-registry.svc:5000/kubota-test/prometheus-example-app:latest ...
Getting image source signatures
Copying blob sha256:a5e344f477e23a8dcafc25df603a178a9470835a1524867bfd1db3e3de38f41c
Copying blob sha256:47db82df7f3f4393c1f19c362a2db2c47ca049b6fb20bef041dfc9bdb12a4504
Copying blob sha256:6cc5487eb078291c64e0539c6d57546606b3936b71eabc7eec7960d069927ba4
Copying blob sha256:71391dc11a78542160544b68e45bc123ff55a2e84aeb6fa99b672d75765bc2f8
Copying blob sha256:77c58f19bd6e67185938abb6bbb6ec229e07a5e607453904294d982de141d2f0
Copying blob sha256:0b1d2fb42752674d5c08548ef22a1c25885dd8588c0df75278a6a17fa1362e80
Copying config sha256:fda5edea5118eeb68890239e18a706f07cee81550e4029540c9cfaa8834a5ee5
Writing manifest to image destination
Storing signatures
Successfully pushed image-registry.openshift-image-registry.svc:5000/kubota-test/prometheus-example-app@sha256:5613eb8474ea6ab372ec6c1c98a9517be61cb39ccaf20214c348c4ab04c3b227
Push successful
PS D:\git>
-
Successfully pushed
以降のコンテナ・イメージのURIをメモしておく
image-registry.openshift-image-registry.svc:5000/kubota-test/prometheus-example-app@sha256:5613eb8474ea6ab372ec6c1c98a9517be61cb39ccaf20214c348c4ab04c3b227
- Podがデプロイされて
Running
となっていることを確認
PS D:\git> oc get po
NAME READY STATUS RESTARTS AGE
prometheus-example-app-1-56mtd 1/1 Running 0 18s
prometheus-example-app-1-build 0/1 Completed 0 94s
prometheus-example-app-1-deploy 0/1 Completed 0 23s
- Podに接続して稼働確認
PS D:\git> oc rsh prometheus-example-app-1-56mtd
sh-4.4$ curl -si http://localhost:8080/
HTTP/1.1 500 Internal Server Error
Date: Thu, 15 Jul 2021 05:16:11 GMT
Content-Length: 0
sh-4.4$ exit
exit
PS D:\git>
OpenShift Service Meshのインストール
OpenShift Service Meshのインストール手順については以下の記事を参照してください。
Argo Rolloutsのインストール
Argo Rolloutsのインストール手順については以下の記事を参照してください。
Prometheus Operatorのインストール
Prometheus Operatorのインストール手順については以下の記事を参照してください。
Argo RolloutsおよびOpenShift Service Mesh用のリソースを作成
以下のマニュアルを参考にArgo Rolloutsのリソースを作成します。
今回はHost-level Traffic Splittingの例を使用
Istioと連携する場合はstrategy->canaryの下に以下の設定を追加します
strategy:
canary:
canaryService: canary-svc # required
stableService: stable-svc # required
trafficRouting:
istio:
virtualService:
name: rollout-vsvc # required
routes:
- primary # optional if there is a single route in VirtualService, required otherwise
- istio-systemのistio-ingressgatewayのRouteを取得
PS D:\git> oc get route -n istio-system
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
grafana grafana-istio-system.dte-ocp46-8uvivd-915b3b336cabec458a7c7ec2aa7c625f-0000.us-east.containers.appdomain.cloud grafana <all> reencrypt/Redirect None
istio-ingressgateway istio-ingressgateway-istio-system.dte-ocp46-8uvivd-915b3b336cabec458a7c7ec2aa7c625f-0000.us-east.containers.appdomain.cloud istio-ingressgateway 8080 None
jaeger jaeger-istio-system.dte-ocp46-8uvivd-915b3b336cabec458a7c7ec2aa7c625f-0000.us-east.containers.appdomain.cloud jaeger-query <all> reencrypt None
kiali kiali-istio-system.dte-ocp46-8uvivd-915b3b336cabec458a7c7ec2aa7c625f-0000.us-east.containers.appdomain.cloud kiali <all> reencrypt/Redirect None
kubota-test-bookinfo-gateway-525eca1d5089dbdc kubota-test-bookinfo-gateway-525eca1d5089dbdc-istio-system.dte-ocp46-8uvivd-915b3b336cabec458a7c7ec2aa7c625f-0000.us-east.containers.appdomain.cloud istio-ingressgateway http2 None
kubota-test-rollouts-demo-gateway-525eca1d5089dbdc kubota-test-rollouts-demo-gateway-525eca1d5089dbdc-istio-system.dte-ocp46-8uvivd-915b3b336cabec458a7c7ec2aa7c625f-0000.us-east.containers.appdomain.cloud istio-ingressgateway http2 None
prometheus prometheus-istio-system.dte-ocp46-8uvivd-915b3b336cabec458a7c7ec2aa7c625f-0000.us-east.containers.appdomain.cloud prometheus <all> reencrypt/Redirect None
PS D:\git>
- Prometheusと連携するためのAnalysisTemplateのマニフェストファイルを作成
- Prometheusのアドレスにはistio-systemのistio-ingressgatewayのRouteのアドレスを設定
- Prometheusのクエリーにはcanaryで発生した直近5分の500 InternalServerErrorの回数を取得するクエリーを設定
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: failure-count
spec:
metrics:
- name: http_error_count
successCondition: result[0] <= 5
provider:
prometheus:
address: "http://istio-ingressgateway-istio-system.dte-ocp46-8uvivd-915b3b336cabec458a7c7ec2aa7c625f-0000.us-east.containers.appdomain.cloud"
query: |
delta(http_requests_total{code="500",namespace="kubota-test",service="rollouts-demo-canary"}[5m])
- Rolloutのマニフェストファイルを作成
- IstioのSidecarを注入するためAnnotationsに
sidecar.istio.io/inject: "true"
を追加 - ステップは以下の通り
- 50%をcanaryに割り当て一時停止
- 再開されたらfailure-countのAnalysisTemplateを実行
- IstioのSidecarを注入するためAnnotationsに
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: rollouts-demo
spec:
replicas: 1
strategy:
canary:
canaryService: rollouts-demo-canary
stableService: rollouts-demo-stable
trafficRouting:
istio:
virtualService:
name: rollouts-demo-vsvc
routes:
- primary # At least one route is required
steps:
- setWeight: 50
- pause: {}
- analysis:
templates:
- templateName: failure-count
revisionHistoryLimit: 2
selector:
matchLabels:
app: rollouts-demo
template:
metadata:
annotations:
sidecar.istio.io/inject: "true"
labels:
app: rollouts-demo
spec:
containers:
- name: rollouts-demo
image: quay.io/brancz/prometheus-example-app:v0.2.0
ports:
- name: http
containerPort: 8080
protocol: TCP
resources:
requests:
memory: 32Mi
cpu: 5m
- Serviceのマニフェストファイルを作成
- OpenShift Service Meshでのトラフィックコントロールに対応するためStableとCanaryの2つのサービスを定義
apiVersion: v1
kind: Service
metadata:
name: rollouts-demo-canary
labels:
app: rollouts-demo-canary
spec:
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: rollouts-demo
# This selector will be updated with the pod-template-hash of the canary ReplicaSet. e.g.:
# rollouts-pod-template-hash: 7bf84f9696
---
apiVersion: v1
kind: Service
metadata:
name: rollouts-demo-stable
labels:
app: rollouts-demo-stable
spec:
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: rollouts-demo
# This selector will be updated with the pod-template-hash of the stable ReplicaSet. e.g.:
# rollouts-pod-template-hash: 789746c88d
- ServiceMonitorのマニフェストファイルを作成
- 2つのサービスを定義するのでこちらも2つのMonitorを定義
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
labels:
team: frontend
k8s-app: rollouts-demo-canary
name: rollouts-demo-canary
spec:
endpoints:
- interval: 30s
port: http
scheme: http
selector:
matchLabels:
app: rollouts-demo-canary
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
labels:
team: frontend
k8s-app: rollouts-demo-stable
name: rollouts-demo-stable
spec:
endpoints:
- interval: 30s
port: http
scheme: http
selector:
matchLabels:
app: rollouts-demo-stable
- Gatewayのマニフェストファイルを作成
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: rollouts-demo-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
- VirtualServiceのマニフェストファイルを作成
- コンテキストルート(/)と/errへのアクセスが検証用アプリケーションに割り振られるように設定
- /apiへのアクセスがPrometheusに割り振られるように設定
- サービスメッシュに参加しているプロジェクトではサービスのFQDN(prometheus.kubota-test.svc.cluster.local:9090)ではアクセスできないためingressgateway経由でアクセスできるようする
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: rollouts-demo-vsvc
spec:
gateways:
- rollouts-demo-gateway
hosts:
- "*"
http:
- name: primary
match:
- uri:
exact: /
- uri:
exact: /err
route:
- destination:
host: rollouts-demo-stable
weight: 100
- destination:
host: rollouts-demo-canary
weight: 0
- name: prometheus
match:
- uri:
prefix: /api
route:
- destination:
host: prometheus
- マニフェストファイルを以下の順番で適用
- Gateway
- VirtualService
- AnalysisTemplate
- Rollout
- Service
- ServiceMonitor
PS D:\git> oc apply -f .\gateway.yaml
gateway.networking.istio.io/rollouts-demo-gateway created
PS D:\git> oc apply -f .\virtualservice.yaml
virtualservice.networking.istio.io/rollouts-demo-vsvc created
PS D:\git> oc apply -f .\prometheus-anlysis-template.yaml
analysistemplate.argoproj.io/failure-count created
PS D:\git> oc apply -f .\rollout.yaml
rollout.argoproj.io/rollouts-demo created
PS D:\git> oc apply -f .\services.yaml
service/rollouts-demo-canary created
service/rollouts-demo-stable created
PS D:\git> oc apply -f .\servicemonitors.yaml
servicemonitor.monitoring.coreos.com/rollouts-demo-canary created
servicemonitor.monitoring.coreos.com/rollouts-demo-stable created
PS D:\git>
- Argo RolloutsのDashboardを起動
起動方法は以下の記事を参照してください。
- コンテナ・イメージを500 InternalServerErrorが出力される新しいバージョンに変更
- なお、DashboardからだとOpenShiftの内部レジストリーを参照する形式のURIを正しく設定できないようなので以下のコマンドを実行して変更
PS D:\git> docker run --rm -v C:\Users\YASUYUKIKUBOTA\.kube\config:/.kube/config quay.io/argoproj/kubectl-argo-rollouts:master set image rollouts-demo rollouts-demo=image-registry.openshift-image-registry.svc:5000/kubota-test/prometheus-example-app@sha256:5613eb8474ea6ab372ec6c1c98a9517be61cb39ccaf20214c348c4ab04c3b227 --insecure-skip-tls-verify
rollout "rollouts-demo" image updated
PS D:\git>
PS D:\git> oc describe vs rollouts-demo-vsvc
Name: rollouts-demo-vsvc
Namespace: kubota-test
Labels: <none>
Annotations: <none>
API Version: networking.istio.io/v1beta1
Kind: VirtualService
Metadata:
Creation Timestamp: 2021-07-16T09:32:47Z
Generation: 8
Managed Fields:
API Version: networking.istio.io/v1alpha3
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.:
f:kubectl.kubernetes.io/last-applied-configuration:
f:spec:
.:
f:gateways:
f:hosts:
Manager: kubectl-client-side-apply
Operation: Update
Time: 2021-07-16T09:32:47Z
API Version: networking.istio.io/v1alpha3
Fields Type: FieldsV1
fieldsV1:
f:spec:
f:http:
Manager: rollouts-controller
Operation: Update
Time: 2021-07-16T10:32:56Z
Resource Version: 735642
Self Link: /apis/networking.istio.io/v1beta1/namespaces/kubota-test/virtualservices/rollouts-demo-vsvc
UID: ac110ed1-dc46-4797-946f-6dad62d067e0
Spec:
Gateways:
rollouts-demo-gateway
Hosts:
*
Http:
Match:
Uri:
Exact: /
Uri:
Exact: /err
Name: primary
Route:
Destination:
Host: rollouts-demo-stable
Weight: 50
Destination:
Host: rollouts-demo-canary
Weight: 50
Match:
Uri:
Prefix: /api
Name: prometheus
Route:
Destination:
Host: prometheus
Events: <none>
PS D:\git>
StableとCanaryの割合がどちらも50%になっていることがわかります。
-
ブラウザから以下のURLで検証用のアプリケーションに何度かアクセスし、500 InternalServerErrorを6回以上表示させる
-
Prometheus Serviceの9090ポートをlocalhostに転送し、以下のクエリーを実行する
delta(http_requests_total{code="500",namespace="kubota-test",service="rollouts-demo-canary"}[5m])
結果が5より大きくなることを確認します。
上記のようにEmpty query resultが表示される場合はAnalysisTemplateが失敗するので、何度か新バージョンを表示させてから再度クエリーを実行します。
Prometheusのクエリーの結果が5より大きいためRolloutは失敗します。
- 以下のコマンドでAnalysisRunの内容を確認
PS D:\git> oc get analysisrun -o yaml
apiVersion: v1
items:
- apiVersion: argoproj.io/v1alpha1
kind: AnalysisRun
metadata:
annotations:
rollout.argoproj.io/revision: "2"
creationTimestamp: "2021-07-16T10:15:58Z"
generation: 2
labels:
rollout-type: Step
rollouts-pod-template-hash: 59b469fdf7
step-index: "2"
--- 中略 ---
name: rollouts-demo-59b469fdf7-2-2
namespace: kubota-test
ownerReferences:
- apiVersion: argoproj.io/v1alpha1
blockOwnerDeletion: true
controller: true
kind: Rollout
name: rollouts-demo
uid: 5dc549be-f03e-4628-9e25-3182f7884180
resourceVersion: "729720"
selfLink: /apis/argoproj.io/v1alpha1/namespaces/kubota-test/analysisruns/rollouts-demo-59b469fdf7-2-2
uid: b7932425-5502-4345-a603-94b269b0d1f0
spec:
metrics:
- name: http_error_count
provider:
prometheus:
address: http://istio-ingressgateway-istio-system.dte-ocp46-8uvivd-915b3b336cabec458a7c7ec2aa7c625f-0000.us-east.containers.appdomain.cloud
query: |
delta(http_requests_total{code="500",namespace="kubota-test",service="rollouts-demo-canary"}[5m])
successCondition: result[0] <= 5
status:
message: metric "http_error_count" assessed Failed due to failed (1) > failureLimit (0)
metricResults:
- count: 1
failed: 1
measurements:
- finishedAt: "2021-07-16T10:15:58Z"
phase: Failed
startedAt: "2021-07-16T10:15:58Z"
value: '[16.311243770937153]'
name: http_error_count
phase: Failed
phase: Failed
startedAt: "2021-07-16T10:15:58Z"
kind: List
metadata:
resourceVersion: ""
selfLink: ""
PS D:\git>
クエリーの結果が'[16.311243770937153]'だったため失敗したことがわかります。
クエリーの結果が5以下であることを確認
以下のコマンドでVirtualServiceの設定を確認すると自動的にStableが100%に戻っていることがわかります。
PS D:\git> oc describe vs rollouts-demo-vsvc
Name: rollouts-demo-vsvc
Namespace: kubota-test
Labels: <none>
Annotations: <none>
API Version: networking.istio.io/v1beta1
Kind: VirtualService
Metadata:
Creation Timestamp: 2021-07-16T09:32:47Z
Generation: 7
Managed Fields:
API Version: networking.istio.io/v1alpha3
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.:
f:kubectl.kubernetes.io/last-applied-configuration:
f:spec:
.:
f:gateways:
f:hosts:
Manager: kubectl-client-side-apply
Operation: Update
Time: 2021-07-16T09:32:47Z
API Version: networking.istio.io/v1alpha3
Fields Type: FieldsV1
fieldsV1:
f:spec:
f:http:
Manager: rollouts-controller
Operation: Update
Time: 2021-07-16T10:24:58Z
Resource Version: 732846
Self Link: /apis/networking.istio.io/v1beta1/namespaces/kubota-test/virtualservices/rollouts-demo-vsvc
UID: ac110ed1-dc46-4797-946f-6dad62d067e0
Spec:
Gateways:
rollouts-demo-gateway
Hosts:
*
Http:
Match:
Uri:
Exact: /
Uri:
Exact: /err
Name: primary
Route:
Destination:
Host: rollouts-demo-stable
Weight: 100
Destination:
Host: rollouts-demo-canary
Weight: 0
Match:
Uri:
Prefix: /api
Name: prometheus
Route:
Destination:
Host: prometheus
Events: <none>
PS D:\git>
--- 省略 ---
spec:
metrics:
- name: http_error_count
provider:
prometheus:
address: http://istio-ingressgateway-istio-system.dte-ocp46-8uvivd-915b3b336cabec458a7c7ec2aa7c625f-0000.us-east.containers.appdomain.cloud
query: |
delta(http_requests_total{code="500",namespace="kubota-test",service="rollouts-demo-canary"}[5m])
successCondition: result[0] <= 5
status:
metricResults:
- count: 1
measurements:
- finishedAt: "2021-07-16T10:24:58Z"
phase: Successful
startedAt: "2021-07-16T10:24:58Z"
value: '[0]'
name: http_error_count
phase: Successful
successful: 1
phase: Successful
startedAt: "2021-07-16T10:24:58Z"
--- 省略 ---
クエリーの結果が'[0]'だったため成功になったことが分かる。
まとめ
今回の記事の検証でArgo RolloutsとOpenShift Service Meshを連携することでトラフィックコントロールをServiceMeshと連携して実施できることがわかりました。
ServiceMeshと連携することで、Canaryへのアクセスのみのメトリクスを取得することが可能となったのでより精度の高い情報を元に分析を行うことが出来ることがわかりました。
また、ServiceMeshを利用しない場合のトラフィックの割り当ては全体のPod数(5)に対して、20%ならPodを1つCanaryにする、という方式となるため、Replica数がRolloutのステップに依存してしまうためよろしくありません。
ServiceMeshを利用している場合はこのような無駄も排除できます。
今後の課題としては、PrometheusのクエリーがEmpty query resultとなった場合にAnalysisRunが失敗してしまうため、失敗しない方法はないのかを調査していきたいと思います。