Guest post originally published on Solo.io’s blog by Lin Sun and Daniel Hawton

While there was not much new in Istio 1.15, Istio 1.16, led by our own release manager Daniel Hawton, has a lot of improvements. Interestingly, with skip version upgrade support from N-2 to N, the Istio project has been focusing on releasing more improvements on the even release numbers with odd release numbers serving as stability releases so that folks can skip version upgrade easily from N-2 to N.

In this blog post, we highlight a few new Istio 1.16 features and improvements that we are particularly excited about.

HTTP-Based Overlay Network Environment (HBONE) support in sidecars and ingress

At KubeCon US 2022 in Detroit, we observed tremendous excitement around Istio ambient mesh and how users love the 2 layer architecture for better incremental adoption, and how simple it is to include workloads in ambient mesh. Ambient mesh is not part of Istio 1.16 yet, and the community formed a dedicated ambient working group to drive ambient mesh to Istio master as the top priority. For Istio 1.16 or newer, the community has paved the road for sidecars to interoperate with pods in ambient mesh by adding HBONE support in sidecars and ingress gateways.

If you are not familiar with HBONE, it is a new tunneling mechanism for interservice mesh communications. This is not something an application owner sees or uses directly as it is designed to operate transparently behind the scenes between proxies (sidecar <-> ztunnel <-> waypoint proxy <-> gateway). Given ztunnels and waypoint proxies can only send and receive traffic via HBONE, for the sidecars to interoperate with them, sidecars understand if the destination can process HBONE traffic or not and only send traffic via HBONE if the destination can understand HBONE traffic (pic 1 below, App C to App A). If the destination doesn’t support HBONE, sidecars continue sending the classic mutual TLS traffic as usual (pic 1 below, App C to App B).

Diagram flow showing sidecar side ambient

Similarly, sidecars know how to terminate HBONE traffic when receiving traffic from ztunnels or waypoint proxies (pic 2 below).

Diagram flow showing Ambient sidecar

To explore this feature, you can simply install the ambient profile using your preferred Istio installer, for example:

code example

Note this profile only enables HBONE for sidecars, and the full ambient mode will be implemented soon. After you deploy a simple sleep application with sidecar injected, you’ll notice the networking.istio.io/tunnel: http label is added to the sleep pod, similar to the security.istio.io/tlsMode: istio label. This new tunnel label enables Istio to know whether or not a proxy supports HBONE.

code example

Given this feature is experimental, it is disabled by default thus we don’t recommend you use it in production. We have done some initial interop testing among Istio sidecars with pods in Ambient and verified they can interop as we have demonstrated in the last lab of our Istio Ambient workshop.

Discovery Selectors enhancement

After listening to our large-scale customers at Solo.io, we contributed discovery selectors to Istio upstream last year so that users can dynamically restrict the set of namespaces that are part of the mesh. We are extremely excited about the wide adoption of discovery selectors by the community which resulted in enhancements made to discovery selectors in Istio 1.16!

Not only can you use discovery selectors to configure Kubernetes resources, but with 1.16, you can also use discovery selectors to configure the Istio custom resources such as Gateway, VirtualService, DestinationRule, etc. Furthermore, you can leverage discovery selectors to configure the Istio control plane on which namespaces you want the istio-ca-root-cert config map. These enhancements are very useful if you want to specify the allowed mesh namespaces for a given control plane as mesh operators, or enable soft multi-tenancy for your mesh based on the boundary of one or more namespaces. What is best about this improvement is that there is no API change for developers, you can continue using discovery selectors as before 1.16.

To enable this feature, you can enable the discovery selectors along with the ENABLE_ENHANCED_RESOURCE_SCOPING environment variable. The following YAML contains an example to enable the feature with the ambient profile:Copy

# The ambient profile has ambient mesh enabled
# Note: currently this only enables HBONE for sidecars, as the full ambient mode is not yet implemented.
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    discoverySelectors: 
      - matchLabels:
          istio-discovery: enabled
    defaultConfig:
      proxyMetadata:
        ISTIO_META_ENABLE_HBONE: "true"
values:
  pilot:
    env:
      PILOT_ENABLE_INBOUND_PASSTHROUGH: "false"
      PILOT_ENABLE_HBONE: "true"
      ENABLE_ENHANCED_RESOURCE_SCOPING: "true"

Label the default and foo namespace with istio-discovery=enabled and display the route configuration for the sleep deployment:

code example

Apply the review virtual service to the foo and bar namespaces, then display the route for the sleep deployment. You’ll notice the reviews.foo virtual service is in the route list but not the reviews.bar.

code example

