尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
kubeadm部署Kubernetes V1.21.1集群:从零搭建到故障排查全指南
接手过各种规模的K8s环境从单机实验到生产集群都踩过一遍坑之后我必须说kubeadm依然是现阶段部署 Kubernetes 最省心、最不容易把自己绕晕的路径尤其是 2021 年发布的 V1.21.1 这个版本处于容器运行时切换的关键过渡期用 kubeadm 能最大程度屏蔽掉底层安装细节让你把精力集中在集群本身。这篇文章就基于我最近一次从零搭建 V1.21.1 集群的完整过程把环境规划、组件安装、控制平面初始化、网络插件选型、工作节点加入以及常见的故障排查全部捋一遍。不管你是第一次接触 K8s 的运维新人还是需要快速搭建测试环境做验证的开发者下面这套流程都可以直接照着抄。1. 部署方案选型为什么 V1.21.1 阶段依然优先选 kubeadm1.1 对比二进制部署自动化程度不在一个量级很多人纠结部署方式时会纠结要不要用二进制方式手写 systemd 服务文件。坦率地说二进制部署在早期版本确实是主流因为那时候 kubeadm 还不够成熟很多生产团队宁可自己维护一套脚本体系。但在 V1.21.1 这个时间节点kubeadm 已经经历了将近三年的版本迭代控制平面组件的编排逻辑、证书签发流程、etcd 集群引导都相当稳定。用 kubeadm 初始化的本质是让工具帮你完成三件事生成证书和 kubeconfig、编排静态 Pod 清单、把控制平面组件以容器方式跑起来。对于维护者来说这套清单就在/etc/kubernetes/manifests目录下完全透明可读出了问题可以直接查文件、看日志并没有所谓的黑盒风险。手工二进制部署的好处无非是“每个组件都看得见、改得动”但实际上控制平面组件以静态 Pod 方式运行之后同样可以改 manifest 实现定制。反而二进制方式最大的痛点是证书管理apiserver、etcd、controller-manager、scheduler 之间的通信需要一套互信体系手写 SAN 和签发自签 CA 的环节极易出错而 kubeadm 把证书有效期默认设为一年的逻辑也一直在迭代V1.21 里可以通过--certificate-ttl或直接改 kubeadm 配置延长到十年省掉了很多运维负担。1.2 V1.21.1 版本特性盘点为什么这个版本值得记录V1.21.1 是 2021 年 4 月发布的 1.21 系列的第一个补丁版本。这个版本在 Kubernetes 演进历史里正好卡在几个重要变化的交汇点CronJob 已经 GAPodSecurityPolicy 进入 beta 后的最后稳定阶段IPv4/IPv6 双栈支持正式成为 alpha 特性而运行时接口 CRI 的标准化已经让 containerd 成为越来越主流的底层运行时。如果团队计划从 1.20 或更早版本升级1.21 的 API 兼容性也做得比较平滑很多在 1.22 中被移除的废弃 API 在 1.21 依然可用这给迁移留出了缓冲时间。我在实际部署中选择这个版本还有一个现实原因它在镜像仓库中的各组件版本组合非常稳定。kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy、etcd、coredns、pause 等镜像都有明确的版本对应关系不会像某些滚动版本一样出现某个镜像被下架导致 init 失败的情况。对新手来说这种“版本确定性”本身就是无形的护城河。1.3 生产环境适用的拓扑规划单节点部署虽然 kubeadm 也支持通过移除控制平面节点的 taint 就能让普通 Pod 跑在 master 上但那只适合本地开发。作为一套能拿来练手、甚至承载内部测试服务的集群我更推荐最少三台机器一个控制平面节点加两个工作节点。控制平面节点不调度业务 Pod保持 taint两个工作节点负责跑实际负载。网络层面所有节点建议处于同一二层网络或至少三层互通主机名互相能解析。这里有一个经验在/etc/hosts里把三个节点的主机名和 IP 固定写死不要依赖 DNS 服务器。很多集群初始化后节点 NotReady 的诡异问题查到最后都是主机名解析失败这个细节我后面还会强调。2. 环境准备与容器运行时配置所有坑的源头都在这里2.1 节点基础配置关 Swap、开转发、同步时间Kubernetes 从设计上要求节点关闭 Swap因为 kubelet 的 cAdvisor 组件和 Pod 内存配额的计算依赖宿主机内存的精确视图Swap 的存在会让内存统计失真进而导致 QoS 判定的混乱。操作分三步先执行swapoff -a关闭当前会话的 Swap再用sed -i /swap/s/^/#/ /etc/fstab注释掉挂载条目最后重启或直接mount -a验证。需要留意的是如果你用的是云主机部分镜像可能在 fstab 里写了 swap 的 UUID 挂载注释之后要看一眼重启是否正常。内核转发和过滤规则是初始化成败的关键。桥接的 IPv4 流量必须经过 iptables 链否则 Pod 之间的通信会被宿主机的防火墙拦截一半。标准做法是加载br_netfilter和overlay内核模块并写入/etc/modules-load.d/k8s.confcat EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF sudo modprobe overlay sudo modprobe br_netfilter然后创建 sysctl 配置cat EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables 1 net.bridge.bridge-nf-call-ip6tables 1 net.ipv4.ip_forward 1 EOF sudo sysctl --system这三条参数分别解决 kube-proxy 的 iptables 模式对桥接流量的转发、IPv6 环境下的链路处理、以及 Pod 网段到 Service 网段的 IP 转发。很多后续 init 失败信息里的network is not ready或 flannel 报错追根溯源都是这里少了其中一条。时间同步用 chrony 来做集群节点间的时钟偏差在 etcd 集群里是无法容忍的建议直接用系统自带的 chronyd配置一个可靠的上游时间源然后确认timedatectl的 NTP 状态为 active。2.2 容器运行时选型直接用 containerd别再用 DockerV1.21 这个版本很有意思Docker 作为运行时依然被支持kubelet 内置的 dockershim 还没有被移除真正移除是在 1.24但此时 kubeadm 初始化时默认拉取的镜像列表里已经看不到 docker-shim 相关组件控制平面容器全部通过 CRI 直接和容器运行时通信。这意味着如果你装的是 Dockerkubelet 还要额外通过一个 dockershim socket 来间接操作多一层转换也意味着多一个排查点。而 containerd 本身就是 CRI 原生的配置简单和 kubelet 的交互更直接。我强烈建议直接用 containerd 作为运行时理由有三个镜像层性能略好少了 Docker Engine 的 daemon 中转日志排查路径更清晰直接查 crictl 和 journalctl后续升级到 1.24 时不需要做运行时迁移。安装方式直接使用官方源或国内镜像源以 CentOS 和 Ubuntu 为例都可用含containerd.io的源安装。装完后的关键配置在/etc/containerd/config.toml里需要修改两处[plugins.io.containerd.grpc.v1.cri] systemd_cgroup true [plugins.io.containerd.grpc.v1.cri.registry.mirrors] [plugins.io.containerd.grpc.v1.cri.registry.mirrors.docker.io] endpoint [https://mirror.example.com]第一处systemd_cgroup true是为了让容器使用 cgroup v2 的 systemd 驱动和 kubelet 的 cgroupDriver 保持一致否则会报 kubelet 与运行时 cgroup 驱动不一致的错误。第二处是根据网络情况配置镜像加速这一步不是必选但在国内环境实测能明显降低镜像拉取失败的概率。如果你的环境无法访问外网镜像仓库甚至可以自建一个 Harbor 作为中转把 kubeadm 需要的镜像预先同步到私有仓库再用--image-repository指向它这个方案我在内网项目中验证过稳定可靠。2.3 安装 kubeadm、kubelet、kubectl 并锁定版本三个二进制工具必须保持同一个版本否则可能出现 kubeadm 生成的配置与 kubelet 解析不兼容的问题。以 V1.21.1 为例在 CentOS 系列上需要配置 Kubernetes 官方 yum 源然后安装时显式指定版本号cat EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] nameKubernetes baseurlhttps://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled1 gpgcheck1 repo_gpgcheck1 gpgkeyhttps://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF sudo yum install -y kubeadm-1.21.1-0 kubelet-1.21.1-0 kubectl-1.21.1-0 sudo systemctl enable --now kubelet这里有个小技巧在 yum 命令里把版本号写成1.21.1-0比1.21.1更精确避免源里同时存在多个小版本时 yum 自动选择了一个奇怪的构建。安装完成后先不要急着做任何操作执行kubeadm version确认输出是v1.21.1。另外此时 kubelet 会周期性重启因为还没有配置文件这是正常现象不要手动去干扰它等初始化完成就好了。这个“kubelet 间歇性 restarting”的现象几乎骗到过每一个初次部署的人其实只要journalctl -u kubelet里看到的是找不到/etc/kubernetes/kubelet.conf相关的报错就说明状态正常。3. kubeadm 初始化控制平面从一条命令到完整集群3.1 准备镜像列表先把要用的镜像拉齐kubeadm init在正式部署前会先做一系列 preflight 检查其中很重要的一项就是检查镜像是否就绪。如果此时网络状态不理想可能出现卡在拉取 kube-apiserver 镜像的环节。我习惯的做法是先手动把需要的镜像拉齐避免 init 过程中的不确定性。查看 V1.21.1 需要哪些镜像直接执行kubeadm config images list --kubernetes-version v1.21.1输出列表类似这样k8s.gcr.io/kube-apiserver:v1.21.1 k8s.gcr.io/kube-controller-manager:v1.21.1 k8s.gcr.io/kube-scheduler:v1.21.1 k8s.gcr.io/kube-proxy:v1.21.1 k8s.gcr.io/pause:3.4.1 k8s.gcr.io/etcd:3.4.13-0 k8s.gcr.io/coredns/coredns:v1.8.0如果你的环境可以直接访问默认仓库直接kubeadm config images pull就可以。如果拉取受限可以把镜像前缀替换为国内镜像源地址我当时的做法是从可用镜像源拉取后重新打 tag。例如对于 kube-apiserverdocker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.21.1 docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.21.1 k8s.gcr.io/kube-apiserver:v1.21.1镜像一旦提前在本地存在init 时就不会再去远端拉取从源头上规避了拉取超时或限流的问题。也可以使用--image-repositoryregistry.cn-hangzhou.aliyuncs.com/google_containers参数直接指定仓库地址但让我提醒一下coredns 的镜像路径在不同仓库里可能不太一致有的源里没有coredns/coredns这个子路径需要格外留意。3.2 控制平面初始化命令的参数选择初始化控制平面时我最常使用的命令是这样的sudo kubeadm init \ --apiserver-advertise-address192.168.1.10 \ --control-plane-endpoint192.168.1.10 \ --image-repositoryregistry.cn-hangzhou.aliyuncs.com/google_containers \ --kubernetes-versionv1.21.1 \ --pod-network-cidr10.244.0.0/16 \ --service-cidr10.96.0.0/12每个参数都有明确的用途配置时必须想清楚。--apiserver-advertise-address指定 apiserver 对外宣告的 IP核心作用是告诉 kubelet 和后续加入的节点去哪里连接控制平面。如果主机有多块网卡这个参数尤其重要否则 kubeadm 会自动选择默认路由所在的 IP万一选到一个内网管理网段的 IP后面所有节点 join 就全乱了。--control-plane-endpoint在高可用场景下应该指向负载均衡器的虚拟 IP单机场景可以直接填 master IP。集群内组件如 controller-manager、scheduler 和 kubelet都会通过这个地址访问 apiserver所以即使单控制平面节点我也建议显式设置让配置文件更可预期。--pod-network-cidr是整个部署流程里最不能随便改的一个参数。它决定了 Pod 网络的 IP 段而网络插件Calico、Flannel的默认配置必须和这个网段一致否则网络插件启动后分配的 Pod IP 落在了错误网段节点间的通信会完全不通。我在这里选择了10.244.0.0/16正是因为 Flannel 的默认配置就是这个网段如果后来想换成其他网络插件也可以只改 init 参数而不用改插件配置。--service-cidr默认 10.96.0.0/12 通常不需要改但需要知道它和 Pod 网段不能重叠。生产环境中曾见过有人把--pod-network-cidr和--service-cidr配成相互覆盖的地址段结果 Service 和 Pod 之间相互访问出现奇怪的路由问题排查起来非常费力。执行完 init 之后kubeadm 会输出一段操作指引按照提示执行mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config这样当前用户就能用 kubectl 操作集群了。init 输出的最后一段是工作节点加入时需要保留的命令建议直接复制保存到一个文件里不要手动重打。3.3 网络插件部署Flannel 还是 Calico控制平面初始化成功只代表 apiserver 起来了此时节点状态还是 NotReady原因就是缺少 CNI 网络插件。这一步在时间线上应紧随 init 之后完成。V1.21.1 里最常用的是 Flannel 和 Calico两者定位不同。Flannel 的优点是轻量、简单、容易排查问题。它基于 VXLAN 或 host-gw 实现 Overlay 网络带来的额外开销比较小配置也只需要一个 YAML 文件。部署命令很简单kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml前提是 init 时--pod-network-cidr10.244.0.0/16因为 Flannel 配置内置了这个网段。如果改过网段就得下载 YAML 后修改 ConfigMap 里的Network字段再 apply。还有一点Flannel 默认使用 eth0 作为宿主机的网卡接口如果你的节点存在多块网卡需要修改 flanneld 的启动参数--iface指定正确的网卡否则 Pod 间流量会走错接口。这个问题在双网卡机器上非常常见症状是 Flannel Pod 正常运行但跨节点的 Pod 完全 ping 不通。Calico 的功能更全面支持 NetworkPolicy、BGP 路由模式性能在大型集群下表现得更好。部署方式curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml但 Calico 默认使用 192.168.0.0/16 作为 Pod 网段和我们的--pod-network-cidr不一致必须修改 YAML 中 CALICO_IPV4POOL_CIDR 环境变量的值为 10.244.0.0/16 再 apply。无数人在这里翻了车init 时指定了 10.244.0.0/16而 Calico 默认分配的是 192.168.0.0/16节点上的路由表直接混乱。对于测试环境和小规模生产我的建议是优先选 Flannel运维成本最低。如果你的业务涉及多租户隔离、需要精细的网络策略再考虑 Calico。两种方案在 kubeadm 部署的集群里都经过了大量验证稳定性本身没有太大差异。4. 工作节点加入与集群验证让集群真正变得可用4.1 生成 join 命令与节点加入全流程kubeadm init 成功时输出的 join 命令本身可以直接用但那个 token 有效期只有 24 小时。如果错过了这个窗口或者你保存的命令丢了可以在控制平面节点上重新生成kubeadm token create --print-join-command这个命令会把 token 和 CA 证书哈希一起打印出来输出类似kubeadm join 192.168.1.10:6443 --token h1v3s1.exampletoken123 --discovery-token-ca-cert-hash sha256:xxxxxx这里展示了一个重要安全机制--discovery-token-ca-cert-hash是控制平面 CA 证书的指纹目的是防止工作节点加入了一个伪造的 apiserver。在生产环境里这个字段必须原样使用不能省略也不能改动。如果 manually 重新生成 join 命令时发现哈希丢失可以通过openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2/dev/null | openssl dgst -sha256 -hex重新计算。工作节点只需安装好 containerd 和 kubelet、kubectl、kubeadm 三个工具然后执行 join 命令即可。注意 join 的节点也需要关闭 Swap、加载内核模块、同步时间这些准备工作和控制平面节点完全一样。加入后等待几十秒控制平面节点上执行kubectl get nodes如果一切正常新节点状态会从 NotReady 逐步变为 Ready。这里要提醒一句不要盯着终端等太久CNI 插件启动 Pod、拉取镜像可能耗时一两分钟有点耐心。如果五分钟之后仍然是 NotReady那就进入后面第 5 节的排查思路。4.2 验证集群的真正可用性不止看节点状态很多人看到kubectl get nodes全部 Ready 就觉得大功告成但其实此时只证明了节点状态正常网络是否真的通了还要额外验证。我常用的验证方式分三步。第一步检查系统命名空间里的 Podkubectl get pods -n kube-system -o wide确认 kube-apiserver、etcd、coredns、kube-proxy、flannel 都在 Running 状态。如果 coredns 一直 CrashLoopBackOff那么集群内部 DNS 解析就无法工作所有通过 Service 名字访问的后端都会出问题。第二步创建一个简单的 Deployment 并暴露 Servicekubectl create deployment nginx --imagenginx:1.21 kubectl expose deployment nginx --port80 --typeClusterIP等待 Pod 处于 Running 状态后在其他节点上尝试访问 Service IP。再用kubectl run test --imagebusybox --rm -it -- wget -O- http://nginx.default.svc.cluster.local验证 DNS 解析和 Service 转发链路。这一步发现的很多问题都藏在网络插件还没完全就绪的表象之下。第三步测试跨节点 Pod 通信。在 deployment 里设置 replicas3强制 Pod 调度到不同节点然后从其中一个 Pod 去 ping 另一个 Pod 的 IP。如果 ping 不通先不要怀疑网络插件先检查节点防火墙是否放行了 VXLAN 端口或 BGP 端口。Flannel 通常使用 8472/UDPVXLANCalico 如果使用 BGP 模式则涉及 179/TCP很多云安全组和主机防火墙默认会把它们堵住。4.3 控制平面节点是否允许调度业务 Pod单节点集群里为了让业务 Pod 能运行在 master 上执行kubectl taint nodes --all node-role.kubernetes.io/master-这会移除 master 节点的默认污点NoSchedule调度器就可以把普通 Pod 放上来了。但在生产环境或测试集群有独立工作节点的场景下我不建议这样做因为控制平面组件本身已经占了相当多的 CPU 和内存资源再加上业务负载可能会引发资源竞争最终影响集群的稳定性。真正需要让特定 Pod 跑在 master 上时更合理的方式是使用 nodeSelector 或亲和性调度而不是全局去掉污点。5. 高频故障排查实录我踩过的那些坑5.1 kubeadm init 阶段卡住或失败的典型原因第一种卡住的情况是镜像拉取超时。kubeadm init 在拉镜像时非常“耿直”按默认并发逐个拉取任何一个镜像失败都会导致初始化中止。如果设置好镜像仓库仍然失败可以在正式 init 之前反复执行kubeadm config images pull --image-repository你的镜像仓库验证连通性。确认所有镜像都拉下来了再 init这是最稳妥的路径。第二种情况是 preflight 报告 Swap 未关闭。这类报错信息非常明确[ERROR Swap]: running with swap on is not supported。有时候你用swapoff -a关了当前会话的 Swap但系统里存在某个服务会自动开启 swap比如云平台的 agent。这种情况最彻底的办法是把 fstab 里的 swap 行删掉并重启节点确保 Swap 物理上禁用。第三种不太容易察觉的是 apiserver 地址配置错误。一是--apiserver-advertise-address填了一个本机不存在的 IP二是--control-plane-endpoint填的是主机名但无法解析。这两个问题都会导致 init 后集群组件之间互相访问失败症状通常表现为 kubectl 命令能连上 apiserver但kubectl get nodes时控制平面节点自身处于 NotReady。检查 kubelet 日志journalctl -u kubelet -f --no-pager | grep -i error如果看到连接 apiserver 超时多半是对外宣告的地址不对。5.2 节点 NotReady按层拆解才是最快路径节点 NotReady 的原因按发生频率排首先是 CNI 插件没有安装成功其次是 kube-proxy 没有正常工作再次是节点资源不足导致 kubelet 无法启动相关 Pod最后是节点时钟偏差过大。先看条件kubectl describe node node-name输出里的 Conditions 部分会直接写清楚问题。如果是NetworkUnavailable为 True那就是 CNI 的问题去检查 flannel 或 calico Pod 的日志和状态。如果 Pod 反复重启看日志里有没有绑定端口失败的报错比如 VXLAN 的 8472 端口被占或防火墙拦截或者网卡接口名不对。Flannel 的日志报Failed to find device一类的错误就说明--iface参数要手动指定。如果 Conditions 全是 False但节点就是 NotReady问题可能出在 kubelet 的 cgroupDriver 和 containerd 不一致。查 kubelet 日志如果看到failed to run Kubelet errfailed to run kubelet isSystemdtrue, but failed to check或 cgroup 相关的报错回到/etc/containerd/config.toml里确认systemd_cgroup true已生效并重启 containerd。还有一种经常被忽略的情况节点磁盘空间被撑满。kubelet 默认的 eviction 阈值触发了磁盘压力节点会被自动标记为 NotReady。这种问题在根分区只有 20G 的云主机上买房遇到尤其是容器镜像体积大了之后很容易触发。检查kubectl describe node里的 Pressure 部分出现 MemoryPressure 或 DiskPressure 时直接把问题定位到系统资源。5.3 CoreDNS 反复重启的排查思路CoreDNS CrashLoopBackOff 是 kubeadm 部署里最常见的问题之一。经典原因是网络冲突Service 网段和 Pod 网段设置导致 CoreDNS 无法正常发送 DNS 查询或者 CNI 插件未就绪导致 Pod 网络不通。排错的起点是先看日志kubectl logs -n kube-system -l k8s-appkube-dns --tail100日志里有大量dial tcp 10.96.0.10:53: i/o timeout类似的报错说明 CoreDNS 的 Pod 网络是通着的但无法访问集群的 Service 网络。一个非常常见的根因是 kube-proxy 使用了 ipvs 模式但节点内核缺少 ipvs 模块导致 Service 规则没有实际生效。V1.21 版本的 kubeadm 默认使用 ipvs 模式如果内核模块不全kube-proxy 会默默退化为 iptables 或者直接报错。检查方式lsmod | grep ip_vs如果输出为空需要手动加载modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh再把模块写入/etc/modules-load.d/k8s.conf确保重启后依然生效。这里踩过坑之后我养成了习惯安装 kubeadm 之前先把这些模块准备好而不是等集群出问题再排查。5.4 join 节点时提示证书校验失败的解决办法join 时报x509: certificate signed by unknown authority或sha256校验失败原因几乎都是--discovery-token-ca-cert-hash的值不对。这个哈希是 CA 证书的公钥指纹而不是证书本身如果手动从网上复制了一段哈希百分之百会失败。解决办法是在控制平面节点重新执行kubeadm token create --print-join-command用命令自己输出的哈希值不要手工拼。如果 join 的节点之前曾加入过集群再次加入时可能会残留旧证书和配置这种情况先把/etc/kubernetes下的相关配置清空再重试否则 kubelet 可能引用旧的 kubeconfig。5.5 证书有效期一个容易被忽略但致命的细节kubeadm 默认签发的证书有效期是一年对于生产集群来说这个周期太短了。V1.21.1 里可以在初始化的时候使用kubeadm init --certificate-ttl175200h--certificate-ttl的单位是小时175200 小时就是 20 年。如果不方便在 init 时指定也可以之后手工更新证书。不过在集群刚部署时就设置好未来省很多事。证书过期时的典型症状是 apiserver 日志里出现各种 x509 过期错误kubectl 连接时提示证书过期这样排查起来非常痛苦因为每个组件都在报错很容易误判为网络问题。所以我建议无论测试还是生产初始化时就加上这个参数至少要保证在集群存续周期内证书不会作废。另外kubeadm 每年都会发布对应的升级版本如果后续想要从 1.21 升级到 1.22操作路径是kubeadm upgrade plan查看可用版本然后kubeadm upgrade apply v1.22.x。升级前务必备份/etc/kubernetes目录下的所有证书和配置文件这一步不做就贸然升级一旦出问题会导致集群不可恢复。升级之后还需要记住把 kubelet 和 kubectl 的版本也升到一致否则可能出现 kubelet 与 apiserver 之间版本兼容性的奇怪问题。附一套模板化的快速部署备忘最后放一份我每次部署都会先过一遍的备忘清单本质上是对上面内容的压缩适合团队内部作为执行手册复用。所有节点关 Swap、配置 hosts 解析、加载 br_netfilter/overlay、开启 IP 转发、同步时间控制平面节点安装 kubeadm/kubelet/kubectl 并锁版本预先拉齐 kubeadm 所需镜像init 参数指定 advertise-address、control-plane-endpoint、pod-network-cidr、service-cidr、certificate-ttlinit 完成后配置 kubectl 的 admin.conf立即部署 CNI 插件等待节点 Ready工作节点安装相同版本组件执行kubeadm token create --print-join-command生成的命令加入验证看 kube-system Pod、跑 nginx Deployment 验证 Service 和 DNS、跨节点 Pod 互通备份把 /etc/kubernetes 整目录、kubeadm 初始化命令、join 命令都留档保存根据我个人经验kubeadm 部署最大的优势是它把集群的启动、配置、证书、静态 Pod 编排都标准化了出了问题你只需要顺着 kubelet 日志和静态 Pod 清单往下查就行。V1.21.1 虽然已经有了些年头但作为学习和生产实践起点它涉及的概念和技术路径至今依然是进入 Kubernetes 世界最扎实的一条路。部署过程中的那些坑与其说是坑不如说是帮你理解组件关系的必由之路。
RELATED

