基于K8s+Helm部署OpenClaw实践笔记

本文记录了一套Windows + VirtualBox 环境下的OpenClaw部署流程,核心用到K8s、Helm、local-static-provisioner、nginx-ingress,所有组件镜像均使用私有仓库 ,同时解决了私有镜像拉取卡住、本地静态存储、Windows访问虚拟机K8s集群、OpenClaw HTTPS配置等关键问题,仅供测试学习使用

一、环境前置说明

  • 底层环境:Windows 10/11 + VirtualBox 虚拟机
  • K8s集群:已部署完成(本文不赘述K8s/Helm基础部署)
  • 虚拟机网卡:Host-Only 网卡(网段:192.168.56.x)
  • 私有镜像仓库:192.168.56.102(Harbor)
  • 核心组件私有镜像地址:
    • Nginx-Ingress Controller:192.168.56.102/library/registry.k8s.io/ingress-nginx/controller:v1.15.1
    • Nginx Webhook:192.168.56.102/library/registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9
    • Local Static Provisioner:192.168.56.102/library/registry.k8s.io/sig-storage/local-volume-provisioner:v2.8.0
    • OpenClaw:192.168.56.102/library/ghcr.io/openclaw/openclaw:2026.3.13-1

二、local-static-provisioner 部署(本地静态存储)

2.1 本地目录创建(含子目录,完整步骤)

所有K8s节点执行:

bash 复制代码
# 1. 创建根目录
mkdir -p /mnt/fast-disks

# 2. 批量创建子目录 vol-0000 ~ vol-0009
for i in $(seq -w 0 9); do
    mkdir -p /mnt/fast-disks/vol-00$i
    chmod 777 /mnt/fast-disks/vol-00$i
done

# 3. 查看目录是否创建成功
ls -l /mnt/fast-disks/

2.2 目录绑定挂载(必须执行)

bash 复制代码
for i in $(seq -w 0 9); do
    DIR="/mnt/fast-disks/vol-00$i";
    if [ -d "$DIR" ]; then
        echo "Mounting $DIR ...";
        mount --bind "$DIR" "$DIR";
        # 永久挂载(重启不失效)
        echo "$DIR $DIR none bind 0 0" >> /etc/fstab
    fi;
done

# 验证挂载
mount | grep fast-disks

2.3 创建 StorageClass

fast-disks.yaml

yaml 复制代码
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-disks
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
bash 复制代码
kubectl apply -f fast-disks.yaml

2.4 Helm 部署 local-static-provisioner(私有镜像)

provisioner-values.yaml

yaml 复制代码
image: "192.168.56.102/library/registry.k8s.io/sig-storage/local-volume-provisioner:v2.8.0"
nameOverride: local-static-provisioner

storageClassName: fast-disks

discovery:
  useMountPoint: false
  volumes:
  - name: local-disks
    hostPath: /mnt/disks
    mountPath: /mnt/disks
    blockCleanerCommand:
      - "/scripts/shred.sh"
      - "2"
    volumeMode: Filesystem
    fsType: ext4
    namePattern: "*"

部署:

bash 复制代码
helm repo add sig-storage https://kubernetes-sigs.github.io/sig-storage-local-static-provisioner/
helm repo update
helm install local-provisioner sig-storage/local-static-provisioner -f provisioner-values.yaml

三、Nginx-Ingress 部署(私有镜像)

3.1 下载官方YAML并替换镜像

bash 复制代码
curl -O https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yaml

替换为私有仓库镜像

  • registry.k8s.io/ingress-nginx/controller:v1.15.1
    192.168.56.102/library/registry.k8s.io/ingress-nginx/controller:v1.15.1
  • registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9
    192.168.56.102/library/registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9

3.2 部署

bash 复制代码
kubectl apply -f deploy.yaml

四、私有镜像同步(全组件)

能访问外网的机器/虚拟机执行:

bash 复制代码
# 1. OpenClaw
docker pull ghcr.io/openclaw/openclaw:2026.3.13-1
docker tag ghcr.io/openclaw/openclaw:2026.3.13-1 192.168.56.102/library/ghcr.io/openclaw/openclaw:2026.3.13-1
docker push 192.168.56.102/library/ghcr.io/openclaw/openclaw:2026.3.13-1

# 2. local-static-provisioner
docker pull registry.k8s.io/sig-storage/local-volume-provisioner:v2.8.0
docker tag registry.k8s.io/sig-storage/local-volume-provisioner:v2.8.0 192.168.56.102/library/registry.k8s.io/sig-storage/local-volume-provisioner:v2.8.0
docker push 192.168.56.102/library/registry.k8s.io/sig-storage/local-volume-provisioner:v2.8.0

# 3. nginx-ingress controller
docker pull registry.k8s.io/ingress-nginx/controller:v1.15.1
docker tag registry.k8s.io/ingress-nginx/controller:v1.15.1 192.168.56.102/library/registry.k8s.io/ingress-nginx/controller:v1.15.1
docker push 192.168.56.102/library/registry.k8s.io/ingress-nginx/controller:v1.15.1

# 4. nginx-ingress webhook
docker pull registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9
docker tag registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9 192.168.56.102/library/registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9
docker push 192.168.56.102/library/registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9

五、私有镜像拉取卡住问题(根因+解决方案)

问题现象

  • 普通镜像:配置 certs.d/hosts.toml 就能拉取
  • 嵌套路径镜像(如 192.168.56.102/library/ghcr.io/openclaw/openclaw):一直卡住

必须配置两处

  1. /etc/containerd/certs.d/192.168.56.102/hosts.toml
toml 复制代码
server = "http://192.168.56.102"
[host."http://192.168.56.102"]
  capabilities = ["pull", "resolve", "push"]
  skip_verify = true
  allow_insecure = true
  [host."http://192.168.56.102".auth]
    username = "admin"
    password = "Harbor12345"
  1. /etc/containerd/config.toml解决嵌套镜像拉取关键
