ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

Argo Rollouts の Traffic Management

読んでいく。

argoproj.github.io

Quipper では日本サイドにおいて Progressive Delivery の方法として Deployment から Rollout への移行が進んでいる。

これにより Pod 単位での Traffic Splitting / Canary Releasing が可能になるが、Front Proxy 部分と連携することでより柔軟な Traffic Splitting ができる。(たぶん)

Overview

できること

  • Percentage-based は Traffic Splitting
  • Header-based routing
  • Traffic Mirroring

夢がひろがりんぐですね。

基本的に、Kubernetes Native の機能では上記のようなサポートは提供されないため、Service Mesh をサポートする以下の外部ツールを使う必要がある。

  • Istio
  • Nginx Ingress Controller
  • AWS ALB Ingress Controller
  • Service Mesh Interface(SMI)

Argo Rollout Controller はこれらの外部 Service に対して変更を行うことで Traffic Routing を行う。

1つずつみていく。

Istio

最終的に本格的に Controll Plane を入れる場合にIstio は強力な選択肢の1つであるが、まだベネフィットに対して運用負荷のほうが高そうなので、来年4月に再検討する、ぐらいの温度感である。

Argo Rollouts Controller は Istio の virtualService を指定する。

virtualService では route として destination を定義し、stable-svc と canary-svc を宛先として指定する。

Argo Rollouts Controller はこの Weight を Rollout の設定にしたがって変更することになる。

ところで Canary Service と Stable Service の2つを用意しないといけないと思うんだけど、これのセレクターはこの Rollout でいいんだろうか?このへんがよくわかってない。

それとも Service + Rollout で2セット用意するんだろうか?だとすると Kind Rollout の Resource も2種類必要になってきてよくわからなくなるから多分違う。

なお GitOps と連携する場合、Controller が Weight を変えてもすぐに戻ってしまうが、ArgoCD では Annotation をつけることで Argo Rollout Controller の変更のほうを優先するとのこと。便利。

Nginx

次のステップとして Nginx Ingress Controller を導入しようと考えている。現在 Application が Rollout に移行していることを考えると、この組み合わせでやることになると思っている。

ちょっと Nginx Ingress Controller 自体がどういう動きをするのかまだ理解できてないが、Nginx の Deployment に対応する Ingress Resource が存在して、それぞれが Annotation を持つ。Canary 用の Ingress の canary-weight field を Argo Rollouts Controller が変更する。

うーん、雰囲気はわかったけど雰囲気しかわからない。

Traffic が Front -> Nginx(Stable) -> Service -> Rollout だったとして、Nginx(Canary) があらたに存在するとして、何を持ってトラフィックを Canary 経由にするのだろうか?さらにその前段に Traffic Splitting をする Layer が必要な気がする。

AWS ALB

一度 ALB Ingress 導入したが、今は Multi Cluster を Canary Switching するために Ingress をはがしたのでもうこの選択肢は使わない。

Ingress で ALB の Weight Target Groups の機能を使い、行き先の Service を指定するようだ。とはいえ、結局宛先は Node Port が受けるような Target Groups になると思うんだが、何を持って後続で区別されるのかが謎。ALB 的には Kubernetes の Service って見えないと思うので、"ServiceName":"stable-service", が ALB 上でどんな設定になるのか気になる。

SMI

SMI も雰囲気でしか理解していない。Service Mesh のための CRD が標準的にあって、それを使おうぜって感じなのかなという雑な理解。

で、Argo Rollouts Controller は TrafficSplit CRD を操作して、Weight を変更する。

あーで、ようやくわかりやすい図が出てきた。

なるほど、Canary Service と Stable Service はそれぞれ App の Selector 以外に、Rollout の Replicaset の hash を持たせておいて、そっちに転送させるみたいなことができるのか。すごい。で、Rollouts Controller はそのそれぞれの Service がもってる hash を replicaset が変わるたびに指定すると。なるほどがってん。

おわりに

いずれの手法も、Front Proxy の層で Traffic Splitting する部分の Weight を Argo Rollout Controller が変更する。その部分の宛先はそれぞれ Canary と Stable のService を事前に作成しておき、それらの Service は Rollout 管理の Replicaset へ Routing することで、Rollout による2世代の Replicaset 管理に対して Canary Releasing を実現している。

次回は実際に使っていくであろう Nginx Ingress Controler 自体の理解を深めていく。