Advertisement · 728 × 90
#
Hashtag
#spinkube
Advertisement · 728 × 90

Great usage of #kube-virt and #spinkube for #webassembly and AI

0 1 0 0
Post image

@thorstenhans.bsky.social talking about #Spin and #SpinKube at the Akamai booth at #KubeCon.

5 2 0 0

First video of the week is up from #ArgoCon - had a great time with @radu-matei.com - www.youtube.com/watch?v=Oayq... - at #KubeCon about Continuous Delivery with #Argo for #Wasm apps, with #Spin and #SpinKube.

0 0 0 0

I'm talking with @lukepatrick.dev at #KubeCon about Continuous Delivery with #Argo for #Wasm apps, with #Spin and #SpinKube.

#kubecon #cloudnativecon #argocon #wasm

2 1 0 0
Preview
CNCF-hosted Co-located Events Europe 2025: Continuous Delivery & Resource Health fo... View more about this event at CNCF-hosted Co-located Events Europe 2025

You can catch me this week presenting w/ @radu-matei.com Tuesday @ #ArgoCon sched.co/1u5e1 #spinkube & Thursday @ TAG-A Project Pavilion - 12:37 - Lightning Talk - “Your AppDelivery Ran Over My CI/CD: Expanding Beyond Pipeline Thinking” - tag-app-delivery.cncf.io/blog/tag-app... #kubecon #kubeconeu

2 1 0 2
Post image

WASM.IO, the conference all about WebAssembly and WASI. For me mainly to follow my track on Serverless specially to get the latest news from Fermyon and Spin.

#webassembly #wasm #wasi #fermyon #spin #spinkube #rust #rustlang

1 0 0 0

PSA: migrate to SpinKube cause WebAssembly System Interface (WASI) Node Pools in AKS will be retired #aks #kubernetes #webassembly #spinkube https://azure.microsoft.com/updates?id=484102

