您的位置:  首页 > 技术杂谈 > 正文

使用 OpenYurt 管理 WasmEdge | 轻量级边缘计算方案

2022-02-16 19:04 https://my.oschina.net/u/4532842/blog/5448960 WasmEdge 次阅读 条评论

晋晨(OpenYurt)、Vivian Hu(WasmEdge)

边缘计算 是一种分布式应用架构,将计算资源(例如 CPU 和存储)放置在靠近数据源的位置。通过这种方式,为各种应用程序提供了低延迟、高性能和强大的安全性。

然而,与数据中心的云计算类似,边缘计算也面临着跨异构设备和网络的工作负载分发、管理和编排等挑战。为了应对以上云计算中的这些挑战,很多开发者会选择基于容器的解决方案。因此,开发者们现在正在将 Kubernetes (K8s) 和容器等解决方案引入边缘计算。然而遗憾的是,K8s 和 Linux 容器都不是为边缘计算而设计的。

边缘上标准 K8s 的潜在问题包括:

  • 边缘设备的计算、存储和网络资源有限。在边缘设备上运行完整的 K8s 节点通常过于耗费资源。
  • K8s 只能管理具有公共 IP 地址的设备。然而,许多边缘设备不会暴露其公共 IP。
  • 边缘设备经常离线,而标准的 K8s 要求其 pod 始终处于连接状态。
  • 边缘设备通常通过非 TCP 网络连接,并且需要专门的网络接口与它们的 K8s 管理器进行通信。

因此,开发者为边缘计算创建了专门的 Kubernetes 发行版本。一个领先的为边缘优化的 K8s 发行版本是 OpenYurt。OpenYurt 最初由阿里巴巴创建,现在是 CNCF 的沙箱项目。OpenYurt 是一个开放平台,囊括了上游 Kubernetes 强大的编排能力。因此,用户可以使用相同的上游 Kubernetes API 交付、管理和监控边缘工作负载。

即便使用像 OpenYurt 这样的为边缘优化了的 K8s 发行版,标准 Linux 容器仍然过于笨重,无法在小型设备上运行边缘工作负载。一个典型的 Linux 容器镜像占用的空间通常以 GB 为单位,并且启动一个完整的 CPU 需要几秒钟。考虑到典型的边缘应用程序通常较精简,Linux 容器在资源受限的设备上占用了过多的存储、CPU 和电池资源。此外,Linux 容器应用程序在边缘设备上不可跨平台,且不安全。

对于边缘容器化应用程序而言,符合 OCI 标准的,且兼容 k8s 的轻量级 WebAssembly runtime, 比如 WasmEdge相较于 Linux 容器是更好的替代选项。 WasmEdge 提供基于能力的安全沙箱,对底层操作系统服务做很少的假设,同时在前端支持多种编程语言。 除了 Linux、 macOS、 Windows, WasmEdge 甚至可以在实时操作系统(RTOS)上运行,像 Linux 基金会的 seL4

OpenYurtWasmEdge 团队一起展示如何使用 OpenYurt 在一个边缘集群中管理 WasmEdge 应用。 OpenYurt 和 WasmEdge 将终于把云原生的容器化的应用带入边缘计算了!让我们开始吧!

准备工作

OpenYurt 使用中心化 Kubernetes 控制面板来管理云服务器中的多个边缘节点。 此外,它将上游 Kubernetes 扩展到边缘。 在这个演示中,我们将设置两台机器。 一个模拟的云节点称为 Master,另一个模拟的边缘节点称为 Node。 这两个节点构成了最简单的 OpenYurt 集群,OpenYurt 组件在其中运行。

首先,关闭 swap 分区

sudo swapoff -a      
free -m    //验证

接下来,配置两个节点的文件 node/etc/hosts

然后,加载内核模块 br_netfilter,并调整内核参数。

//load the module
sudo modprobe br_netfilter
//verify   
lsmod | grep br_netfilter
// create k8s.conf
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system 

最后,设置 rp-filter 值,将文件 /etc/sysctl.d/10-network-security.conf 中两个参数的值由 2 改为 1,且将 /proc/sys/net/ipv4/ip_forward 设置为 1。

sudo vi /etc/sysctl.d/10-network-security.confecho 1 > 
/proc/sys/net/ipv4/ip_forward
sudo sysctl --system

安装 Containerd

使用下面命令行在边缘节点上安装 containerd 。

export VERSION="1.5.7"
echo -e "Version: $VERSION"
echo -e "Installing libseccomp2 ..."
sudo apt install -y libseccomp2
echo -e "Installing wget"
sudo apt install -y wget

