HelloCoder HelloCoder
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
  • 《可观测和监控》
  • 《k8s学习心得》
随笔
关于作者
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
  • 《可观测和监控》
  • 《k8s学习心得》
随笔
关于作者
  • 《从0到1学习Java多线程》

  • 《从0到1搭建服务器》

  • 可观测和监控

  • 玩转IDEA

  • 03-RPC

  • 04-Spring源码

  • 05-《Java日志框架》

  • Flyme公有云平台建设
  • k8s

    • (一)线程是什么
    • 常见疑问
    • 运行一个k8s部署的应用
    • 网络组件
    • docker compose和k8s deployment文件
    • dokcer的网卡
    • k8s-master初始化网段
    • Kubernetes API Service
    • k8s的DNS
    • 什么是 Sandbox
    • 如何访问pod
    • 常见命令
  • 专栏
  • k8s
#常见疑问
HaC
2026-06-13
目录

常见疑问

# 疑问一

我们在安装k8s的过程中,会出现以下的操作:

systemctl stop firewalld

systemctl disable firewalld# 2. 禁用 SELinux(临时+永久)

setenforce 0

sed -i 's/enforcing/disabled/g' /etc/selinux/config# 3. 关闭 Swap 分区(面试常考点,保证容器性能可控)

swapoff -a

sed -ri 's/.*swap.*/#&/' /etc/fstab

在生产环境中,K8s 作为一个分布式集群操作系统,它需要拥有对底层网络、进程和物理内存的绝对控制权。而 Linux 原生自带的这三个组件(防火墙、SELinux、Swap)会和 K8s 的控制策略发生严重冲突。

以下我用最通俗的语言,结合面试考点为你拆解为什么必须关掉它们:

# 1. 关闭防火墙 (firewalld)

  • 命令: systemctl stop firewalld && systemctl disable firewalld
  • 大白话原因: K8s 集群里的 Pod(容器)跨机器通信、或是暴露端口时,底层都是靠 K8s 的 kube-proxy 组件去动态修改 Linux 的 iptables 规则 来引流的。如果系统自带的 firewalld 防火墙服务一直开着,它会经常和 K8s 争夺 iptables 的控制权,把你刚建好的容器通道一脚踢断,导致你的多个飞书网关之间无法互相通信。
  • 面试加分点: 真正的生产环境并不是“裸奔”,我们通常会关闭操作系统的 firewalld 服务,转而使用云厂商的安全组(Security Group)或者 K8s 原生的 NetworkPolicy(网络策略) 来做更细粒度的容器间隔离。

# 2. 禁用 SELinux

  • 命令: setenforce 0 加上修改配置文件
  • 大白话原因: SELinux 是美国国家安全局(NSA)给 Linux 开发的一个极其严格的权限控制安全系统。它有一个原则:“除了我知道的,其他默认都是禁止的”。而 K8s 的容器在宿主机上运行时,需要频繁地读写挂载目录(比如你存放配置文件和记忆的 ./bot_hr_data)、接管底层网络设备。一旦开启 SELinux,它就会误认为这些容器是“木马病毒在越权作乱”,直接强行拦截,导致容器无法启动(频繁报 Permission Denied 错误)。
  • 面试加分点: 彻底禁用它是为了保证云原生生态的 CRI 容器运行时(如 Containerd)能顺利地为容器进行文件系统挂载和权限重映射。

