今回はIstioのEnvoyFilterでのgzip圧縮をしたのでそれを書いていきます。
gzip圧縮自体は Envoy が提供しているのでこれを使用するだけなのですが、EnvoyFilter を初めて使ったのでそれのメモがてらの記事でもあります。
https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/compressor_filter
今回は2通りの方法を試しています。
両者の違いとしては Filter をどこまで適用するかで、アプリケーション側で行う時は Filter はそのアプリケーションに対して適用されますが、 Istio Ingress Gateway の場合は複数のアプリケーションが紐づいている場合はそれらすべてに Filter が適用されるという認識です。
環境
- Kubernetes: v1.18.14
- Istio: v1.9.0
- Envoy: 1.17.0
- バージョンは
kubectl exec -it [サイドカーが動いてるPod] -c istio-proxy -- pilot-agent request GET server_info | jq {version}
で確認しました
- バージョンは
アプリケーションのサイドカーで gzip 圧縮
適用する EnvoyFilter の YAML ファイルは下記になります。
apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: gzip namespace: sample-app spec: workloadSelector: labels: # Podのラベル app: sample-app configPatches: - applyTo: HTTP_FILTER match: context: SIDECAR_INBOUND listener: filterChain: filter: name: envoy.filters.network.http_connection_manager subFilter: name: envoy.filters.http.router proxy: proxyVersion: ^1\.9.* patch: operation: INSERT_BEFORE value: name: envoy.filters.http.compressor typed_config: '@type': type.googleapis.com/envoy.extensions.filters.http.compressor.v3.Compressor compressor_library: name: for_response typed_config: '@type': type.googleapis.com/envoy.extensions.compression.gzip.compressor.v3.Gzip compression_level: "COMPRESSION_LEVEL_6" response_direction_config: common_config: content_type: - text/html - text/css - application/javascript remove_accept_encoding_header: true request_direction_config: common_config: enabled: default_value: false runtime_key: request_compressor_enabled
gzip周りの設定は spec. configPatches[0].patch.value
に書かれています。
各値に関しては公式のドキュメントを参照します。
ひとつ注意するところとしては今自分がどのバージョンの Envoy のドキュメントを見ているかは最初に確認します。
これをしないと設定できない項目を設定しようとして反映されない。。。なんでだろう。。。と悩むことになります。
www.envoyproxy.io
今回は Content-Type が text/html
, text/css
, application/javascript
の時に gzip 圧縮を Envoy 側でかけるようにしています。
実際にこれが適用されるアプリケーションは spec.workloadSelector
をみます。
ここに記載されている labels が Pod のラベルと照合されます。
EnvoyFilter は namespace ごとに配置されており今回は sample-app
という namespace に適用します。
そのため、今回の gzip 圧縮は sample-app
という namespace で istio-proxy がサイドカーとして動いている app: sample-app
というラベルをもった Pod に適用されます。
適用自体は kubectl apply すると適用されます。
適用されたかの確認は kubectl exec -it [Pod名] -c istio-proxy -- curl -s localhost:15000/config_dump
で確認することができます。
envoy.filters.http.compressor
で grep とかすると設定した値が反映されている箇所が見つかるはずです。
設定に不備により適用されない時は kubectl apply 時に istiod
のログをみると Proto constraint validation failed
など原因が見つかるかもしれません。
Istio Ingress Gateway のサイドカーで gzip 圧縮
Istio Ingress Gateway のサイドカーに適用する場合はアプリケーション側の YAML から大きな変更はなくて context を SIDECAR_INBOUND
から GATEWAY
に変更して namespace と label を Istio Ingress Gateway に合わせるだけです。
kind: EnvoyFilter metadata: name: gzip - namespace: sample-app + namespace: istio-system spec: workloadSelector: labels: # Pod's Label - app: sample-app + app: istio-ingressgateway configPatches: - applyTo: HTTP_FILTER match: - context: SIDECAR_INBOUND + context: GATEWAY listener: filterChain: filter:
最後に
今回は EnvoyFilter を作ってみましたが、結構楽しいので色々試して活用していきたい。