0 0 0 0
Preview
Protect Your REST APIs with Service Chaining **By: Matt Butcher** Spin applications are composed of one or more serverless functions. One serverless function can easily call to another function regardless of source language. In fact, it is easy to build REST API-style apps that function like microservices, but deploy in unison. And protecting REST APIs is simple. In this post, we’ll write an app with two components — a REST API in Javascript and a simple frontend in Python. Then we’ll show how the Python serverless function can make a REST-style call to the Javascript component. But then we’ll take things one level further: We’ll preserve the feel of a REST-based microservice, but eliminate the network connection between the two. Finally, we’ll make the Javascript REST API private (internal-use only) to prevent external users or apps from accessing the endpoint while allowing our Python code to continue using it. In this example, we’ll create a simple “book of the day” app with a REST-like API service that chooses a book and a Python front-end that renders a user-facing page. ## Creating a Multi-component Project A Spin app is composed of one or more components. Components act like serverless functions, receiving an event (like an HTTP request), doing some processing, and then returning a response. We’re going to build two such serverless functions. Usually when we start a Spin project, we create a “top-level” component. Any additional components we create are nested inside that component. For example, to create a new Rust-based HTTP handler, we might run a command like `spin new -t http-rust my-rust-app`. And then we might later add another function with `spin add -t http-js ....`. It is also possible to create an empty project with no top-level components. In this case, while a `spin.toml` file will be created, no language-specific directories will be dropped into the app directory. This is useful when you are creating a multi-component Spin application as we are about to do. To get going, we will start an empty project: $ spin new -t http-empty bookserver Description: A multi-component book service Looking inside of this new project, we’ll see only a few basic files: $ tree -a bookserver bookserver ├── .gitignore └── spin.toml At this point, we can use `spin add` to add components one at a time. Next up, let’s create our Javascript API service. ## Creating a Simple JSON Service in Javascript The `book-api` service will return a book recommendation for the book of the day. We’re going to write it in Javascript. And it will be one of two components inside of our `bookserver` app. $ cd bookserver $ spin add -t http-js book-api Description: API server for recommending a book HTTP path: /api Enable AoT Compilation [y/N]: n Now our project is a little bit larger: $ tree -a bookserver bookserver ├── .gitignore ├── book-api │ ├── .gitignore │ ├── knitwit.json │ ├── package.json │ ├── src │ │ ├── index.js │ │ └── spin.js │ └── webpack.config.js └── spin.toml And now the top-level `spin.toml` points to our new JS service: spin_manifest_version = 2 [application] name = "bookserver" version = "0.1.0" authors = ["Matt Butcher <matt.butcher@fermyon.com>"] description = "A multi-component book service" # This is the new service we just added with `spin add...` [[trigger.http]] route = "/api" component = "book-api" [component.book-api] source = "book-api/target/book-api.wasm" allowed_outbound_hosts = [] [component.book-api.build] command = "npm run build" workdir = "book-api" Before we go too far into coding, we need to make sure that we run `npm install` inside of the `bookserver/book-api` directory: `cd book-api && npm install` . That installs all the Javascript libraries we need. Now we can start building our serverless function. Our REST API will be very basic. It’ll recommend a different book for each day of the week. We’ll statically code all seven books in one array. Then, per request we will return a simple JSON object that looks like this: `{ "title": "BOOK TITLE", "author": "BOOK AUTHOR"}`. import { ResponseBuilder } from "@fermyon/spin-sdk"; let books = [ { title: "Dead Souls", author: "Nokolai Gogol" }, { title: "The Little Drummer Girl", author: "John Le Carré" }, { title: "We Were Eight Years In Power", author: "Ta-Nehisi Coates" }, { title: "My Ántonia", author: "Willa Cather" }, { title: "Haroun and the Sea of Stories", author: "Salman Rushdie" }, { title: "The Bird King", author: "G. Willow Wilson" }, { title: "The Hobbit", author: "J.R.R. Tolkien" } ] export async function handler(req, res) { let todaysBook = (new Date()).getDay(); res.send(JSON.stringify(books[todaysBook])); } The `handler` function figures out what day of the week it is, looks up the relevant entry in the `books` array, and returns that object encoded as JSON. That’s all there is to it. With a simple `spin build --up` in the `bookserver` directory, we can compile and run our app. Then, in another console we can test it out with `curl`: $ curl localhost:3000/api {"title":"The Little Drummer Girl","author":"John Le Carré"} I’m writing this post on a Monday, which is day `1` in Javascript’s `0`-indexed day-of-week. So we are getting the correct result. We’ve created a simple REST API in Javascript. Next, let’s write a simple frontend using Python. ## Accessing the Javascript Service from Python Just like last time, we’ll add a new component with `spin add`: $ spin add -t http-py frontend Description: Book of the Day Frontend HTTP path: / Now, `bookserver/frontend` contains the template Python code. Setting up a modern Python environment is a bit trickier than configuring Javascript, and will depend on how you configured your local toolchain. Read the Spin Python docs to see how we set up our Javascript environment using virtual environments. For my local environment, I followed the recommendations in the quickstart guide. Regardless of how you configured your environment, at some point in your setup, you should do a `pip3 install -r requirements.txt` on the requirements file in `bookserver/frontend`. Now that the toolchain is properly configured, we can edit the code in `bookserver/frontend/app.py`. import json from spin_sdk.http import IncomingHandler, Request, Response, send class IncomingHandler(IncomingHandler): def handle_request(self, request: Request) -> Response: # Get the book of the day from JS: resp = send(Request("GET", "http://localhost:3000/api", {}, None)) book = json.loads(resp.body.decode("utf-8")) msg = f"Today's book is _{book['title']}_ by {book['author']}" return Response(200, {"content-type": "text/plain"}, bytes(msg, "utf-8")) The `handle_request` method is doing the following: 1. Sending a request to our JS REST API on `localhost:3000/api` 2. Reading the JSON response and parsing it into a `dict` stored in the variable `book` 3. Creating a string `msg` that contains a the text of our response, and then… 4. Returning an HTTP response with `msg` as the body Before testing, we need to make one important change in the `spin.toml` file. We need to let Spin know that it is okay for our Python frontend to access the Javascript backend. By default, Spin apps are not allowed to make arbitrary outbound network connections. This is part of the security sandbox. But a small amount of configuration let’s us OK the REST API. Here’s what our `allowed_outbound_hosts` looks like in the `spin.toml` configuration for our `frontend` component: [component.frontend] source = "frontend/app.wasm" # Added this line to allow network connection to JS component allowed_outbound_hosts = ["http://localhost:3000"] [component.frontend.build] command = "componentize-py -w spin-http componentize app -o app.wasm" workdir = "frontend" watch = ["*.py", "requirements.txt"] With both the code and configuration changed, we can use `spin build --up` to compile and test our entire app. And then we can use a web browser or client like `curl` to see the result: $ curl localhost:3000/ Today's book is _The Little Drummer Girl_ by John Le Carré At this point, what we have is a REST API listening at `localhost:3000/api` and a frontend listening at `localhost:3000/`. And what is happening behind the scenes is that our Python code is making a network request to our Javascript service. Our code above is making a network connection, using the `localhost` loopback interface, to access the REST API we wrote in the previous section. Phrasing this the long way, when a request comes in to the Python handler, Spin executes the Python code. Then when the Python `send` function is executed, Spin creates a new network connection from the Python code to the Javascript code and sends the request over that network connection. And that causes Spin to then execute the Javascript code. This is the way normal REST APIs work, and there is certainly nothing wrong with it. But with a few minor changes, we can get rid of the network request and all of the overhead that entails and call directly from the Python code to the Javascript code in a way that still feels like a REST-style request. ## Dropping Network Overhead with Local Service Chaining In Spin apps, local service _chaining_ allows you to call from one component to another without traversing the network (even on a loopback). Furthermore, it provides a way for us to optionally say, “This Javascript service can _only_ be accessed by other parts of the app, and is not publicly available.” FIrst, let’s do one quick pass over the Python code and configuration to avoid hard-coding the URL to the Javascript component: import json from spin_sdk.http import IncomingHandler, Request, Response, send # Allows us to load the service URL from config, instead of hard-coding from spin_sdk import variables class IncomingHandler(IncomingHandler): def handle_request(self, request: Request) -> Response: # Get the URL from config url = variables.get("book_api_url") # Get the book of the day from JS: resp = send(Request("GET", url, {}, None)) book = json.loads(resp.body.decode("utf-8")) msg = f"Today's book is _{book['title']}_ by {book['author']}" return Response(200, {"content-type": "text/plain"}, bytes(msg, "utf-8")) In the code above, we replaced the hard-coded URL with one fetched from an application variable. We imported the `variables` object from `spin_sdk` and then used it to get an application variables called `"book_api_url"`. Now we just need to update the `spin.toml` with that variable. Here’s the relevant section of the `spin.toml` file: [component.frontend] allowed_outbound_hosts = ["http://localhost:3000"] source = "frontend/app.wasm" # Declare application-specific variables [component.frontend.variables] book_api_url = "http://localhost:3000/api" [component.frontend.build] command = "componentize-py -w spin-http componentize app -o app.wasm" workdir = "frontend" watch = ["*.py", "requirements.txt"] As before, we’re pointing to `http://localhost:3000/api` as the endpoint for the Javascript REST API. If we rebuild and restart the app (using `spin build --up`) then we will see exactly the same behavior as last time. But now let’s switch to using local service chaining and, in so doing, get rid of the needless overhead of opening a network connection between the Python component and the Javascript component. # Declare application-specific variables [component.frontend.variables] book_api_url = "http://book-api.spin.internal/api" Now we are pointing to a special `spin.internal` URL. When Spin sees a request to something inside of `spin.internal`, it will look for a component that has a matching name, and invoke that directly instead of creating a socket connection. Recalling our earlier configuration, we named the Javascript service `book-api`. So the above URL informs Spin to direct the request directly to the Javascript service. Spin executes that component in place (again, without routing it down to the networking layer and opening a socket). From the developer perspective, it looks and feels exactly like working with any REST service, but it is much faster to execute and avoids a needless HTTP transaction. In local testing, I was able to get a 10% performance boost when switching to service chaining. ### Making the REST service private We can add one more bit of configuration and improve our security. If we don’t want the Javascript service to be accessible by anything other than our app, we can annotate its configuration to tell Spin to only expose it using local service chain. [[trigger.http]] # Old config: Public route # route = "/api" # New config: Make the route private route = { private = true } component = "book-api" Before, if I used `curl` to access `http://localhost:3000/api`, I would get something like this: $ curl localhost:3000/api {"title":"The Little Drummer Girl","author":"John Le Carré"} But now, because we have made that route private, we will instead get a `404 Not Found` error: $ curl -v localhost:3000/api * Host localhost:3000 was resolved. * IPv6: ::1 * IPv4: 127.0.0.1 * Trying [::1]:3000... * connect to ::1 port 3000 from ::1 port 57309 failed: Connection refused * Trying 127.0.0.1:3000... * Connected to localhost (127.0.0.1) port 3000 > GET /api HTTP/1.1 > Host: localhost:3000 > User-Agent: curl/8.7.1 > Accept: */* > * Request completely sent off < HTTP/1.1 404 Not Found < content-length: 0 < date: Tue, 28 Jan 2025 18:40:52 GMT < * Connection #0 to host localhost left intact Note that we don’t even have to recompile the code for this change to take effect. It’s merely a matter of restarting the service with the updated config. ## When Is This Useful? In many ways, using local service chaining is great simply for the security and performance benefits. You can write Spin apps using a microservice-style design pattern, but without needing to deal with pointless network overhead or adding authentication to microservices that are internal-only. But this idea is even more powerful when combined withe SpinKube’s ability to do Selective Deployments. With Selective Deployments, you can deploy some parts of your app to one deployment, and the other parts of the app to another deployment. That is, in our example above, you could choose to run the whole thing as one deployment, or you could (through configuration) run the Javascript REST API as one deployment and the Python frontend as another. In Kubernetes, that makes those two things independently routable, scalable, and configurable. All of this is enabled by the WebAssembly Component Model, a powerful abstraction that allows different WebAssembly binaries (in this case, the JS app and the Python app) to communicate with each other. Spin 3 provides other interesting ways to compose components. Even while these possibilities are exciting, in my view the performance and security improvements we saw here in this post are a good reason to build apps with local service chaining.
0 0 0 0
Introduction to SpinKube | Conf42 SpinKube streamlines developing, deploying and operating Spin WebAssembly applications in Kubernetes, resulting in delivering smaller, and more portable applications. The session will also introduce y...

