尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Kubernetes从安装到生产部署全攻略:kubeadm实战与避坑指南

Kubernetes从安装到生产部署全攻略:kubeadm实战与避坑指南 搞Kubernetes踩坑踩了这么多年从最早自己瞎折腾二进制部署到后来用kubeadm一键拉起集群再到现在帮团队维护跨机房的产线集群中间交过的学费真不少。这篇东西我把”从安装到生产部署“这条完整链路整理出来包括方案选型、安装细节、生产化改造思路还有一堆实际踩过的坑希望你看完能少走点弯路。文章不会讲太虚的东西每一步基本都能照着做适合正在搭集群的运维、后端开发以及准备把Kubernetes真正用起来的架构师。1. 从零到生产的全局路线图Kubernetes集群到底怎么搭1.1 为什么上Kubernetes你要解决的真实问题在动手装之前我建议你先想清楚一个基本问题你到底为什么要上Kubernetes是老板拍板要容器化还是自己团队真的遇到了单机Docker搞不定的问题这个想不清楚后面装完大概率也是个困兽之斗的玩具集群。我把实际项目中常见的诉求归纳成三类你可以对照一下自己的处境资源利用率太低一堆物理机或者云主机各自跑着业务CPU平均使用率不到10%内存也大量空闲。Kubernetes能做的事情是把这些碎片资源统一纳管按需调度顺手把内部多个服务的部署方式统一掉。服务扩容太慢流量一冲上来人肉去云控制台点加机器、再手动部署新实例一套流程走完半小时过去了。Kubernetes的HPA配合合理的Pod水平扩展几十秒就能把副本数拉上来。发布流程太痛苦每次发版本都是胆战心惊回滚靠备份、靠人肉。Kubernetes的Deployment滚动更新和回滚机制能让发布变成一个可预测的操作。这三种痛点对应到Kubernetes上分别是资源调度、弹性伸缩、应用编排三大核心能力。理解了这些你再去看后面安装配置里的很多参数就不会一头雾水了。比如后面要讲的Node污点和亲和性本质上就是在解决“调度策略”的问题装完集群后你要做的HPA配置就是冲着“弹性伸缩”去的。1.2 安装方案选型二进制、kubeadm、还是发行版Kubernetes集群的安装方式多到让人眼花但我实际工作下来选择其实就三条主线二进制手动部署、kubeadm官方工具部署、商业或社区发行版一键部署。二进制部署所有组件kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、kube-proxy等全部用二进制文件自己拉起conf文件和证书全部自己手写。优点是看得最深、可控性最强缺点是极其耗时初次折腾可能要一周后续升级维护也费劲。我早期为了搞懂原理这么干过一次之后再没碰过。kubeadm部署Kubernetes官方的集群初始化工具帮你把证书生成、组件配置、Token管理等脏活累活都封装掉了。整个过程核心命令就两条kubeadm init和kubeadm join。目前生产环境下我基本上都是用它。发行版一键部署比如RKE、K3s、Kubesphere之类的更偏重开箱即用但如果你对底层网络和组件行为不了解出问题时会比较抓瞎。这类更适合快速搭一套内部环境不太适合需要深度掌控的产线场景。我的建议很明确想认真搞Kubernetes选kubeadm没有之一。理由是它背后就是标准Kubernetes组件没有任何魔改出了任何问题都能用官方文档和社区经验来解决。后面的内容我全部基于kubeadm展开。1.3 生产环境与测试环境的本质差异很多人开发环境搭得飞起到了生产就频频出事关键在于一开始就没把一个理念掰扯明白开发环境要的是“能用”生产环境要的是“可控”。开发环境里你可以在master节点上同时跑业务Pod可以把etcd和master混部可以不用考虑日志怎么收集、监控怎么建设。但生产环境里这些“偷懒”都会在某个深夜里变成事故。我见过一个团队在测试环境用了kube-proxy的iptables模式没出过问题上了生产后流量一大便遭遇了严重延迟排查到最后才发现是service转发链路问题——如果一开始就意识到生产环境流量模型不同网络组件选型这块就会更谨慎。我在文章的后半部分会专门讲生产化改造要做的那些事包括节点角色分离、资源配额、监控日志、灾备恢复。这些内容不是花架子是真真切切能在事故里救命的。2. 安装核心准备版本选型、系统初始化与容器运行时2.1 版本选型Kubernetes版本和配套组件的对应关系这一步是很多人忽略但代价最大的环节。Kubernetes版本迭代极快每个小版本的支持周期大概一年你需要选一个社区还在维护、而且你后面规划期内不会被迫升级的版本。以我最近一次搭集群为例选的是1.27.xx具体选当时最新的补丁版本。为什么选它因为1.27在当时属于GA不久且社区支持稳定的版本配套工具链如Calico、Ingress-nginx、Metrics Server兼容性也比较好。具体的选型原则我整理了下面几条主版本至少提前一个版本再上生产比如社区已经把1.30放出来了我通常选1.28或1.29为主力版本因为新版本组件兼容性问题通常在前一个版本周期内才能暴露完。kubeadm、kubelet、kubectl版本必须匹配三者版本相差最好不超过一个minor版本。我用的是apt-get install kubeadm1.27.x-* kubelet1.27.x-* kubectl1.27.x-*这种方式锁定版本安装避免apt源更新后拉出一个大版本跳变的组件。提前查好CNI插件和容器运行时对你的版本是否支持比如Calico某个大版本是否适配你选的Kubernetes版本这点在官方文档的兼容性表里都有。版本选定后的第一件事是在所有节点统一配置apt或yum源。如果是国内网络环境需要用国内镜像源华为源或阿里源都行关键是机器能稳定拉到kubeadm、kubelet、kubectl三个包。2.2 系统初始化关防火墙、禁用swap、配置内核参数这部分是安装Kubernetes之前最容易被跳过、又最容易坑人的环节。我在一次客户现场遇到过kubeadm init之后kubelet一直报错查到最后是swap没关干净。Kubernetes在1.8之后就对swap明确说“不建议”cgroup v2环境下swap更是会导致kubelet启动失败。我列一下我在所有节点上都会跑的初始化配置一份标准的/etc/sysctl.d/k8s.conf内核参数如下net.bridge.bridge-nf-call-iptables 1 net.bridge.bridge-nf-call-ip6tables 1 net.ipv4.ip_forward 1 net.ipv4.tcp_tw_reuse 1 vm.swappiness 0设置完成后执行sysctl --system使之生效。注意net.bridge.bridge-nf-call-iptables这个参数如果系统没加载br_netfilter模块它可能会设置失败所以要先执行modprobe br_netfilter并把它写进/etc/modules-load.d/k8s.conf确保重启后仍能加载。禁用swap的命令swapoff -a sed -i / swap / s/^/#/ /etc/fstab为什么要禁swap因为Kubernetes的调度器在做资源调度时把内存当作确定性资源如果Pod在节点上触发了swap内存的确定性就没了kubelet无法准确判断节点资源瓶颈调度决策就会失真导致整体稳定性下降。同时需要关闭firewalld或ufw并且清掉iptables的默认策略。我习惯直接systemctl stop firewalld并systemctl disable firewalld内网集群场景下安全策略应该由Kubernetes的NetworkPolicy来管而不是节点防火墙。2.3 容器运行时选型containerd还是Docker这里要先澄清一个历史问题Kubernetes从1.20开始逐步弃用Docker作为运行时到1.24已经完全移除dockershim。但你不用慌这跟你平时用Docker命令构建镜像完全不冲突Kubernetes只是不再直接用Docker来跑容器而已你依然可以用Docker来打包镜像再通过containerd去运行这些容器。我在生产环境直接选了containerd作为容器运行时原因很直接节点上不需要多装一个Docker daemon资源占用更小containerd本身是CNCF的标准运行时实现和Kubernetes的兼容性反而是最自然的出问题时排查链路更短就一个containerd服务。containerd安装很简单但配置文件有个坑默认的config.toml不会启用cri插件并且镜像仓库地址是默认的docker.io。我在安装后都会手动改一下配置mkdir -p /etc/containerd containerd config default | tee /etc/containerd/config.toml然后修改/etc/containerd/config.tomlsystemd_cgroup true [plugins.io.containerd.grpc.v1.cri] sandbox_image registry.aliyuncs.com/google_containers/pause:3.9systemd_cgroup必须设为true因为Kubernetes默认用cgroupfs或者systemd来管理cgroup推荐的驱动是systemd这样kubelet和containerd的cgroup驱动才能保持一致否则启动Pod时会报failed to run Kubelet: misconfigured: kubelet cgroup driver: systemd is different from docker cgroup driver: cgroupfs这类错误。另外pause这个基础镜像地址在国内默认拉不下来必须改成国内镜像源这是每个新手第一课。3. 集群搭建实操控制面初始化到工作节点加入全程记录3.1 控制面节点初始化kubeadm init的关键参数系统准备做完终于可以正式初始化控制面了。我先列一下我的初始化命令然后逐项解释这些参数为什么这么设kubeadm init \ --apiserver-advertise-address192.168.10.10 \ --image-repositoryregistry.aliyuncs.com/google_containers \ --kubernetes-versionv1.27.3 \ --pod-network-cidr10.244.0.0/16 \ --service-cidr10.96.0.0/12 \ --cri-socketunix:///run/containerd/containerd.sock--apiserver-advertise-address指定APIServer对外通告的IP。如果机器有多网卡这一步不声明的话kubeadm可能选错IP导致后续节点join时连不上APIServer。这里最好填你期望的节点固定内网IP。--image-repository指定镜像仓库镜像地址弥补从k8s.gcr.io拉不下来的问题。--pod-network-cidrPod网段必须和后面要装的CNI插件配置一致。比如我用了10.244.0.0/16对应的Calico默认配置就是这样如果你用Flannel它默认也是10.244.0.0/16。这个网段一定不能和宿主机的内网网段冲突否则路由会打架。--service-cidrService网段默认10.96.0.0/12一般不需要改但同样要避免和现有网络冲突。--cri-socket告诉kubeadm使用containerd作为运行时接口。init的过程会持续几十秒中间会生成一堆证书、拉起静态Pod。等完整执行完你会在尾部看到一段输出里面包含一个kubeadm join的命令一定要复制保存好那是工作节点加入集群的凭证。这个Token默认有效期只有24小时如果你过几天才加节点需要重新生成kubeadm token create --print-join-command。这里我还想多说一句控制面初始化完了先不要急着加工作节点先把kubectl配好、CNI装好、控制面状态健康了再继续。3.2 kubectl配置与本地验证init完成之后kubeadm会提示你执行以下三条命令来配置kubectlmkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config这三条的本质就是把admin.conf这个超级管理员证书拷到你的用户目录下让kubectl能通过这个证书跟APIServer通信。配置完执行kubectl get nodes你会看到master节点处于NotReady状态这是正常的——因为还没装网络插件。这时候我习惯先检查一下核心组件的静态Pod是否都正常kubectl get pods -n kube-system -o wide你会看到etcd、kube-apiserver、kube-controller-manager、kube-scheduler这些以kube-system前缀命名的Pod在跑。如果某个Pod处于CrashLoopBackOff可以用kubectl logs看具体日志。这个阶段排错的关键是看静态Pod的日志因为它们是由kubelet直接拉起来的并不是普通Deployment。3.3 安装CNI网络插件Calico的配置细节CNI网络插件是整个集群能跑起来的“神经系统”。没有它Pod之间、Pod和Service之间的通信完全不通。CNI选型上我长期用Calico原因是它同时支持BGP路由和IPIP/VXLAN封装性能比纯Flannel的overlay好一些还支持NetworkPolicy的强制执行。如果只是要快速搭测试环境Flannel也不是不行但上了生产早晚得换Calico。安装命令通常是这样kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml但直接apply之前必须改一个地方calico.yaml里的CALICO_IPV4POOL_CIDR默认是192.168.0.0/16而我初始化的时候Pod网段是10.244.0.0/16。不改的话Calico创建的IP池跟APIServer配置的Pod CIDR对不上Pod永远拿不到合法IP。具体修改方式是下载yaml后编辑wget https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml # 找到 CALICO_IPV4POOL_CIDR 环境变量在 configMap 里设置 vim calico.yaml在ConfigMap段中新增kind: ConfigMap apiVersion: v1 metadata: name: calico-config namespace: kube-system data: calico_backend: bird cni_network_config: |- { name: k8s-pod-network, cniVersion: 0.3.1, plugins: [ { type: calico, log_level: info, datastore_type: kubernetes, nodename: __KUBERNETES_NODE_NAME__, ipam: { type: host-local, subnet: usePodCidr }, policy: { type: k8s }, kubernetes: { kubeconfig: __KUBECONFIG_FILEPATH__ } } ] } typha_service_name: calico-typha然后修改环境变量里的CALICO_IPV4POOL_CIDR- name: CALICO_IPV4POOL_CIDR value: 10.244.0.0/16改完再apply等Calico的Pod全部Running后再执行kubectl get nodes节点状态就会变成Ready。这一步如果卡住排查顺序是先看calico-node的日志再确认节点间的IPIP隧道或BGP peer连通性最后看路由表ip route里有没有Pod网段的路由。3.4 工作节点加入与集群状态验证控制面Ready后就可以把工作节点拉进集群了。工作节点上重复之前的系统初始化、安装containerd、安装kubeadm/kubelet/kubectl然后直接执行之前保存的join命令kubeadm join 192.168.10.10:6443 --token xxxxx --discovery-token-ca-cert-hash sha256:xxxxxxxxjoin命令的核心是token和发现证书指纹。token是授权凭证discovery-token-ca-cert-hash则保证你连接到的APIServer确实是你要的那个防止中间人欺骗。加入后去控制面节点上确认状态kubectl get nodes如果新节点还是NotReady大概率有两种情况一是CNI插件还没在其上正常启动二是节点上的kubelet启动时报错。看kubelet日志的命令是journalctl -u kubelet -f这个命令我用了无数次遇到节点起不来先别慌先把这几行日志抓出来再说。节点全部Ready后我还会做一轮冒烟测试创建一个临时nginx deployment暴露NodePort服务确认从外部能访问到业务Pod再登上某个Pod用kubectl exec去ping另一个Pod的IP验证跨节点容器通信。这一步做完集群才算真正“跑通”。4. 生产部署的关键改造从玩具到产线的进化逻辑4.1 namespace和资源管理多团队共存的基础集群刚刚搭好时只有一个default命名空间所有资源堆在一起这种状态绝对不能在产线上持续太久。我强烈建议一开始就按业务域划分namespace并且在每个namespace下设置ResourceQuota。这能解决两个典型问题团队间互相“抢资源”以及某个应用出问题后把所有节点内存打爆。给某个业务空间资源配置的示例apiVersion: v1 kind: ResourceQuota metadata: name: biz-quota namespace: biz-a spec: hard: requests.cpu: 8 requests.memory: 16Gi limits.cpu: 16 limits.memory: 32Gi persistentvolumeclaims: 10 pods: 50配合LimitRange也很有用。假如某个Pod忘了写resource limitLimitRange会给它套一个默认值防止它无限使用节点资源。这套组合拳是生产环境下“防呆”的第一道防线。命名空间对应的还有RBAC。各团队用各自的ServiceAccount权限只下放到自己的namespace这是多团队集群的基本修养。别把什么东西都扔给cluster-admin不然出了事连责任人都不好找。4.2 Deployment滚动更新与探针配置发布不出事故的底气容器跑起来只是第一步真正决定生产品质的是Deployment的更新策略和健康检查配置。很多团队在生产初始阶段只用默认的Deployment配置结果一发布就断服原因是没配探针或者探针配得太粗糙。一个核心服务Deployment的关键片段如下apiVersion: apps/v1 kind: Deployment metadata: name: api-service namespace: biz-a spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 selector: matchLabels: app: api-service template: metadata: labels: app: api-service spec: containers: - name: app image: registry.internal/biz/api-service:1.2.0 ports: - containerPort: 8080 readinessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 10 periodSeconds: 5 failureThreshold: 3 livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 30 periodSeconds: 10 failureThreshold: 3 resources: requests: cpu: 250m memory: 512Mi limits: cpu: 1 memory: 1GimaxUnavailable: 1表示更新过程中最多允许1个旧Pod不可用maxSurge: 1表示最多允许额外创建1个新Pod所以整个发布过程中服务能力始终是充足的。不过要注意这两个值加起来的百分比或绝对数量不能太多否则滚动更新会瞬间把节点资源吃满。就绪探针和存活探针的区别一定要分清楚就绪探针决定流量要不要打到这个Pod上存活探针决定容器要不要被重启。如果业务启动慢initialDelaySeconds得调大否则Pod一启动就被反复杀掉。4.3 HPA弹性伸缩流量高峰不用人肉加副本生产环境流量是会波动的人工加副本每小时一次的频率根本撑不住突发流量。HPAHorizontalPodAutoscaler是Kubernetes给的“自动扩缩容”方案它会根据Pod的CPU、内存或自定义指标自动调整Deployment的副本数。先装Metrics ServerHPA才有数据来源kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml装好之后等状态Running然后创建HPAapiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: api-service-hpa namespace: biz-a spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: api-service minReplicas: 3 maxReplicas: 20 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 60这个HPA会尝试让所有Pod的平均CPU使用率维持在60%。如果持续超过60%它会在扩容时逐步增加副本反过来低于60%则会缩容。注意缩容有一个默认的冷却时间不会流量一降马上缩这能避免“抖动”。用HPA有个我踩过的坑如果你的Deployment设置了Pod的CPU requestsHPA的CPU平均利用率才能算得准。不然就是拿实际CPU除以Pod数量而不是除以每个Pod的request值。4.4 日志与监控生产运维的“眼睛”集群装好、应用部署完如果不搭日志和监控就等于蒙着眼睛开飞机。监控方面我的标配是Prometheus Grafana用kube-prometheus-stack一把梭它能直接把节点、容器、Kubernetes控制面的指标全采出来安装方式最简单helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring --create-namespace装完后通过Port-forward或者Ingress访问Grafana默认账号密码是admin/prom-operator具体看版本建议装完立刻改密码。内置的Kubernetes集群监控面板里节点CPU、内存、磁盘、网络流量POD状态、restart次数全都能直接看到。日志收集这块稍微复杂点但又是刚需。日志组件通常围绕ELK/EFK或者Loki展开。我推荐轻方案Loki Promtail它不依赖密集的Java生态资源占用小查询方式也比Elasticsearch简单对中小团队很友好。需要特别强调的是生产环境的Pod日志一定要收集到集群外部持久化存储里比如对象存储或者NFS否则节点一旦挂了日志就全没了排障时会非常被动。4.5 etcd备份与恢复出大事时的最后底牌提到生产就绕不开数据安全。Kubernetes集群里的etcd保存着所有集群状态包括资源定义、配置、证书信息、Namespace、工作负载等它是整个集群的“数据库”。如果etcd数据坏了集群就全废了。我习惯用cron job定期给etcd做快照快照命令不需要停止etcd可以直接在线打ETCDCTL_API3 etcdctl --endpointshttps://127.0.0.1:2379 \ --cacert/etc/kubernetes/pki/etcd/ca.crt \ --cert/etc/kubernetes/pki/etcd/server.crt \ --key/etc/kubernetes/pki/etcd/server.key \ snapshot save /backup/etcd-snapshot-$(date %Y%m%d%H%M).db恢复的流程是先停掉apiserver再用etcdctl snapshot restore恢复到一个新目录最后把新目录配置到etcd的Pod定义中。整个操作过程虽然只需几条命令但一旦执行失误后果非常严重所以恢复前一定要在测试环境完整演练一遍。别等到数据真丢了才第一次尝试恢复流程那时你没有任何容错机会。5. 常见生产问题与排查技巧实录5.1 kubeadm init卡住或者失败这是安装阶段最常见的问题情像是卡在[wait-control-plane] Waiting for the kubelet to boot。这时候几乎是kubelet没正常起来或者是镜像拉不下来。我的排查顺序是先看kubelet状态systemctl status kubelet如果状态是failed就直接看日志journalctl -xeu kubelet -n 100 --no-pager日志里常见的两种错误一种是container runtime is not running这是containerd没起来或者CRI socket路径不对另一种是failed to pull image这是镜像仓库地址不通或者当前kubeadm配置的镜像仓库有误。这里有一个小技巧先手动在节点上执行ctr -n k8s.io images ls看看pause这类基础镜像是否已经被containerd拉下来了。如果镜像明明在本地还是报拉取失败先把containerd重启一下再重新reset和initkubeadm reset -f然后检查镜像源配置再重新init。kubeadm reset是每个装集群的人都会用到的命令建议记牢。5.2 节点始终NotReadyPod启动不了我遇到的最大比例是CNI网络插件出了问题。比如Calico起不来或者Pod一直ContainerCreating。先看Pod事件总能发现线索kubectl describe pod pod-name -n namespace事件里通常会写network plugin is not ready: cni config uninitialized或者sandbox status: network plugin not ready。这两种情况基本要把矛头指向calico-node。再看calico-node的日志常见是BGP peer建立失败或者bird进程报路由冲突。常见解决路径是确认所有节点的Pod网段一致确认ip_forward已开启确认kube-proxy的转发模式是否正常。还有一次我遇到过是因为主机名重复导致Calico认为两个节点是同一个Node改掉其中一个主机名后恢复正常。另一种常见情况是工作节点上kubelet一直起不来手动排查节点内存不足也会让系统OOM把kubelet杀掉了这时候journalctl里能看到大量OOM痕迹解决办法就是加内存或者减少节点上的Pod密度。5.3 CoreDNS的CrashLoopBackOffCoreDNS是集群内置DNS服务如果它挂了所有service域名解析都会失败。不过CoreDNS最常见的CrashLoopBackOff原因不是CoreDNS自己不行而是资源限制太低或者loop检测插件出了问题。查看日志kubectl logs -f deployment/coredns -n kube-system如果看到plugin/loop: Loop (127.0.0.1:53) detected for zone .说明CoreDNS在自己的解析循环里转圈通常是节点上的/etc/resolv.conf把nameserver指向了本机127.0.0.1。解决思路是修改CoreDNS的ConfigMap或节点的resolv.conf把上游DNS地址配置成实际可用的外部DNS。如果日志里是资源不足的报错就把CoreDNS的requests和limits调大一点或者检查节点是不是真的内存不足。5.4 Service无法访问kube-proxy和iptables隐患集群跑了一段时间突然某天Service访问不稳定多半和kube-proxy的iptables规则异常有关。排查步骤先确认Service的Endpoints有没有绑定到Podkubectl get endpoints service-name确认kube-proxy是否正常kubectl get pods -n kube-system | grep kube-proxy在节点上用iptables-save查看是否有对应Service的规则如果不能确认直接在Pod内curl Service ClusterIP测试看通不通。如果是kube-proxy的IPVS模式还要检查节点是否加载了ip_vs内核模块没加载的话kube-proxy会一直报错退出。5.5 证书过期问题有计划但总是被忽略Kubernetes集群默认证书有效期是一年。等哪天kubectl突然报certificate has expired or is not yet valid不用慌首要事情是快速续期或重建集群证书。kubeadm时代续期变得很简单kubeadm certs renew all这个命令会重新生成所有admin.conf、apiserver、etcd等证书。执行完需要重建相关组件的静态Podkubectl delete pod -n kube-system -l componentkube-apiserver kubectl delete pod -n kube-system -l componentkube-controller-manager kubectl delete pod -n kube-system -l componentkube-scheduler再把/etc/kubernetes/admin.conf重新拷给kubectl使用。我这里要特别强调给证书到期时间加个提醒写进日历或监控别等到过期了才发现。5.6 常见问题速查表现象可能原因快速处置kubeadm init卡在kubelet启动containerd未启动 / CRI socket路径不对检查crictl info重启containerdkubeadm reset后重来节点NotReady持续CNI未部署 / 网络插件异常看kubectl get pods -n kube-system确认calico-node日志Pod停留在ContainerCreatingCNI插件冲突 / 镜像拉取失败describe看事件手动crictl pull验证镜像CoreDNS反复重启上游DNS配置成127.0.0.1修改CoreDNS ConfigMap或节点resolv.confService访问不通Endpoints为空 / kube-proxy异常检查Endpoints、kube-proxy Pod和iptables/IPVS规则kubectl报证书过期一年有效期到了kubeadm certs renew all重建静态Pod更新kubeconfigPod被驱逐清理节点磁盘/内存压力过大释放资源增加节点或降低资源配额最后再说两句碎碎念我这几年的体会是Kubernetes集群的安装只是整个运维体系的开头真正值钱的东西在上线后的治理和排障经验。而所有生产事故里最可怕的往往不是某个组件坏了而是链路上没有任何冗余、也没有任何监测手段。所以生产集群的底线必须守住三条etcd有备份且能恢复、监控日志能看到、证书和资源配额提前规划。最后再分享一个小技巧每次改完集群核心配置后先在测试集群做一遍同样的变更并记录耗时这样生产变更时的预期会非常明确真出问题也能立刻判断出卡在哪一步。祝你的集群稳定业务长红。
返回列表