Skip to main content

Command Palette

Search for a command to run...

不用 API Server 也能运行 Pod?

Updated
3 min read

遇到一个奇怪的需求:想复用 Pod 的 YAML,但是家境贫寒,不想搞个高可用 API Server;又惜字如金,不想上 Docker Compose。一顿 Google 猛如虎之后,得到了两个方案:静态 Pod 和 podman play kube

静态 Pod

Kubernetes 有个功能,就是 static pod,官网介绍大致如下:

静态 Pod 由特定节点上的 kubelet 守护进程直接管理的,API 服务器并不关注静态 Pod。通常说来,Pod 是由 Deployments 之类的控制器管理的,而静态 Pod 则是在 Kubelet 的看护之下,并负责其重新启动的。

那么 Kubelet 是否可以脱离 API Server 直接运行呢?答案是肯定的,Kelsey Hightower 早在七年前就做了这样的尝试。

https://github.com/kelseyhightower/standalone-kubelet-tutorial

想法很简单,单独运行一个 Kubelet,使用 Kubelet 拉起磁盘上的 Pod 文件。

测试

以目前最新版本的 1.29 为例,在 Ubuntu 中按照默认方式使用 apt 部署 Containerd:

$ apt install containerd cri-tools
...

然后按照官网文档安装 kubelet:

$ apt-get install -y apt-transport-https ca-certificates curl gpg
$ curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
$ echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
$ sudo apt-get update
$ sudo apt-get install -y kubelet
...

编写如下 kubelet.yaml

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
enableServer: false
staticPodPath: /home/kubelet/pods
readOnlyPort: 10250
failSwapOn: false
podCIDR: 10.241.1.0/24
authentication:
  anonymous:
    enabled: true
  webhook:
    enabled: false
authorization:
  mode: AlwaysAllow

最后,我们启动 Kubelet:

$ kubelet --config=kubelet.yaml
I0302 11:39:14.006446    9890 server.go:487] "Kubelet version" kubeletVersion="v1.29.2"
I0302 11:39:14.006492    9890 server.go:489] "Golang settings" GOGC="" GOMAXPROCS="" GOTRACEBACK=""
I0302 11:39:14.006622    9890 server.go:650] "Standalone mode, no API client"
I0302 11:39:14.010584    9890 server.go:538] "No api server defined - no events will be sent to API server"
...

注意,如果使用其它配置方法的容器运行时,可能需要指定不同的 Endpoint

这里会看到,日志中直接就表明这是一个独立运行模式的 Kubelet。

最后只要把一个 Pod 定义的文件拷贝到上文配置中的指定目录就能启动 Pod 了:

apiVersion: v1
kind: Pod
metadata:
  name: apache
spec:
  containers:
  - name: apache
    image: httpd
    ports:
    - name: http
      containerPort: 80
      hostPort: 45678
    volumeMounts:
    - name: local
      mountPath: /data
  volumes:
  - name: local
    hostPath:
      path: /home/volumes/data
      type: Directory

使用 crictl 查看运行中的 Pod:

$  sudo crictl ps
55a65b4642f47       50a1bd9b297f7       18 seconds ago      Running             apache              0                   c141f4e021cdf       apache-ubuntu
$ curl http://127.0.0.1:45678
<html><body><h1>It works!</h1></body></html>

Pod 已经启动。

限制

因为没有 API Server 的支持,所以静态 Pod 里面是无法引用 ConfigmapSecret 之类的外部对象的。更不要提 Deployment 了。

Podman Play Kube

和独立模式的 Kubelet 不同,podman play kube 支持的 Kubernetes 对象除了 Pod 之外,还支持:

  • Deployment

  • PVC

  • Configmap

启动 Pod

Ubuntu 下可以直接使用 apt install podman 安装部署。安装结束后,可以复用刚才的 pod.yaml

$ podman play kube pod.yaml
a container exists with the same name ("apache") as the pod in your YAML file; changing pod name to apache_pod
Pod:
...
Container:
...

$ podman pod ls
POD ID        NAME        STATUS      CREATED        INFRA ID      # OF CONTAINERS
99e235dfe7a3  apache_pod  Running     9 seconds ago  b54991e35f58  2

$ podman ps
CONTAINER ID  IMAGE                           COMMAND           CREATED         STATUS             PORTS                  NAMES
b54991e35f58  k8s.gcr.io/pause:3.5                              41 seconds ago  Up 38 seconds ago  0.0.0.0:45678->80/tcp  99e235dfe7a3-infra
aa4a4ba1af39  docker.io/library/httpd:latest  httpd-foreground  38 seconds ago  Up 38 seconds ago  0.0.0.0:45678->80/tcp  apache_pod-apache

看到这里有几个发现:

  1. podman pod lspodman ps 可以查看 Pod 和容器的情况

  2. Podman 取了个巧,使用命名的方式来区分容器和 Pod

  3. Podman 启动的 Pod 用到了 Infra 容器,所以一个 Pod 里面会有两个容器。

为了让后续动作顺利,可以把容器名称修改为 httpd,用于消除这种隐式变更。在应用新版本 YAML 之前,需要因为发生了改名情况,所以无法使用 podman play kube pod.yaml --down 的方式停止 Pod,这里用 podman pod kill apache_pod && podman pod rm apache_pod 删除 Pod,然后重新创建修改后的 Pod:

