概要
istio/envoyを使ってB/Gデプロイとかカナリアリリースとかを試してみた際のメモです。
Istio/Envoyとは
ざっくりいうとクラウドネイティブなWebサービスのために設計されたロードバランサーのツール群。サービスメッシュの通信なんかを(多分)楽にしてくれるツールです。分散システムを構築・運用する際に直面する課題を解決してくレたりもします。
IstioがコントロールプレーンならEnvoyはデータプレーンに相当する。
Istioを利用すればこんな感じのプロキシーをサイドカーとして手間なく組み込むことができます。
Istioのインストール
最新版を以下の手順で入れます。特に困ることはなかったですが情報が古い記事が多く今は使えない手順が多かったので公式をみておくのが一番良さげです。
サンプルアプリを作成する
B/Gやるにしろカナリアをやるにしろアプリケーションの変更が分かりやすい仕組みが必要なので以下のimageを使用してサンプルDeploymenとServiceを生成します。
--- apiVersion: apps/v1 kind: Deployment metadata: name: httpbin-deployment-v1 labels: app: httpbin version: v1 spec: replicas: 1 selector: matchLabels: app: httpbin version: v1 template: metadata: labels: app: httpbin version: v1 spec: containers: - name: httpbin image: kennethreitz/httpbin:latest imagePullPolicy: IfNotPresent ports: - containerPort: 80 readinessProbe: httpGet: path: /status/200 port: 80 initialDelaySeconds: 10 periodSeconds: 5 livenessProbe: httpGet: path: /status/200 port: 80 initialDelaySeconds: 15 periodSeconds: 5 --- apiVersion: apps/v1 kind: Deployment metadata: name: httpbin-deployment-v2 labels: app: httpbin version: v2 spec: replicas: 1 selector: matchLabels: app: httpbin version: v2 template: metadata: labels: app: httpbin version: v2 spec: containers: - name: httpbin image: kennethreitz/httpbin:latest imagePullPolicy: IfNotPresent ports: - containerPort: 80 readinessProbe: httpGet: path: /status/200 port: 80 initialDelaySeconds: 10 periodSeconds: 5 livenessProbe: httpGet: path: /status/200 port: 80 initialDelaySeconds: 15 periodSeconds: 5 --- apiVersion: v1 kind: Service metadata: name: httpbin-service spec: selector: app: httpbin ports: - name: http protocol: TCP port: 80 targetPort: 80
動作確認としてClusterIPに対してcurlを実行して問題ないことを確認します。この時点ではサイドカーはデプロイされていないのでhttpヘッダーは特に何も設定されていません。
inject
kube-injectを毎回実行する必要をなくすために以下のコマンドでサイドカーのinjectを自動実行させるよう設定します。istioctl kube-inject -f ${yaml}
を都度打つ必要がなくなります。
$ kubectl label namespace default istio-injection=enabled $ kubectl describe namespaces default Name: default Labels: istio-injection=enabled Annotations: <none> Status: Active No resource quota. No LimitRange resource.
この設定を有効化したら先ほど作成したサンプルアプリをapplyします。その後にcurlをすることでhttpヘッダーにenvoyの情報が追加されていることを確認します。
curl -o /dev/null -sv 10.107.7.138 * About to connect() to 10.107.7.138 port 80 (#0) * Trying 10.107.7.138... * Connected to 10.107.7.138 (10.107.7.138) port 80 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.29.0 > Host: 10.107.7.138 > Accept: */* > < HTTP/1.1 200 OK < server: istio-envoy < date: Sun, 20 Dec 2020 03:56:29 GMT < content-type: text/html; charset=utf-8 < content-length: 9593 < access-control-allow-origin: * < access-control-allow-credentials: true < x-envoy-upstream-service-time: 2 < x-envoy-decorator-operation: httpbin-service.default.svc.cluster.local:80/* < { [data not shown] * Connection #0 to host 10.107.7.138 left intact
Destination Rule
Destination Ruleはサービスへのルーティングを定義するためのカスタムリソースです。
apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: httpbin-destination-rule spec: host: httpbin-service subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2
Virtual Service
Virtual Serviceは実際のトラフィックの流量を制御するための設定を記載します。以下ではカナリアリリースを想定しv1へ90%のトラフィックを10%をアップデート対象のv2へとトラフィックを流す設定です。
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: httpbin-virtual-service spec: hosts: - httpbin-service http: - route: - destination: host: httpbin-service subset: v1 weight: 90 - destination: host: httpbin-service subset: v2 weight: 10
その他できること
- パスベースでアプリバージョンを制御
- httpヘッダーベースでアプリバージョンを制御
- cookieなどで宛先podをある程度固定できる
訳しながら理解していくIstio_Traffic Management編 - Qiita
まとめ
Istio/Envoyはさっとやる分には便利。ただブラックボックスな点が多いので今後もちゃんと理解していかないと運用には持っていけないなという印象。