来自Deis工作室的新玩具-Krustlet

  1. 1. 简单介绍
  2. 2. 部署
    1. 2.1. 部署一个能用的kubernetes集群
    2. 2.2. 准备bootstrap文件
      1. 2.2.1. 执行官方提供的脚本
      2. 2.2.2. 拷贝kubeconfig
    3. 2.3. 安装krustlet
      1. 2.3.1. krustlet 在部分系统可能存在的问题
    4. 2.4. 启动krustlet
    5. 2.5. 一些问题

简单介绍

大家都知道,Kubernetes 正在成为一个统一的调度器,只要符合kubernetes的标准,那么就可以通过它来进行调度,比如说kubevirt(调度虚拟机),当然我们今天不是为了调度虚拟机来的,我们需要调度的是WASM。

Krustlethelm同出一源,使用rust实现kubelet,用于在kubernetes中运行wasm,只不过成熟度还是相对不足,不过作为一个概念性的尝试,确实很有意思。

部署

部署其实比较简单,按照官方文档按部就班的部署就可以,简单的执行一下

部署一个能用的kubernetes集群

这个集群能用就行,也包括kind,minikube,microk8s等

这边图省事,就用微软官方视频里介绍的kind方案好了,同样也可用于其他的k8s集群。

1
2
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.11.1/kind-linux-amd64
mv kind /usr/bin

kind的yaml文件(cluster.yaml):

1
2
3
4
5
6
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker

这个yaml文件会定义一个单master双worker的kubernetes集群

简单执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
kind create cluster --config=cluster.yaml

Creating cluster "kind" ...
✓ Ensuring node image (kindest/node:v1.21.1) 🖼
✓ Preparing nodes 📦 📦 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
✓ Joining worker nodes 🚜
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Have a nice day! 👋

看一下集群状态:

1
2
3
4
5
kubectl  get nodes
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready control-plane,master 90s v1.21.1
kind-worker Ready <none> 58s v1.21.1
kind-worker2 Ready <none> 60s v1.21.1

记一下宿主机的ip地址:

1
2
3
docker network inspect kind |grep Gateway
"Gateway": "172.18.0.1"

准备bootstrap文件

安装一下kubectl,拷贝一份kubeconfig,用户须有权限操作kube-systemSecret并且能审批CertificateSigningRequests,

这边我们用默认的就好。

执行官方提供的脚本

官方提供了一个脚本,用于帮助我们生成bootstrap.conf

1
2
3
4
5
6
7
8
9
10
11
12
 bash <(curl https://raw.githubusercontent.com/krustlet/krustlet/main/scripts/bootstrap.sh)

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2456 100 2456 0 0 2251 0 0:00:01 0:00:01 --:--:-- 2253
secret/bootstrap-token-3amumr created
Switched to context "kind-kind".
Context "kind-kind" renamed to "tls-bootstrap-token-user@kubernetes".
User "tls-bootstrap-token-user" set.
Context "tls-bootstrap-token-user@kubernetes" modified.
Context "tls-bootstrap-token-user@kubernetes" modified.

这个脚本在官方仓库script目录下

拷贝kubeconfig

cp ~/.kube/config ~/.krustlet/config/kubeconfig

安装krustlet

根据自己操作系统的版本选择,下载地址

1
2
3
4
wget https://krustlet.blob.core.windows.net/releases/krustlet-canary-linux-amd64.tar.gz
tar -xf krustlet-canary-linux-amd64.tar.gz
chmod +x krustlet-wasi
mv krustlet /usr/bin/

krustlet 在部分系统可能存在的问题

因为图顺手用的是CentOS7的系统,这个系统相对来说比较老,krustlet部署时会出现一些问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 下载腾讯源提供的openssl 1.11
wget https://mirrors.cloud.tencent.com/openssl/source/openssl-1.1.1l.tar.gz
tar -xf openssl-1.1.1l.tar.gz
cd openssl-1.1.1l
./config shared --openssldir=/usr/local/openssl --prefix=/usr/local/openssl
make && make install
ln -s /usr/local/openssl/lib/libssl.so.1.1 /usr/lib64/libssl.so.1.1
ln -s /usr/local/openssl/lib/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1

# 更新glibc
curl -O http://ftp.gnu.org/gnu/glibc/glibc-2.18.tar.gz
tar zxf glibc-2.18.tar.gz
cd glibc-2.18/
mkdir build
cd build/
../configure --prefix=/usr
make -j2
make install

启动krustlet

1
krustlet-wasi  --node-ip 172.18.0.1 --bootstrap-file=~/.krustlet/config/bootstrap.conf

启动后会提示你kubectl certificate approve <hostname>-tls,我们另起一个终端,

1
2
kubectl certificate approve dmz-jmxtest-01.novalocal-tls
certificatesigningrequest.certificates.k8s.io/dmz-jmxtest-01.novalocal-tls approved
1
2
3
4
5
6
kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
testos Ready <none> 12s 1.0.0-alpha.1 172.18.0.1 <none> <unknown> <unknown> mvp
kind-control-plane Ready control-plane,master 144m v1.21.1 172.18.0.2 <none> Ubuntu 21.04 3.10.0-862.3.2.el7.x86_64 containerd://1.5.2
kind-worker Ready <none> 144m v1.21.1 172.18.0.4 <none> Ubuntu 21.04 3.10.0-862.3.2.el7.x86_64 containerd://1.5.2
kind-worker2 Ready <none> 144m v1.21.1 172.18.0.3 <none> Ubuntu 21.04 3.10.0-862.3.2.el7.x86_64 containerd://1.5.2

一些问题

kind启动集群时 大概是会出现这种报错。

1
2
3
4
5
6
BOOTSTRAP: received TLS certificate approval: continuing
Nov 14 04:21:06.747 ERROR kubelet::state::common::image_pull: error=unsupported media type: application/vnd.docker.distribution.manifest.list.v2+json
Nov 14 04:21:17.892 ERROR kubelet::state::common::image_pull: error=unsupported media type: application/vnd.docker.distribution.manifest.list.v2+json
Nov 14 04:21:39.162 ERROR kubelet::state::common::image_pull: error=unsupported media type: application/vnd.docker.distribution.manifest.list.v2+json
Nov 14 04:22:20.411 ERROR kubelet::state::common::image_pull: error=unsupported media type: application/vnd.docker.distribution.manifest.list.v2+json
Nov 14 04:23:41.632 ERROR kubelet::state::common::image_pull: error=unsupported media type: application/vnd.docker.distribution.manifest.list.v2+json

官方的issue也有这个问题,参考链接

无需介意,kind的集群会尝试在krustlet机器上部署kindnet。因为我们的机器没有运行容器的环境,所以尝试会一直失败,问题不大.。

运行一下官方提供的mod

kubectl apply --filename=https://raw.githubusercontent.com/krustlet/krustlet/main/demos/wasi/hello-world-rust/k8s.yaml

k8s.yaml的内容:

文件内容
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
apiVersion: v1
kind: ConfigMap
metadata:
name: hello-world-wasi-rust
data:
myval: "cool stuff"
bacon_ipsum.txt: |
Bacon ipsum dolor amet chuck turducken porchetta, tri-tip spare ribs t-bone ham hock. Meatloaf
pork belly leberkas, ham beef pig corned beef boudin ground round meatball alcatra jerky.
Pancetta brisket pastrami, flank pork chop ball tip short loin burgdoggen. Tri-tip kevin
shoulder cow andouille. Prosciutto chislic cupim, short ribs venison jerky beef ribs ham hock
short loin fatback. Bresaola meatloaf capicola pancetta, prosciutto chicken landjaeger andouille
swine kielbasa drumstick cupim tenderloin chuck shank. Flank jowl leberkas turducken ham tongue
beef ribs shankle meatloaf drumstick pork t-bone frankfurter tri-tip.
---
apiVersion: v1
kind: Pod
metadata:
name: hello-world-wasi-rust
spec:
containers:
- name: hello-world-wasi-rust
image: webassembly.azurecr.io/hello-world-wasi-rust:v0.2.0
env:
- name: FOO
value: bar
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: CONFIG_MAP_VAL
valueFrom:
configMapKeyRef:
key: myval
name: hello-world-wasi-rust
volumeMounts:
- name: storage
mountPath: /mnt/storage
volumes:
- name: storage
configMap:
name: hello-world-wasi-rust
nodeSelector:
kubernetes.io/arch: "wasm32-wasi"
tolerations:
- key: "kubernetes.io/arch"
operator: "Equal"
value: "wasm32-wasi"
effect: "NoExecute"
- key: "node.kubernetes.io/network-unavailable"
operator: "Exists"
effect: "NoSchedule"
- key: "kubernetes.io/arch"
operator: "Equal"
value: "wasm32-wasi"
effect: "NoSchedule"

很快这个pod就执行完任务退出了:

1
2
3
kubectl  get pods
NAME READY STATUS RESTARTS AGE
hello-world-wasi-rust 0/1 ExitCode:0 0 13s

看一眼输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 kubectl logs  hello-world-wasi-rust
hello from stdout!
hello from stderr!
CONFIG_MAP_VAL=cool stuff
POD_NAME=hello-world-wasi-rust
FOO=bar
Args are: []

Bacon ipsum dolor amet chuck turducken porchetta, tri-tip spare ribs t-bone ham hock. Meatloaf
pork belly leberkas, ham beef pig corned beef boudin ground round meatball alcatra jerky.
Pancetta brisket pastrami, flank pork chop ball tip short loin burgdoggen. Tri-tip kevin
shoulder cow andouille. Prosciutto chislic cupim, short ribs venison jerky beef ribs ham hock
short loin fatback. Bresaola meatloaf capicola pancetta, prosciutto chicken landjaeger andouille
swine kielbasa drumstick cupim tenderloin chuck shank. Flank jowl leberkas turducken ham tongue
beef ribs shankle meatloaf drumstick pork t-bone frankfurter tri-tip.

不过krustlet的镜像和普通的镜像不同,需要用专门的工具,如果你想从头到尾体验一遍,可以参考这个项目