ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Kubernetes实战指南:从集群搭建到生产运维

Kubernetes实战指南:从集群搭建到生产运维 干这行久了你会发现现在出去聊技术简历上不写点Kubernetes的东西HR和面试官都会多问你几句。这个曾经听起来像是“给运维用的玩具”的调度系统如今已经成了后端工程师、DevOps工程师、甚至算法工程师跑模型推理都躲不开的基础设施。你就算没亲手搭过生产集群至少也得看得懂kubectl get pods输出的是什么。这篇文章不是我临时整理的概念手册而是这些年从零搭建、日常运维、再到被线上故障“教育”之后沉淀下来的知识点集合。我尽量按我理解的“认知路径”来讲先搞懂它解决什么问题再上手搭集群然后深入工作机制最后聊聊生产环境里那些绕不开的存储、GPU、监控和排查思路。读完你未必能三天内成为K8s专家但至少能建立一个不混乱的知识骨架知道该往哪些方向深挖。1. K8s到底解决了什么问题从一次“人肉运维”说起很多教程上来就讲架构图、讲Pod、讲Service结果新手听了一头雾水这玩意儿到底比我写个Shell脚本强在哪我倾向于换个思路先想清楚K8s出现之前我们是怎么部署服务的。1.1 没有控制器的时候扩展服务有多痛苦假如你维护一个Java应用最早部署方式是打包扔到服务器上用nohup启动日志输出到文件挂了就登上去重启。业务量涨了就在多个服务器上重复这个流程再用Nginx做负载均衡。听着简单但你会发现几个痛点环境不一致这台机器缺个依赖、那台机器Java版本低了、扩容靠人工半夜流量暴增你得登服务器敲命令、某台机器宕机服务直接中断因为没有任何机制帮你把进程“挪”到别的机器上。K8s干的事情本质上是把“部署、扩容、自愈、服务发现、滚动升级”这些运维动作从人肉脚本变成了一组可声明、可自动执行的控制逻辑。1.2 用一组生活化类比理解架构角色我记得自己刚接触K8s时被一堆组件名吓到etcd、kube-apiserver、kube-scheduler、kube-controller-manager、kubelet、kube-proxy加起来七八个。其实你把它们套进一家餐厅的运作逻辑一下就顺了etcd餐厅的账本和公告栏所有数据谁在哪个桌、点了几道菜都记在这里所有人都得跟它对齐。kube-apiserver前台接待所有指令连接上来的kubectl、其他组件通信都经过它它负责校验身份、验证参数然后去账本上记账。kube-scheduler排桌经理看到新来的客人Pod就根据空桌情况节点资源决定安排到哪张桌子哪台Node。kube-controller-manager大堂经理不断对照期望状态比如“应该有两桌客人”和实际情况少了就赶紧补位、多了就协调撤桌。kubelet各桌的专属服务员负责执行自己这桌的命令启停容器、上报状态。kube-proxy传菜通道负责把外部流量按照规则转发到正确的桌子上。这套设计里最值得琢磨的是“控制循环”思想。K8s不是一个“命令-执行”的僵化系统它时刻在对比“我想变成什么样”和“现在是什么样”然后通过一系列控制器让现实向期望收敛。这也是它和传统配置管理工具比如Ansible最大的区别Ansible是“你让我干嘛我就干嘛”K8s是“你告诉我目标我自己想办法”。2. 从零到一基于Kubeadm搭建v1.26.0集群实录搭建集群是每个K8s学习者必过的关。市面上的方式不少Minikube适合本地单机Kind适合测试环境但生产环境里最常见的还是Kubeadm。我用Kubeadm在虚拟机Ubuntu 22.04上部署v1.26.0集群的完整流程几乎每一步都踩过坑下面把关键节点和当时的输出记录整理出来给你当参考。2.1 环境准备这一步决定了你后面踩坑的数量我建议第一次实操至少准备两台机器一台Master、一台Node每台2核4G以上。装好Ubuntu系统之后首先要做三件“政治任务”禁用Swapswapoff -a并注释掉/etc/fstab里的swap行。Kubelet的cgroup管理跟swap天生冲突这一步不做kubeadm init 百分之百爆[ERROR Swap]: running with swap on is not supported。加载内核模块与网络参数把overlay、br_netfilter模块加载起来并设置net.bridge.bridge-nf-call-iptables 1。不然后面Pod网络Calico会出现跨节点通信诡异不通的问题。安装容器运行时K8s 1.24之后不再直接支持Docker作为运行时如果你被Docker和containerd的概念绕晕可以只看这层关系containerd是容器运行时负责真正拉起容器Docker默认也调containerd所以集群里装containerd就够了。生产实践最稳妥的方式是装containerd并且给它生成默认配置时确认SystemdCgroup true不然Kubelet报cgroup驱动不匹配节点会一直NotReady。做完初始化接下来是装三个核心工具kubeadm、kubelet、kubectl。需要注意安装时需要从K8s官方apt源拉取国内环境的话用阿里云或中科大镜像源替换即可这里涉及镜像下载跟云厂商的镜像仓库有关网上搜一下对应源的配置就清楚了。2.2 kubeadm init的完整输出与参数选择配置好源、安装完工具在Master节点上执行初始化命令我当时的写法和常见的推荐一致sudo kubeadm init \ --apiserver-advertise-address192.168.1.100 \ --pod-network-cidr10.244.0.0/16 \ --kubernetes-versionv1.26.0执行之后你会看到一段很有仪式感的输出第一段就是这个热词里的内容[init] Using Kubernetes version: v1.26.0 [preflight] Running pre-flight checks[preflight]阶段就是Kubeadm帮你做“手术前体检”检查内核版本、检查swap是否关闭、检查端口是否被占用、检查容器运行时是否可用、检查cgroup驱动是否一致。我记得第一次执行时卡在[ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1就是前面提到的网络参数没配好找到/etc/sysctl.d/k8s.conf里补上配置再sysctl --system就好。初始化成功后会给出三段信息一段kubeconfig配置命令让你自己复制到自己家目录一段kubeadm join命令Node节点加入时要用还有一段是提示你“必须装一个CNI网络插件”。如果这三种信息会计不住建议用一个文件把这结果存起来像这样kubeadm init ... k8s-init.log而且在跑init之前可以先想好--apiserver-advertise-address和--pod-network-cidr。前者是API Server对外广播的IP一般填Master节点的内网IP后者是Pod网络分配的CIDR需要跟你选的网络插件Calico/Flannel保持一致比如Calico常用192.168.0.0/16Flannel常用10.244.0.0/16魔改了很容易出现Pod跨节点回包失败。2.3 网络插件与Node加入为什么CNI几乎决定成败init完成但集群还是“瘫痪”的因为Node和Pod之间没法通信必须安装CNI。Flannel配置简单适合入门Calico功能更强支持NetworkPolicy适合生产。我选Calicokubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26/manifests/calico.yaml装上之后kubectl get pods -n kube-system会看到calico相关Pod从ContainerCreating变成Running。这中间常碰的坑是镜像拉不下来——Calico组件镜像在docker.io上网络环境不稳定你需要提前在Node节点上ctr images pull或配置好镜像加速不然就一直卡在ImagePullBackOff。Node节点加入就简单多了直接跑Master给出的join命令token有效期默认24小时过期就重新执行kubeadm token create --print-join-commandkubeadm join 192.168.1.100:6443 --token xxxx --discovery-token-ca-cert-hash sha256:xxxx等到两个节点都kubectl get nodes显示Ready这个集群才算真正“活”了。我建议完成这一步后马上跑一个kubectl run nginx --imagenginx然后kubectl get pods -o wide确认调度情况再kubectl exec进去访问一下验证整个链路是通的。3. 把服务跑起来Pod、Deployment、Service与外部访问的实操笔记集群搭完只是开始日常工作中你接触最多的还是“怎么把应用跑起来、怎么访问它”。这里有几个层次理解透了就抓住了K8s编排的核心。3.1 Pod与Deployment别慌它俩就是“进程”和“进程管理器”Pod是K8s里最小的调度单位可以理解为“一个或多个容器的集合”。为什么要有这一层而不是直接用容器因为有时候两个进程必须共享网络、共享存储比如日志收集sidecar跟业务容器K8s把这种强绑定的关系用一个Pod包起来调度的原子单位就从“单个容器”变成了“这个组合”。但生产环境里很少有人直接创建Pod因为Pod挂了就真的没了。我们通常用Deployment无状态应用最常用的控制器来管Pod。它的职责是声明“我要3个Nginx副本”然后通过ReplicaSet维持这3个副本2个挂了自动补2个。Deployment还支持滚动更新比如镜像从nginx:1.20升级到nginx:1.21你可以设置maxSurge和maxUnavailable控制同时多起几个、同时停几个保证升级期间服务不中断。这块是面试爱问的也是线上发布最容易踩雷的点发布时没有控制好Pod数量、导致瞬间流量被踢到运营商故障是很多事故的根源。这里我把最基础的Deployment文件贴出来你能看得明白这个“想长成什么样”的声明apiVersion: apps/v1 kind: Deployment metadata: name: nginx-demo spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.21 ports: - containerPort: 80如果你刚上手可以多练习几个命令组合kubectl scale deployment nginx-demo --replicas5手动扩缩容kubectl rollout status deployment nginx-demo看发布进度kubectl rollout undo deployment nginx-demo回滚。这三个命令用熟了你会发现自己养成了“随时检查期望状态”的习惯。3.2 Service层从“Pod飘忽不定”到“稳定访问入口”Pod是有“原罪”的——IP不固定随时可能被重新调度新Pod的IP和旧的完全不同。所以K8s引入了Service你可以把它理解成一个“稳定的VIP负载均衡器”。它通过Label Selector挑中一组Pod然后给这组Pod提供一个稳定的ClusterIP不管底层Pod怎么变访问Service的IP和端口都不变。Service的类型这句话面试也经常被问到我把几种类型的区别整理成一张表Service类型访问范围典型场景等价类比ClusterIP集群内部服务间调用、数据库访问内网专线NodePort集群外部通过节点IP端口临时暴露、调试、小型应用电话分机播报LoadBalancer集群外部通过负载均衡器IP云厂商环境AWS ALB、腾讯云LB公司总机转接ExternalNameDNS别名把集群内服务映射到外部域名转发外卖电话这里要专门提一下热词里的externalIPs。很多自建机房没有云厂商的负载均衡器又想直接给Service指定一个固定的外部IP比如公司的公网IP或内网IP池就可以像下面这样配置apiVersion: v1 kind: Service metadata: name: nginx-demo spec: selector: app: nginx ports: - port: 80 targetPort: 80 externalIPs: - 192.168.1.200这样一个集群外的IP就“长”在Service上了通过192.168.1.200:80直接访问到Pod这可以说是“穷人版LoadBalancer”。但有个坑externalIPs其实是由kube-proxy在节点上实现的所以当应用流量量很大时这台节点网卡会承担大量转发工作你要评估这台节点的带宽和性能不能让它在高流量下变成瓶颈。生产里更推荐的方式是用MetalLB这类开源项目把LoadBalancer的能力在裸机上落实它会通过BGP或ARP协议把IP广播到局域网里。3.3 Ingress当你发现端口不够用网关必须出场NodePort的坑在于它占的是节点的物理端口而且一般范围限定在30000-32767Service多了端口管理和防火墙配置会非常痛苦。Ingress就是这层“HTTP层网关”它负责根据域名、URL路径把请求路由到不同的Service。比如api.example.com进到订单服务Serviceweb.example.com进到前端Service。Ingress只是一个API对象真正干活的是Ingress Controller最常见的如NGINX Ingress Controller。你需要先部署Controller通常是DeploymentService再创建Ingress规则apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: demo-ingress spec: rules: - host: demo.example.com http: paths: - path: / pathType: Prefix backend: service: name: nginx-demo port: number: 80创建完之后kubectl get ingress能看到ADDRESS把域名解析到Ingress Controller所在的节点IP流量就通了。这里要提醒一句我见过很多人排错只盯Service结果发现Ingress Controller的Pod没起来或者Ingress的class没写对。使用Nginx Ingress时Ingress对象里必须写ingressClassName: nginx控制器才肯接管不然就是干等一晚上也不通。这也是初学者最抓狂的“莫名奇妙404”之一。4. 从声明式API到Operator : 理解K8s的设计灵魂搭建集群、跑通Deployment你只是学会了“用K8s”还没理解“K8s为什么被设计成这样”。弄懂设计思想对你后面的学习方向尤其面试、二次开发和排障影响巨大。4.1 声明式API和控制器模式它凭什么能“自愈”K8s的核心不是某个具体的调度算法而是“声明式API”和“控制器模式”。声明式API的意思就像你给保洁公司下订单时说“我希望客厅地板每天都是干净的”而不是“你每周三早上9点拿着拖把去客厅拖地”。你只描述目标状态具体执行路径怎么拖、什么时候拖由系统决定。控制器模式则是这个“自愈”的底层机制。Kube-controller-manager里面有一堆控制器Deployment控制器、ReplicaSet控制器、Node控制器、Namespace控制器等等。它们共同遵循同一个循环逻辑Watch观察当前状态→ 对比期望状态 → 如果不一样执行动作去趋近期望状态 → 再观察。这就像你房间里的空调你设定26度期望状态温度计检测到现在28度当前状态于是压缩机启动动作制冷直到温度回到26度然后停止运行但依然每秒都在检测。这个循环的背后是API Server和etcd提供的事件流。控制器通过List-Watch机制订阅资源变化比如Deployment控制器发现ReplicaSet数量跟期望不符就会去创建或删除Pod。这种设计让K8s在故障面前显得非常“淡定”节点宕机节点上的Pod被标记为Unknown控制器自动在别的节点上补齐新Pod。你不需要写任何脚本去“重启服务”因为系统本身就在做这件事。4.2 Operator模式把运维经验“固化”成代码控制器模式接下来最精彩的一跃就是Operator。说是“模式”本质上是“扩展K8s的API”。K8s自带那些资源Deployment、Service都只是通用模板当你想管理的是一个有状态、有特殊运维流程的应用比如etcd集群、Prometheus、MySQL集群时你可能希望K8s能理解“3个etcd节点发现彼此”“备份失败要不要告警”这种高级动作。Operator的做法是你先自定义一种资源类型CRDCustom Resource Definition然后写一个控制器通常是一堆Go代码去监听这类资源的增删改。也就是说你可以定义一个EtcdCluster资源声明“我要3个节点、存储5G”Flux一艘Operator会负责创建StatefulSet、做好集群初始化、监控健康状态、自动处理故障替换。我印象最深的一个案例就是当年用Prometheus Operator时它把整个监控体系都变成了CRD用ServiceMonitor声明“要监控哪些Service”用PrometheusRule声明告警规则。突然你就觉得监控系统从“一堆手工配置文件”变成了“一堆可版本化、可审计的K8s对象”。这就是Operator的奇妙之处它在用K8s的API机制替代传统的运维脚本。当然这也不代表所有场景都应该写Operator。我见过有的团队连个简单的定时任务都要写CRD结果维护成本高得吓人。很多批量任务用CronJob就够了扩展API是面向“有复杂生命周期管理”的应用的比如数据库、消息队列。如果只是部署一个无状态Web应用老老实实用DeploymentHelm就非常合适不要过度设计。5. 存储、GPU调度与监控告警生产环境绕不开的硬骨头平时做Demo挺开心一到生产环境就发现K8s的核心知识点里存储、异构资源、可观测性是三道大坎。这三块整明白了你在团队里的价值马上不一样。5.1 PV/PVC/StorageClass给应用一个“不会丢”的屁股Pod默认是“用完即弃”的容器内的文件写在可写层Pod删了就没了。但数据库、消息队列这类有状态服务需要持久化数据于是K8s抽象出了PersistentVolumePV和PersistentVolumeClaimPVC。我用吃饭来类比PV是“后厨的食材储备”真实存在比如一块云磁盘、一个NFS目录、一个本地盘PVC是“你点的菜”声明我要多大容量、什么访问模式。管理员先把PV准备好开发只需要写PVC声明要5G然后K8s会自动把合适的PV“绑定”给这个PVC。Pod里挂载PVC其实就把一份真实存储挂到了容器里。现代K8s环境里大家更多直接用StorageClass它是“自动卖菜机”。你声明“我要5G的SSD存储”StorageClass就通过CSI插件自动去云厂商创建一个云盘并清好PV、绑定PVC。这套动态供给机制的好处是存储变成了一种“随时申请、按需使用”的资源不需要运维提前囤一堆PV。关于存储类型以及回收策略我画一个对比表方便你参考存储类型生命周期典型用例回收策略注意点emptyDir随Pod存在删除即清空临时缓存、当日志管道无需回收hostPath跟随节点节点数据保留访问宿主机文件、系统级调试节点故障后数据可能丢PV/PVC静态供给生命周期独立于Pod已有NAS、云盘的迁移场景Delete会删底层存储谨慎使用StorageClass动态供给自动创建PV删除PVC后按策略处理云环境最推荐默认回收策略可能是Delete误删PVC会导致数据全没有一个必须记牢的教训PV的回收策略ReclaimPolicy千万别乱选Retain之外的值特别是在云盘场景里。如果设置成Delete有人误删PVC你的云盘和上面所有数据会一起蒸发连恢复的机会都没有。5.2 K8s调用GPU别让NVIDIA驱动成为调度盲区大模型训练和推理现在越来越普遍K8s集群里需要调配GPU资源。K8s原生不认识“GPU”它只知道CPU和内存。要让K8s能调度GPU得靠两个东西扩展资源和Device Plugin。NVIDIA官方提供nvidia-device-plugin以DaemonSet的形式跑在每个GPU节点上。它会向Kubelet汇报“这台机器有8张卡”Kubelet再上报给API Server。调度器在调度时就会把GPU作为一种资源纳入计算——比如某个Pod声明nvidia.com/gpu: 1调度器会优先把它调度到有剩余GPU卡的节点。下面是一个申请GPU的Pod例子apiVersion: v1 kind: Pod metadata: name: gpu-pod spec: restartPolicy: Never containers: - name: cuda-container image: nvidia/cuda:12.2.0-base-ubuntu22.04 command: [nvidia-smi] resources: limits: nvidia.com/gpu: 1这里必须强调一个大坑GPU的requests和limits必须一致都写nvidia.com/gpu: 1。如果你只写limits某些版本的调度器可能把GPU当成可超卖资源两个Pod都认为自己独占整张卡最后跑起来互相抢显存导致OOM。另外Device Plugin工作正常的前提下你还需要确认节点上有NVIDIA驱动、以及Docker/containerd的默认运行时使用了NVIDIA Container Runtime否则Pod即使调度到了GPU节点容器里nvidia-smi依然是“No devices were found”。5.3 用Prometheus监控K8s从手工配置到声明式全家桶监控是K8s生产环境里真正让人安心的一环。Prometheus是标准答案它分成抓取采集、存储、告警、可视化几个部分而落地这套体系的常见方式就是kube-prometheus-stack。这套栈里的组件各管一摊Prometheus Server负责拉取各类指标并存储node-exporter暴露节点CPU、内存、磁盘指标kube-state-metrics把K8s对象Deployment、Pod、Service等的数量和状态转换成指标Grafana负责画好看的监控看板Alertmanager负责把告警发到钉钉、企业微信或邮件。关键的架构优势是kube-prometheus-stack把Prometheus自身也变成了“K8s原生应用”。你不需要手工改Prometheus配置文件只需要创建ServiceMonitor对象声明“我要采集哪个Service的/metrics端口”Prometheus会通过标签自动发现。比如要监控一个自定义应用你可以这样写apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: my-app-monitor namespace: monitoring spec: selector: matchLabels: app: my-app endpoints: - port: metrics interval: 30s告警规则同样也是CRD比如“节点CPU持续高”可以定义成一条PrometheusRule。这套体系维护起来舒心的地方在于所有监控配置都可以像代码一样走Git、做Review、可回滚。排障的时候主看Grafana面板先看Node节点容量CPU/内存/磁盘再看Pod状态、重启次数、QPS/延迟最后看容器日志。按这顺序来大多数问题都能在五分钟内定位个八九不离十。6. 面试必问题型与生产集群常见故障排查思路最后这部分既是给准备面试的朋友准备的高频题库也是实际运维中每天可能碰到的问题排查手册。这两个场景看着不搭其实底层能力是同一个对K8s工作机制理解够不够深对异常现象能不能快速串联原因。6.1 高频面试题我按“概念-原理-实战”三层给你理一遍概念层要熟记Pod生命周期Pending、ContainerCreating、Running、Succeeded、Failed、Unknown以及Deployment、StatefulSet、DaemonSet的区别。StatefulSet管有状态应用稳定的网络标识、独立的存储卷DaemonSet保证每台节点跑一个Pod比如日志采集、节点监控。原理层要能讲清楚调度器选节点的过程先过滤Predicates比如节点资源够不够、端口冲突、taint容忍再打分Priorities资源余量越均衡分数越高。还要理解etcd为什么需要奇数节点——它是基于Raft协议做分布式共识的3个节点允许挂1个5个节点允许挂2个多写一个节点并不是为了“容量”而是为了“多数派可用”。实战层要会解释“Pod一直Pending是什么原因”。可能是资源不够、PVC没有绑定、节点有污点且Pod没加容忍。看到CrashLoopBackOff则第一反应去看日志kubectl logs和kubectl describe pod的Events里往往写着最直接的原因——镜像启动失败、探针失败、或者命令错了。6.2 我在生产环境里真实踩过的几个名场面这里整理几个高频故障现象和排查套路都可以按“描述、可能原因、排查命令、解决方向”的思路来复盘。第一个名场面是节点NotReady。现象是kubectl get nodes里节点状态变成NotReady导致上面的Pod被驱逐或者长时间无响应。原因通常是Kubelet进程异常、节点负载过高、网络不通API Server跟Kubelet通信断了。排查顺序是先SSH上节点systemctl status kubelet再journalctl -u kubelet -f看日志确认是不是磁盘满导致Kubelet拉不了镜像或上报失败。第二个名场面是镜像拉取失败。报错一般是ImagePullBackOff或ErrImagePull。大多数时候不是镜像不存在而是镜像仓库认证失败、网络不通、或者tag写错。这时候kubectl describe pod的Events里会有Failed to pull image xxx:latest: rpc error看清楚是认证问题就去kubectl create secret docker-registry创建imagePullSecrets如果是网络问题就配好镜像仓库或加速器。第三个名场面是Pod被驱逐Evicted。节点内存、磁盘不足时Kubelet会对Pod发起驱逐优先驱逐QoS等级低的PodBestEffort Burstable Guaranteed。生产里遇到批量Pod Evicted先看是不是节点内存被打满了再看Deployment副本数是否正常最后考虑给核心业务设置合理的requests和limits让它们拿到Guaranteed的待遇减少被误伤概率。我把这些“故障现象→排查方向→兜底命令”整理成一个速查表建议收藏排障时真的能救命故障现象可能原因首先执行的命令解决方案方向节点NotReadyKubelet不健康/网络故障journalctl -u kubelet -f处理磁盘满、重启Kubelet、恢复网络Pod一直Pending资源不足/未调度到合适节点kubectl describe pod name加资源/扩节点/去污点或加容忍ImagePullBackOff镜像不存在/认证/仓库网络问题kubectl describe pod查Events修正tag、配置imagePullSecret、换镜像源CrashLoopBackOff容器启动后崩溃/探针失败kubectl logs pod --previous修代码/调启动命令/调整探针参数Evicted节点磁盘/内存压力超阈值kubectl get eventsgrep EvictedDNS解析异常CoreDNS Pod异常/coredns配置问题kubectl get pods -n kube-system检查CoreDNS副本状态、nat/iptables规则Service无法访问标签选择器不匹配/端口没对上kubectl describe svc name检查selector标签、targetPort排障的本质还是回到那个核心看状态、看事件、看日志、看资源。先kubectl get看全局再kubectl describe看事件再kubectl logs看应用日志最后不行就上节点看系统层。按这个顺序来哪怕一时定位不到根因也不至于像无头苍蝇一样到处乱敲命令。一点经验收尾从最早被kubeadm init的报错折磨到半夜到现在能比较淡定地面对节点NotReady和生产环境突发告警我最大的感悟是K8s的知识结构不应该是“记一堆YAML样例”而是理解“声明式目标”和“控制循环”这两个发动机然后用它去统领所有细节。你知道了“系统会不断调整现实去靠近期望”很多故障现象你不需要背也能猜出个大概。如果你想自学我给一个比较顺手的学习路径先把kubectl常用命令练到反射级别get、describe、logs、exec、apply、rollout再亲手用Kubeadm搭两三遍集群体会初始化输出的每一个阶段在干什么然后去啃一个Deployment、Service、Ingress“三件套”的完整Demo之后再往深了看调度、存储和监控。最后有余力去看看Operator是怎么写的或者做一些K8s二次开发的实验你的水平会远超“会用”的层面。做这个圈子的技术人早晚都要爬这几座山与其等到线上故障逼你学不如现在就花点时间把这套知识骨架搭稳。真正运行起来之后你会发现K8s不是让你失业的自动化而是让你能把精力放在更复杂、更值得解决的问题上——这也是我一直喜欢这套系统的地方。
返回列表