1"use strict";(self.webpackChunkbook=self.webpackChunkbook||[]).push([[3414],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>h});var n=a(67294);function s(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function l(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?r(Object(a),!0).forEach((function(t){s(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):r(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function i(e,t){if(null==e)return{};var a,n,s=function(e,t){if(null==e)return{};var a,n,s={},r=Object.keys(e);for(n=0;n<r.length;n++)a=r[n],t.indexOf(a)>=0||(s[a]=e[a]);return s}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n<r.length;n++)a=r[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(s[a]=e[a])}return s}var o=n.createContext({}),p=function(e){var t=n.useContext(o),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},d=function(e){var t=p(e.components);return n.createElement(o.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,s=e.mdxType,r=e.originalType,o=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=p(a),c=s,h=u["".concat(o,".").concat(c)]||u[c]||m[c]||r;return a?n.createElement(h,l(l({ref:t},d),{},{components:a})):n.createElement(h,l({ref:t},d))}));function h(e,t){var a=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var r=a.length,l=new Array(r);l[0]=c;var i={};for(var o in t)hasOwnProperty.call(t,o)&&(i[o]=t[o]);i.originalType=e,i[u]="string"==typeof e?e:s,l[1]=i;for(var p=2;p<r;p++)l[p]=a[p];return n.createElement.apply(null,l)}return n.createElement.apply(null,a)}c.displayName="MDXCreateElement"},68820:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>o,contentTitle:()=>l,default:()=>m,frontMatter:()=>r,metadata:()=>i,toc:()=>p});var n=a(87462),s=(a(67294),a(3905));const r={sidebar_position:12},l="K3s",i={unversionedId:"develop/deploy/kubernetes/k3s",id:"develop/deploy/kubernetes/k3s",title:"K3s",description:"K3s is a lightweight, certified Kubernetes distribution designed for resource-constrained environments such as edge, IoT, and CI/CD. It bundles containerd as the default container runtime and can automatically detect WebAssembly runtimes like WasmEdge.",source:"@site/docs/develop/deploy/kubernetes/k3s.md",sourceDirName:"develop/deploy/kubernetes",slug:"/develop/deploy/kubernetes/k3s",permalink:"/docs/develop/deploy/kubernetes/k3s",draft:!1,editUrl:"https://github.com/wasmedge/docs/blob/main/docs/develop/deploy/kubernetes/k3s.md",tags:[],version:"current",sidebarPosition:12,frontMatter:{sidebar_position:12},sidebar:"developSidebar",previous:{title:"WasmEdge DockerSlim",permalink:"/docs/develop/deploy/kubernetes/docker-slim"}},o={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install WasmEdge",id:"install-wasmedge",level:2},{value:"Install the containerd-shim-wasmedge",id:"install-the-containerd-shim-wasmedge",level:2},{value:"Option A: Pre-built binary",id:"option-a-pre-built-binary",level:3},{value:"Option B: Build from source",id:"option-b-build-from-source",level:3},{value:"Install and start K3s",id:"install-and-start-k3s",level:2},{value:"Run a simple WebAssembly app",id:"run-a-simple-webassembly-app",level:2},{value:"Run a WebAssembly-based HTTP service",id:"run-a-webassembly-based-http-service",level:2}],d={toc:p},u="wrapper";
1function m(e){let{components:t,...a}=e;return(0,s.kt)(u,(0,n.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"k3s"},"K3s"),(0,s.kt)("p",null,(0,s.kt)("a",{parentName:"p",href:"https://k3s.io/"},"K3s")," is a lightweight, certified Kubernetes distribution designed for resource-constrained environments such as edge, IoT, and CI/CD. It bundles containerd as the default container runtime and can automatically detect WebAssembly runtimes like WasmEdge."),(0,s.kt)("admonition",{type:"note"},(0,s.kt)("p",{parentName:"admonition"},"This guide is based on containerd + runwasi (containerd-shim-wasmedge).")),(0,s.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"A Linux machine (x86_64 or aarch64) with systemd"),(0,s.kt)("li",{parentName:"ul"},"Root or sudo access")),(0,s.kt)("h2",{id:"install-wasmedge"},"Install WasmEdge"),(0,s.kt)("p",null,"Use the ",(0,s.kt)("a",{parentName:"p",href:"/docs/start/install"},"simple install script")," to install WasmEdge on your node."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | bash\n")),(0,s.kt)("h2",{id:"install-the-containerd-shim-wasmedge"},"Install the containerd-shim-wasmedge"),(0,s.kt)("p",null,"K3s looks for the ",(0,s.kt)("inlineCode",{parentName:"p"},"containerd-shim-wasmedge-v1")," binary in the system PATH. You can install it from a pre-built release binary or build it from source."),(0,s.kt)("h3",{id:"option-a-pre-built-binary"},"Option A: Pre-built binary"),(0,s.kt)("p",null,"Download the latest release from the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/containerd/runwasi/releases"},"runwasi releases page")," and install it."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"# Detect architecture and download the appropriate binary\nARCH=$(uname -m) # x86_64 or aarch64\nwget https://github.com/containerd/runwasi/releases/download/containerd-shim-wasmedge%2Fv0.6.0/containerd-shim-wasmedge-${ARCH}-linux-musl.tar.gz\ntar xzf containerd-shim-wasmedge-${ARCH}-linux-musl.tar.gz\nsudo install -m 755 containerd-shim-wasmedge-v1 /usr/local/bin/\n")),(0,s.kt)("h3",{id:"option-b-build-from-source"},"Option B: Build from source"),(0,s.kt)("p",null,"Make sure you have ",(0,s.kt)("a",{parentName:"p",href:"https://www.rust-lang.org/tools/install"},"Rust")," installed, then build the shim from the ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/containerd/runwasi"},"runwasi")," project."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'git clone https://github.com/containerd/runwasi.git\ncd runwasi\n./scripts/setup-linux.sh\nmake build-wasmedge\nINSTALL="sudo install" LN="sudo ln -sf" make install-wasmedge\n')),(0,s.kt)("h2",{id:"install-and-start-k3s"},"Install and start K3s"),(0,s.kt)("p",null,"Install K3s after the shim binary is in place, so that K3s can detect the WasmEdge runtime at startup."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"curl -sfL https://get.k3s.io | sh -\n")),(0,s.kt)("p",null,"K3s will automatically detect ",(0,s.kt)("inlineCode",{parentName:"p"},"containerd-shim-wasmedge-v1")," in the system PATH and create a corresponding Kubernetes ",(0,s.kt)("inlineCode",{parentName:"p"},"RuntimeClass")," named ",(0,s.kt)("inlineCode",{parentName:"p"},"wasmedge"),"."),(0,s.kt)("p",null,"Verify that K3s is running and the RuntimeClass exists:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"sudo kubectl get nodes\nsudo kubectl get runtimeclass\n")),(0,s.kt)("p",null,"Expected output:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"$ sudo kubectl get nodes\nNAME STATUS ROLES AGE VERSION\nubuntu Ready control-plane 45s v1.34.6+k3s1\n\n$ sudo kubectl get runtimeclass\nNAME HANDLER AGE\ncrun crun 45s\nlunatic lunatic 45s\nnvidia nvidia 45s\nnvidia-experimental nvidia-experimental 45s\nslight slight 45s\nspin spin 45s\nwasmedge wasmedge 45s\nwasmer wasmer 45s\nwasmtime wasmtime 45s\nwws wws 45s\n")),(0,s.kt)("p",null,"Make sure ",(0,s.kt)("inlineCode",{parentName:"p"},"wasmedge")," is in the list."),(0,s.kt)("admonition",{type:"note"},(0,s.kt)("p",{parentName:"admonition"},"If the ",(0,s.kt)("inlineCode",{parentName:"p"},"wasmedge")," RuntimeClass does not appear, make sure the ",(0,s.kt)("inlineCode",{parentName:"p"},"containerd-shim-wasmedge-v1")," binary is in a directory listed in the K3s service's PATH (e.g., ",(0,s.kt)("inlineCode",{parentName:"p"},"/usr/local/bin"),"), then restart K3s with ",(0,s.kt)("inlineCode",{parentName:"p"},"sudo systemctl restart k3s"),".")),(0,s.kt)("h2",{id:"run-a-simple-webassembly-app"},"Run a simple WebAssembly app"),(0,s.kt)("p",null,(0,s.kt)("a",{parentName:"p",href:"https://github.com/second-state/wasmedge-containers-examples/blob/main/simple_wasi_app.md"},"A separate article")," explains how to compile, package, and publish a simple WebAssembly WASI program as a container image to Docker Hub. Run the WebAssembly-based image from Docker Hub in the K3s cluster as follows."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'sudo kubectl run --restart=Never wasi-demo \\\n --image=wasmedge/example-wasi:latest \\\n --overrides=\'{"kind":"Pod","apiVersion":"v1","spec":{"runtimeClassName":"wasmedge"}}\' \\\n -- /wasi_example_main.wasm 50000000\n')),(0,s.kt)("p",null,"Check the pod status and view the output:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"sudo kubectl get pod wasi-demo\nsudo kubectl logs wasi-demo\n")),(0,s.kt)("p",null,"The output from the containerized application is printed into the console."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"$ sudo kubectl get pod wasi-demo\nNAME READY STATUS RESTARTS AGE\nwasi-demo 0/1 Completed 0 7s\n\n$ sudo kubectl logs wasi-demo\nRandom number: -817406905\nRandom bytes: [7, 7, 147, 202, 106, 102, 198, 6, 42, 39, 198, 92, 59, 247, 54, 99, 249, 117, 113,
1143, 240, 85, 226, 102, 44, 165, 66, 251, 220, 107, 106, 70, 168, 144, 114, 113, 77, 132, 114, 33, 155, 254, 169, 196, 218, 119, 171, 145, 106, 36, 205, 130, 43, 208, 152, 127, 60, 57, 26, 160, 178, 75, 3, 215, 98, 32, 223, 67, 176, 35, 182, 141, 2, 190, 15, 72, 167, 44, 46, 148, 240, 1, 110, 148, 19, 134, 182, 21, 127, 141, 106, 65, 27, 84, 121, 217, 171, 36, 88, 47, 197, 96, 193, 102, 143, 105, 67, 77, 40, 187, 40, 151, 60, 140, 238, 143, 8, 89, 129, 117, 103, 157, 102, 34, 65, 5, 195, 246]\nPrinted from wasi: This is from a main function\nThis is from a main function\nThe env vars are as follows.\nThe args are as follows.\n/wasi_example_main.wasm\n50000000\nFile content is This is in a file\n")),(0,s.kt)("p",null,"Clean up the pod after verifying:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"sudo kubectl delete pod wasi-demo\n")),(0,s.kt)("h2",{id:"run-a-webassembly-based-http-service"},"Run a WebAssembly-based HTTP service"),(0,s.kt)("p",null,(0,s.kt)("a",{parentName:"p",href:"https://github.com/second-state/wasmedge-containers-examples/blob/main/http_server_wasi_app.md"},"A separate article")," explains how to compile, package, and publish a simple WebAssembly HTTP service application as a container image to Docker Hub. Create a deployment using a YAML file:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: http-server\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: http-server\n template:\n metadata:\n labels:\n app: http-server\n spec:\n runtimeClassName: wasmedge\n containers:\n - name: http-server\n image: wasmedge/example-wasi-http:latest\n ports:\n - containerPort: 1234\n protocol: TCP\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: http-server\nspec:\n type: NodePort\n selector:\n app: http-server\n ports:\n - port: 1234\n targetPort: 1234\n")),(0,s.kt)("p",null,"Save the above as ",(0,s.kt)("inlineCode",{parentName:"p"},"k3s-http-server.yaml")," and apply it:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"sudo kubectl apply -f k3s-http-server.yaml\n")),(0,s.kt)("p",null,"Wait for the pod to be ready, then get the NodePort:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"sudo kubectl get svc http-server\n")),(0,s.kt)("p",null,"Access the HTTP service using the NodePort:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},'curl -d "name=WasmEdge" -X POST http://localhost:<NodePort>\necho: name=WasmEdge\n')),(0,s.kt)("p",null,"Clean up the deployment and service after verifying:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"sudo kubectl delete -f k3s-http-server.yaml\n")),(0,s.kt)("p",null,"That's it!"))}m.isMDXComponent=!0}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.