Wasme Operator を利用した Wasm Filter のデプロイ
はじめに
こちらの記事は以前に公開した "wasme を利用した Wasm Filter 開発と Istio の Envoy にデプロイするまでの流れ" の続編となります。
前回の記事では wasme という CLI を利用することで Envoy の Wasm Filter の開発とデプロイを簡単に行えることを紹介しましたが、wasme 自体は Wasm Filter の開発やテストで利用することが想定されているもので、本番環境の Kubernetes クラスタで稼働する Envoy へのデプロイは Wasme Operator を利用して Custom Resource で宣言的に管理することが推奨されています。
Wasme Operator について
引用: Declarative WebAssembly deployment for Istio
Wasme Operator は、WebAssembly Hub などのレジストリから Wasm Filter イメージをダウンロードして Node にキャッシュする wasme-cache
と、Wasm Filter を Envoy にデプロイする wasme-operator
の2つのコンポーネントで構成されており、各コンポーネントはデフォルトで wasme
ネームスペースで稼働する仕様になっています。
各コンポーネントのソースコードは solo-io/wasm の tools/wasme ディレクトリ で管理されており、wasme-cache
は wasme の cache サブコマンドで、wasme-operator
は operator サブコマンドで起動されています。
現時点では Wasme Operator がサポートするデプロイ対象は Istio のみとなっており、Kubernetes クラスタに Istio(具体的には EnvoyFilter
リソース)がインストールされていない場合は処理が失敗するので注意してください。
Wasme Operator が稼働している状態で FilterDeployment
リソース(CRD は こちら, Spec/Status の詳細は こちら)を Kubernetes クラスタに作成することで、自動で Istio 内の Envoy に Wasm Filter がデプロイすることが可能になります。
それでは実際に動かしてみて Wasme Operator がどのように機能するのかを見ていきます。
実際に動かしてみる
Wasme Operator は2020年10月29日時点での最新バージョン v0.0.28
を利用します。
Istio がインストールされた Kuberntes クラスタの作成
Kubernetes クラスタ 1.18.0 を作成します。
minikube start --kubernetes-version v1.18.0
Istio 1.5.6 をインストールします。今回デプロイする Wasm Filter が 1.5.x に互換性があるものなので少々古いバージョンとなりますが 1.5.6 を利用しています。
istioctl manifest apply --set profile=demo
バージョンを確認します。
$ kubectl version --short
Client Version: v1.19.0
Server Version: v1.18.0
$ istioctl version
client version: 1.5.6
control plane version: 1.5.6
data plane version: 1.5.6 (3 proxies)
Wasme Operator のインストール
FilterDeployment
リソースの CRD をインストールします。
kubectl apply -f https://github.com/solo-io/wasm/releases/download/v0.0.28/wasme.io_v1_crds.yaml
Wasme Operator をインストールします。
kubectl apply -f https://github.com/solo-io/wasm/releases/download/v0.0.28/wasme-default.yaml
wasme-cache
は DaemonSet で wasme-operator
は Deployment でデプロイされます。
$ kubectl get all -n wasme
NAME READY STATUS RESTARTS AGE
pod/wasme-cache-drjbd 1/1 Running 0 50s
pod/wasme-operator-7b9c77976b-zlmv8 1/1 Running 0 50s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/wasme-cache 1 1 1 1 1 <none> 50s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/wasme-operator 1/1 1 1 50s
NAME DESIRED CURRENT READY AGE
replicaset.apps/wasme-operator-7b9c77976b 1 1 1 50s
サンプルアプリのデプロイ
Wasm Filter のデプロイ対象のサンプルアプリとして Bookinfo(solo-io/wasm の e2e テスト用のマニフェストを利用)をデプロイします。
kubectl create ns bookinfo
kubectl label namespace bookinfo istio-injection=enabled --overwrite
kubectl apply -n bookinfo -f https://raw.githubusercontent.com/solo-io/wasm/v0.0.28/tools/wasme/cli/test/e2e/operator/bookinfo.yaml
Bookinfo のアプリ内の Envoy へのリクエスト方法は以下となります。
kubectl exec -ti -n bookinfo deploy/productpage-v1 -c istio-proxy -- curl -I http://details.bookinfo:9080/details/123
この時点での HTTP レスポンスヘッダーは以下となります。
$ kubectl exec -ti -n bookinfo deploy/productpage-v1 -c istio-proxy -- curl -I http://details.bookinfo:9080/details/123
HTTP/1.1 200 OK
content-type: application/json
server: istio-envoy
date: Thu, 29 Oct 2020 09:40:51 GMT
content-length: 180
x-envoy-upstream-service-time: 1
x-envoy-peer-metadata: Ch0KDElOU1RBTkNFX0lQUxINGgsxNzIuMTcuMC4xMwrVAQoGTEFCRUxTEsoBKscBChAKA2FwcBIJGgdkZXRhaWxzCiEKEXBvZC10ZW1wbGF0ZS1oYXNoEgwaCjZmYzU1ZDY1YzkKJAoZc2VjdXJpdHkuaXN0aW8uaW8vdGxzTW9kZRIHGgVpc3RpbwosCh9zZXJ2aWNlLmlzdGlvLmlvL2Nhbm9uaWNhbC1uYW1lEgkaB2RldGFpbHMKKwojc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtcmV2aXNpb24SBBoCdjEKDwoHdmVyc2lvbhIEGgJ2MQoaCgdNRVNIX0lEEg8aDWNsdXN0ZXIubG9jYWwKJQoETkFNRRIdGhtkZXRhaWxzLXYxLTZmYzU1ZDY1YzkteHBoemwKFwoJTkFNRVNQQUNFEgoaCGJvb2tpbmZvCk8KBU9XTkVSEkYaRGt1YmVybmV0ZXM6Ly9hcGlzL2FwcHMvdjEvbmFtZXNwYWNlcy9ib29raW5mby9kZXBsb3ltZW50cy9kZXRhaWxzLXYxCiUKD1NFUlZJQ0VfQUNDT1VOVBISGhBib29raW5mby1kZXRhaWxzCh0KDVdPUktMT0FEX05BTUUSDBoKZGV0YWlscy12MQ==
x-envoy-peer-metadata-id: sidecar~172.17.0.13~details-v1-6fc55d65c9-xphzl.bookinfo~bookinfo.svc.cluster.local
x-envoy-decorator-operation: details.bookinfo.svc.cluster.local:9080/*
Wasm Filter のデプロイ
今回は前回の記事で開発した HTTP レスポンスに hello
というヘッダーを追加する Wasm Filter である webassemblyhub.io/ryysud/custom-header:v0.1 を Istio 内の Envoy にデプロイしていきます。
FilterDeployment
リソースは以下のようになります。
apiVersion: wasme.io/v1
kind: FilterDeployment
metadata:
name: bookinfo-custom-filter
namespace: bookinfo
spec:
deployment:
istio:
kind: Deployment
filter:
image: webassemblyhub.io/ryysud/custom-header:v0.1
上記のリソースを作成します。
cat << EOF | kubectl apply -f -
apiVersion: wasme.io/v1
kind: FilterDeployment
metadata:
name: bookinfo-custom-filter
namespace: bookinfo
spec:
deployment:
istio:
kind: Deployment
filter:
image: webassemblyhub.io/ryysud/custom-header:v0.1
EOF
リソースが作成されると wasme-cache
による Wasm Filter イメージのキャッシュが完了した後に、wasme-operator
による Envoy への Wasm Filter のデプロイが開始されます。
Wasm Filter のデプロイは、Node にキャッシュされたイメージを Envoy コンテナに hostPath でマウントするために Istio 仕様の Annotation である sidecar.istio.io/userVolume と sidecar.istio.io/userVolumeMount をアプリの Deployment マニフェストに追加(このタイミングでアプリの Pod がローリングアップデートする)して、Wasm Filter を Envoy で使用する設定を定義した EnvoyFilter
リソースを子リソースとして作成するという流れになります。
以下は FilterDeployment
リソースの子リソースとして作成された EnvoyFilter
リソースとなります。Spec から Wasm Filter が Envoy に設定されることがわかります。
$ kubectl tree -n bookinfo filterdeployment bookinfo-custom-filter
NAMESPACE NAME READY REASON AGE
bookinfo FilterDeployment/bookinfo-custom-filter - 5m54s
bookinfo ├─EnvoyFilter/details-v1-bookinfo-custom-filter.bookinfo - 5m24s
bookinfo └─EnvoyFilter/productpage-v1-bookinfo-custom-filter.bookinfo - 5m24s
$ kubectl get envoyfilters.networking.istio.io -n bookinfo
NAME AGE
details-v1-bookinfo-custom-filter.bookinfo 3m12s
productpage-v1-bookinfo-custom-filter.bookinfo 3m12s
$ kubectl get envoyfilters.networking.istio.io -n bookinfo details-v1-bookinfo-custom-filter.bookinfo -o yaml | kubectl neat
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: details-v1-bookinfo-custom-filter.bookinfo
namespace: bookinfo
spec:
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: envoy.http_connection_manager
subFilter:
name: envoy.router
patch:
operation: INSERT_BEFORE
value:
config:
config:
name: bookinfo-custom-filter.bookinfo
rootId: add_header
vmConfig:
code:
local:
filename: /var/local/lib/wasme-cache/a515a5d244b021c753f2e36c744e03a109cff6f5988e34714dbe725c904fa917
runtime: envoy.wasm.runtime.v8
vmId: bookinfo-custom-filter.bookinfo
name: envoy.filters.http.wasm
workloadSelector:
labels:
app: details
version: v1
また、Wasm Filter のデプロイ状況は作成した FilterDeployment
リソースの Status からも確認できます。
# 余計な情報は削除しています
$ kubectl get filterdeployments.wasme.io -n bookinfo -o yaml bookinfo-custom-filter
apiVersion: wasme.io/v1
kind: FilterDeployment
metadata:
name: bookinfo-custom-filter
namespace: bookinfo
spec:
deployment:
istio:
kind: Deployment
filter:
image: webassemblyhub.io/ryysud/custom-header:v0.1
status:
observedGeneration: "1"
workloads:
details-v1:
state: Succeeded
productpage-v1:
state: Succeeded
最後に Wasm Filter がデプロイされたかを確認します。
$ kubectl exec -ti -n bookinfo deploy/productpage-v1 -c istio-proxy -- curl -I http://details.bookinfo:9080/details/123
HTTP/1.1 200 OK
content-type: application/json
server: istio-envoy
date: Thu, 29 Oct 2020 09:55:32 GMT
content-length: 180
x-envoy-upstream-service-time: 1
hello: world! # <----- Wasm Filter によって `hello` ヘッダーが追加されている
x-envoy-peer-metadata: Ch0KDElOU1RBTkNFX0lQUxINGgsxNzIuMTcuMC4xNwrVAQoGTEFCRUxTEsoBKscBChAKA2FwcBIJGgdkZXRhaWxzCiEKEXBvZC10ZW1wbGF0ZS1oYXNoEgwaCjdiYjg0Njk5YjQKJAoZc2VjdXJpdHkuaXN0aW8uaW8vdGxzTW9kZRIHGgVpc3RpbwosCh9zZXJ2aWNlLmlzdGlvLmlvL2Nhbm9uaWNhbC1uYW1lEgkaB2RldGFpbHMKKwojc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtcmV2aXNpb24SBBoCdjEKDwoHdmVyc2lvbhIEGgJ2MQoaCgdNRVNIX0lEEg8aDWNsdXN0ZXIubG9jYWwKJQoETkFNRRIdGhtkZXRhaWxzLXYxLTdiYjg0Njk5YjQtNzdqN2YKFwoJTkFNRVNQQUNFEgoaCGJvb2tpbmZvCk8KBU9XTkVSEkYaRGt1YmVybmV0ZXM6Ly9hcGlzL2FwcHMvdjEvbmFtZXNwYWNlcy9ib29raW5mby9kZXBsb3ltZW50cy9kZXRhaWxzLXYxCiUKD1NFUlZJQ0VfQUNDT1VOVBISGhBib29raW5mby1kZXRhaWxzCh0KDVdPUktMT0FEX05BTUUSDBoKZGV0YWlscy12MQ==
x-envoy-peer-metadata-id: sidecar~172.17.0.17~details-v1-7bb84699b4-77j7f.bookinfo~bookinfo.svc.cluster.local
x-envoy-decorator-operation: details.bookinfo.svc.cluster.local:9080/*
レスポンスを見てみると hello
ヘッダーが追加されていることから、Wasm Filter が正常にデプロイできたことが確認できました。
さいごに
今回は Wasme Operator を利用して Kubernetes クラスタへの Wasm Filter のデプロイを Custom Resource で宣言的に管理する方法を紹介しました。Wasm Filter の本番運用を検討している場合には Wasme Operator の導入を検討すると良いでしょう。
参考資料
Author And Source
この問題について(Wasme Operator を利用した Wasm Filter のデプロイ), 我々は、より多くの情報をここで見つけました https://qiita.com/ryysud/items/66278bf365200462a942著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .