
直接从头开始给您写一篇完全符合要求的博文。整个正文将围绕 Kubernetes 1.35.1 二进制部署展开内容全部链路、原理、步骤和排错都会写进去直接可用。1. 为什么我坚持用二进制方式部署 Kubernetes 1.35.1先说结论如果你只是想快速搞一套开发测试环境kubeadm 一把梭没问题但如果你要交付生产集群或者你要面试、要真正搞懂 Kubernetes 的组件协作关系那你迟早要过一遍二进制部署。1.1 kubeadm 与二进制部署的本质区别kubeadm 的核心思路是“把复杂留给自己把简单交给用户”。你只要 kubeadm init它就会自动帮你生成证书、生成 kubeconfig、以静态 Pod 的方式把 kube-apiserver、kube-controller-manager、kube-scheduler、etcd 全部跑起来。整个过程不超过五分钟非常方便。但它的代价是证书怎么签发、组件之间怎么认证、kubelet 如何注册、kube-apiserver 的启动参数到底影响了什么这些关键信息全被封装进了黑盒。集群出问题的时候很多人只会 kubectl get nodes、kubectl logs一旦遇到证书过期、Kubelet 无法注册、apiserver 高可用架构设计问题就很难定位到根因。二进制部署则完全相反。你需要手动下载各组件二进制文件自己用 openssl 签发一整套证书体系手写所有 systemd 管理文件手动规划 etcd 集群手动把 kubelet 和 kube-proxy 配上节点。每一步你都清楚正在做什么以及为什么这么做。这就像同样是把菜做熟kubeadm 是买了净菜回家下锅炒二进制是把食材从洗菜切菜开始一步步处理。前者快后者让你真正掌握火候。1.2 适合二进制部署的场景与团队在我实际接触的项目里有几类场景我强烈建议用二进制方式搭建第一类是企业内部私有化交付。甲方机房往往没有外网不能从 Google 的镜像仓库拉组件kubeadm 的默认镜像托管策略会直接卡死。二进制文件拷贝进去就能跑这是最可靠的离线交付手段。第二类是信创或国产化适配环境。底层操作系统可能是麒麟、UOS、OpenEuler 等kubeadm 的某些静态 Pod 镜像在国产架构上不一定有现成可用的 tag二进制方式可以灵活规避这个问题。第三类是 K8s 学习者和面试候选人。你只有亲手部署过二进制集群才真正理解 Pod 调度、证书认证、etcd 选举、CNI 网络插件这四件事是怎么串起来的。面试官问“kubelet 是怎么找到 apiserver 的”答案就在你自己写的 kubeconfig 文件里。1.3 部署前的架构规划决定你后面省不省心很多人一上来就找一台机器开始敲命令结果装到一半发现 etcd 端口和 apiserver 端口冲突或者高可用方案也没设计只能推倒重来。我建议你在动手前先规划好这几点控制平面与工作节点分离。即使是测试环境也建议至少准备两台机器一台作为 master一台作为 worker。这样能完整模拟生产环境的组件分布逻辑后面排错时思路也会更清爽。etcd 集群独立部署。Kubernetes 的 etcd 存储了集群所有状态一旦数据丢失就是灾难。二进制部署时可以先把 etcd 跑成 3 节点集群也可以单节点先跑通但一定要知道 etcd 的 member 列表和管理方式。版本配套关系提前确认。Kubernetes 1.35.1 是相对较新的版本分支需要确认对应的 etcd、containerd、CNI 插件的兼容版本范围。一般推荐 etcd 3.5.xcontainerd 1.7.xFlannel 或 Calico 选当前稳定版避免新版本组件之间的接口不兼容。规划好这三点后续每一步都不会跑偏。2. 从裸机到符合要求的机器环境初始化实操2.1 硬件要求与系统环境准备二进制部署对硬件的要求与 kubeadm 部署完全一致并没有因为“手动安装”就更低。控制平面节点建议至少 4 核 CPU、8GB 内存工作节点 2 核 4GB 起步。存储方面etcd 对磁盘 IOPS 比较敏感如果有条件尽量给 etcd 单独挂一块 SSD而不是和系统盘混用。操作系统我以 CentOS 7.9 为例RHEL、Rocky、Ubuntu 20.04 的操作方式也大同小异。系统的基础要求有几点关闭 swap。K8s 的 kubelet 默认不允许 swap 存在虽然新版本支持了 Swap 特性但仍不建议开启。关闭防火墙或放行 K8s 所需端口。测试环境我直接关掉 firewalld生产环境则需要按端口清单放行。关闭 SELinux 或设置为 permissive。配置好主机名、/etc/hosts 以及时间同步。2.2 主机名、hosts 与时间同步配置每台机器的 /etc/hosts 里要写清楚所有节点的对应关系包括 master 和 worker。比如规划三台机器192.168.31.71 k8s-master01 192.168.31.72 k8s-master02 192.168.31.73 k8s-master03 192.168.31.61 k8s-node01这个 hosts 文件要同步到所有节点因为 kubelet 与 kube-apiserver 之间的通信、etcd 集群内部的 peer 通信都需要通过主机名进行解析。如果使用 IP 直连也可以但后期证书里的 SAN 配置会非常痛苦建议从一开始就把主机名解析规划好。时间同步使用 chrony 或者 ntpd 都可以K8s 的证书校验非常依赖时间一致性。如果某台节点时间偏差超过 5 分钟kubelet 调用 apiserver 时证书校验会直接失败报错信息还不一定直白。2.3 内核参数与系统模块调整Kubernetes 集群的网络转发依赖一组内核参数最重要的两个是net.bridge.bridge-nf-call-iptables 1 net.ipv4.ip_forward 1这两个参数不配置会导致 Pod 之间通信异常、Service 转发失效特别是在使用 Flannel 或 Calico 这类基于 iptables / IPVS 的网络方案时问题尤为突出。建议把这些参数写到 /etc/sysctl.d/k8s.conf 里然后执行 sysctl --system 使其生效。还需要加载 br_netfilter 和 overlay 内核模块modprobe br_netfilter modprobe overlay echo br_netfilter /etc/modules-load.d/k8s.conf echo overlay /etc/modules-load.d/k8s.conf这两个模块是容器网络和容器文件系统正常工作的重要基础很多人在部署时跳过这一步后面启动 Pod 报错才回过头来找。2.4 容器运行时为什么我选 containerdKubernetes 从 1.24 版本开始移除了 dockershimDocker 不再作为默认容器运行时直接集成。现在最主流的方案是 containerd它本身就是 Docker 底层的容器运行时API 更精简、资源占用更少。二进制安装 containerd 的直接方式是从 GitHub Release 页面下载对应架构的压缩包解压到 /usr/local 目录然后生成默认配置containerd config default /etc/containerd/config.toml生成配置后需要修改两个地方一个是 SystemdCgroup 改为 true这个参数决定 containerd 是否使用 systemd 的 cgroup 驱动与 kubelet 的 cgroup 驱动保持一致另一个是 sandbox_image 改成国内能拉到的 pause 镜像地址否则创建 Pod 时会一直卡在拉镜像阶段。containerd 通过 systemd 托管后使用 crictl 或 nerdctl 可以查看容器状态。crictl 是标准 CRI 客户端我常用它来做容器运行时的连通性测试。3. K8s 证书签发体系整个集群安全的基石3.1 需要哪些证书以及各自的用途Kubernetes 集群内部所有组件之间的通信都是 TLS 加密的除了 kube-proxy 与 apiserver 之间有可选的 http 模式其他全部基于证书或 Token。二进制部署时这套证书体系需要手动搭建这也是最容易劝退新手的环节。必须签发的证书主要包括证书用途签发对象CA 根证书签发其他所有证书集群内部信任的根etcd 服务端证书etcd 对外提供服务的 TLS 证书etcd 节点etcd peer 证书etcd 集群内部节点间通信etcd 节点kube-apiserver 证书apiserver 对外提供 HTTPS 服务master 节点apiserver 访问 kubelet 证书apiserver 与 kubelet 通信master 节点kube-controller-manager 证书CM 与 apiserver 认证master 节点kube-scheduler 证书scheduler 与 apiserver 认证master 节点kubelet 证书每个工作节点与 apiserver 通信worker 节点kube-proxy 证书kube-proxy 与 apiserver 认证worker 节点每个证书的 CN 和 SAN 配置都不太一样尤其需要注意 apiserver 证书要包含所有 master 节点的 IP、集群 Service 网段第一个 IP通常是 10.96.0.1、以及访问 apiserver 的域名。如果漏掉某个 IP后面用该 IP 访问 apiserver 时就会提示证书校验失败。3.2 用 openssl 签发证书的实际命令我习惯把证书统一放在 /etc/kubernetes/pki 目录下整个签发过程分四步。首先创建 CA 根证书和私钥mkdir -p /etc/kubernetes/pki cd /etc/kubernetes/pki # 创建 CA 私钥 openssl genrsa -out ca.key 2048 # 创建 CA 根证书 openssl req -x509 -new -nodes -key ca.key -subj /CNkubernetes-ca -days 36500 -out ca.crtCA 证书的有效期我一般设置成 100 年因为它是签发其他证书的根。子证书有效期默认 10 年K8s 运维中证书过期是非常常见的生产故障建议在根证书上把时间放宽减少后续轮换压力。以 kube-apiserver 证书为例需要创建一个 openssl 配置文件把 IP 和域名写入 SANcat apiserver-openssl.cnf EOF [req] req_extensions v3_req distinguished_name req_distinguished_name [req_distinguished_name] [v3_req] basicConstraints critical,CA:FALSE keyUsage critical,digitalSignature,keyEncipherment extendedKeyUsage serverAuth,clientAuth subjectAltName alt_names [alt_names] DNS.1 kubernetes DNS.2 k8s-master01 IP.1 192.168.31.71 IP.2 10.96.0.1 EOF然后生成私钥和证书请求再用 CA 签署openssl genrsa -out apiserver.key 2048 openssl req -new -key apiserver.key -subj /CNkube-apiserver -config apiserver-openssl.cnf -out apiserver.csr openssl x509 -req -in apiserver.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -extensions v3_req -extfile apiserver-openssl.cnf -out apiserver.crt其他证书的签发逻辑基本一致只是 CN、SAN 和用途不同。所有证书签发完成后按组件名称整理目录避免后续混淆。3.3 证书分发的注意事项与权限管理证书文件包含私钥一定要严格控制权限。我通常在所有节点上把 /etc/kubernetes 目录的属主设为 root私钥文件权限设为 600证书文件权限设为 644。kube-apiserver、etcd、kubelet 的证书需要分发到对应节点的 /etc/kubernetes/pki 目录。这里有一个很容易踩坑的地方etcd 的 peer 证书必须包含该节点所有可能的 IP包括内网 IP 和主机名对应的地址否则 etcd 集群组建时节点之间互相验证证书不通过集群永远无法形成 quorum。另外kubelet 的证书与前面几种不太一样它有两条路径一个是手动为每个 worker 节点签发独立的 kubelet 证书另一个是让 kubelet 启动时通过 TLS bootstrapping 自动向 apiserver 申请证书。我建议第一次部署时使用前者逻辑更直观也方便排查问题。等对证书机制熟悉了再切换成自动签发方式以提高运维效率。4. 把数据库先跑起来etcd 集群部署4.1 etcd 在 Kubernetes 中的角色定位etcd 是 Kubernetes 唯一的持久化存储保存了集群的期望状态、实际状态、配置信息、Secret 等敏感数据。etcd 挂了K8s 集群就变成了只读状态etcd 数据损坏了本质上是整个集群的元数据丢失。Kubernetes 1.35.1 对应的 etcd 版本建议选用 3.5.x。下载 etcd 二进制包后bin 目录下包含 etcd 和 etcdctl 两个可执行文件把 etcd 放到 /usr/local/bin把 etcdctl 放到 /usr/local/bin。然后创建数据目录和 systemd 服务文件。4.2 单节点 etcd 的配置方式在测试环境或 master 节点上直接运行 etcd 是最简方案但生产环境我不建议这么做。最少三节点 etcd 集群才能容忍一个节点故障。单节点 etcd 的 systemd 服务文件写法如下[Unit] DescriptionEtcd Server Afternetwork.target Afternetwork-online.target Wantsnetwork-online.target [Service] Typenotify ExecStart/usr/local/bin/etcd \ --nameetcd1 \ --data-dir/var/lib/etcd \ --listen-client-urlshttps://192.168.31.71:2379,https://127.0.0.1:2379 \ --advertise-client-urlshttps://192.168.31.71:2379 \ --listen-peer-urlshttps://192.168.31.71:2380 \ --initial-advertise-peer-urlshttps://192.168.31.71:2380 \ --initial-clusteretcd1https://192.168.31.71:2380 \ --initial-cluster-statenew \ --cert-file/etc/etcd/ssl/etcd-server.crt \ --key-file/etc/etcd/ssl/etcd-server.key \ --peer-cert-file/etc/etcd/ssl/etcd-peer.crt \ --peer-key-file/etc/etcd/ssl/etcd-peer.key \ --trusted-ca-file/etc/etcd/ssl/ca.crt \ --peer-trusted-ca-file/etc/etcd/ssl/ca.crt [Install] WantedBymulti-user.target有几个参数值得单独解释。Typenotify 是 etcd 特有的服务类型etcd 启动完成会向 systemd 发送通知systemd 认为服务启动成功。listen-client-urls 要包含 127.0.0.1这样后续在本地执行 etcdctl 时可以直接访问。advertise-client-urls 则必须写其他节点能访问的地址。三节点 etcd 集群需要将 initial-cluster-state 设置为 new并配置三组 peer 地址。启动第一台后后面两台会在几分钟内自动加入集群。用 etcdctl member list 可以查看成员状态endpoint health 可以查看健康情况。4.3 etcd 部署完成后的验证清单etcd 部署完成后不要急着部署上面控制平面先做一遍健康检查。用 etcdctl 带证书访问etcdctl --endpointshttps://192.168.31.71:2379 \ --cacert/etc/etcd/ssl/ca.crt \ --cert/etc/etcd/ssl/etcd-server.crt \ --key/etc/etcd/ssl/etcd-server.key \ endpoint health输出 healthy 就说明基本正常。再执行 endpoint status 可以查看每个节点的版本与 leader 信息。这一步验证的是证书、端口、网络三层问题。如果这里不通后面 K8s 控制平面的 apiserver 也无法连接到 etcd报错通常五花八门但根因都在 etcd 侧。5. 控制平面三件套apiserver、CM、scheduler 部署5.1 kube-apiserver集群的大脑与流量入口kube-apiserver 是所有 API 请求的统一入口包括 kubectl、kubelet、controller-manager、scheduler甚至 Pod 的调谐请求全部要经过 apiserver。它的可用性直接决定集群的可用性。apiserver 的 systemd 服务文件比 etcd 更复杂需要配置大量启动参数。核心参数包括绑定地址与端口默认 6443与 etcd 通信的地址和证书集群 Service 网段和 Pod 网段这两个网段一旦配置后期不能改授权模式、认证模式。一个可用的 apiserver systemd 配置示例[Unit] DescriptionKubernetes API Server Afternetwork.target Afteretcd.service [Service] ExecStart/usr/local/bin/kube-apiserver \ --bind-address0.0.0.0 \ --secure-port6443 \ --advertise-address192.168.31.71 \ --etcd-servershttps://192.168.31.71:2379 \ --etcd-cafile/etc/kubernetes/pki/ca.crt \ --etcd-certfile/etc/kubernetes/pki/apiserver.crt \ --etcd-keyfile/etc/kubernetes/pki/apiserver.key \ --service-cluster-ip-range10.96.0.0/12 \ --service-node-port-range30000-32767 \ --authorization-modeNode,RBAC \ --client-ca-file/etc/kubernetes/pki/ca.crt \ --service-account-key-file/etc/kubernetes/pki/sa.pub \ --service-account-signing-key-file/etc/kubernetes/pki/sa.key \ --service-account-issuerhttps://kubernetes.default.svc.cluster.local \ --kubelet-certificate-authority/etc/kubernetes/pki/ca.crt \ --kubelet-client-certificate/etc/kubernetes/pki/apiserver.crt \ --kubelet-client-key/etc/kubernetes/pki/apiserver.key [Install] WantedBymulti-user.targetservice-account-key-file 和 service-account-signing-key-file 需要提前生成这是 ServiceAccount Token 签发与验证的基础。命令很简单openssl genrsa -out sa.key 2048 openssl rsa -in sa.key -pubout -out sa.pub这两个文件同样放到 /etc/kubernetes/pki 目录。5.2 kube-controller-manager 与 kube-scheduler 的配置controller-manager 负责集群状态调谐比如确保 ReplicaSet 的副本数符合期望、Node 心跳异常时做驱逐等。scheduler 负责为新创建的 Pod 选择合适的节点。这两个组件都通过 kubeconfig 连接 apiserver。因此需要先生成对应的 kubeconfig 文件。kubeconfig 本质是把 apiserver 地址、客户端证书、CA 证书集合到一个配置文件中降低组件调用时的参数数量。controller-manager 的 systemd 示例[Unit] DescriptionKubernetes Controller Manager Afterkube-apiserver.service [Service] ExecStart/usr/local/bin/kube-controller-manager \ --kubeconfig/etc/kubernetes/controller-manager.kubeconfig \ --leader-electtrue \ --client-ca-file/etc/kubernetes/pki/ca.crt \ --root-ca-file/etc/kubernetes/pki/ca.crt \ --service-account-private-key-file/etc/kubernetes/pki/sa.key \ --cluster-signing-cert-file/etc/kubernetes/pki/ca.crt \ --cluster-signing-key-file/etc/kubernetes/pki/ca.key [Install] WantedBymulti-user.targetleader-electtrue 的作用是在多 master 节点部署时自动选主默认 lease 资源保存在 apiserver 里。scheduler 的配置与 controller-manager 非常类似只是可执行文件不同ExecStart/usr/local/bin/kube-scheduler \ --kubeconfig/etc/kubernetes/scheduler.kubeconfig \ --leader-electtrue5.3 控制平面启动后的首轮验证三个组件都配置好并启动后先不要急着加 worker 节点。先检查一下 apiserver 是否健康kubectl get --raw /healthz如果返回 ok说明 apiserver 基础服务正常。此时执行 kubectl get cs 可以看到 scheduler 和 controller-manager 的状态。但注意在较新的 K8s 版本中kubectl get cs 输出的虽然还是这些组件实际它们通过 leader election 状态展示未必能直接反映健康。需要配合 kubectl logs 查看组件日志。再执行 kubectl get nodes此时还没有任何节点加入输出为空是正常现象。整个控制平面的状态验证标准是etcd 健康、apiserver 健康、scheduler 与 controller-manager 没有持续报错日志。6. worker 节点接入kubelet 与 kube-proxy 的必备配置6.1 为 worker 节点生成 kubelet 证书与 kubeconfigworker 节点是真正运行业务容器的机器。kubelet 必须使用一个身份证书向 apiserver 注册并保持心跳。手动签发 kubelet 证书时CN 必须与该节点的用户名匹配一般是 system:node:节点名。生成 kubelet 证书的 openssl 配置类似于 apiserver但 SAN 需要包含当前节点的主机名和 IP。签发完成后将 kubelet.crt、kubelet.key、ca.crt 分发到 worker 节点的 /etc/kubernetes/pki 目录。然后生成 kubelet.kubeconfig。kubeconfig 中需要指定 apiserver 地址、证书和 CAkubectl config set-cluster kubernetes \ --certificate-authority/etc/kubernetes/pki/ca.crt \ --serverhttps://192.168.31.71:6443 \ --kubeconfig/etc/kubernetes/kubelet.kubeconfig kubectl config set-credentials system:node:k8s-node01 \ --client-certificate/etc/kubernetes/pki/kubelet.crt \ --client-key/etc/kubernetes/pki/kubelet.key \ --kubeconfig/etc/kubernetes/kubelet.kubeconfig kubectl config set-context default \ --clusterkubernetes \ --usersystem:node:k8s-node01 \ --kubeconfig/etc/kubernetes/kubelet.kubeconfig kubectl config use-context default --kubeconfig/etc/kubernetes/kubelet.kubeconfig6.2 kubelet systemd 配置与关键参数kubelet 的启动参数非常容易出错我挑几个关键项说明。cgroup-driver 必须与 containerd 保持一致的 systemd否则会持续报 kubelet cgroup 驱动错误。pod-infra-container-image 即 pause 镜像在离线环境必须配置成内网镜像地址。network-plugin 建议显式指定 cni因为 K8s 需要 kubelet 调用 CNI 插件网络配置。kubeconfig 指向刚生成的配置文件。register-nodetrue 表示让 kubelet 自动向 apiserver 注册 Node 资源。一个可用的 kubelet systemd 配置如下[Unit] DescriptionKubernetes Kubelet Aftercontainerd.service [Service] ExecStart/usr/local/bin/kubelet \ --kubeconfig/etc/kubernetes/kubelet.kubeconfig \ --config/etc/kubernetes/kubelet-config.yaml \ --node-ip192.168.31.61 \ --node-labelsnode-role.kubernetes.io/worker --cgroup-driversystemd \ --network-plugincni \ --pod-infra-container-imageregistry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9 \ --v2 [Install] WantedBymulti-user.targetkubelet-config.yaml 是 K8s 推荐的独立配置文件方式内容包含静态 Pod 路径、clusterDomain、clusterDNS 等。其中 clusterDNS 必须与 Service 网段设计匹配通常取 10.96.0.10。这个地址是 kubelet 注入给 Pod 的 DNS 解析地址错了的话所有 Pod 内域名解析都会失败。6.3 kube-proxy 的两种模式iptables 与 IPVSkube-proxy 负责实现 Service 的负载均衡也就是把 ClusterIP 的流量转发到后端 Pod。它有两种主要实现模式iptables 和 IPVS。iptables 模式兼容性最好逻辑简单但节点上 Service 数量多时会产生大量 iptables 规则性能下降明显。IPVS 模式基于内核 LVS支持更多调度算法性能更好但依赖 ipvs 内核模块。对于 1.35.1 版本我推荐使用 IPVS 模式尤其在业务规模较大的生产环境必须从部署初期就规划好。kube-proxy 的配置文件与 kubelet 类似也需要 kubeconfig 和一份配置文件。systemd 启动后可以用 ipvsadm -L -n 查看节点上生成的 IPVS 规则确认 Service 已经正确写入内核表。最后检查 worker 节点状态kubectl get nodes如果输出 Ready那你的 worker 节点已经成功接入集群。如果输出 NotReady优先看 kubelet 日志和 CNI 网络插件的状态这个问题下一节再展开。7. CNI 网络插件选型与集群最后的临门一脚7.1 Flannel 与 Calico 怎么选CNI 网络插件的职责是给每个 Pod 分配集群内唯一的 IP并保证跨节点的 Pod 网络互通。没有 CNIkubelet 成功启动后节点也会一直 NotReady因为集群网络未就绪。Flannel 是最简单的 Overlay 网络方案核心思想是 VXLAN 隧道把每个节点的 Pod 网段封装在三层网络中。它配置简单、资源消耗低适合中小规模集群和测试环境。Calico 则采用纯三层路由方案基于 BGP 协议交换路由性能更好同时支持 NetworkPolicy 网络策略。Calico 功能丰富但复杂度也高生产环境大规模集群推荐使用。我个人的建议是测试和中等规模随便选 Flannel五分钟搞定如果业务有网络策略隔离需求、或者节点规模很大直接上 Calico少走弯路。7.2 部署 Flannel 的完整过程这里以 Flannel 为例说明因为它配置最简单。先到 Flannel 的 GitHub Release 页面下载 flanneld 二进制文件和 CNI 插件包其中 cni-plugins-linux-amd64 需要放到 /opt/cni/bin。然后创建 flannel 需要的 RBAC 资源和配置。Flannel 官方提供 kube-flannel.yml 清单文件可以直接 kubectl apply -f 部署。但需要注意修改两个地方pod-network-cidr 参数必须与 kube-controller-manager 中 --allocate-node-cidrs 指定的 Pod 网段一致一般使用 10.244.0.0/16flanneld 镜像要替换成内网可达的地址。清单文件应用完成后检查 flannel Pod 是否处于 Running 状态kubectl get pods -n kube-flannel -o wide有时 Pod 启动成功但节点仍然 NotReady可以进入 flannel Pod 查看日志看到 Backend type: vxlan 和 Network: 10.244.0.0/16 就说明网络配置正确。如果一切正常执行 kubectl get nodes 应该看到所有节点均为 Ready。7.3 部署完成后的自检清单与常用命令集群的网络插件部署完成意味着基本功能已经全部打通。但我建议不要立刻急着部署业务应用先做一轮系统性的自检。把这份清单保存下来以后排查集群问题也用得上kubectl get nodes确认所有节点 Readykubectl get pods -n kube-system确认核心系统组件全部 Running 或 Completedkubectl get svc -n kube-system确认 kube-dns 或 coredns 的 ClusterIP 已分配kubectl run test-pod --imagebusybox -- sleep 3600创建测试 Pod 并进入 Pod 内执行 nslookup kubernetes.default确认 DNS 解析可用在测试 Pod 中 ping 其他节点的 Pod IP确认跨节点容器网络通。K8s 常用命令里kubectl get events 是排查故障最高频的命令任何组件出问题都会在事件中有记录。还有一个是 kubectl describe node 节点名如果节点状态异常底部会显示详细的异常信息比如磁盘压力、内存压力、kubelet 未就绪等。8. 二进制部署中我实际踩过的坑与速查表8.1 证书相关故障别被报错骗了最常见的问题就是 etcd 集群起不来日志里大量出现 verify failed: x509: certificate signed by unknown authority。这类报错九成是因为 etcd 的 trusted-ca-file 没有正确指向根证书或者 peer 证书的 SAN 里没有对方节点的 IP。还有个容易忽略的坑是 kube-apiserver 无法连接 etcd报错 context deadline exceeded。表面看是超时实际上往往是 etcd 节点接受连接的监听地址不对或者防火墙没有放行 2379 端口。排查时先 telnet 一下端口通不通再带证书跑 etcdctl endpoint health不要一上来就怀疑证书配置按层级排查效率最高。8.2 kubelet 无法注册节点kubelet 启动后kubectl get nodes 一直看不到新节点或者节点状态 NotReady。最直接的排查方式是 journalctl -u kubelet -f 实时查看 kubelet 日志。我遇到最多的情况是 kubelet 的 kubeconfig 中证书 CN 配置错误。kubelet 必须使用 system:node:主机名 这样的用户apiserver 的 Node 授权模型才会放行节点注册请求。如果改成其他 CNapiserver 会直接拒绝 Node 创建。另一个常见问题是节点主机名与证书 CN 不一致导致注册的节点名和 kubelet 上报的 nodeName 不匹配apiserver 内部会校验。8.3 CNI 网络不通或 DNS 解析失败网络插件部署完成后容器能创建但 Pod 之间互不通或者 Service 访问不了这种情况需要从两个方向排查。第一是检查各节点的路由表。Flannel 会在 /run/flannel/subnet.env 里生成当前节点的子网信息如果没有生成说明 flanneld 没有正常获取到 Pod 网段。第二是检查 iptables 或 IPVS 规则。kube-proxy 未启动或驱动选择错误时ClusterIP 的转发规则不会写入节点Service 无法访问。DNS 解析失败常见原因是 coredns 无法解析外部域名或者 Pod 的 resolv.conf 指向了错误 DNS。可以进入 Pod 执行 cat /etc/resolv.conf 查看 nameserver 是否指向 10.96.0.10。如果不是检查 kubelet 的 clusterDNS 参数是否配置正确。8.4 二进制部署工具与后续可扩展方向说实话二进制部署整套流程走一遍正常人都会觉得累。但如果条件允许可以试试辅助工具 kubeasz 或者 sealos它们本质上也是二进制部署的自动化封装比 kubeadm 更适合离线交付场景。基于二进制部署的经验后续扩展的方向很多比如升级控制平面高可用L4 负载均衡或者接入外部 etcd 集群。这些方向都需要你现在打下的基础。9. 我个人几点实操体会最后分享几个触发在原厂文档里看不到的小经验。第一配置端口的证书时尽量把后续可能用到的所有域名和 IP 都写进 SAN。否则集群跑几个月后你想从新域名访问 apiserver就必须重新生成证书并重启组件影响面很大。第二永远不要在生产环境直接尝试二进制部署而不做回滚预案。至少要有完整备份 etcd 数据、备份证书目录的习惯因为证书私钥丢了整个集群的信任链就断了恢复起来比重新搭建还痛苦。第三把所有节点的时间同步务必放在第一步。即使只偏差几十秒证书校验也会间歇性失败这种随机故障排查起来会让人怀疑人生。第四能脚本化就脚本化。我后来把证书签发、文件分发、systemd 配置全部改成了 Ansible 脚本二次部署时效率提升非常明显。建议你在手工打通一次流程后立刻着手把这些步骤脚本化这才是二进制部署的真正价值所在。