Mark your calendars for Conf42's CloudNative 2025. I've just submitted an "Introduction to SpinKube" video. Hope you'll enjoy it! #wasm #spin #spinframework #spinkube @spinkube.bsky.social www.conf42.com/Cloud_Native...

2 1 0 0
Preview
Deploying Distributed Apps (Spin + Dapr) on SpinKube (AKS) Introduction In the last part, we walk through the journey of how to build and run Spin...

Deploying Distributed Apps (Spin + Dapr) on SpinKube (AKS) #spin #spinkube #aks #dapr /cc @technosophos.bsky.social @daprdev.bsky.social @fermyon.com

Check it out: dev.to/thangchung/d...

5 2 1 0
Post image

Excited to be speaking at #ArgoCon EU with @radu-matei.com , 1 Apr in London! Check out our session, "Continuous Delivery & Resource Health for SpinKube/WASM Applications With ArgoCD", details sched.co/1u5e1. 🗓️ Register today. Learn more: bit.ly/3S7Bn5T

#kubecon #kubeconeu #wasm #spinkube

2 1 0 1

Hope also to get a lot of news on #spinkube from #fermyon in the domain of #serverless

1 0 0 0
Preview
Deploy SpinKube to Azure Kubernetes Service (AKS) to run serverless WebAssembly (Wasm) workloads - Azure Kubernetes Service Learn how to deploy the open-source stack SpinKube to Azure Kubernetes Service (AKS) to run serverless WebAssembly (Wasm) workload on Kubernetes.

