k8s - k8s使用gvisor
k8s - k8s使用gvisor
k8s使用gvisor部署单一的pod方式
https://github.com/google/gvisor https://gvisor.dev/
跟着官方文档走一圈。
背景
- 要安全隔离运行pod内的程序;
- 要有且只有一个pod来提供某一个服务,例如one for one claw;
- pod异常时能自动恢复。
使用deployment
gVisor
前一篇文章已经提到过安装gvisor。
1 2 root@wfy-0002:~# which runsc /usr/local/bin/runsc
为什么用deployment
控制平面(API Server + etcd)完全可以支撑一万个 Deployment,许多大型集群甚至运行着数十万个 Deployment。真正的资源挑战在节点层面——你需要有足够的 CPU/内存来运行一万个 Pod。
无Deployment控制的pod:
- pod被误删除,无法自动创建。
- 节点宕机,其他节点更不会重建。
- 手动创建同名pod会因名字冲突而失败,确实能保证唯一。
如果你确实需要自动恢复并保证唯一性,就必须使用 控制器(Deployment、ReplicationController、StatefulSet)。即使是最轻量的 kubectl run --restart=Always 命令,其背后也会创建一个 Deployment 或 ReplicationController。
deployment.yaml
1
2
3
4
5
6
7
#gvisor-runtimeclass.yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: gvisor
handler: runsc
当前目录的 deployment.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
57
58
59
60
61
#
# kubectl apply -f deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: unique-claw-001 # Deployment 自身标识:名称 + 命名空间唯一(与 Pod 类似)。
namespace: default
spec:
replicas: 1 # 永远只运行一个实例
strategy:
type: Recreate # 默认 RollingUpdate 策略,绝对不能容忍双 Pod 同时存在,可以把 strategy.type 改为 Recreate
revisionHistoryLimit: 2 # 减少历史版本
selector:
matchLabels:
app: unique-claw-001 # 用来匹配 Pod 的标签
template:
metadata:
labels:
app: unique-claw-001
spec:
restartPolicy: Always # Pod 异常退出后自动重启(默认就是 Always,可省略)
runtimeClassName: gvisor # 关键:指定使用 gvisor 运行时
containers:
- name: app
image: redis:7.2.5
ports:
- containerPort: 6379
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
# 1. 启动探针:仅在 Pod 启动期间执行,成功后不再介入
startupProbe:
exec:
command:
- sh
- -c
- |
# 使用 timeout 防止 redis-cli 卡死
timeout 3 redis-cli -h 127.0.0.1 -p 6379 --no-auth-warning PING | grep PONG
initialDelaySeconds: 10 # 容器启动后等10秒才开始探测
periodSeconds: 5 # 每5秒探测一次
timeoutSeconds: 3 # 探测超时时间3秒
failureThreshold: 30 # 允许失败30次,启动慢时可适当放宽
successThreshold: 1 # 成功1次即认为探针成功
# 2. 存活探针:Pod 稳定运行后,持续检查 Redis 状态
livenessProbe:
exec:
command:
- sh
- -c
- |
timeout 3 redis-cli -h 127.0.0.1 -p 6379 --no-auth-warning PING | grep PONG
initialDelaySeconds: 0 # 从 startup 结束后开始
periodSeconds: 15 # 每15秒探测一次
timeoutSeconds: 3 # 超时时间3秒
failureThreshold: 3 # 连续失败3次才重启容器
successThreshold: 1 # 成功1次即恢复健康
观察对应的进程和pod状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 未使用runsc
root@raha-0002:~# ps axu|grep redis
dnsmasq 2401711 0.9 0.3 55600 14752 ? Ssl 17:51 0:00 redis-server *:6379
root 2401779 0.0 0.0 6336 2176 pts/0 S+ 17:51 0:00 grep redis
# 使用runsc以后
root@raha-0002:~# ps axu|grep redis
root 2403160 0.0 0.0 6336 2176 pts/0 S+ 17:53 0:00 grep redis
root@raha-0002:~# ps axu|grep redis
# pod删除后,可以自动拉起
root@raha-0001:/data/tmp# kubectl get pods
NAME READY STATUS RESTARTS AGE
openclaw-deployment-77785d7699-2pw5z 1/1 Running 0 24d
unique-claw-001-ddcdd6b9c-8867z 1/1 Running 0 16m
本文由作者按照 CC BY 4.0 进行授权