LoginSignup
2
3

More than 3 years have passed since last update.

Wasme Operator を利用した Wasm Filter のデプロイ

Last updated at Posted at 2020-10-30

はじめに

こちらの記事は以前に公開した "wasme を利用した Wasm Filter 開発と Istio の Envoy にデプロイするまでの流れ" の続編となります。

前回の記事では wasme という CLI を利用することで Envoy の Wasm Filter の開発とデプロイを簡単に行えることを紹介しましたが、wasme 自体は Wasm Filter の開発やテストで利用することが想定されているもので、本番環境の Kubernetes クラスタで稼働する Envoy へのデプロイは Wasme Operator を利用して Custom Resource で宣言的に管理することが推奨されています。

Wasme Operator について

image.png
引用: 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 の導入を検討すると良いでしょう。

参考資料

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3