# 3. 关闭 Swap 交换分区(🔥 面试重灾区,必考!)

  • 命令: swapoff -a
  • 什么是 Swap: 当你的服务器物理内存(RAM)不够用时,Linux 会在硬盘上划出一块空间当成临时内存来用,这个硬盘“假内存”就叫 Swap。
  • 大白话原因: 1. 性能不可控(致命损耗): 硬盘的读写速度比物理内存慢上万倍!如果你的 K8s 容器不小心跑进了 Swap 区,原本响应只需几毫秒的飞书机器人,可能会因为硬盘卡顿变成十几秒才回答,这在生产环境是不可接受的。 2. 调度器会“变瞎”: K8s 脑子里的调度器(kube-scheduler)是非常精准的。它在给节点分配 Pod 时,计算的是:“Node 1 还剩 2G 物理内存,正好可以塞进一个 2G 的 Hermes 容器”。如果开启了 Swap,宿主机内存表面上被假内存撑大了,调度器就无法准确感知节点真实的资源极限,从而做出错误的调度决策,导致集群雪崩。
  • 面试硬核回答: > “K8s 的资源隔离与限额是基于 Linux 内核的 cgroups(控制组) 机制实现的。K8s 默认的设计理念是让容器完全在纯物理内存中运行,从而保证应用性能的确定性与可控性。因此,为了防止 cgroups 资源限额计算失效以及硬盘 I/O 导致集群响应雪崩,K8s 团队在代码中硬编码了检测:一旦发现系统开启了 Swap,kubelet 就会默认直接拒绝启动。”

# 💡 总结

做这三个操作,本质上就是“一山不容二虎”。把操作系统的这三个原生管家关掉,K8s 才能真正成为这台服务器上的“绝对独裁者”,从而由它来全权负责安全、网络和内存的调度。

理解了这三个底层逻辑后,在后续的 K8s 面试中,只要聊到集群初始化,你就能非常专业地从“组件冲突”和“cgroups 调度原理”这两个高阶维度来解释它们了。

# 疑问2

# 生成默认配置并修改

mkdir -p /etc/containerd

containerd config default | sudo tee /etc/containerd/config.toml# 修改 SystemdCgroup 为 true,并将默认沙箱镜像(Pause 容器)切到国内阿里云源

sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

sed -i 's|registry.k8s.io/pause:3.8|registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9|g' /etc/containerd/config.toml# 启动并开机自启

systemctl daemon-reload

systemctl restart containerd

systemctl enable containerd

# 1. 为什么要将 SystemdCgroup 改为 true?(🔥 面试超高频)

  • 大白话原因: 为了避免宿主机上出现“两个管家,互相打架”的混乱局面。

  • 底层逻辑: Linux 内核通过 cgroups(控制组) 来限制容器能用多少 CPU 和内存。但在 CentOS 8 等较新的 Linux 系统中,系统默认启动时是由 Systemd 来作为初始化和资源管理的总管(cgroup 驱动)。

    当你安装 Containerd 时,它默认的 cgroup 驱动是 cgroupfs(这是它自带的一个独立管理器)。

    这就出问题了:如果保持默认配置(false),系统里就会同时存在 Systemd 和 cgroupfs 两个驱动在抢着管资源。当服务器内存紧张时,cgroupfs 认为这个容器还能跑,但 Systemd 觉得它超标了、直接强行把容器进程杀掉(OOM)。这种“双驱动”模式会导致 K8s 极不稳定,容器经常莫名其妙崩溃。

    我们将它改为 true,就是强行命令 Containerd:放弃你自带的驱动,完全服从宿主机的 Systemd 管辖。这样 K8s(kubelet)和 Containerd 都用 Systemd,天下太平。

  • 面试硬核话术:

    “在现代化 Linux 发行版中,系统默认使用 Systemd 作为初始化系统并全权管理 cgroup 树。为了避免在单机上同时存在 systemd 和 cgroupfs 两种 cgroup 驱动导致资源配额计算冲突、甚至引发不确定性的 OOM Kills,Kubernetes 官方极力推荐驱动一致性原则。因此,我们在 Containerd 的 config.toml 中显式开启 SystemdCgroup = true,使整个容器栈统一使用 Systemd 驱动,从而保证生产环境的拓扑稳定性。”