By default, Istio creates the istio-ca-root-cert config map for each namespace in the Kubernetes cluster, regardless if the namespace has any services in the mesh. With the enhancements from discovery selectors in 1.16, you can choose what namespaces to have the config map created. If you display the config maps for each namespace, you’ll notice the istio-ca-root-cert config maps are created for the default and foo namespace, but not the bar namespace:

code example

Isn’t it nice to be able to select which namespaces are part of the mesh, not only for Kubernetes service but also for Istio resources?

Istio API & Kubernetes Gateway API

One of the key changes with Istio 1.16 is that Gateway API tabs are added next to the Istio existing APIs for some traffic management tasks, a result of Istio adopting Kubernetes Gateway API. While you browse through traffic management tasks, you will see some tasks can only be accomplished with Istio APIs, for example, request timeout or fault injection.  Why? Because they can’t be translated to Gateway API yet. As the service mesh community is working on the GAMMA initiative to attempt to standardize the mesh API for mesh operators and developers across Istio, Linkerd, Consul connect, Kuma, and OSM, we expect it will take quite some time to get the mesh API standardized while continuing to enable each project to innovate and stay ahead of the common API. As one of the contributors to the GAMMA initiative, we are excited about GAMMA and where the role-based project-neutral mesh APIs are headed as part of the GAMMA initiative.

Wasm Enhancements

It is great that the Istio community is adopting the Wasm OCI image specification started by Solo.io. Lately, there is a specification enhancement to support more than one layer. For example, you could easily add another layer to label your images based on your business needs. Another exciting change is the introduction of the traffic selector in the WasmPlugin resource, which enables users to precisely select which traffic the WasmPlugin resource should apply to. You might be wondering, “how this is different from the workload selectors which are typically for service producers?” Without specifying any traffic selector configuration, the WasmPlugin is for the target workload selected via workload selector, regardless of which listeners the service has. The traffic selector configuration enables you to fine-tune the selector to a particular port as well as specifying the workload mode.

apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: httpbin-rust-test
  namespace: httpbin
spec:
  selector:
    matchLabels:
      app: httpbin
  # Define traffic selector match conditions
  # All conditions must evaluate to true for the plugin to be applied
  match:
    # Define the workload mode, valid options are: SERVER, CLIENT, CLIENT_AND_SERVER
    - mode: SERVER
    # Define port numbers to match. If not specified, all ports are matched
    - ports:
      - number: 80
  url: oci://docker.io/dhawton/wasm-rust-test:v1

With the above WasmPlugin resource for the httpbin workload’s port 80 service, we can deploy a simple Wasm filter into our httpbin‘s Envoy proxy that does very basic logging and waits for an HTTP request to /get comes through. When a path match is found, the plugin will return a status code of 418 and ASCII art of a teapot before pausing the remainder of the Envoy filters. The following is the logic of the Wasm filter:Copy

match self.get_http_request_header(":path") {
    Some(path) if path == "/get" => {
        info!("on_http_request_headers: {} - /get intercepted", self.context_id);
        self.send_http_response(
            418,
            vec![("x-powered-by", "rust"), ("content-type", "text/plain")],
            Some(TEAPOT_ASCII),
        );
        Action::Pause
    }
    _ => Action::Continue,
}

After deploying the WasmPlugin configuration, we can see that a curl to httpbin’s /get endpoint on port 80 is intercepted by the Wasm filter without needing to restart the httpbin deployment.

code example

How can we demonstrate selective matching? We’ll apply the below configuration (changing port number 80 to 81) to demonstrate the Wasm filter not being applied to the httpbin traffic:Copy

apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: httpbin-rust-test
  namespace: httpbin
spec:
  selector:
    matchLabels:
      app: httpbin
  match:
    - ports:
      - number: 81
  url: oci://docker.io/dhawton/wasm-rust-test:v1

And if we run the same curl, we should see that the above WasmPlugin resource did not impact the httpbin workload on port 80, so we get httpbin’s expected response.

code example

Wrapping Up

Istio 1.16 is another exciting release from the community, sailing further toward the future of Istio with Ambient Mesh. There are numerous other improvements that we didn’t cover here, please refer to the release change notes to view all other improvements, including: support for MAGLEV load balancing algorithm, support for use of the OpenTelemetry tracing provider with the Telemetry API, new remote profile, etc. To learn more about the 1.16 release, join the Hoot Livestream hosted by us on Nov 29th at 1 pm ET.

As the community works towards making Istio the de facto service mesh for Kubernetes, we invite you to be part of the journey, with your feedback or contribution to help shape the future of Istio via the Istio Slack or GitHub.