Pod 与 Docker
基本概念
- Docker 三要素:镜像、容器、仓库。
- Pod:K8S 的基本单元。K8S中部署容器,容器处于Pod中。
区别
- Docker 为单进程设计(类似单机应用),这个进程对应我们部署的一个单一应用项目,比如运行一个Go项目。
- Pod 为多进程设计(类似集群应用),创建一个Pod,这个Pod中有多个容器,对应多个项目。
Pod 优势
- 方便K8s管理,与底层容器解耦
- 同一Pod不需要IP就能调用
- 定义一组容器,统一监控
Pod 定义参数
首先需要强调下记忆:Pod 是一组容器的集合。
创建一个简单Pod
创建并编辑 pod-busybox.yaml:
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: test
labels:
app: busybox
spec:
containers:
- name: busybox
# 将原来的 image: busybox 替换为国内可用的代理节点
image: docker.m.daocloud.io/library/busybox:latest
# 核心:让 busybox 保持运行状态,防止启动后立刻退出
command: ["sleep", "3600"]
这个yaml文件会用于kubectl来创建Pod。Yaml 文件由3不分组成:
头部:资源的API信息和资源类型
元数据信息:名称、命名空间、标签等信息。
规格信息:
什么是命名空间?
命名空间,就是将资源进行隔离的单位,例如相同名称的Pod,但是命名空间不同是允许的。命名空间类似学校的班级,将不同学生分成不同的班级,将这些学生隔离成了不同的班级。 不同的命名空间名字可以相同,同一个命名空间,名字不能相同。
创建Pod
在 vm-1 Master 节点中执行:
kubectl apply -f pod_busybox.yaml
由于yaml定义中指定了 命名空间test,首次创建时一般会出错 Error from server (NotFound): error when creating "pod_busybox.yaml": namespaces "test" not found:
这是因为如果不指定命名空间,会默认放到 default命名空间中,可以通过下面方式创建test并查看命名空间:
kubectl create ns test
kubectl get ns
创建完后需要注意命名空间的状态一定要为 Active,然后重新创建 Pod:
kubectl apply -f pod_busybox.yaml
查看:
kubectl get pod -n test
补充
如果Pod启动失败可以通过下面命令查看错误原因:
# 使用 describe 查看详细事件
kubectl describe pod busybox -n test
# 删除之前失败的 Pod
kubectl delete pod busybox -n test
# 应用新的 YAML
kubectl apply -f pod_busybox.yaml
为 Pod 添加参数
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: test
labels:
app: busybox
spec:
containers:
- name: busybox
# ⭐ 核心调整:结合之前的网络问题,将 image 替换为国内镜像源
image: docker.m.daocloud.io/library/busybox:latest
# 可选值: Always|IfNotPresent|Never
imagePullPolicy: IfNotPresent
# 环境变量
env:
- name: app
value: busybox
# 运行终端
tty: true
# 特权模式 对宿主机有root权限
securityContext:
privileged: true
# 工作目录
workingDir: /test
# 命令
command: ["/bin/sh"]
# 参数(每10秒打印一次hello,保持容器一直处于Running状态)
args: ["-c", "while true; do echo hello; sleep 10;done"]
- imagePullPolicy:镜像拉取策略,Always表示始终拉取最新镜像,IfNotPresent表示主机上存在就不去远端拉取,Never表示始终不去拉取
- env:环境变量,比如MySQL的连接信息等环境变量。
- tty:
- securityContext:
- workingDir:
- command:
删除之前卡在错误状态的旧 Pod
# 命令式删除(直接指名道姓)
kubectl delete pod busybox -n test
# 声明式删除(按图索骥)
kubectl delete -f pod_busybox.yaml
重新创建:
kubectl apply -f pod-busybox.yaml
检查 Pod 状态:
kubectl get pod -n test -w
验证日志输出(测试你的脚本是否正常运行):
kubectl logs -f busybox -n test
为Pod容器分配资源
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: test
labels:
app: busybox
spec:
containers:
- name: busybox
# ⭐ 核心调整:结合之前的网络问题,将 image 替换为国内镜像源
image: docker.m.daocloud.io/library/busybox:latest
# 可选值: Always|IfNotPresent|Never
imagePullPolicy: IfNotPresent
# 环境变量
env:
- name: app
value: busybox
# 运行终端
tty: true
# 特权模式 对宿主机有root权限
securityContext:
privileged: true
# 工作目录
workingDir: /test
# 命令
command: ["/bin/sh"]
# 参数(每10秒打印一次hello,保持容器一直处于Running状态)
args: ["-c", "while true; do echo hello; sleep 10;done"]
resources:
requests:
memory: "100Mi"
cpu: "1000m"
limits:
memory: "200Mi"
cpu: "1000m"
资源的配额并不是针对Pod,而是针对的Pod中的容器。
重新创建并查看分配节点:
kubectl apply -f pod_busybox_3.yaml
kubectl get pod -n test -o wide
网络
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: test
labels:
app: nginx
spec:
hostNetwork: true
#可选值: Default|ClusterFirst|ClusterFirstWithHostNet|None
dnsPolicy: "Default"
#dns配置
dnsConfig:
nameservers:
- 8.8.8.8
#域名映射
hostAliases:
- ip: 192.168.1.18
hostnames:
- "foo.local"
- "bar.local"
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- 比如指定是否使用宿主机的网络,比如Docker中–host参数可以让容器和宿主机共享局域网,
- dns策略:K8S默认是有DNS的,还可以配置DNS的IP,比如8.8.8.8,114.114.114.114
- hostAliases域名映射,
Pod Container 健康检查
Pod 卷挂载
作用于Pod的全局参数
首先恭喜你,看到一连串的 hello,说明 Pod 终于成功拉取镜像并正常运行起来了! 之前的网络问题已经完美解决。
至于你现在遇到的新错误 failed to create fsnotify watcher: too many open files,这并不是你的 Pod 或 YAML 写错了,而是操作系统的限制。
🔍 错误原因分析
当你使用 kubectl logs -f(-f 代表 follow,实时追踪)时,底层依赖于 Linux 系统的 inotify 机制来监听日志文件的实时变化。
这个错误提示你的宿主机(从你的提示符看是 vm-1 这台机器)上的 文件监听器(inotify instances/watches)数量已经达到了系统的最大上限。在运行容器化环境(Docker/Kubernetes)的节点上,这是一个非常常见的系统级瓶颈。
🛠️ 解决办法:调高操作系统的 inotify 上限
你需要在报错的这台机器(即 vm-1)上修改内核参数。
第一步:临时修改并立即生效
直接在终端执行以下命令,将最大实例数和监听数调高:
sudo sysctl fs.inotify.max_user_instances=8192
sudo sysctl fs.inotify.max_user_watches=524288
执行完这两行命令后,你再次运行 kubectl logs -f busybox -n test,应该就不会再报错了,日志会持续平滑地输出。
第二步:永久修改(防止重启后失效)
为了让机器下次重启后依然生效,你需要将配置写入系统的 sysctl 配置文件中。
执行以下命令追加配置:
cat <<EOF | sudo tee -a /etc/sysctl.conf
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=524288
EOF
然后刷新配置使其生效:
sudo sysctl -p
💡 补充提示
如果你是一个多节点的集群(比如有 vm-1、vm-2 等),强烈建议你在所有节点上都执行一下上述操作。Kubernetes 节点上通常运行着大量的容器和系统组件(如 kubelet、kube-proxy),它们都会消耗大量的文件监听资源,提前调优可以避免日后出现类似 “too many open files” 的诡异报错。