Skip to content

Latest commit

 

History

History
190 lines (171 loc) · 6.71 KB

File metadata and controls

190 lines (171 loc) · 6.71 KB

A kubernetes operator to manage Envoy filter configuration for Feature Targeting

The Istio EnvoyFilter resource carries significant cognitive overhead when all you want to do is configure the WASM filter for feature targeting.

This is a Kubernetes operator (written in Rust) that manages the configuration of specified envoy side-cars by wrapping the specified configuration in an EnvoyFilter resource, which Istio can use to configure the proxy.

It defines a Custom Resource (CRD) that allows us to send a config to the set of proxies whose pods' labels match the selector:

apiVersion: red-badger.com/v1alpha1
kind: FeatureTargetConfig
metadata:
  namespace: echo-service
  name: echo
spec:
  selector:
    app: echo
  configuration: |
    {
      "header_name": "x-features",
      "explicit": [
        {
          "_extract": "list",
          "attribute": "x-feature-override"
        },
        {
          "_extract": "pattern",
          "attribute": ":authority",
          "pattern": "f-*.localhost"
        }
      ]
    }

In this example, all pods that match the label selector will have their envoy side-cars configured with the specified configuration. This is managed by the operator and by Istio. If you update or delete the CRD, the relevant side-cars will take on, or remove, the configuration. You shouldn't need to restart any pods.

The above example will result in an EnvoyFilter that looks like this:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  creationTimestamp: "2020-05-24T14:12:03Z"
  generation: 3
  labels:
    app.kubernetes.io/instance: ddf66595-45ff-4de5-8b15-f092aa05d1c7
    app.kubernetes.io/managed-by: feature-targeting
  name: echo-filter
  namespace: echo-service
  ownerReferences:
    - apiVersion: red-badger.com/v1alpha1
      controller: true
      kind: FeatureTargetConfig
      name: echo
      uid: ddf66595-45ff-4de5-8b15-f092aa05d1c7
  resourceVersion: "456699"
  selfLink: /apis/networking.istio.io/v1alpha3/namespaces/echo-service/envoyfilters/echo-filter
  uid: 3651c239-af91-4715-83c0-01fa3a1ace52
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:
          name: envoy.filters.http.wasm
          typedConfig:
            "@type": type.googleapis.com/udpa.type.v1.TypedStruct
            typeUrl: type.googleapis.com/envoy.config.filter.http.wasm.v2.Wasm
            value:
              config:
                configuration: |
                  {
                    "header_name": "x-features",
                    "explicit": [
                      {
                        "_extract": "list",
                        "attribute": "x-feature-override"
                      },
                      {
                        "_extract": "pattern",
                        "attribute": ":authority",
                        "pattern": "f-*.localhost"
                      }
                    ]
                  }
                name: feature_targeting
                root_id: redbadger.feature_targeting
                vm_config:
                  allow_precompiled: true
                  code:
                    local:
                      filename: /var/local/lib/envoy-filters/feature_targeting.wasm
                  runtime: envoy.wasm.runtime.v8
                  vm_id: feature_targeting
  workloadSelector:
    labels:
      app: echo

You can also view the status of the CRD, in order to verify that there hasn't been a problem:

k describe features echo

Name:         echo
Namespace:    echo-service
Labels:       <none>
Annotations:  API Version:  red-badger.com/v1alpha1
Kind:         FeatureTargetConfig
Metadata:
  Creation Timestamp:  2020-05-24T13:15:31Z
  Finalizers:
    feature-targeting
  Generation:        4
  Resource Version:  488014
  Self Link:         /apis/red-badger.com/v1alpha1/namespaces/echo-service/featuretargetconfigs/echo
  UID:               ddf66595-45ff-4de5-8b15-f092aa05d1c7
Spec:
  Configuration:  {
  "header_name": "x-features",
  "explicit": [
    {
      "_extract": "list",
      "attribute": "x-feature-override"
    },
    {
      "_extract": "pattern",
      "attribute": ":authority",
      "pattern": "f-*.localhost"
    }
  ]
}

  Selector:
    App:  echo
Status:
  Message:              Filter created at: 2020-05-24T14:12:03Z, Generation 3
  Observed Generation:  4
  Phase:                Running
Events:                 <none>

Installation and testing

Ensure your context points to a Kubernetes cluster running Istio 1.6+ and the adapter-proxy-wasm.

(cd manifests && make)

You can install the example CRD and test that the x-features header is populated when you curl the echo service.

(cd examples && make)

curl --resolve f-echo.localhost:80:127.0.0.1 -vvv http://f-echo.localhost -H x-feature-override:viktor

* Added f-echo.localhost:80:127.0.0.1 to DNS cache
* Hostname f-echo.localhost was found in DNS cache
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to f-echo.localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: f-echo.localhost
> User-Agent: curl/7.64.1
> Accept: */*
> x-feature-override:viktor
>
< HTTP/1.1 200 OK
< x-powered-by: Express
< content-type: application/json; charset=utf-8
< content-length: 869
< etag: W/"365-YjtDHWFv65tp8bl4bntZeCTc2G4"
< date: Mon, 25 May 2020 08:42:14 GMT
< x-envoy-upstream-service-time: 5
< server: istio-envoy
<
* Connection #0 to host f-echo.localhost left intact
{"path":"/","headers":{"host":"f-echo.localhost","user-agent":"curl/7.64.1","accept":"*/*","x-feature-override":"viktor","x-forwarded-for":"192.168.65.3","x-forwarded-proto":"http","x-request-id":"42e52fee-c8e9-4c65-8fe5-11c9bd2bb05c","content-length":"0","x-envoy-internal":"true","x-forwarded-client-cert":"By=spiffe://cluster.local/ns/echo-service/sa/default;Hash=73ddec0d7911bd15c46bb2b7c38dbae1acefe7585de9aa2639b5ea4bccbc4a71;Subject=\"\";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account","x-features":"echo new_feature viktor","x-b3-traceid":"2c4fc919aebee1eb135e17fecd56a81c","x-b3-spanid":"064ca899e56f374d","x-b3-parentspanid":"135e17fecd56a81c","x-b3-sampled":"0"},"method":"GET","body":{},"fresh":false,"hostname":"f-echo.localhost","ip":"::ffff:127.0.0.1","ips":[],"protocol":"http","query":{},"subdomains":[],"xhr":false}* Closing connection 0

Try changing the FeatureTargetConfig CRD and make another curl request to observe the effect.