目录结构

1
2
3
4
5
6
7
8
9
10
root@k8s-master1:~/workerd# tree
.
├── Dockerfile
├── config.capnp
├── deployment.yaml
├── index.js
└── workerd # 可以在官方github开源地址下载编译好的版本,https://github.com/cloudflare/workerd

1 directory, 5 files
root@k8s-master1:~/workerd#

workerd 本质上是一个 js 代码运行环境,而且因为其无状态的特性,非常适合放到 k8s 里。

我去找过 Cloudflare workerd 开源项目主页和 docker hub 官方的仓库,没看到有构建好的 docker 镜像,遂只能自己写 Dockerfile 构建,也很简单。

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 选用轻量的 Debian 12 (bookworm) 镜像
FROM debian:bookworm-slim AS runtime

# 安装 TLS 根证书
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
tzdata \
&& rm -rf /var/lib/apt/lists/*

# 设置工作目录
WORKDIR /app

# 将 workerd 二进制文件和配置文件、代码复制进镜像
COPY workerd index.js config.capnp /app/

# 暴露 workerd 监听的端口(按 config.capnp 配置决定)
EXPOSE 8080

# 运行 workerd
ENTRYPOINT ["/app/workerd", "serve", "/app/config.capnp"]

workerd的配置文件config.capnp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using Workerd = import "/workerd/workerd.capnp";

const config :Workerd.Config = (
services = [
(name = "main", worker = .mainWorker),
],
sockets = [
( name = "http", address = "*:8080", http = (), service = "main" )
]
);

const mainWorker :Workerd.Worker = (
modules = [
(name = "index.js", esModule = embed "index.js")
],
compatibilityDate = "2024-01-01",
);
1
2
3
4
5
6
export default {
async fetch(request, env, ctx) {
return new Response("Hello from Cloudflare workerd on K8s! version:1.0.2\n");
}
};

k8s声明配置文件deployment.yaml,其中ingress也在里面定义了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
apiVersion: v1
kind: Namespace
metadata:
name: workerd
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: workerd-deployment
namespace: workerd
spec:
replicas: 10 # 副本数量
selector:
matchLabels:
app: workerd
template:
metadata:
labels:
app: workerd
spec:
containers:
- name: workerd
image: workerd:v1.0.2 # 镜像名字
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: workerd-ingress
namespace: workerd
annotations:
# 允许的跨域配置或请求头大小等可在此扩展
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
spec:
ingressClassName: nginx
rules:
- host: workerd.k8s.cn # 域名
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: workerd-service
port:
number: 8080
---
apiVersion: v1
kind: Service
metadata:
name: workerd-service
namespace: workerd
spec:
selector:
app: workerd
ports:
- name: http
port: 8080
targetPort: 8080

可执行程序 workerd 则可以在官方 github 开源地址下载编译好的版本,https://github.com/cloudflare/workerd

可以在其他主机构建好workerd的镜像并导出

1
2
3
docker build -t workerd:v1.0.2 .

docker save -o workerd-v1.0.2.tar workerd:v1.0.2

然后把 workerd-v1.0.2.tar 上传到 k8s 上的各个节点上并加载镜像到 k8s 的镜像命名空间,如果有镜像仓库的话也可以直接推送镜像上去,省略

1
ctr -n=k8s.io images import workerd-v1.0.2.tar

kubectl apply -f deployment.yaml 就能直接部署

检查 pod 和 svc、ingress

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
root@k8s-master1:~# kubectl get pod -n workerd -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
workerd-deployment-64644bdbc9-5gdsr 1/1 Running 0 4d 10.244.5.102 k8s-node3 <none> <none>
workerd-deployment-64644bdbc9-fkg99 1/1 Running 0 4d 10.244.4.93 k8s-node2 <none> <none>
workerd-deployment-64644bdbc9-h4zdg 1/1 Running 0 4d 10.244.7.94 k8s-node4 <none> <none>
workerd-deployment-64644bdbc9-h6ncm 1/1 Running 0 4d 10.244.4.94 k8s-node2 <none> <none>
workerd-deployment-64644bdbc9-njq8b 1/1 Running 0 4d 10.244.3.72 k8s-node1 <none> <none>
workerd-deployment-64644bdbc9-pk8h7 1/1 Running 0 4d 10.244.5.101 k8s-node3 <none> <none>
workerd-deployment-64644bdbc9-r2xzd 1/1 Running 0 4d 10.244.6.62 k8s-node5 <none> <none>
workerd-deployment-64644bdbc9-vd99f 1/1 Running 0 4d 10.244.3.71 k8s-node1 <none> <none>
workerd-deployment-64644bdbc9-wvs8z 1/1 Running 0 4d 10.244.6.63 k8s-node5 <none> <none>
workerd-deployment-64644bdbc9-xfs4l 1/1 Running 0 4d 10.244.7.95 k8s-node4 <none> <none>
root@k8s-master1:~#
root@k8s-master1:~# kubectl get svc -n workerd
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
workerd-service ClusterIP 10.103.32.102 <none> 8080/TCP 4d
root@k8s-master1:~#
root@k8s-master1:~# kubectl get ingress -n workerd -o wide
NAME CLASS HOSTS ADDRESS PORTS AGE
workerd-ingress nginx workerd.k8s.cn 10.10.0.200 80, 443 4d
root@k8s-master1:~#
1
2
3
root@k8s-master1:~# root@k8s-master1:~# curl --resolve workerd.k8s.cn:80:10.10.0.200 https://workerd.k8s.cn/
Hello from Cloudflare workerd on K8s! version:1.0.2
root@k8s-master1:~#

Cloudflare 虽然开源了 workerd ,但 workerd 本质上只是一个运行环境,并没有集成 KV 键值对存储和 D1 数据库,只能依赖外部服务来实现,调度、多租户引擎也没有开源。

如果想要更完善的且兼容 Cloudflare workerd 的边缘函数,可以看看基于 workerd 开发的 celld 项目

https://github.com/denoland/celld