toml 复制代码
[plugins."io.containerd.grpc.v1.cri".registry.configs]
  [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.56.102"]
    [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.56.102".auth]
      username = "admin"
      password = "Harbor12345"

根因

containerd 对包含多层级/嵌套域名路径的镜像解析逻辑不同:

  • 普通镜像:走 certs.d
  • 嵌套路径镜像:必须读取 config.toml 里的全局认证才能正确鉴权

生效

bash 复制代码
systemctl daemon-reload
systemctl restart containerd

六、OpenClaw 部署(核心配置完整版)

6.1 生成 HTTPS 证书(openclaw.local)

bash 复制代码
cat > openssl.cnf <<EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
x509_extensions = v3_req

[dn]
CN = openclaw.local

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = openclaw.local
EOF

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout tls.key \
  -out tls.crt \
  -config openssl.cnf

kubectl create secret tls openclaw-tls --cert=tls.crt --key=tls.key

6.2 openclaw-values.yaml(最关键正确配置)

yaml 复制代码
app-template:
  # ====================== 1. 私有镜像仓库 ======================
  imageRegistry: "192.168.56.102/library"

  controllers:
    main:
      initContainers:
        init-config:
          image:
            repository: "{{ .Values.imageRegistry }}/ghcr.io/openclaw/openclaw"
            tag: 2026.3.13-1

      containers:
        main:
          image:
            repository: "{{ .Values.imageRegistry }}/ghcr.io/openclaw/openclaw"
            tag: 2026.3.13-1
	#.....还有其他地方的镜像要修改,这里忽略...........................
  # ====================== 2. Ingress + TLS ======================
  ingress:
    main:
      enabled: true
      className: nginx
      annotations:
        nginx.ingress.kubernetes.io/ssl-redirect: "true"
        nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
        nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
        nginx.ingress.kubernetes.io/proxy-body-size: "0"
      tls:
        - secretName: openclaw-tls
      hosts:
        - host: openclaw.local
          paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  number: 18789

  # ====================== 3. OpenClaw 配置文件 ======================
  configMaps:
    config:
      enabled: true
      data:
        bash_aliases: |
          alias openclaw='node /app/dist/index.js'
        openclaw.json: |
          {
            // Gateway configuration
            "gateway": {
              "port": 18789,
              "mode": "local",
              "controlUi": {
                "dangerouslyAllowHostHeaderOriginFallback": true
              },
              "auth": {
                "mode": "token",
                "token": "xxxxxxxx"
              },
              .....................
          }
  # ====================== 4. 持久化存储 ======================
  persistence:
    enabled: true
    storageClass: fast-disks
    size: 10Gi
    mountPath: /data

6.3 部署 OpenClaw

bash 复制代码
helm repo add openclaw-helm https://openclaw-helm.github.io/helm-charts
helm repo update
helm install my-openclaw openclaw-helm/openclaw -f openclaw-values.yaml

七、Windows 访问 openclaw.local(关键!Host-Only 虚拟机环境)

因为你是 Windows + VirtualBox K8s ,必须同时配置 hosts + 静态路由 才能访问。

7.1 配置 Windows hosts

路径:
C:\Windows\System32\drivers\etc\hosts

添加:

复制代码
192.168.56.111  openclaw.local

192.168.56.111 为你的 K8s 节点IP)

7.2 配置 Windows 静态路由(必须!)

管理员身份 打开 CMD 执行:

cmd 复制代码
route add 192.156.48.0 mask 255.255.255.0 192.168.56.111 -p

说明:

  • 192.156.48.0/24:你的 K8s 服务网段(Service CIDR)
  • 192.168.56.111:虚拟机网关/节点IP
  • -p:永久路由(重启不失效)

7.3 验证路由

cmd 复制代码
route print | findstr 192.156.48.0

八、最终访问

浏览器直接打开:

复制代码
https://openclaw.local

(自签名证书选择继续访问即可)

九、注意事项

  1. 所有配置均为测试环境,不可直接用于生产
  2. Local PV 绑定单节点,节点宕机数据不可用
  3. 自签名证书仅用于测试
  4. Windows 必须配置 hosts + 静态路由 才能正常访问虚拟机内 Ingress
  5. 嵌套路径镜像必须配置 config.toml 认证,否则拉取失败
相关推荐
七牛云行业应用4 小时前
解决OpenClaw越改越崩:doctor诊断排错与配置恢复指南
配置文件·故障排查·报错解决·ai编程工具·openclaw
arvin_xiaoting5 小时前
OpenClaw学习总结_II_频道系统_5:Signal集成详解
java·前端·学习·signal·ai agent·openclaw·signal-cli
和平宇宙6 小时前
Openclaw记录07.全局提示词,已实现
hook·openclaw·全局提示词
河码匠7 小时前
Kubernetes YAML 详解之网络服务二( Ingress、IngressClasses)
云原生·容器·kubernetes
MarsBighead7 小时前
OpenClaw(Docker)极简安装配置教程
ai·llm·agent·openclaw
晨曦蜗牛7 小时前
OpenClaw 接入飞书详细教程
ai·飞书·大语言模型·openclaw
blackorbird8 小时前
一个来自法国的基于K8s的规模化扫描集群
云原生·容器·kubernetes
Entropy-Go8 小时前
一图了解AI热门词汇 - OpenClaw/Prompt/Agent/Skill/MCP/LLM/GPU
人工智能·agent·skill·mcp·openclaw
风向决定发型丶8 小时前
浅谈K8S的Label和Annotation
云原生·容器·kubernetes
2401_840192278 小时前
监控的作用
分布式·kubernetes