wget https://github.com/containerd/containerd/releases/download/v${VERSION}/cri-containerd-cni-${VERSION}-linux-amd64.tar.gz
wget https://github.com/containerd/containerd/releases/download/v${VERSION}/cri-containerd-cni-${VERSION}-linux-amd64.tar.gz.sha256sum sha256sum --check cri-containerd-cni-${VERSION}-linux-amd64.tar.gz.sha256sum

sudo tar --no-overwrite-dir -C / -xzf cri-containerd-cni-${VERSION}-linux-amd64.tar.gz
sudo systemctl daemon-reload

由于 crun 项目默认支持 WasmEdge,我们只需要为 runc 配置 containerd 配置即可。 所以我们需要修改 /etc/containerd/config.toml 中的 runc 参数为 curn,添加 pod_annotation

sudo mkdir -p /etc/containerd/
sudo bash -c "containerd config default > /etc/containerd/config.toml"
wget https://raw.githubusercontent.com/second-state/wasmedge-containers-examples/main/containerd/containerd_config.diff
sudo patch -d/ -p0 < containerd_config.diff

之后,重启 containerd 使配置生效。

systemctl start containerd

安装 WasmEdge

使用下面的安装脚本,在 edge 节点上安装 WasmEdge。

curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | bash

安装并构建 crun

我们需要在 edge node 上构建一个支持 WasmEdge 的 crun 二进制文件。目前,最直接的方法是你自己从源代码开始构建 crun。首先请确保你在 Ubuntu 20.04 已经安装了 crun 的依赖项。如果你使用的是其他版本的 Linux,请参考官方文档

sudo apt update
sudo apt install -y make git gcc build-essential pkgconf libtool \
    libsystemd-dev libprotobuf-c-dev libcap-dev libseccomp-dev libyajl-dev \
    go-md2man libtool autoconf python3 automake

接下来,配置、构建、安装带有 WasmEdge 支持的 crun 二进制文件

sudo make install
git clone https://github.com/containers/crun
cd crun
./autogen.sh
./configure —with-wasmedge
make
sudo make install

安装 OpenYurt

现在,我们可以在 Edge 节点上安装 OpenYurt 来控制它下面的 containerd、crun 和 wasmedge 堆栈。

构建 OpenYrut 集群最简单的方法是使用 OpenYurt 体验中心。 你只需注册一个用于测试的帐户,然后就可以获得一个 OpenYurt 集群。 接下来,你可以使用 yurtctl join 命令行来加入边缘节点。 在此处查看更多详细信息。 目前,OpenYurt 体验中心提供的 OpenYurt 组件版本为 0.6.0(最新版),Kubernetes 版本为 1.20.11。

或者,你也可以根据下面的指南,从头开始构建 OpenYurt 集群。

设置一个 K8s 集群

这里我们使用 yurtctl convert 将 K8s 集群转换为 OpenYurt 集群,所以我们需要先搭建一个 K8s 集群。 需要注意的一点,如果你使用 yurtctl init/join 来设置OpenYurt 集群并加入节点,你可以跳过这一步。

$ sudo apt-get update && sudo apt-get install -y ca-certificates curl software-properties-common apt-transport-https
// add K8s source
$ curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
$ sudo tee /etc/apt/sources.list.d/kubernetes.list <<EOF
$ deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
// install K8s components 1.18.9
$ sudo apt-get update && sudo apt-get install -y kubelet=1.18.9-00 kubeadm=1.18.9-00 kubectl=1.18.9-00 
// Initialize the master node
$ sudo kubeadm init --pod-network-cidr 172.16.0.0/16 \
--apiserver-advertise-address=192.168.3.167 \
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers
// join the work node
$ kubeadm join 192.168.3.167:6443 --token 3zefbt.99e6denc1cxpk9fg \
   --discovery-token-ca-cert-hash sha256:8077d4e7dd6eee64a999d56866ae4336073ed5ffc3f23281d757276b08b9b195

安装 yurtctl 工具

使用以下命令行安装 yurtctl 。 yurtcli CLI 工具可以安装/卸载 OpenYurt 并将标准 Kubernetes 集群转换为 OpenYurt 集群。

git clone https://github.com/openyurtio/openyurt.git
cd openyurt
make build WHAT=cmd/yurtctl

安装 OpenYurt 各组件

yurtctl convert --deploy-yurttunnel --cloud-nodes oy-master --provider kubeadm\
 --yurt-controller-manager-image="openyurt/yurt-controller-manager:v0.5.0"\
 --yurt-tunnel-agent-image="openyurt/yurt-tunnel-agent:v0.5.0"\
 --yurt-tunnel-server-image="openyurt/yurt-tunnel-server:v0.5.0"\
 --node-servant-image="openyurt/node-servant:latest"\
 --yurthub-image="openyurt/yurthub:v0.5.0"

注:需要将 -- yurtctl-servant-image="openyurt/yurtctl-servant:v0.5.0" 改成 --node-servant-image="openyurt/node-servant:latest"

运行一个简单的 WebAssembly app

接下来,让我们通过 Kubernetes 集群作为 pod 中的容器运行 WebAssembly 程序。 本节将从 Docker hub 拉取基于 WebAssembly 的容器镜像开始。 如果你想知道如何编译、打包 WebAssembly 程序并将其作为容器镜像发布到 Docker hub,请参阅 WasmEdge Book

从 master 节点的另一个终端窗口输入以下命令,然后开始使用集群。

root@master:~# kubectl cluster-info
Kubernetes master is running at https://192.168.3.167:6443
KubeDNS is running at https://192.168.3.167:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

因为 kubectl 1.18.9 没有 annotations 参数,所以我们在这里需要调整命令行。 如果你使用的是 OpenYurt Experience Center,其默认版本为 OpenYurt 0.6.0 和 Kubernetes 1.20.11,请直接参阅 WasmEdge Book 中的 Kubernetes 部分来运行 wasm 应用程序。

// kubectl 1.18.9
$ sudo kubectl run -it --rm --restart=Never wasi-demo --image=hydai/wasm-wasi-example:with-wasm-annotation  --overrides='{"kind":"Pod","metadata":{"annotations":{"module.wasm.image/variant":"compat"}} , "apiVersion":"v1", "spec": {"hostNetwork": true}}' /wasi_example_main.wasm 50000000

// kubectl 1.20.11
$ sudo kubectl run -it --rm --restart=Never wasi-demo --image=hydai/wasm-wasi-example:with-wasm-annotation --annotations="module.wasm.image/variant=compat" --overrides='{"kind":"Pod", "apiVersion":"v1", "spec": {"hostNetwork": true}}' /wasi_example_main.wasm 50000000

容器化应用程序的输出被打印到控制台。 所有 Kubernetes 版本都是一样的。

Random number: 1123434661
Random bytes: [25, 169, 202, 211, 22, 29, 128, 133, 168, 185, 114, 161, 48, 154, 56, 54, 99, 5, 229, 161, 225, 47, 85, 133, 90, 61, 156, 86, 3, 14, 10, 69, 185, 225, 226, 181, 141, 67, 44, 121, 157, 98, 247, 148, 201, 248, 236, 190, 217, 245, 131, 68, 124, 28, 193, 143, 215, 32, 184, 50, 71, 92, 148, 35, 180, 112, 125, 12, 152, 111, 32, 30, 86, 15, 107, 225, 39, 30, 178, 215, 182, 113, 216, 137, 98, 189, 72, 68, 107, 246, 108, 210, 148, 191, 28, 40, 233, 200, 222, 132, 247, 207, 239, 32, 79, 238, 18, 62, 67, 114, 186, 6, 212, 215, 31, 13, 53, 138, 97, 169, 28, 183, 235, 221, 218, 81, 84, 235]
Printed from wasi: This is from a main function
This is from a main function
The env vars are as follows.
The args are as follows.
/wasi_example_main.wasm
50000000
File content is This is in a file
pod "wasi-demo" deleted

现在,你可以通过 Kubernetes 命令行查看 pod 状态。

crictl ps -a

你可以在日志中看到从调度到运行 WebAssembly 工作负载的事件。

CONTAINER           IMAGE               CREATED             STATE               
NAME                 ATTEMPT             POD ID
0c176ed65599a       0423b8eb71e31       8 seconds ago       Exited              wasi-demo    

这样完成了。接下来,你可以尝试使用 OpenYurt 管理自己的 WasmEdge 应用

未来可期

WasmEdgeOpenYurt 共同将 Kubernetes 的全部优势引入到了边缘计算。 以上的 demo 演示了一个非常简单的使用场景,只是触及了其中巨大潜力和前景的一角。 请在 GitHub 上关注这两个项目,以了解我们合作的最新信息。同时,如果你有从此技术路径中受益的应用,我们也很乐意聆听!

展开阅读全文
  • 0
    感动
  • 0
    路过
  • 0
    高兴
  • 0
    难过
  • 0
    搞笑
  • 0
    无聊
  • 0
    愤怒
  • 0
    同情
热度排行
友情链接