The documentation to try out #spinkube in #AKS is here: learn.microsoft.com/en-us/azure/...

3 3 0 0
Inside KubeCon: Interview With Tim Enwall
Inside KubeCon: Interview With Tim Enwall YouTube video by DevOps in Agile way

I have a few videos to announce :) Next interview from KubeCon! This time I chat with Tim Enwall from Fermyon Technologies about SpinKube. Enjoy!

www.youtube.com/watch?v=ZC9s...

#kubecon #cncf #devops #spinkube #fermyontechnologies

0 0 0 0
Post image

Yesterday, I joined Saim and Richard on the Cloud Native Podcast live from the @fermyon.com at KubeCon to talk about all the things #Wasm #Spin and #SpinKube

www.youtube.com/live/ZYyB2x5...

5 1 0 0
SpinKube Hyper-efficient serverless on Kubernetes, powered by WebAssembly. Get Started SpinKube is an open source project that streamlines developing, deploying and operating WebAssembly workloads in Kubernete...

In other #webassembly component news, #azure Kubernetes Service now has a new topic for installing and using #spinkube: learn.microsoft.com/en-us/azure/.... If you want start using www.spinkube.dev in AKS, this is a great place to start.

4 1 0 0
Preview
WebAssembly Jobs and CronJobs in Kubernetes with SpinKube & the Spin Command Trigger Learn how to run WebAssembly apps as Kubernetes Jobs and CronJobs using Spin Command Trigger and SpinKube

Check out my most recent article!

💡 Learn how to build Kubernetes Jobs and CronJobs with #WebAssembly #Spin & #SpinKube

www.fermyon.com/blog/wasm-jo...

3 2 0 0
Post image Post image

#NDCPorto was a blast.

Such a great venue! It was a honor to deliver two talks focusing #Wasm #Spin #SpinKube and #Aspire

4 1 0 0