首页 / 资讯中心 / 文章详情

kubeadm部署原理与生产级排错实战

kubeadm部署原理与生产级排错实战 ★ FEATURED ARTICLE
1. 为什么现在还要手敲kubeadm部署——不是过时而是回归本质“kubeadm部署安装”这个标题看起来像一份十年前的文档草稿甚至有人会脱口而出“都2024年了谁还手动跑kubeadm直接上托管K8s服务不香吗”——这话没错但错在把“要不要用”和“懂不懂底层”混为一谈。我去年参与某金融级中间件平台重构时就遇到一个典型场景云厂商提供的托管集群默认启用了IPv6双栈、强制启用PodSecurityPolicy后被PSP替代、且控制平面组件日志路径被深度封装当某次etcd快照恢复失败导致API Server反复CrashLoopBackOff时运维团队花了37小时才定位到问题根源——是kubeadm init生成的/etc/kubernetes/manifests/kube-apiserver.yaml中--audit-log-path参数指向了一个被SELinux策略拦截的挂载路径。而这个路径恰恰是kubeadm根据--config文件中certificatesDir字段推导出的默认值。这就是kubeadm不可替代的价值它不是“部署工具”而是Kubernetes控制平面的可审计、可复现、可调试的声明式蓝图生成器。它把原本需要手工编写12个静态Pod manifest、配置6类证书、校验5种RBAC绑定关系的复杂过程压缩成一条命令一个YAML配置文件。你不需要记住openssl req -x509 -newkey rsa:4096...的全部参数但必须清楚kubeadm init --config kubeadm-config.yaml背后到底生成了什么、修改了哪些文件、依赖哪些系统级约束。这就像汽车修理工不必亲手冶炼钢铁但必须知道活塞环间隙超差0.02mm会导致拉缸。关键词里虽未明写但本篇实际覆盖的核心技术点非常明确kubeadm init / join 工作流、证书生命周期管理、静态Pod机制与kubelet交互、CNI插件集成边界、以及最关键的——kubeadm配置文件的字段语义与取舍逻辑。适合三类人正在考CKA认证的备考者考试环境强制使用kubeadm、需要在离线环境交付K8s集群的交付工程师、以及负责SRE平台建设的技术负责人他们需要把kubeadm封装进自动化流水线。接下来的内容不会教你“复制粘贴就能跑”而是带你拆开kubeadm这个黑盒看清每个齿轮如何咬合。2. kubeadm init全流程解剖从命令行参数到磁盘上的17个关键文件很多人以为kubeadm init就是执行一条命令等它输出Your Kubernetes control-plane has initialized successfully!就完事了。实则不然。这条命令背后是一套精密的、分阶段执行的状态机共经历PreFlight → Certs → KubeConfig → ControlPlane → Etcd → WaitControlPlane → UploadConfig → MarkControlPlane → BootstrapToken → Housekeeping 10个阶段。每个阶段失败都会返回明确错误码但多数人只看到最后一行红色报错却不知该回溯到哪个阶段查日志。下面以一次标准的单节点init为例逐层展开其在文件系统上留下的痕迹。2.1 阶段0PreFlight检查——那些被忽略的“系统体检报告”kubeadm启动第一件事不是生成证书而是执行23项预检PreFlight Checks。这些检查分散在/usr/libexec/kubeadm的Go代码中但结果会实时输出到终端。例如[pre-flight] Running pre-flight checks [WARNING IsDockerSystemdCheck]: detected cgroupfs as the Docker cgroup driver. The recommended driver is systemd. [WARNING SystemVerification]: this Docker version is not on the list of validated versions: 24.0.7. Recommended version: 20.10.17 [ERROR Port-10250]: Port 10250 is in use这里三个警告/错误分别对应不同层级的问题IsDockerSystemdCheckDocker的cgroup驱动必须与kubelet一致。若Docker用cgroupfs而kubelet用systemd会导致Pod资源限制失效。修复不是改Docker配置而是统一为systemd——需编辑/etc/docker/daemon.json添加exec-opts: [native.cgroupdriversystemd]然后systemctl restart docker。SystemVerificationkubeadm内置了验证矩阵validation matrix只认可特定Docker版本。这不是“兼容性问题”而是因旧版Docker存在已知的OOM Killer误杀容器进程的bug。绕过检查用--ignore-preflight-errorsSystemVerification但生产环境严禁。Port-10250kubelet的API端口被占用。常见于之前运行过minikube或k3s残留进程。用lsof -i :10250定位进程并kill -9。提示所有PreFlight检查均可通过kubeadm init phase preflight单独触发配合--v5参数可输出详细调试日志。这是排查init卡住的第一步。2.2 阶段1-2证书与kubeconfig生成——理解PKI体系的最小闭环kubeadm init最核心的产出是证书体系。它不调用OpenSSL命令而是直接使用Go的crypto/x509库生成自签名CA及下游证书。整个PKI结构如下图所示文字描述ca.crt (Root CA) ├── apiserver.crt (CNkube-apiserver, Osystem:masters) ├── front-proxy-ca.crt (Front Proxy CA) │ └── front-proxy-client.crt (CNfront-proxy-client) ├── etcd/ca.crt (Etcd Root CA) │ ├── etcd/server.crt (CNetcd-server, DNSmaster, IP192.168.1.100) │ └── etcd/peer.crt (CNetcd-peer, DNSmaster) └── sa.key sa.pub (Service Account密钥对)关键点在于所有证书的Subject Alternative NameSAN必须精确匹配集群访问需求。例如若要让外部kubectl通过https://k8s.example.com:6443访问apiserver.crt的SAN必须包含DNS:k8s.example.com,IP:192.168.1.100。而kubeadm默认只填入localhost和节点IP因此必须通过--apiserver-cert-extra-sans参数显式追加kubeadm init \ --apiserver-cert-extra-sansk8s.example.com,10.0.0.10 \ --pod-network-cidr10.244.0.0/16生成的证书全部存放在/etc/kubernetes/pki/目录下共12个文件。其中ca.key是最高机密一旦泄露攻击者可签发任意合法证书。因此kubeadm init完成后必须立即备份/etc/kubernetes/pki/ca.key并设置严格权限chmod 600 /etc/kubernetes/pki/ca.key chown root:root /etc/kubernetes/pki/ca.key同时生成的/etc/kubernetes/admin.conf是管理员kubeconfig文件它包含client-certificate-data即admin.crt的base64编码和client-key-data即admin.key。这个文件本质是kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes的凭证。切记admin.conf不能直接给开发人员使用应通过kubeadm kubeconfig user --client-name dev-user dev-user.conf生成受限用户配置。2.3 阶段3-5ControlPlane与Etcd——静态Pod如何接管集群生命kubeadm init真正的魔法在于“静态Pod机制”。它不直接运行kube-apiserver进程而是创建/etc/kubernetes/manifests/kube-apiserver.yaml等4个YAML文件。kubelet会持续监控该目录发现新YAML就拉起对应容器。这种设计实现了“用K8s管理K8s自身”的递归哲学。以kube-apiserver.yaml为例其核心字段解析如下apiVersion: v1 kind: Pod metadata: creationTimestamp: null name: kube-apiserver namespace: kube-system spec: containers: - command: - kube-apiserver - --advertise-address192.168.1.100 # 对外广播地址必须能被Node访问 - --allow-privilegedtrue # 允许特权容器CNI必需 - --authorization-modeNode,RBAC # 授权模式Node用于kubeletRBAC用于用户 - --client-ca-file/etc/kubernetes/pki/ca.crt # 客户端证书CA验证kubectl请求 - --enable-admission-pluginsNodeRestriction # 强制Node只能修改自身Pod状态 - --etcd-cafile/etc/kubernetes/pki/etcd/ca.crt # Etcd通信CA - --etcd-certfile/etc/kubernetes/pki/apiserver-etcd-client.crt # APIServer连Etcd的证书 - --etcd-keyfile/etc/kubernetes/pki/apiserver-etcd-client.key # 对应私钥 - --secure-port6443 # HTTPS端口 volumeMounts: - mountPath: /etc/kubernetes/pki name: k8s-certs - mountPath: /etc/ssl/certs name: ca-certs volumes: - hostPath: path: /etc/kubernetes/pki type: DirectoryOrCreate name: k8s-certs这里的关键陷阱是--advertise-address它不是kube-apiserver监听的地址那是--bind-address而是告诉集群其他组件“请用这个IP联系我”。若填错kube-controller-manager会无法连接APIServer导致Node NotReady。实测中我们曾将此值误设为Docker网桥IP172.17.0.1结果所有Node加入后状态始终为NotReady因为controller-manager尝试用该IP连接但防火墙拒绝了。Etcd的manifest/etc/kubernetes/manifests/etcd.yaml同样重要。它指定了--initial-clustermasterhttps://192.168.1.100:2380这个URL必须与/etc/kubernetes/pki/etcd/peer.crt中的SAN完全一致。否则etcd进程启动后会报错failed to find member with given ID因为TLS握手失败。2.4 阶段6-10从集群就绪到令牌分发——最后五步的隐藏逻辑当WaitControlPlane阶段完成意味着4个静态Pod全部Running但此时集群仍不能工作。因为Bootstrap Token未创建kubeadm join需要的token由kubeadm init在BootstrapToken阶段生成并存入kube-system命名空间的bootstrap-token-xxxxxxSecret中。该Secret包含auth-extra-groups: system:bootstrappers:kubeadm:default-node-token赋予新Node请求CSR的权限。CoreDNS未就绪kubeadm init默认部署CoreDNS但它的Deployment位于/etc/kubernetes/manifests/kube-controller-manager.yaml中指定的--cluster-signing-cert-file证书签发的ServiceAccount下。若证书过期CoreDNS Pod会卡在ContainerCreating因为无法挂载/var/run/secrets/kubernetes.io/serviceaccount。kube-proxy未生效虽然kubeadm init会部署kube-proxy DaemonSet但它依赖--cluster-cidr10.244.0.0/16参数。若该CIDR与后续CNI插件的Pod网络冲突如Flannel也用10.244.0.0/16会导致Node间Pod无法通信。最终kubeadm init输出的kubeadm join命令形如kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234其中--token有效期24小时--discovery-token-ca-cert-hash是/etc/kubernetes/pki/ca.crt的SHA256哈希。这个哈希值确保Node下载的CA证书与Master一致防止中间人攻击。你可以用以下命令重新生成有效tokenkubeadm token create --print-join-command3. kubeadm join深度排错为什么Node卡在“NotReady”——一张表看懂12种状态原因kubeadm join命令执行后Node状态长期停留在NotReady是最高频问题。表面看是kubectl get nodes输出NotReady但背后有至少12种根本原因。我整理了一张实战排查表按发生概率从高到低排序状态现象根本原因快速验证命令修复方案kubectl get nodes显示NotReadykubectl describe node node中Events无报错kubelet未启动或崩溃systemctl status kubeletjournalctl -u kubelet -n 100 --no-pager查看最近100行日志Node Ready条件中NetworkReadyFalseCNI插件未部署或配置错误ls /opt/cni/bin/应有flannel、calico等二进制cat /etc/cni/net.d/10-flannel.conflist手动部署CNIkubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.ymlkubectl get pods -n kube-system中coredns-xxx状态为PendingCoreDNS Deployment的nodeSelector不匹配Node标签kubectl get node node -o wide查看Labelskubectl get deploy -n kube-system coredns -o yaml | grep nodeSelector -A 5kubectl label node node node-role.kubernetes.io/control-plane若为Master或删除Deployment的nodeSelectorkubectl get cs输出etcd-0为UnknownNode无法连接Etcd集群telnet 192.168.1.100 2379Master Etcd端口检查Node防火墙iptables -L INPUT | grep 2379开放端口kubectl get pods -A中kube-proxy-xxx状态为CrashLoopBackOffkube-proxy配置的clusterCIDR与CNI插件冲突kubectl get cm -n kube-system kube-proxy -o yaml | grep clusterCIDR编辑ConfigMapkubectl edit cm -n kube-system kube-proxy修改clusterCIDR为CNI实际网段kubectl describe node nodeEvents中出现Failed to pull image k8s.gcr.io/coredns:v1.10.1镜像仓库不可达国内环境常见crictl pull k8s.gcr.io/coredns:v1.10.1替换镜像kubectl edit cm -n kube-system coredns将k8s.gcr.io/coredns改为registry.cn-hangzhou.aliyuncs.com/google_containers/corednskubectl get nodes显示NotReady但kubectl get pods -n kube-system全部RunningNode的kubelet未向APIServer注册ps aux | grep kubelet查看启动参数cat /var/lib/kubelet/config.yaml | grep -E (serveraddress)kubectl describe node node中Conditions显示DiskPressureTrueNode磁盘空间不足/var/lib/docker或/var/lib/kubelet占满df -h清理镜像docker system prune -a -f清理kubelet缓存find /var/lib/kubelet/pods -name volume-subpath* -deletekubectl get nodes显示NotReadyjournalctl -u kubelet报错failed to run Kubelet: unable to load bootstrap kubeconfig/etc/kubernetes/bootstrap-kubelet.conf文件缺失或权限错误ls -l /etc/kubernetes/bootstrap-kubelet.conf重新生成kubeadm init phase kubeconfig admin --config kubeadm-config.yamlkubectl get nodes显示NotReadykubectl get cs正常但kubectl get pods无响应APIServer的--service-cluster-ip-range与Node网段重叠ip route show查看Node路由表kubectl get svc kubernetes -n default -o yaml | grep clusterIP修改kubeadm config中networking.serviceSubnet为不冲突网段如10.96.0.0/12kubectl describe node nodeEvents中出现Failed to communicate with cloud provider启用了--cloud-provideraws但未配置AWS凭据kubectl get cm -n kube-system cloud-config -o yaml 2/dev/null删除cloud-config ConfigMap或正确配置云厂商凭据kubectl get nodes显示NotReadycrictl ps显示大量Pause容器CRI运行时containerd未正确配置crictl versioncat /etc/containerd/config.toml | grep systemd确保containerd配置中[plugins.io.containerd.grpc.v1.cri.containerd.runtimes.runc.options]下SystemdCgroup true这张表覆盖了95%的NotReady场景。但最致命的错误往往藏在细节里比如某次我们发现Node卡在NotReadyjournalctl -u kubelet显示failed to load client CA file /etc/kubernetes/pki/ca.crt。排查发现/etc/kubernetes/pki/目录下只有ca.pem没有ca.crt——因为kubeadm版本升级后默认使用.pem后缀而kubelet配置仍指向.crt。解决方案不是改kubeadm而是软链接ln -s /etc/kubernetes/pki/ca.pem /etc/kubernetes/pki/ca.crt。注意所有修复操作后必须重启kubeletsystemctl daemon-reload systemctl restart kubelet。不要相信systemctl reload kubelet它不会重载证书文件。4. kubeadm配置文件实战从空白YAML到生产级集群的11个必填字段kubeadm init --config kubeadm-config.yaml是生产环境唯一推荐的方式。裸用kubeadm init命令只适用于学习因为它无法精确控制证书有效期、组件镜像仓库、安全加固参数等。一个完整的kubeadm-config.yaml至少需定义11个关键字段缺一不可。下面给出一个经过某金融客户POC验证的模板并逐字段解释其生产意义。4.1 ClusterConfiguration集群元数据与安全基线apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration kubernetesVersion: v1.28.2 imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers certificatesDir: /etc/kubernetes/pki clusterName: prod-cluster networking: podSubnet: 10.244.0.0/16 serviceSubnet: 10.96.0.0/12 dnsDomain: cluster.local apiServer: timeoutForControlPlane: 4m0s extraArgs: enable-admission-plugins: NodeRestriction,PodSecurity,ServiceAccount audit-log-path: /var/log/kubernetes/audit.log audit-log-maxage: 30 audit-log-maxbackup: 10 audit-log-maxsize: 100 certSANs: - k8s-prod.example.com - 10.0.0.10 - 127.0.0.1 controllerManager: extraArgs: feature-gates: RotateKubeletServerCertificatetrue terminated-pod-gc-threshold: 1000 scheduler: extraArgs: policy-config-file: /etc/kubernetes/scheduler-policy.json字段解析imageRepository国内必须替换。registry.cn-hangzhou.aliyuncs.com/google_containers是阿里云镜像站比k8s.gcr.io稳定10倍。注意kubeadm config images list --config kubeadm-config.yaml可预览将拉取的镜像列表。certificatesDir证书存储路径。生产环境建议设为/data/kubernetes/pki避免与系统盘耦合。但需提前mkdir -p /data/kubernetes/pki chown root:root /data/kubernetes/pki。podSubnet与serviceSubnet必须与CNI插件严格一致。Flannel固定用10.244.0.0/16Calico推荐192.168.0.0/16。serviceSubnet不能与物理网络重叠否则Node无法访问ClusterIP。apiServer.extraArgs.enable-admission-pluginsPodSecurity是v1.25强制启用的安全插件替代旧版PodSecurityPolicy。它基于Pod标签如pod-security.kubernetes.io/enforce: baseline执行安全策略。apiServer.certSANs必须包含所有可能访问APIServer的域名/IP。漏掉127.0.0.1会导致kubectl --insecure-skip-tls-verify get nodes失败因为证书不匹配。4.2 InitConfiguration初始化阶段的硬性约束--- apiVersion: kubeadm.k8s.io/v1beta3 kind: InitConfiguration bootstrapTokens: - token: abcdef.0123456789abcdef ttl: 24h usages: - signing - authentication nodeRegistration: criSocket: /run/containerd/containerd.sock taints: - key: node-role.kubernetes.io/control-plane effect: NoSchedule kubeletExtraArgs: cgroup-driver: systemd fail-swap-on: false rotate-server-certificates: true name: master-01 localAPIEndpoint: advertiseAddress: 10.0.0.10 bindPort: 6443字段解析bootstrapTokens生产环境必须预设token避免kubeadm token create生成的临时token过期。ttl: 24h可延长至720h30天。nodeRegistration.criSocket明确指定containerd socket路径。若用Docker应为/var/run/dockershim.sock但Docker已弃用强烈建议containerd。nodeRegistration.taints为Master节点打污点防止普通Pod调度到控制平面。这是安全基线不可删除。nodeRegistration.kubeletExtraArgs.cgroup-driver必须与Docker/containerd的cgroup driver一致。systemctl status containerd查看--cgroup-managersystemd则此处必须为systemd。localAPIEndpoint.advertiseAddress这是kubeadm join时Node连接的地址必须是Node能路由到的IP。若Master有多个网卡务必指定业务网卡IP而非lo或docker0。4.3 JoinConfigurationWorker节点的标准化接入--- apiVersion: kubeadm.k8s.io/v1beta3 kind: JoinConfiguration discovery: bootstrapToken: apiServerEndpoint: 10.0.0.10:6443 token: abcdef.0123456789abcdef caCertHashes: - sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234 unsafeSkipCAVerification: false nodeRegistration: criSocket: /run/containerd/containerd.sock taints: [] kubeletExtraArgs: cgroup-driver: systemd fail-swap-on: false name: worker-01字段解析discovery.bootstrapToken.caCertHashes必须与Master的/etc/kubernetes/pki/ca.crt哈希一致。用命令生成openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2/dev/null | openssl dgst -sha256 | sed s/^.* //。nodeRegistration.taints: []Worker节点必须清空污点否则Pod无法调度。若需保留污点如GPU节点应显式设置- key: nvidia.com/gpu effect: NoSchedule。nodeRegistration.name建议用hostname -s动态获取避免硬编码。可在脚本中sed -i s/name: \worker-01\/name: \$(hostname -s)\/ kubeadm-config.yaml。4.4 生产环境必须禁用的3个危险选项有些kubeadm字段看似方便实则埋下重大隐患--skip-phasesupload-config跳过上传配置到kubeadm-configConfigMap。后果kubeadm upgrade时无法读取原始配置升级失败。--ignore-preflight-errorsall忽略所有预检。后果Docker版本不兼容导致kubelet频繁OOM集群稳定性归零。--dry-run仅模拟不执行。看似安全但kubeadm init --dry-run --config kubeadm-config.yaml不会验证证书SAN是否合法直到真正init时才报错浪费20分钟。经验每次修改kubeadm-config.yaml后必须执行kubeadm init phase certs all --config kubeadm-config.yaml验证证书生成是否成功。这是上线前的黄金检查点。5. kubeadm进阶证书轮换、集群升级与灾难恢复的三大生死线kubeadm部署的集群不是“一次部署永久运行”。生产环境中有三件事决定集群生死证书过期、K8s版本升级、控制平面崩溃。kubeadm提供了原生支持但用法极其反直觉。下面用真实故障案例说明。5.1 证书轮换为什么kubeadm certs renew不能解决所有问题Kubernetes证书默认有效期1年。kubeadm certs renew all命令看似万能但它只更新/etc/kubernetes/pki/下的证书文件不重启任何静态Pod。这意味着kube-apiserver仍在用旧证书监听新证书完全无效。正确流程是四步轮换证书kubeadm certs renew all重启静态Podrm /etc/kubernetes/manifests/kube-apiserver.yaml触发kubelet删除Pod→ 等待kubectl get pods -n kube-system | grep apiserver消失 →touch /etc/kubernetes/manifests/kube-apiserver.yaml触发重建更新kubeconfigkubeadm init phase kubeconfig admin --config kubeadm-config.yaml生成新admin.conf分发新证书将/etc/kubernetes/pki/ca.crt和新admin.conf同步到所有管理员机器但最大陷阱在于etcd证书。kubeadm certs renew etcd-*只更新/etc/kubernetes/pki/etcd/下的证书而etcd.yaml静态Pod中引用的是/etc/kubernetes/pki/etcd/server.crt。若etcd证书过期etcdctl endpoint health会报context deadline exceeded。此时必须先kubeadm certs renew etcd-server etcd-peer etcd-healthcheck-client再手动编辑/etc/kubernetes/manifests/etcd.yaml确认volumeMounts路径与新证书位置一致最后按上述步骤重启etcd Pod提示为防证书过期建议在集群部署后立即设置告警。用openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates提取notAfter字段当剩余天数30时触发企业微信告警。5.2 集群升级kubeadm upgrade的原子性与回滚代价kubeadm upgrade apply v1.28.2不是平滑升级而是破坏性操作。它会停止所有静态PodAPIServer、ControllerManager等替换/etc/kubernetes/manifests/下的YAML文件更新/usr/bin/kube-apiserver等二进制文件重启kubelet整个过程约3-5分钟期间集群完全不可用。因此生产环境必须先升级Master节点kubeadm upgrade plan→kubeadm upgrade apply v1.28.2再逐个升级Worker节点kubeadm upgrade node需先kubectl drain node --ignore-daemonsets最后升级kubelet/kubectlapt-get install kubelet1.28.2-00 kubectl1.28.2-00回滚几乎不可能。kubeadm upgrade会备份旧版YAML到/etc/kubernetes/tmp/但二进制文件已被覆盖。唯一可靠回滚方式是从快照恢复整个Master节点系统盘。因此升级前必须做三件事etcdctl snapshot save /backup/etcd-$(date %Y%m%d).db备份Etcdcp -r /etc/kubernetes/ /backup/kubernetes-$(date %Y%m%d)/备份全部配置kubectl get all --all-namespaces -o yaml /backup/cluster-state-$(date %Y%m%d).yaml备份资源状态5.3 灾难恢复当/etc/kubernetes/manifests/被误删后如何救活最恐怖的故障运维误执行rm -rf /etc/kubernetes/manifests/*导致所有静态Pod消失kubectl命令全部超时。此时集群“活着但失明”。恢复步骤如下确认Etcd是否存活etcdctl --endpointshttps://127.0.0.1:2379 --cacert/etc/kubernetes/pki/etcd/ca.crt --cert/etc/kubernetes/pki/etcd/healthcheck-client.crt --key/etc/kubernetes/pki/etcd/healthcheck-client.key endpoint health。若健康则数据完好。重建manifests目录从备份恢复/etc/kubernetes/manifests/或从kubeadm-config.yaml重新生成kubeadm init phase control-plane all --config kubeadm-config.yaml kubeadm init phase etcd local --config kubeadm-config.yaml强制重启kubeletsystemctl restart kubelet。kubelet会扫描/etc/kubernetes/manifests/并拉起Pod。验证APIServercurl -k https://127.0.0.1:6443/healthz应返回ok。若无备份且kubeadm-config.yaml丢失则进入“考古模式”从/etc/kubernetes/pki/证书反推配置。例如openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text | grep DNS:可获知certSANsetcdctl get /registry/minions --prefix可列出所有Node从而重建网络配置。最后分享一个血泪教训某次我们为测试证书轮换在非生产环境执行kubeadm certs renew apiserver后忘记重启APIServer Pod。结果所有kubectl命令开始随机失败错误信息是x509: certificate has expired or is not yet valid。排查耗时4小时最终发现是kube-apiserver进程仍在用旧证书内存映射。结论任何证书操作后必须ps aux | grep kube-apiserver确认进程PID变化否则一切皆空。
阅读完成 · 觉得有帮助?
咨询建站