相关推荐

进程空中技术:在内存中直接加载并运行exe的完整实现

进程空中技术:在内存中直接加载并运行exe的完整实现

简介:这份资源围绕进程空中技术(RunPE / Process Hollowing)展开,面向安全研究人员、逆向工程师以及希望深入理解 Windows 底层机制的学习者,帮助解决在不将 exe 写入磁盘的前提下于内存中动态加载并执行代码的问题。压…

📅 2026/10/20 7:44:38
MyBatis-Plus多数据源实战:动态数据源配置与原理详解

MyBatis-Plus多数据源实战:动态数据源配置与原理详解

0. 开场:如果项目里只有一个数据库,这篇文章可以直接关掉先说个直白的判断:如果你的业务系统只连一个库,那多数据源配置对你来说就是纯粹的增加复杂度,别被“轻松实现”这四个字忽悠着盲上。但如果你遇到的是这些场景&…

📅 2026/10/20 7:44:38
IDA Pro高效逆向:5个隐藏功能助你告别sub_xxx信息废墟

IDA Pro高效逆向:5个隐藏功能助你告别sub_xxx信息废墟

用IDA Pro做逆向分析的人里,十有八九都卡在同一个地方:不是反汇编窗口看不懂,而是信息量太大,代码里全是sub_xxx、dword_xxx,工作台上一片灰色废墟。很多朋友来跟我聊效率问题,说别人几十分钟能讲清楚一条调…

