 I do hope you've been enjoying the talks in the ServiceMeshCon 2020 track this year. My session will be taking ServiceMesh a step further with a technology called WebAssembly. So my name is Christian and I am the field CTO here at solo.io. I've been involved in helping organizations build large distributed systems for quite some time and most recently last three years or so in building architectures on top of Kubernetes and cloud native infrastructure, including things like ServiceMesh. So at solo, real quick, what we do is we help organizations after they've figured out how to automate their deployments with CI CD and deploying into containers and kind of breaking up some of their applications into microservices. How do they get those systems to communicate with each other? And the organizations that we typically deal with are trying to deploy redundant, highly available systems that are capable of experiencing degradation and failover in a seamless way. And at solo, what we do is we help build API infrastructure on technology like Envoy and ServiceMesh to be able to span multiple clusters, multiple zones, multiple geographies and use things like mesh and gateways to be able to get this transparent routing and secure communication, observable network, and these types of things. So in helping these organizations build these types of architectures, we see a lot of what's happening on the ground and more importantly in practice and what's really happening. So what we do see is folks are adopting ServiceMesh and they are taking it into production. They do have some initial challenges around which one to use because as you're probably familiar with, and as you see the talks in this track, there are a lot of different options. And then your next question, especially as a large enterprise, is who's going to support you? Who's going to give you the level of support that you need? And then there's always questions around how does it fit within an existing organization? How does it fit with existing applications that weren't very native to a cloud like platform? And one of the biggest that we see and that we've been able to help out with with our customers is how do we customize that last 10%? So we've introduced, let's say a gateway or we introduced a ServiceMesh and either at the edge or sometimes even in between the applications, there are needs around customizing the behavior of the network or customizing the behavior of the proxies. So typical customizations look like supporting existing wire protocols, maybe some of them are industry or vertical specific. You'll see the need to add more specific customizations and telemetry that the proxy captures, especially things like implementing security protocols, things that might not be industry standard, but have existed in these organizations. And if the mesh or this technology is going to be adopted, then it needs to be backward compatible with these existing brownfield applications and the way they communicate on the network. There's also going to be things like light transformations. How do we take this header, mangle it up a little bit, put it over here in this header, because that's what that's what the upstream applications expect, and so on. So there's a really large almost never ending list of what customizations you might need to actually productionize and get a system like a ServiceMesh into an organization. Now, at solo, what we've been doing is a lot of the technology that we focus on is built on Envoy. So either our glue gateway is built on Envoy or Istio is something that we've been supporting for our customers is built on Envoy. And so we can build the customization directly into Envoy, but WebAssembly has kind of come to the forefront as the right way to build these types of extensions. And I can explain a little bit more about that. So WebAssembly actually originated in the web browsers as a way to speed up the execution of code in the web browsers, but also open up the opportunity for folks to write extensions to web applications in different languages than JavaScript. So WebAssembly is a binary format that you write your length, your programs and your extensions in any language that you like, high level language like a C++ or a Rust or Golang or whatever, and then compile that into a binary module that can then be loaded into a host VM, a WebAssembly VM. And this is something that is not a new idea. We've been building and taking high level languages and compiling them down into different portable formats and running them in either some sort of VM or some sort of host. This is the same idea. So we can take this, again, we can take the code in a language that you desire to write in or maybe code that you have already existing and try to compile that down into a format that can be embedded into a web browser or in this case, as we see on this last line, on OnBoy proxy. And as I mentioned, OnBoy is one of the leading proxies for building this type of mesh or application networking technology. So an important part of WebAssembly and running it in any of these hosts is that you're kind of taking untrusted code and embedding it into an existing system. Now, WebAssembly is built to be secure. I mean, if it's running in the browsers, just like a JavaScript engine, it needs to be secure. And one of the things WebAssembly does is it enforces a very tight memory boundary around that module. The module can only use whatever memory and functions and variables that the host gives it. So it can't just start calling out to either any other host functions or outside of that sandbox. So it's very safe and secure. It's also extremely fast, at least compared to alternatives, right? So if we look at in the browser, we see that it's faster than a JavaScript implementation. If we look at maybe OnBoy specifically, it's faster than some of the alternatives. So some of the alternatives to extending the capabilities of OnBoy include things like calling out to an external service and having it process some logic like, I don't know, for example, we have customers that do funky things with HMAC on the request come in, they have to do some HMAC validation, or they might reach out to an external host service to do that out of the process of the proxy. If we could do something like that inside the proxy, now we don't have to take that additional hop. And that speeds things up. It's not as fast as writing the code directly into the OnBoy proxy itself. So if you wrote it as a C++ extension to OnBoy, well, but something's not going to be as fast as that. But the downsides to baking it directly into the proxy itself is, first of all, you have to write it in C++. You have to compile it and statically link it into OnBoy itself. So now the binary that you're running isn't upstream OnBoy anymore. It's your own distribution that you just created. And so that's a very important consideration, especially when you start talking about all the different types of customizations that you might want. So will you have one build of OnBoy that has all of the customizations? Or will you have, you know, 10, 20 different distributions that you're going to try to support? It'd be nice if you just had the one single distribution and dynamically load those customizations in as needed. So as I said earlier, with WebAssembly, we can use ideally any language. Now in practice, we'll see some are better suited today than others, but we can use any language which then gets compiled down into an intermediate representation of the code and then eventually executed into the VM. So here's where it gets interesting. Because for frameworks like ServiceMesh, especially those built on OnBoy, we have this opportunity now to not only... So ServiceMesh itself kind of organizes and programs the network at the L7 or the application layer. Now we can have very fine-grained customizations that are tailored toward the way you've written applications already, and especially that might be organizational specific. So if we take a look at OnBoy today and the mechanisms and how a request would flow through the filter chains in OnBoy. So OnBoy is built on this pipes and filter type architecture. And request comes in, goes through one of these first steps, continues on to the next, to the next, and eventually gets routed either sent back or routed to an upstream service. So OnBoy is a proxy, right? So it's proxying the request, it's adding some additional capabilities to the request once it gets on the wire. Now you can see the fourth box here going down. As you flow through this chain of filters, you can add... First of all, you can configure any of the out-of-the-box filters that exist in OnBoy to live in this chain. But you can also add your own custom filters. And so that's something that we've done in the past. You write this in C++. But as I said, with WebAssembly, you can write this in a different language than C++, compile this down to WebAssembly module, and then run that piece, run that module as a step in this filter chain. So WebAssembly becomes this mechanism of extending the capabilities of an existing OnBoy proxy with the code of your choice and the language of your choice. Now how that happens is the filter in OnBoy... So the filter in OnBoy has an API, right? And how we translate that into code that the WebAssembly module will be able to understand is we have... So first of all, we need an execution engine to be able to run WebAssembly. And then we need a interface between the OnBoy filter, and what OnBoy understands natively, and the sandboxed WebAssembly VM. And so that's called the application binary interface. So you might see this term, and that's why I'm covering it. You might see this term when you start looking at building WebAssembly modules for OnBoy. And all the ABI does is specifies a set of functions that can be imported into your WebAssembly module, and functions that are exported. So in other words, you're only allowed to use and see a certain handful of functions, for example, make external calls or something that OnBoy will allow you to use, and then your application can implement these callbacks that the ABI and the filters will actually call into. Now all this stuff sounds a little bit complicated, but you shouldn't worry too much about that because this is what's happening in the OnBoy side. What you are more interested in as a developer, let's say, you're interested in the SDKs that kind of wrap this ABI and abstract some of these details away from you. So there are SDKs for C++, assembly script, Rust, and TinyGo to be able to write your applications in these languages, compile them down into a WebAssembly module, and inject that and run that in an existing OnBoy. So again, the SDKs that have been built around this to abstract some of this detail are your entryway into building WebAssembly modules for OnBoy. So then the question becomes, how do you start using these SDKs? How do you build these modules, pull the correct tool chains and all this stuff to be able to build the modules, and then when you build the modules, what do you do? How do you install them? How do you maybe share them, publish them? And there's some interesting parallels here between the experience that we saw crop up around Linux containers and the experience that we want with something like WebAssembly. And this is a very important distinction because with Linux containers and setting up C groups and namespaces, all that stuff, even LXC and some of those APIs that built up around it initially, they weren't all that well suited for the developer experience, let's say. And so that's where Docker came in and built a nice API and nice developer experience around using containers. And so that's what this open source project WebAssembly hub is aiming and trying to do for WebAssembly. So we have this simple CLI that allows you to quickly bootstrap a new WebAssembly for OnBoy project in a handful of different languages that you can choose. And then it automates a lot of the boilerplate, lining up the ABI versions, lining up the SDKs, finding all the tool chains that you need to properly build the WebAssembly module. We've also have a OCI style and spec that describes what a WebAssembly module would look like once it's packaged. And then you can take that publish it into an OCI registry and share it and ultimately pull it down and install it into a running OnBoy framework like a service mesh. So WebAssembly hub and the WASMI tool allow us to do that. And to get started, let's say we go to Firefox, we go to WebAssembly hub. To get started, you can do so first of all, you can you can come take a look at WebAssembly hub. You can see some of the WebAssembly modules that folks have been kicking the tires on. You can come over here to the docs and get started. So install the WASMI tool tutorials for getting started and starting to build your own project and so forth. And what we're going to take a look at is a demo here of us building out a WebAssembly module and going through this developer workflow and figuring out how do you deploy this to a running OnBoy based framework. So let's take a look at that. So again, the demo we will be taking a look at WebAssembly hub and specifically the CLI tooling around getting started with a project, building it and the whole life cycle around that. So if you come to the docs here, you can look in the installation and getting started tutorials, building our different WebAssembly modules just a little bit outdated. We have more languages that we support here. So let's take a look at the at the demo. So the CLI that we would use to start get started with our WebAssembly experience here for especially for building for OnBoy is this WASMI tool. And with WASMI what we can do is create new projects, we can build them, deploy them to existing OnBoy based frameworks. And then we can also there's a workflow around pushing them and pulling them from a registry. So let's take a look at building a WebAssembly module for OnBoy using using this developer experience for a couple different languages. So if we do demo, let's do tiny go. Let's take a look at our existing deployment. We're going to be using Istio for this. We have the Istio control plan deployed. We also have the book info application running. Now if we make a call between the product page and the details service, we see the call completes. It's an HTTP call. We've also dumped some of the headers. What we're going to do in this demo is just create a WebAssembly module that extends the capability of either transforming headers or adding new headers to the request or the response. So the first thing we're going to do is we're going to build, we're going to bootstrap a new project and we're going to use Wasmian it and then we're going to put it in a new directory and we're going to pick a language that we want to we want to use for this WebAssembly module. So if I click on tiny go, which is what we're going to use a subset of the goal language, we will pick the platform that we want to target. In this case, it's Istio 1.7 and then it creates it. Now if we go in and open our project, we can see we have some of the boilerplate code already set up for us. So all we have to do now is either go in and edit existing functions that override so the callbacks that Envoy will be calling into or we can add new ones that align with the SDK. If we look at this runtime config JSON file, this is a metadata file that is used in the packaging of this WebAssembly module as a OCI style package. So that's all good. Now let's say we want to build our project and turn that into a WebAssembly module. So what we're going to do is run was me build will tell it what type of language we're using here. And then we're going to tag it using a format that's similar or familiar to what you would do with other OCI images. And so we'll give that a few moments to complete while it downloads while we wait. What this is going to do is download the the document as you can see to provides all of the right versions of go the right versions of the SDK and builds everything consistently. Now it's still going almost there. Apologies. I should have downloaded this ahead of time. And there we go. Now we've downloaded the builder and and now we're going to build it shouldn't take too long. We're going to tag it using the tag that we specified here. And now we built the image. If we take a look and list it locally, we can see that 14 of this ad header demo was built and is packaged as a OCI style container. And then from there, what we can do is we can push that to a registry. So in this case, we're going to push this to the WebAssembly hub registry. If we go take a look, if we log in under my name, you can see our demo ad header repo that's been out of here at zero dot 14 is the one we just created. Click on tags. We should see that indeed zero dot 14 is is available as a 21 seconds ago. So that's awesome, right? Now we just built a extension to envoy using go or tiny go subset of go. We packaged it as a WebAssembly module. We pushed it to a registry now that other other folks can can come to this. This repo and explore the various different WebAssembly modules that that are, you know, other folks have been have been working on and experimenting with and so on. And we're not limited to just C++, which is what Envoy has written. And we're not statically building this into the proxy. This is dynamically loaded or will be when I show you that part. Let's let's do it again. Let's let's reset this. Let's pick a different language. Let's do assembly script. All right, so we have the same thing. We have this deal running. We have our book info demo running. And when we make a call, what we're going to do is we're going to insert one of these WebAssembly modules into the envoy proxy. So we see headers here. We don't see any additional headers yet. So what we're going to do is we're going to do was me and it do the same workflow. But now we're going to do it with assembly script, which is a variant of TypeScript. And we're going to pick the platform we're targeting. And now if we open our project, we see something like this. We see our assembly assembly script source here, which was automatically bootstrap by was me the was me tool. We see the same runtime config packaging here. So now if we build our project, it'll use the same build, build container that we did. But now it's going to do this using npm and using JavaScript style build tools. So we'll give that a moment shouldn't take too long. We see it tagged again as zero dot 15. In this case, if I list it, we see zero dot 15. The assembly script was a module is a little bit smaller than the goal line one. And now we can also push that one to the WebAssembly hub repo. Now what we want to do is actually deploy this to an unboy based framework. So let's take a look. Again, we'll call between product page and details. We don't see any, any headers are yet. What we're going to do is was me deploy Istio. Let me give that a second here. I'm going to pause the output. This is a live demo. So and it is typing, but in the output still coming. I just pause the output was me deploy Istio the specific tag that we want. And then any configuration that we that we want to give to it. Now sometimes there is a there's still a race condition that we are aware of here. Give it a second. Not very nice. All right, well, let's let's try this again. I should cross our fingers here. All right, there we go. Now it looks like it has taken so what this has done is is injected the WebAssembly module into each of the pods running in the book info name space. So in the book info name space, we should see the output of our WebAssembly module, which in this case, I didn't do too much. We just added a new header when when we get the response. So if that's the case, now that my demo is not automated anymore, let's let's first take a look at what what we created under the covers for Istio. So if I do get envoy filter book info, what we see is we've created these book in or these envoy filters to patch the envoy proxies to load the wasm module. If we actually take a look at one of these, let's take a look. We can see that we are adding a the wasm filter and that it is calling out to a wasm module. So if that's the case, then what we should see is when we call between product page and details what we should see across our fingers is this new header that we that we added. So let's run this. And indeed, we do see the the new header that we've added with the with the specific configuration. Let's come back here. We're using hello instead of world or saying hello tomorrow and that and that's what we see in the request path here. So that's the extent of my my demo here. I do encourage you take a look at the WebAssembly Hub tooling. Go ahead and take a look at Istio and some of the service meshes that are supporting WebAssembly. The caveat that I should point out is that WebAssembly and envoy was just recently merged into upstream up until now it's been on its own fork. But it's recently merged into upstream. It it's in a state of let's just say it's still settling out a little bit. It will I believe it will be available in in envoy 1.17. Even then I still caution that this is still kind of new technology that will need some soak time. So definitely experiment with it, push the boundaries of it and the limits of it and you know, jump in and contribute in the community in terms of issues and you know, whatever experience that you have with WebAssembly and definitely feel free to reach out to us or the broader WebAssembly community for any thoughts or questions. So thanks again for stopping by my talk.