$podman play kube pod.yaml
Pod:
...
Container:
...

甚至可以启动一个 Deployment,例如:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx

play kube 运行一下:

$ podman play kube deploy.yaml
...
podman pod ls
POD ID        NAME         STATUS      CREATED         INFRA ID      # OF CONTAINERS
0a6e4dcda93c  nginx-pod-2  Running     15 seconds ago  319f12f3b6f2  2
266df25c4df1  nginx-pod-1  Running     19 seconds ago  a65f6b601160  2
e6966f42c5fd  nginx-pod-0  Running     22 seconds ago  953e3e830528  2
573597e627ec  apache       Running     9 minutes ago   3b4ff4625b46  2

可以看到,这里生成了 3 个 nginx-pod 为前缀的 Pod。

Configmap

修改一下刚才的 pod.yaml,其中加入 Configmap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-sample
data:
  key1: value1
---
apiVersion: v1
kind: Pod
metadata:
  name: apache
spec:
  containers:
  - name: httpd
    image: httpd
    ports:
    - name: http
      containerPort: 80
      hostPort: 45678
    envFrom:
    - configMapRef:
        name: cm-sample
        optional: false

这里加入了一个引用 Configmap 作为环境变量的选项,使用 --down 开关停止当前 Pod 并重建后(4.x 版本有了 --replace 开关),验证一下:

$ podman exec -it [your container id] env | grep key
key1=value1

可以看到已经成功引用了 Configmap。

结论

除了简单的运行功能之外,Podman Play 还提供了网络、命名空间等功能,甚至还有现场构建的能力,比孤零零的 kubelet 强大不少,但是如果 Kubelet 加入 crictl、nerdctl 之类的东西的话,勉强也算各擅胜场。

More from this blog

龙虾恐慌:AIOps 又要改名了?

ChatGPT 开始,把 AI 拉近到普罗大众的面前,让无数人感受到 AI 的亲民魅力。而龙虾,则把大模型驱动的自动化能力,突然间变得水灵灵、活泼泼地走进千家万户。它不只是“风口上的猪”,而是风口本身。热度高到让 Mac mini 一度断货,不知道这在不在库克的预料之内。 每代人都有每代人的鸡蛋,春节期间,我就领了我的鸡蛋。翻出古老的 MacBook Air M1,充值各种大模型。当然了,这个工具

Mar 9, 20261 min read

再见 2025

我猜不少人以为这个号废了吧?并没有,只是今年变化有点大,一直有种抄起键盘,无从说起的感觉,所以一直偷懒到今天,2025 的最后一天。 今年是我的第四个本命年,去年末一期播客里,大内说本命年不是灾年,是变化年,有危也有机。可是讲真啊,只看到危,没看到机。 各种因缘际会,从鹅厂跳槽到前东家,已经接近四年,第一个合同期已经进入尾声。除了前两年还在云原生领域嗷嗷叫,后两年基本都是些鸡零狗碎的东西了,用老东家的术语说是——偏离主航道,可谓是前景暗淡了。 一旦确定要滚蛋,反倒心思轻松起来,每天骑着我的小红车...

Jan 5, 20261 min read

辅助编程?dora 说:我知道你很急可是请你别急

从 OpenGPT 把大模型的火烧旺了之后,这三年来,相信很多组织或摩拳擦掌、或躬身入局,希望借助聪明能干的大模型,或想偿还技术宅,或想降本增效,或想弯道超车。一时间,沉寂许久的 AIxx 又活过来了,LLM Ops、Vibe Coding、中医大模型、GPT 算命等等,全都老树发新芽,焕发了勃勃生机。那么视角拉回从业者最关注的饭碗相关的领域之一——AI 辅助开发,产生了什么触动,应该如何拥抱呢? DORA 的年度报告中给出了很有意思的结论——强者恒强。 执行摘要部分总结了几个有趣的点: 问题...

Oct 6, 20251 min read

[译]dora:ai 辅助软件开发状态报告

执行摘要 在 2025 年,科技领导者面临的核心问题已不再是“是否要采用 AI”,而是“如何实现其价值”。 DORA 的研究基于超过 100 小时的定性访谈和来自全球近 5,000 名技术专业人士的问卷调查。研究揭示了一个关键事实:AI 在软件开发中的主要角色是“放大器”。它会放大高效能组织的优势,也会凸显组织的缺陷。 关键结论:AI 是放大器 AI 投资的最大回报并非来自工具本身,而是来自组织底层系统的战略性建设: 高质量的内部平台 清晰的工作流 团队的协同能力 缺少这些基础,AI ...

Oct 2, 202514 min read

僭越了,有人在用 Rust 写 Kubernetes

一个新语言问世,最爱做的事情之一,就是重写存量软件了。 云原生喝酒 SIG 重点扶持项目——rk8s(https://github.com/rk8s-dev/rk8s) 也可以归在这个范畴里,只不过这个项目重写的东西比较大,是 Kubernetes。 从 2025 年 1 月第一个 Commit 开始,到现在有了 200 多次 Commit,十几万行代码。当然距离 Kubernetes 的几百万行代码还差得远——老马就是喜欢整这种大无畏项目。 另外该项目也是国内第一个脱离 Cargo 转向使用 ...

Sep 27, 20253 min read

【伪】架构师

342 posts

运行 Pod 无需 API 服务器