# 2. 为什么要将 registry.k8s.io/pause 切换到阿里云源?

  • 大白话原因: 原生的基础镜像在国内下载不到(被墙了),不改的话你的 K8s 里的所有 Pod 永远无法启动,全部卡在 ContainerCreating 状态。

  • 什么是 Pause 容器?(核心考点): 在 K8s 的设计里,Pod 是最小调度单位,一个 Pod 里面可以跑多个业务容器(比如你的 Hermes Agent 加上一个旁路日志容器)。

    那么,同一个 Pod 里的多个容器,是如何做到无缝共享同一个 IP 地址和网络空间的呢?

    K8s 的天才设计就在这里:每当你创建一个 Pod,K8s 并不是先启动你的业务容器,而是先偷偷启动一个极其微小的、不干任何脏活累活的容器,这个容器就叫 Pause 容器(又叫基础设施/沙箱容器)。

    Pause 容器启动后,会向 Linux 内核申请一个独立的网络 Namespace。接着,你真正的业务容器(如 Hermes Agent)启动时,会通过 Linux 的 netns 技术,直接强行加入到这个 Pause 容器的网络里。这样,业务容器之间就可以直接通过 localhost 互相通信,并共享同一个 Pod IP。

  • 面试硬核话术:

    “Pause 容器是 Kubernetes 实现 Pod 概念的基石。在 CRI(如 Containerd)中,它是最先启动的沙箱容器(Sandbox Container),负责接管整个 Pod 的网络和 IPC Namespace。随后启动的业务容器通过 Container-Network 模式共享该网络命名空间。由于官方默认的 registry.k8s.io 镜像源在国内无法访问,会导致沙箱容器创建失败、Pod 持续卡在 ContainerCreating。因此需要将其重定向到阿里云等国内镜像源,以保证 K8s 基础底座能够顺利初始化。”

# 💡 总结最后三句命令:

systemctl daemon-reload # 重新加载操作系统的服务配置文件
systemctl restart containerd # 重启 Containerd 顺便应用你刚才改的 SystemdCgroup 和 阿里云源
systemctl enable containerd # 设置开机自启,保证服务器重启后容器运行时自动活着

# 疑问3

# 原则一:三网绝对互斥(不能重叠)

在设计 K8s 集群时,以下三个网段绝对不能有任何交集,否则会导致严重的路由冲突,流量直接在内核里“鬼打墙”:

  1. Node 物理网段(你虚拟机的真实 IP 段,比如 192.168.1.0/24)
  2. Pod 虚拟网段(--pod-network-cidr)
  3. Service 虚拟网段(--service-cidr)

# 原则二:根据业务体量算好掩码(CIDR)

  • 为什么 Service 默认给的是 /12,而 Pod 给的是 /16?
  • 面试加分回答: “/16 意味着可以容纳 $2^{16}-2 = 65534$ 个 IP 地址。在 Flannel 网络模型中,它会为每个加入集群的 Worker 节点默认切分一个 /24 的子网(即每个子节点最多能跑 254 个 Pod)。我们在规划生产环境时,会根据预期加入的最大节点数和单节点 Pod 密度,来倒推并自定义 --pod-network-cidr 的掩码大小,防止未来业务扩容时 IP 地址枯竭。”

# 原则三:禁止与公司现有内网冲突

如果你把 K8s 的 Pod 网段自定义成了 192.168.0.0/16,而你们公司办公区的 Wi-Fi 刚好也是 192.168.x.x,那就会导致你的 K8s 容器在试图访问公司内部系统时,误以为是访问集群内部的 Pod,导致网络彻底断开。所以生产环境一般会选一个公司绝对没人用的冷门私有网段。

现在你对这两个参数的含义和底层的网络结构完全吃透了吧?如果你的 Master 节点 IP 已经准备好,就可以把这行 kubeadm init 替换并砸进终端,开始唤醒你的 K8s 大脑了!

阅读全文
×

(为防止恶意爬虫)
扫码或搜索:HelloCoder
发送:290992
即可永久解锁本站全部文章

解锁
#常见疑问
上次更新: 2026-06-13 17:29:54
最近更新
01
(一)线程是什么
06-14
02
MySQL支持的锁有哪些
06-13
03
HTTP 是不保存状态的协议, 如何保存用户状态
06-13
更多文章>
Theme by Vdoing | Copyright © 2020-2026 HaC
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式