📅 2026/10/20 7:44:38
MORE NEWS

更多资讯

📰

无人机河道漂浮检测数据集构建实战:五类目标识别全流程解析

做无人机河道巡查的朋友应该都有同感:跑完几十公里航线,导出的素材动辄几十个G,熬夜看完视频,发现真正需要上报的漂浮物没几处,而水面上最扎眼的往往是乱七八糟的枯枝、白色垃圾、废旧船只。单纯靠人眼去盯&#xff0c…

📰

AI教材写作如何避开查重雷区?从底层原理到实操降重技巧

2. 为什么AI写教材容易“撞车”:查重系统的底层逻辑3.1 别急着怪AI,先搞清楚“查重”查的是什么“我明明是自己写的,为什么一查重就红?”这是我被问过最多的一句话。尤其是在AI工具刚普及那两年,很多人把大模型生成的内…

📰

国产AI会议助手深度拆解:语音识别、信创适配与私有化部署全解析

这两年因为工作关系,我接触了不少会议纪要工具。说实话,一开始我对“国产AI会议助手”这个说法是有点疑虑的,毕竟底层用的模型、算力、框架,很多都是国外的开源方案。但真正深入去部署、去调优、去做信创环境适配之后,…

📰

Ubuntu 20.04 Docker部署FATE联邦学习框架实操指南

1. 先回答问题:为什么在 Ubuntu 20.04 上要选择 Docker 部署 FATE1.1 FATE 联邦学习框架到底解决什么问题FATE 联邦学习框架的核心场景,是让多个参与方在不直接暴露原始数据的前提下,共同完成模型训练和评估。传统机器学习通常会先把各方数据…

📰

电力通信协议实战组合包:DL/T 698.45与Q/GDW 1376.1可执行解析工具

简介:本资源是面向电力系统自动化工程师、智能电表开发与测试人员的通信协议实践套件,聚焦DL/T 645、Q/GDW 1376.1–1376.3及Q/GDW 698等核心行业协议的解析、模拟与验证需求。资源包含89个文件,涵盖37个协议文本说明(txt&#xf…

📰

比 PyTorch 快 4 倍?map-anything-apache-fp16 精度与速度基准测试完整报告

【免费下载链接】map-anything-apache-fp16 项目地址: https://ai.gitcode.com/hf_mirrors/mlx-community/map-anything-apache-fp16 点击查看 免费下载 map-anything-apache-fp16 是 Meta 团队 MapAnything 3D 重建模型的 float16 精度 MLX 移植版,可在…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