资讯详情

资讯详情

K8s运维必会:kubectl常用命令按场景分类实战整理

干过K8s运维的应该都有同感集群搭建好了、应用部署上去了真正日常打交道最多的不是什么高深理论而是那一串串命令行操作。Pod起不来要看日志、Service访问不到要查端点、节点有压力要排节点、配置要改得先看当前生效值。这些操作单个看都不难难的是在故障现场能快速想到对应的命令并且知道这条命令在不同参数下会看到什么不同的信息。我最早接触K8s的时候面对一长串帮助文档其实是很懵的因为命令太多、参数太杂记了后面忘了前面。后来频繁踩坑才慢慢梳理出一套自己的命令使用逻辑——不按资源类型死记而是按使用场景分类查状态、看日志、进容器、改配置、排故障、删资源。这套思路比单纯背命令实用得多这篇文章我就把这些常用命令整理出来把参数含义和容易出错的地方一并讲清楚。1. 环境与工具先搞清楚你在操作哪个集群1.1 kubectl 的配置和行为习惯K8s所有运维操作基本都是通过kubectl这个命令行工具完成的所以先把这个工具的基础行为搞清楚。kubectl默认会读取家目录下的.kube/config文件这里面保存了集群地址、证书信息和当前使用的上下文。如果你的环境里有多个集群可以像我一样习惯性地为每个集群设置不同的上下文名称用kubectl config get-contexts查看当前有哪些可用环境。kubectl config get-contexts kubectl config current-context kubectl config use-context 集群上下文名称这些命令是我每天都会用的。真正要提醒的是切换集群上下文之前一定确认一下当前指向哪个环境我见过不止一次有人把测试环境的操作命令敲到了生产环境上。一个比较实用的防护方法是在切换上下文后用kubectl get nodes快速确认一下节点名称是否符合预期毕竟节点名通常和集群环境是强相关的。1.2 命名空间与资源作用域K8s里的资源是分命名空间的很多命令默认只操作default命名空间。不加参数的时候你查到的Pod、Service、Deployment都只是default这个空间里的很容易漏掉实际运行在kube-system或者其他业务命名空间里的资源。kubectl get pods -n kube-system kubectl get all -n 命名空间 kubectl get namespaces如果嫌每次都要带-n参数麻烦可以在kubectl配置里给当前上下文设置默认命名空间kubectl config set-context --current --namespace命名空间这样设置之后后续命令如果不带-n参数默认查询的就是你指定的这个命名空间了。多人共用一个集群的时候我其实不太推荐改默认命名空间因为别人看你的操作记录时容易产生误解。更稳妥的做法是每敲一条命令都明确指定-n参数或者在执行批量操作前先用一条只读命令确认一下范围。1.3 查看帮助与命令自动补全K8s的命令体系比较大我不觉得每个人都应该把全部参数背下来但至少要会用帮助系统和自动补全。kubectl的每个操作都可以用-h或者--help查看详细参数说明比如kubectl get -h会列出支持的所有资源类型和输出格式kubectl logs -h会说明日志查询的各种筛选条件。bash环境下还能开启自动补全这一条我强烈建议配置上效果立竿见影source (kubectl completion bash) echo source (kubectl completion bash) ~/.bashrc如果你用的是zsh把bash换成zsh即可。配好之后输入kubectl d再按Tab就能自动补全为describe输入kubectl get po再按Tab能列出所有Pod名称根本不用记完整名字。日常操作效率至少提升一半而且减少了很多拼写错误导致的低级事故。2. 工作负载操作Pod、Deployment与Service的日常命令2.1 查看Pod状态与常用输出格式Pod是K8s里最小的调度单元排查问题十有八九从查Pod开始。最基础的命令是kubectl get pods kubectl get pods -n 命名空间 kubectl get pods -o wide-outputwide这个参数会额外显示Pod所在的节点IP和节点名称以及Pod的IP地址排查调度问题时特别有用。只看默认输出的话你是无法判断Pod被调度到了哪台机器上的。还有更进阶的格式kubectl get pods -o yaml kubectl get pods -o json kubectl get pods -o custom-columnsNAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName-o yaml和-o json输出完整资源定义适合要看详细字段的场景。custom-columns可以根据需要自定义显示的字段列当你想快速对比一批Pod的某种属性时这个参数比yaml全文更直观。查看Pod状态的时候还需要区分READY列和STATUS列的关系。READY显示的是“可用副本数/期望副本数”比如2/3表示期望3个副本但只有2个就绪此时STATUS处可能显示Running。只看STATUS容易被误导因为Running不代表应用真的就绪了。这个细节我在排查滚动更新问题时吃过亏当时看到Pod都是Running就以为发布成功了结果接口一直报错最后才发现是readinessProbe探测失败流量没有真正切过去。2.2 查看Deployment和副本状态Deployment是管理无状态应用的主要方式相关命令自然也得熟练掌握kubectl get deployments kubectl get deploy -n 命名空间 kubectl get deploy -o wide kubectl describe deploy 应用名describe命令会输出该Deployment的完整事件记录包括ReplicaSet的创建历史、镜像更新记录、探针检查结果、调度事件等。事件部分不带时间戳没法直接看出问题发生的时间线我通常会配合-o yaml看status字段里的conditions里面会记录最近一次变更的reason和message信息量比describe更大。查看ReplicaSet和滚动更新历史也是常见的需求kubectl get rs kubectl rollout status deployment/应用名 kubectl rollout history deployment/应用名rollout status会一直阻塞等待直到发布完成或超时适合在CI脚本里用。rollout history则可以看到历次发布的版本号和对应镜像回滚的时候需要根据这个列表选择版本。2.3 Service与端点查询Service是K8s内部的服务发现和负载均衡抽象Pod IP不稳定Service提供了一个稳定的访问入口。排查访问不通的问题时先看Service定义再看它的Endpointskubectl get svc kubectl get svc -n 命名空间 kubectl get endpoints kubectl get endpoints -n 命名空间 -o wide如果Endpoints列表为空说明后端的Pod没有匹配上Service的selector或者Pod没有通过 readinessProbe 检查。这是一个非常常见的踩坑点Service的selector写错一个标签或者Pod的标签和selector不一致就会导致Endpoints为空服务自然访问不通。我想特别强调下这几个资源之间的关系Deployment管理Pod副本Service通过selector选中PodPod就绪后才会被加入Endpoints流量才能进来。链路中任何一个环节对不上服务就崩了。2.4 标签选择器过滤K8s的标签系统是管理资源的基础手段。在实际运维中通过标签筛选资源比一个个记名字高效得多kubectl get pods -l appnginx kubectl get pods -l appnginx,envprod kubectl get pods -l app in (nginx,redis) kubectl get pods -l version!v1标签选择器支持等式选择器和集合选择器。等式的写法是keyvalue或者key!value集合的写法是key in (v1, v2)或者key notin (v1, v2。多个条件用逗号分隔表示AND关系。标签选择器不仅用于命令行查询更常用于Service的selector定义。我在给业务方排查问题时经常用到一个组合命令kubectl get pods -l app应用名 -o wide kubectl get svc -l app应用名一条命令既看到Pod所在节点又看到Service的ClusterIP排查网络链路时少敲好几轮命令。3. 日志与容器交互进入Pod内部的实用操作3.1 查看日志的几种姿势日志是排查应用问题的第一手资料。K8s里查看Pod日志的基础命令是kubectl logs Pod名称 kubectl logs Pod名称 -n 命名空间 kubectl logs -f Pod名称-f参数用于实时跟踪日志输出类似tail -f的用法。如果一个Pod里有多个容器需要用-c参数指定容器名kubectl logs Pod名称 -c 容器名称不指定容器名的话会报错或者只输出默认容器的日志具体行为取决于集群版本和kubectl的配置。查看前一个容器的日志也是排查崩溃问题的常用手段比如Pod一直CrashLoopBackOff这时候当前容器还没起来日志为空要看的是上一次退出时的日志kubectl logs Pod名称 --previous这条命令在容器不断重启的场景下非常有价值。有些应用崩溃是因为启动时配置读不到--previous能看到上一次进程退出前的全部输出错误信息往往是直接定位问题的关键。另外如果Pod已经不在Running状态只要Pod对象还在日志就还能拉取。Pod被删除后就彻底没了所以遇到需要保留现场的场景先把日志导出来再删Pod。3.2 进入容器执行命令进容器内部检查和操作也是高频需求。K8s里通过exec命令实现kubectl exec -it Pod名称 -- /bin/sh kubectl exec -it Pod名称 -c 容器名称 -- /bin/bash-it参数表示交互式终端--后面的部分是容器内要执行的命令。很多精简镜像里没有bash只有sh所以进入容器时应该先尝试sh。有的镜像连shell都没有那就只能靠logs和describe来排查了。不需要进入交互式shell也可以直接执行单条命令kubectl exec Pod名称 -- env kubectl exec Pod名称 -- cat /etc/nginx/nginx.conf kubectl exec Pod名称 -- ls -la /app这种方式适合快速检查容器内的环境变量、配置文件或目录文件列表。不过要注意的是kubectl exec的本质是在容器内起一个新进程如果你在容器内执行了重操作会占用容器资源。生产环境要慎用尤其是那些CPU和内存limit设得比较紧的Pod可能因为你执行了一个top命令就触发了OOM Kill。3.3 端口转发与临时调试很多场景下你不想暴露Service到集群外部只希望在本机临时访问一下某个Pod内的服务。这时候可以用port-forwardkubectl port-forward pod/Pod名称 8080:80 kubectl port-forward deploy/应用名 8080:80 kubectl port-forward -n 命名空间 svc/服务名 8080:80命令执行后访问本机的8080端就会转发到Pod的80端口。这个功能在调试数据库连接、访问管理后台、验证服务接口时都非常有用。需要注意port-forward是前台阻塞进程保持终端开启才有效。实际脚本里如果需要后台运行可以用nohup或者放到CI的background步骤。我可以分享一个我们团队常用的临时调试案例某个应用的管理后台没有对外暴露Service我处理问题时先通过kubectl port-forward把本机端口映射到Pod端口然后用浏览器直接访问。好处是不需要动集群里的任何配置用完直接CtrlC关掉就行。如果要在远端跳板机上操作记得配合ssh隧道做二次转发。4. 资源与配置管理ConfigMap、Secret与节点的常用命令4.1 ConfigMap的创建与查看应用配置管理是K8s运维里很日常的工作。ConfigMap用来存放非敏感配置常用操作如下kubectl create configmap 配置名 --from-literalkeyvalue kubectl create configmap 配置名 --from-file./app.properties kubectl get configmaps kubectl get cm 配置名 -o yaml--from-literal适合少量配置项直接写命令行--from-file适合整个配置文件导入。生产环境中我比较推荐用YAML文件管理ConfigMap因为可以随代码仓库一起走版本管理变更可回溯。用kubectl create生成后再通过kubectl apply更新不会出现命令行创建后没法溯源的问题。修改ConfigMap后已经运行的Pod不会自动感知配置变化除非应用本身实现了配置热更新。对于大部分应用需要触发一次滚动重启才能让新配置生效。盲目的做法是直接删除Pod让Deployment重建规范一点的做法是kubectl rollout restart deployment/应用名这一条命令会让Deployment滚动更新Pod逐个重新创建而且不会影响Service的高可用能力。如果不重启而直接删Pod如果配置变了但应用没生效容易产生不一致的状态。4.2 Secret的创建与解码Secret和ConfigMap类似不同的是内容以base64编码存储。注意只是编码不是加密任何人都能解码看到明文不能把Secret当成加密存储来用。kubectl create secret generic 密钥名 --from-literalusernameadmin --from-literalpassword密码 kubectl get secrets kubectl get secret 密钥名 -o yaml查看Secret内容时yaml里显示的data字段是base64编码的。需要看明文的话要手动解码echo base64字符串 | base64 -d高阶一点的做法是直接用jsonpath提取某个字段再解码kubectl get secret 密钥名 -o jsonpath{.data.password} | base64 -dSecret相关的权限控制值得特别留意。默认情况下任何能读Secret的人都能解出明文如果集群里给普通开发者授予了比较宽泛的list权限敏感信息泄露风险比较大。对于生产集群建议在规划RBAC时把Secret的读写权限严格限定在运维角色范围内。4.3 节点操作与集群节点状态管理节点层面的操作通常涉及硬件故障处理、节点维护和资源排查。最常用的节点命令kubectl get nodes kubectl get nodes -o wide kubectl describe node 节点名称 kubectl top nodedescribe node是排查节点问题的核心命令里面包含节点的资源总量、已分配量、系统版本、容器运行时、条件状态MemoryPressure、DiskPressure、PIDPressure、Ready以及最近的事件列表。当节点状态显示NotReady时第一件事就是describe看事件的详细报错常见原因包括kubelet异常、网络插件故障、磁盘空间满或者容器运行时停止响应。kubectl cordon 节点名称 kubectl drain 节点名称 --ignore-daemonsets --delete-emptydir-data kubectl uncordon 节点名称cordon把节点标记为不可调度新的Pod不会调度上去。drain则会把节点上已有的Pod驱逐到其他节点。drain的时候经常需要带--ignore-daemonsets参数因为DaemonSet的Pod是每个节点都要跑的驱逐不掉是正常的。如果节点上有使用emptyDir的Pod还得加--delete-emptydir-data参数。这两个参数不带上drain通常会卡住或者报错。4.4 资源请求与限制的相关命令资源管理方面最直观的是查看当前节点和Pod的资源使用情况kubectl top node kubectl top pod -n 命名空间top命令依赖metrics-server组件正常部署才能返回数据。如果执行top报错先检查metrics-server的Pod是否Running。在空跑了一个测试集群后我发现很多人明明部署了metrics-server却看到top命令一直报错深入排查才发现是metrics-server的证书问题后面问题解决后资源监控才恢复正常。查询资源请求和限制的配置kubectl get pod Pod名称 -o yaml | grep -A 10 resources kubectl describe node 节点名称 | grep -A 10 Allocated resources第一行看Pod自身的requests和limits配置第二行看节点上所有Pod的分配情况。节点分配情况是判断“为什么Pod没调度到这个节点”的重要依据如果一个节点的可分配资源已经用完新Pod自然是Pending状态。5. 故障排查的通用流程与组合命令5.1 定位问题Pod的排查四步法故障场景下先别慌按固定的排查顺序走是最高效的。我自己的惯用套路是四步先看Pod状态再看事件然后看日志最后进容器确认。kubectl get pods -n 命名空间 -o wide kubectl describe pod Pod名称 -n 命名空间 kubectl logs Pod名称 -n 命名空间 --tail200 kubectl exec -it Pod名称 -n 命名空间 -- /bin/sh第一步看状态Pending说明调度没完成CrashLoopBackOff说明容器反复崩溃ImagePullBackOff说明镜像拉取失败Running但READY列不是完整比例说明就绪探针有问题。第二步看事件这是describe里最有价值的部分Events区记录了调度、拉镜像、启动、探针探测等所有关键节点的状态变化大部分问题的原因在这一步就能找到。第三步看日志定位应用层面的报错。第四步进容器确认文件、进程、端口、环境变量等现场信息。这四步可以覆盖绝大部分日常故障。如果你做完四步还定位不到问题再考虑网络层排查、存储排查或者控制平面排查。5.2 批量操作与字段提取批量场景下灵活运用jsonpath和自定义输出列可以节省大量时间。例如查看所有命名空间下所有异常状态的Podkubectl get pods -A | grep -v Running | grep -v Completed-A参数表示所有命名空间这一条命令能快速找出集群中有没有异常Pod。又比如查看所有Pod使用的镜像kubectl get pods -A -o jsonpath{range .items[*]}{.metadata.name}{\t}{.spec.containers[*].image}{\n}{end}jsonpath语法初看比较绕但原理不复杂range表示循环遍历.items[]表示所有元素.metadata.name是资源名.spec.containers[].image是容器镜像列表中间用\t和\n控制输出格式。再看一个常见需求找出某个节点上运行的所有Podkubectl get pods -A -o wide | grep 节点名称这些组合命令用一个grep就能解决很多问题。不过我不太建议写特别复杂的单行jsonpath看懂别人的还可以自己维护成本偏高。有复杂需求的时候用-o yaml导出后配合jq或者python脚本处理会更灵活。5.3 事件查看Events是排查问题的一手情报Events是K8s控制面在调度、拉起容器、探针检查过程中产生的事件记录。用以下命令查看命名空间内的事件kubectl get events -n 命名空间 kubectl get events -n 命名空间 --sort-by.lastTimestamp kubectl get events -n 命名空间 --field-selector typeWarningkubectl get events默认按时间倒序排列不过实际体验中不同集群版本的排序行为略有差异所以需要明确时间排序时我会手动加--sort-by参数。只看Warning类型也能快速过滤噪音kubectl get events --all-namespaces --field-selector typeWarning这里我想提醒一件事很多事件记录有TTL过期机制尤其是大批量重复事件时会压缩合并。在登录一个不熟悉的集群时很快地翻看events是了解这个集群近期发生了什么最直接的方式。比如看到大量FailedScheduling事件说明有Pod一直调度不上去看到大量BackOff事件说明有容器一直在重启。6. 常用运维操作导出、导入、滚动重启与删除6.1 导出资源定义把集群里的资源定义导出成文件是常见需求不管是备份还是迁移都绕不开。导出的方式通常有两种一种直接导出当前运行的定义另一种是只导出清单不导出状态。默认的-o yaml导出会带上status字段、resourceVersion、uid等集群内部信息这些不是我们想要的内容导出来反而会让文件很冗余。比较干净的做法是kubectl get deployment 应用名 -n 命名空间 -o yaml --export历史版本中--export参数可以把运行时状态剥离只输出精简的声明式定义。这个参数在较新版本中已经被标记为废弃但大部分版本仍然可用。如果不想依赖--export还可以用kubectl create的方式重新生成或者手动清理yaml中的status等字段。对于批量导出可以for循环处理kubectl get deployments -n 命名空间 -o name | xargs -I {} kubectl get {} -n 命名空间 -o yaml all-deployments.yaml这样一条命令就能把命名空间下所有Deployment导出到同一个YAML文件方便整体备份或者迁移。6.2 重新创建与滚动重启前文提到了rollout restart这里再展开一下。滚动重启的本质不是删除重建而是触发一次新的ReplicaSet滚动。它的好处是保证有副本可用不会出现服务完全中断。kubectl rollout restart deployment/应用名对于StatefulSet同样适用。如果集群里应用通过Helm管理更规范的做法是改配置后helm upgrade让Helm自己触发更新而不是手动rollout restart。手动restart只适合临时让应用重新加载配置或者让调度重新平衡的场景。6.3 删除操作的注意事项与保护措施删除操作是K8s里最容易出事故的一类命令所以我把这部分单独拉出来讲。不考虑Terminating状态的Pod卡住直接挂在这里需要额外处理。kubectl delete pod Pod名称 kubectl delete deployment 应用名 kubectl delete svc 服务名单独删除一个PodDeployment会立即重新创建一个这在很多场景下其实是期望行为。比如配置更新了或者Pod状态异常需要重启。但如果你的本意是要彻底下线一个应用就得把相关的Deployment、Service、ConfigMap等一起删掉否则Deployment控制器会不断重建Pod。批量删除要尤其小心kubectl delete pods -l app应用名 kubectl delete deployment,svc -l app应用名按标签删除的好处是可以精确选择目标资源。但删除前务必先用get命令加上同样的-l条件确认一遍影响范围。这一步不能省我身边发生过因为标签写得不够精确把公共组件一起删掉导致大面积服务不可用的真实事故。另外有些Pod删除时会一直卡在Terminating状态常见原因是节点失联、kubelet无响应、finalizer阻塞或者Pod内有自定义的优雅终止钩子没完成。强制删除的保守方式是kubectl delete pod Pod名称 --grace-period0 --force这个操作要谨慎带--force直接清理Pod记录如果底层容器还在跑就成了孤儿进程。生产环境建议先排查为什么删不掉而不是立刻强删。7. 实际场景组合操作把命令串成解决问题的流程7.1 场景一版本发布后接口报错假设你刚发了一个新版本滚动更新完成后有用户反馈接口报错。有种情况是Pod虽然起来了但代码逻辑有bug。排查时可以这样组合kubectl get pods -l app应用名 kubectl rollout status deployment/应用名 kubectl logs -f deployment/应用名 --tail100 kubectl rollout history deployment/应用名先确认Pod是不是全部Running且READY列是期望的值。新增了bug的版本如果导致readinessProbe失败Pod不会变为Ready此时会有新旧版本Pod同时存续的情况因为滚动更新会等待新Pod Ready后再删旧Pod。确认是代码问题时回滚到上一个版本kubectl rollout undo deployment/应用名默认会回滚到上一个版本。如果要回到更早的版本用--to-revision指定kubectl rollout undo deployment/应用名 --to-revision版本号回滚动作本身也是一次滚动更新同样不会中断服务。回滚完成后Status会显示deployment rolled back此时再观察一段时间确认接口恢复。这个场景还容易遇到一个细节回滚后镜像变了但某些缓存或者数据库迁移脚本还在新版本状态。K8s层面是干净的回滚了应用层的数据兼容性需要业务团队自行确认。所以我处理这类事故时有个习惯回滚动作做完后立刻让业务同事验证一批关键接口确认数据一致性没有问题。7.2 场景二Pod一直PendingPod长时间处于Pending状态说明调度器没有成功把Pod调度到某个节点。常见原因有资源不足、节点亲和性不满足、存储卷无法挂载、存在污点不容忍等。kubectl get pods -n 命名空间 | grep Pending kubectl describe pod Pod名称 -n 命名空间describe里的Events区会有具体的调度失败原因最常见的是类似0/3 nodes are available: 1 Insufficient cpu, 1 node(s) had taint...这样的信息。Insufficient cpu说明某个节点CPU资源不够满足Pod的requeststaint则说明节点有污点而Pod没有对应的容忍。如果是资源不足可以用以下命令确认集群整体资源情况kubectl top nodes kubectl describe nodes | grep -E Name:|Allocated resources|ACK通过top nodes先看整体水位再看具体节点的分配情况。有一种情况是集群总资源够但单个节点的资源碎片化严重每个节点剩余资源都小于Pod的request需求量所以调度不上去。这种碎片化问题没有很好的自动解决方案通常靠调整资源配额或者适当放宽某些Pod的资源request来缓解。7.3 场景三Service访问不通Service访问不通的排查链路比Pod问题更复杂需要逐层检查。我的排查顺序是先确认Pod正常再看Endpoints然后看Service定义最后检查网络策略和DNS。kubectl get pods -l app应用名 kubectl get endpoints 服务名 kubectl get svc 服务名 -o yaml kubectl describe svc 服务名如果Endpoints列表为空问题基本锁定在selector匹配或者Pod未就绪。对照Service的spec.selector和Pod的labelskubectl get pod Pod名称 -o yaml | grep labels -A 5如果Endpoints正常但访问仍然不通检查Service的type。ClusterIP类型的只能在集群内部访问如果希望外部访问需要NodePort或者Ingress。另外StatefulSet这类有状态服务还要检查headless service的DNS解析是否能解析到Pod IP。网络策略NetworkPolicy这个因素也很容易被忽略。某些命名空间启用了默认拒绝的网络策略未知来源的流量会被直接丢弃。检查网络策略kubectl get networkpolicies -n 命名空间如果这部分没问题但流量还是不通最后排查节点上的kube-proxy和iptables规则不过这就超出kubectl命令的范畴了需要登录节点操作。7.4 场景四节点NotReady节点NotReady是影响面比较大的故障整台机器上的Pod都会受影响。首先看节点状态kubectl get nodes -o wide kubectl describe node 节点名称describe node的Conditions部分会显示Ready状态为False还是Unknown以及LastHeartbeatTime。如果心跳时间停留在很久以前说明kubelet无法上报状态可能的原因包括kubelet进程崩溃、网络失联、磁盘空间满、容器运行时异常等。查看kubelet日志需要登录节点操作一般位置在journalctl里journalctl -u kubelet -n 200如果确认是节点磁盘空间满清理后通常会自动恢复。恢复后记得确认节点上的Pod状态NotReady期间如果节点一直处于网络分区状态控制面可能会把Pod重新调度到其他节点恢复后原节点上可能同时存在孤儿Pod。处理这种场景时要留意双副本同时运行的问题确保业务有幂等保护机制。8. 常见坑位与我的个人操作习惯8.1 操作记录和变更备份K8s的命令是即敲即生效的没有撤销选项所以我在处理生产问题时有一条自己的规矩执行任何变更类命令之前先执行一条同维度的查询命令把当前状态保存下来。比如要删一个Pod先kubectl get pod Pod名称 -o yaml backup.yaml要改一个Deployment先kubectl get deploy 应用名 -o yaml backup.yaml。这个习惯看着麻烦关键时刻能救命因为回滚时你手上有一份完整的、和线上完全一致的原始定义。做事后复盘的时候我建议把当时的命令、输出和解决过程都整理到文档里。K8s的报错信息有很强的相似性很多问题两三个月后会再遇到一次有记录就能直接翻出之前的解决方案不需要从头排查一遍。8.2 不要迷信自动修复不少运维同学遇到Pod异常第一反应是删除重建。这个思路有一定道理因为Deployment会拉一个新Pod出来有时候问题确实就消失了。但我要提醒的是重建只能掩盖问题不能根治问题。如果Pod反复崩溃就算删十次还是崩溃。应该先看日志定位根因而不是盲删。尤其涉及有状态应用时删除Pod的行为就更需要谨慎。对于StatefulSetPod的名称带有序号标识删除后重建虽然会用同一个名字但如果有数据依赖或者身份标识重建后的Pod可能跟原有状态不一致引发数据问题。我在实际中遇到过由于重建有状态Pod导致主从集群脑裂的情况那一次的处理代价比想象中大得多。8.3 权限与最小化原则团队多人共用集群时应该基于RBAC对不同角色做权限隔离。开发人员可能有某个命名空间的读写权限但没有生产环境的删除权限。运维人员的操作也应该尽可能用kubectl apply来管理资源少直接kubectl edit因为apply可以走审批和审计edit是直接改线上对象出问题没法追溯。对于个人学习/测试环境可以放开了操作但建议给kubectl配置独立的kubeconfig文件而不是用集群管理员账号。这样就算误操作也只是影响自己的测试集群不会波及其他环境。8.4 持续学习命令背后的原理命令只是触达K8s功能的接口如果不理解命令背后对应的控制器逻辑和调度基准遇到极端问题就难以判断。比如kubectl delete pod和kubectl rollout restart虽然最终表现都是Pod重建但前者是单独删一个Pod由Deployment控制器补齐副本后者是生成一个新的ReplicaSet滚动替换并且会保留历史版本用于回滚。理解这个差异就知道什么场景该用哪个命令。我自己的经验是每次遇到一个不熟悉的报错花15分钟看看相关资源的API定义和字段说明比直接搜索引擎找答案收获更多。K8s的官方文档对每个字段的语义描述得很清楚清楚字段含义之后操作命令就是加减乘除级别的应用了。这些就是我在K8s日常运维中最常用的一批命令和操作思路。写到最后我个人最想强调的是命令本身只占解决问题的小部分真正的价值在于你知不知道当前系统处于什么状态、为什么处于这个状态、以及你敲下的命令会对状态产生什么影响。希望这份整理对你有用也希望你以后在集群面前越来越少敲错命令、越来越多一次到位。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →