其他
“网红” WebAssembly 与 K8s 如何实现双剑合璧?
The following article is from 阿里巴巴云原生 Author 易立
导读:WebAssembly 技术已经走出浏览器,让计算无处不在。本文利用 containerd 的扩展机制,可以为 WebAssembly 应用提供与其他容器应用一致的、抽象的、应用分发、交付和运维模型,可以在 Kubernetes 集群中进行统一调度和管理。
无处不在的 WebAssembly
在 2019 年 12 月,万维网联盟 (World Wide Web Consortium - W3C) 宣布, 这使得 WebAssembly 成为互联网上与 HTML, CSS, and JavaScript 并列的第四种官方语言,可以原生的运行在浏览器上。
WASM 与容器相爱相杀
1. WebAssembly 是否会取代容器?
2. WebAssembly 容器
应用分发
WebAssembly 开发者可以完全复用 Docker/OCI 镜像规范和工具链,进一步简化应用分发和交付。比如,我们可以将 Nginx 的 WASM 镜像作为基础镜像,基于这个镜像可以构建包含不同 Web 内容的应用镜像;我们可以利用 tag 对应用版本进行追踪;利用 Docker Registry 进行应用分发;在这个过程我们还可以进一步利用数字签名来保障安全的软件供应链;
Docker 镜像规范支持 镜像,可以简化不同 CPU 体系架构(如 x86, ARM, RISC-V 等)的应用镜像的构建与分发。而 WebAssembly 天生具备可移植性,大大简化了跨平台 Docker 应用镜像的构建和分发。参考:。
$ sudo ctr image ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
docker.io/denverdino/c-http-server-wasm:latest application/vnd.docker.distribution.manifest.v2+json sha256:2efa759f46f901cda2e6a9b4228c423b17a960c06e957964e72c21dc5b42408f 29.2 KiB linux/amd64 -
docker.io/denverdino/hellowasm:latest application/vnd.docker.distribution.manifest.v2+json sha256:cadcc8b07eb82b18db2c8f500fa2b11e5ebf2e9054cfa687e4ffe44861860132 8.2 KiB linux/amd64 -
docker.io/denverdino/nginxwasm:latest application/vnd.docker.distribution.manifest.v2+json sha256:8735c82524a463b842b7c79f2c1be8094ee1c57cfd34154f68752fbe79c25998 582.7 KiB linux/amd64 -
安全隔离
资源隔离
网络安全
共享进程资源 - 多个 WASM 应用模块运行在一个 WASM 虚拟机进程内部,依赖 WASM 运行时进行隔离。隔离级别低,控制粒度比较粗,资源开销极小。可以以较小代价保障系统安全。适合受限问题域的应用安全隔离;
独立进程资源 - 不同 WASM 应用模块运行在不同的 WASM 虚拟机进程中,可以复用操作系统的进程级隔离能力,比如 CGroup。此外,还可以利用类似 Kubernetes 中的 Network Policy (网络策略),或者服务网格(如Istio)等技术,对进程的网络访问进行细粒度的控制,甚至实现零信任网络。隔离级别比较高,控制粒度比较细,资源开销适中。可以应用于更加通用的场景。
调度与编排
Talk is Cheap, 放码过来
1. 创建虚拟机测试环境
minikube start --image-mirror-country cn \
--iso-url=https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.6.0.iso \
--registry-mirror=https://tgtsuwdg.mirror.aliyuncs.com \
--container-runtime=containerd
$ minikube ssh
_ _
_ _ ( ) ( )
___ ___ (_) ___ (_)| |/') _ _ | |_ __
/' _ ` _ `\| |/' _ `\| || , < ( ) ( )| '_`\ /'__`\
| ( ) ( ) || || ( ) || || |\`\ | (_) || |_) )( ___/
(_) (_) (_)(_)(_) (_)(_)(_) (_)`\___/'(_,__/'`\____)
wasmer 0.13; minikube 缺省安装了 container 1.2.x,需要升级 containerd 1.3.x; 我提供了一个预编译的 containerd-wasm-shim-v1,也可自己编译一个版本。
cd ~
# Install Wasmer 0.13.1
curl -L -O https://github.com/wasmerio/wasmer/releases/download/0.13.1/wasmer-linux-amd64.tar.gz
gunzip wasmer-linux-amd64.tar.gz
tar xvf wasmer-linux-amd64.tar
sudo cp bin/* /usr/bin/
# Upgrade containerd to v1.3.2
curl -L -O https://github.com/containerd/containerd/releases/download/v1.3.2/containerd-1.3.2.linux-amd64.tar.gz
gunzip containerd-1.3.2.linux-amd64.tar.gz
tar xvf containerd-1.3.2.linux-amd64.tar
sudo systemctl stop containerd
sudo cp bin/* /usr/bin/
sudo systemctl restart containerd
# Install containerd-wasm-shim
wget http://kubernetes.oss-cn-hangzhou.aliyuncs.com/containerd-wasm/containerd-shim-wasm-v1
chmod +x containerd-shim-wasm-v1
sudo mv containerd-shim-wasm-v1 /usr/bin/
2. 配置 containerd 支持 WASM shim
$ cat <<EOF | sudo tee -a /etc/containerd/config.toml
disabled_plugins = ["restart"]
[plugins.cri.containerd.runtimes.wasm]
runtime_type = "io.containerd.wasm.v1"
EOF
$ sudo systemctl restart containerd
$ sudo ctr image pull docker.io/denverdino/hellowasm:latest
docker.io/denverdino/hellowasm:latest: resolved |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:cadcc8b07eb82b18db2c8f500fa2b11e5ebf2e9054cfa687e4ffe44861860132: done |++++++++++++++++++++++++++++++++++++++|
layer-sha256:ecda28441283ecf01d35bca0361f2c1ef26a203454a06789ee5ce71ba1e32ca3: done |++++++++++++++++++++++++++++++++++++++|
config-sha256:57974480d640c8d60d254a8b0fa4606b2c7107fe169bc3ddd455091277c3a5e4: done |++++++++++++++++++++++++++++++++++++++|
elapsed: 3.0 s total: 0.0 B (0.0 B/s)
unpacking linux/amd64 sha256:cadcc8b07eb82b18db2c8f500fa2b11e5ebf2e9054cfa687e4ffe44861860132...
done
$ sudo ctr run --rm --runtime io.containerd.wasm.v1 docker.io/denverdino/hellowasm:latest test1
Hello world
$ sudo ctr image pull docker.io/denverdino/nginxwasm:latest
docker.io/denverdino/nginxwasm:latest: resolved |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:8735c82524a463b842b7c79f2c1be8094ee1c57cfd34154f68752fbe79c25998: exists |++++++++++++++++++++++++++++++++++++++|
layer-sha256:27f4d8ad067fbb709d18ea5acd7a5ddfb85851e5d9f030636e9da3d16cc4bd07: done |++++++++++++++++++++++++++++++++++++++|
config-sha256:a55bd3bdb9d00fdac5ee2f64bfc1856e58e8bb90587943969ad3d8115f4ced70: done |++++++++++++++++++++++++++++++++++++++|
elapsed: 3.0 s total: 0.0 B (0.0 B/s)
unpacking linux/amd64 sha256:8735c82524a463b842b7c79f2c1be8094ee1c57cfd34154f68752fbe79c25998...
done
$ sudo ctr run --rm --runtime io.containerd.wasm.v1 docker.io/denverdino/nginxwasm:latest test2
2020/02/01 07:01:21 [notice] 30672#0: using the "select" event method
2020/02/01 07:01:21 [notice] 30672#0: nginx/1.15.3
2020/02/01 07:01:21 [notice] 30672#0: built by clang 6.0.1 (emscripten 1.38.11 : 1.38.11)
2020/02/01 07:01:21 [notice] 30672#0: OS: Linux 4.19.81
2020/02/01 07:01:21 [notice] 30672#0: getrlimit(RLIMIT_NOFILE): 1024:1024
$ echo http://$(minikube ip):8080
http://192.168.64.13:8080
3. 创建 WASM 容器的 RuntimeClass CRD
$ git clone https://github.com/denverdino/wasm-container-samples
$ cd wasm-container-samples
$ cat wasm-runtimeclass.yaml
apiVersion: node.k8s.io/v1beta1
kind: RuntimeClass
metadata:
name: wasm
handler: wasm
$ kubectl apply -f wasm-runtimeclass.yaml
runtimeclass.node.k8s.io/wasm created
$ kubectl get runtimeclass
kubectl get runtimeclass
NAME CREATED AT
wasm 2020-02-01T06:24:12Z
4. 在 K8s 中运行 WASM 容器应用
$ cat nginx-wasm.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-wasm
spec:
runtimeClassName: wasm
containers:
- name: nginx
image: denverdino/nginxwasm
ports:
- containerPort: 8080
$ kubectl apply -f nginx-wasm.yaml
pod/nginx-wasm created
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-wasm 1/1 Running 0 9s
新机遇、新希望