1. 从零开始:为什么要先把 Kubectl 玩熟
如果你刚接触 Kubernetes,或者已经在看各种 YAML 文件但总觉得没摸到门道,我强烈建议你先别急着写复杂编排,把kubectl这个命令行工具练到像用ls一样自然。kubectl是 Kubernetes 的官方控制台命令,所有对集群的查看、部署、调试、排错,几乎都能通过它完成。换句话说,你可以在不写一行 YAML 的情况下,先靠kubectl把 Pod 跑起来、看日志、进容器、改配置,这套流程通了,再回头理解那些清单文件,会顺很多。
这篇文章从一个实际场景出发:我手里有一个刚搭好的 Kubernetes 集群(无论你是用 kind、minikube 还是云厂商的托管集群,操作逻辑一致),现在要做的第一件事就是部署第一个 Pod,并围绕这个 Pod 完成状态查看、日志获取、文件拷贝、环境变量注入、配置挂载等一系列日常操作。整个过程全部用kubectl命令行完成,不涉及复杂的 Helm 或 Operator,适合作为入门的第一课,也适合老手拿来梳理自己的命令体系。
文章里会用到一些高频关键词:kubectl、Pod、ConfigMap、deploy、cp,这些是日常操作中出现频率最高的几个点。我会从原理讲到实操,最后附上我踩过的坑和排查思路,希望你看完能直接上手,而不是停留在“看得懂”的层面。
2. Kubectl 的工作方式与集群交互逻辑
2.1 kubectl 到底在做什么
很多人第一次用kubectl时会有个错觉:以为它是一个像ssh一样直接连进集群的隧道工具。其实不是。kubectl本质是一个 HTTP 客户端,它读取你本地的~/.kube/config配置文件,拿到 API Server 的地址、证书和认证信息,然后把你的操作请求封装成 REST API 调用,发给 Kubernetes 的控制面组件。控制面经过认证、授权、准入控制等一系列校验后,再把结果返回给kubectl展示。
这套逻辑解释了为什么你经常要配kubeconfig,也解释了为什么kubectl本身不需要安装什么 Agent。你只要有了正确的配置文件和网络连通性,就能操作集群。理解这一点后,很多怪异现象就好解释了:比如你在 A 机器上能访问集群,在 B 机器上不行,多半是配置文件或网络环境不同,而不是集群本身“拒绝了你”。
2.2 kubeconfig 与上下文切换
平时用得最多的三个配置相关命令是:
kubectl config get-contexts:查看当前可用的所有上下文kubectl config current-context:查看当前正在使用哪个上下文kubectl config use-context <名称>:切换上下文
上下文(context)由集群地址、用户身份、命名空间三者组合而成。我经常遇到的情况是:本地同时配了开发集群和测试集群的访问权限,如果不小心用错上下文,可能把测试环境的资源删了,或者把开发环境的 Pod 误判成生产故障。所以我的习惯是,在操作任何重要资源前,先执行kubectl config current-context确认一下当前环境,这个习惯帮我避免过不止一次事故。
如果你需要临时指定不同的 kubeconfig 文件,可以加--kubeconfig参数,或者设置环境变量KUBECONFIG。不过日常场景下,切换 context 已经足够。
2.3 命名空间:资源隔离的第一道门
命名空间(Namespace)是 Kubernetes 里实现资源逻辑隔离的方式。默认情况下,集群里会有default、kube-system、kube-public等命名空间。kube-system里跑的是控制面组件和系统级插件,一般不建议动它;我们日常操作主要是在自己创建的业务命名空间里进行。
创建命名空间用:
kubectl create namespace demo查看已有的命名空间:
kubectl get namespaces指定命名空间操作资源时,习惯性加-n参数,比如:
kubectl get pods -n demo如果不加-n,kubectl会默认操作default命名空间。初学者最容易犯的错就是“忘了加 -n”,结果明明部署了资源却看不到,或者删错了资源。我的建议是:只要不是刻意操作default空间,一律显式加上-n参数,形成肌肉记忆。
提示:如果你经常在某个固定命名空间下工作,可以查看上下文里的默认命名空间,或者直接用
kubectl config set-context --current --namespace=demo把当前上下文的默认命名空间改成demo,这样即使忘了加-n,也不会跑到default里。
3. 部署第一个 Pod:从命令行到运行状态
3.1 先用 kubectl run 快速启动一个 Pod
很多教程喜欢先让你写一个 YAML 文件再 apply,但我想换个顺序:先用一条命令把 Pod 跑起来,看看它长什么样,再谈 YAML。这样你更容易建立“Pod 是一个可运行对象”的直觉。
最简单的启动命令是:
kubectl run nginx-pod --image=nginx:1.24 --port=80这条命令的含义是:在集群里创建一个名为nginx-pod的 Pod,使用nginx:1.24镜像,容器内监听 80 端口。执行后,kubectl会立刻返回pod/nginx-pod created这样的信息,但注意,这并不代表 Pod 已经就绪,它只是被 API Server 接受了。
查看 Pod 状态:
kubectl get pods刚启动时,你大概率会看到类似这样的输出:
NAME READY STATUS RESTARTS AGE nginx-pod 0/1 ContainerCreating 0 5sContainerCreating表示节点正在拉取镜像、创建容器。如果镜像已经在节点本地存在,很快就变成Running;如果网络拉取慢,可能会停留较长时间。等几秒后再执行kubectl get pods,看到Running且READY为1/1,就说明 Pod 成功运行了。
想看更多细节,用:
kubectl describe pod nginx-pod这个命令会列出从 Pod 调度到容器启动全过程的详细事件,包括被分配到了哪个节点、使用的镜像、容器状态、最近事件等。当 Pod 启动失败时,describe输出里的事件部分(Events)往往直接告诉你原因。
3.2 Pod 的四个常见状态与判断方法
我见过不少新手被 Pod 状态搞懵,这里把最常见的几种状态用一个表格列出来:
| 状态 | 含义 | 常见原因 | 下一步 |
|---|---|---|---|
| Pending | 已接受创建请求,但还没有完成调度 | 节点资源不足、缺少持久卷、节点亲和性不满足 | 看describe事件,确认调度器卡在哪 |
| ContainerCreating | 已经在节点上创建容器 | 镜像拉取中、存储卷挂载失败 | 等待,或看节点上容器运行时日志 |
| Running | 容器正常运行 | 健康检查通过 | 执行logs或exec查看内部情况 |
| CrashLoopBackOff | 容器反复启动又崩溃 | 启动命令错误、配置缺失、资源不足 | 查看容器日志,调整启动参数 |
| Error | 容器退出且报错 | 镜像不存在、启动命令退出非零 | 看logs和describe事件 |
判断一个 Pod 是否真的“健康”,不能只看状态是 Running,还要看READY列是否达到预期副本数。如果设置了存活探针和就绪探针,探针失败也会反映在READY列上。日常巡检时,一条kubectl get pods -A看清所有命名空间的 Pod,是很多运维老手的开场命令。
3.3 通过 Deployment 管理 Pod 而不是直接裸建
kubectl run创建的是单个 Pod,但它没有副本管理、滚动更新、故障自愈这些能力。一旦 Pod 所在节点出问题,这个 Pod 不会自动迁移或重建。所以实际生产环境,我们一般不会直接kubectl run,而是使用 Deployment 这类工作负载资源。
创建 Deployment 的命令:
kubectl create deployment nginx-deploy --image=nginx:1.24 --replicas=2这个命令会创建一个名为nginx-deploy的 Deployment,管理两个副本。查看 Deployment:
kubectl get deployments kubectl get rs kubectl get podsRS指的是 ReplicaSet,Deployment 通过 ReplicaSet 来管理 Pod 副本数。这条链路是:Deployment -> ReplicaSet -> Pod。明白了这条链,你再看滚动更新、回滚、扩缩容,就都顺了。
注意:
kubectl run和kubectl create deployment都会生成对应的资源对象,并且支持用--dry-run=client -o yaml导出 YAML 内容。这个技巧对“从命令行反推 YAML”、或者给不熟悉 YAML 的同事演示非常有用。例如:kubectl create deployment nginx-deploy --image=nginx:1.24 --replicas=2 --dry-run=client -o yaml。
3.4 扩缩容、更新镜像、回滚
一旦用 Deployment 管理 Pod,日常运维常见操作就变成了:
- 扩容到 5 个副本:
kubectl scale deployment nginx-deploy --replicas=5- 更新镜像版本:
kubectl set image deployment/nginx-deploy nginx=nginx:1.25这里nginx=nginx:1.25中的nginx是容器名,不是镜像名。如果你不确定容器名,可以用kubectl describe deployment nginx-deploy查看。
- 查看更新过程:
kubectl rollout status deployment/nginx-deploy- 查看历史版本并回滚:
kubectl rollout history deployment/nginx-deploy kubectl rollout undo deployment/nginx-deploy如果你希望回滚到指定版本,在后面加--to-revision=<序号>即可。
这里我想强调一个观点:kubectl用得好不好,不在于你会多少条命令,而在于你对“Deployment 管理 Pod 生命周期”这个模型理解得深不深。命令只是表象,模型才是核心。
4. 进入 Pod 内部:日志、执行命令与文件拷贝
4.1 查看日志是排错的第一动作
Pod 运行起来后,第一件想做的事通常是看日志。最基本的命令:
kubectl logs nginx-pod如果 Pod 里只有一个容器,直接写 Pod 名即可。如果 Pod 里有多个容器,需要指定容器名:
kubectl logs nginx-pod -c nginx如果容器之前崩溃过,想看看上一次退出的日志:
kubectl logs nginx-pod --previous--previous在CrashLoopBackOff场景特别有用,因为当前容器还没起来或者刚起来就没了,普通logs拿不到有效输出,反而上次的日志里有报错线索。
跟踪日志输出:
kubectl logs -f nginx-pod退出跟踪用Ctrl+C。如果日志量大,可以加--tail=50只取最后 50 行。还有一个我常用的组合:kubectl logs -f deployment/nginx-deploy --tail=20,直接跟踪某个 Deployment 下所有 Pod 的日志尾部,相当于一个轻量聚合日志。
实操心得:查看日志时如果发现“无日志输出”,先检查容器的启动命令是否把日志写到了 stdout/stderr。Kubernetes 默认只收集容器标准输出和标准错误,如果应用写的是文件,你需要用
kubectl exec进容器查看,或者配置日志收集方案。
4.2 用 exec 进入 Pod 执行命令
调试验证时,kubectl exec是我的首选。格式为:
kubectl exec -it nginx-pod -- /bin/sh-it表示交互式终端,--后面是你在容器里要执行的命令。进去以后,你就在一个正常可交互的 shell 里了,可以执行ls、cat、curl、ps等命令进行排查。
如果不进入交互模式,也可以一次性执行单条命令,比如:
kubectl exec nginx-pod -- ls /usr/share/nginx/html这种写法适合在脚本里批量执行。需要注意的是,不同镜像里带的 shell 不同,有的只有sh,有的有bash。如果bash不存在,就用sh。
还有一个容易踩的坑:容器里可能没有curl、ping、vi这些工具,因为很多基础镜像刻意精简了体积,尤其是使用 distroless 或 Alpine 的镜像。所以进容器前先想清楚你依赖哪些工具,如果没有,要么改用宿主机的kubectl logs排查,要么装个带调试工具的临时 Pod。
4.3 kubectl cp:从 Pod 里拷文件出来
标题里专门提到了kubectl cp,这个命令确实实用。它的格式跟scp很像:
kubectl cp <pod名>:<容器内路径> <本地路径>比如把 Pod 内的 nginx 默认页面拷到本地:
kubectl cp nginx-pod:/usr/share/nginx/html/index.html ./index.html反过来,把本地文件拷进 Pod:
kubectl cp ./test.html nginx-pod:/usr/share/nginx/html/test.html执行kubectl cp时,kubectl会自动在 Pod 内执行tar命令打包再传输,因此要求 Pod 内存在tar。大多数标准镜像都有,但极简镜像可能没有,这时候你会看到tar: not found之类的报错。解决办法是:要么换一个带有tar的镜像,要么用kubectl exec配合cat和重定向变通完成拷贝。
另外,如果 Pod 里有多个容器,需要指定容器名:
kubectl cp nginx-pod:/etc/nginx/nginx.conf ./nginx.conf -c nginx拷贝目录时,注意路径末尾斜杠的语义与cp命令一致。比如写到容器目录:/usr/share/nginx/html/,表示把目录内容拷贝到目标目录;写:/usr/share/nginx/html不带斜杠,则行为可能更接近把整个目录按名字拷贝。
实操心得:
kubectl cp对二进制文件、中文字符文件、大文件偶尔会有坑。最常见的是符号链接和权限信息丢失,这是因为传输过程中经过了tar打包再解包,部分元数据可能变化。如果只是临时提取日志或配置文件,问题不大;但如果你要做备份或迁移,建议优先用挂载存储卷,而不是依赖kubectl cp。
5. ConfigMap 与配置注入:让 Pod 的配置不再写死
5.1 为什么需要 ConfigMap
容器镜像设计的一个原则是“镜像不变,配置可变”。同一份镜像,在开发环境、测试环境、生产环境里跑,行为应该不同,而这个区别就来自配置。如果每次改配置都要重新构建镜像,那 Dev/Prod 环境切换的成本就太高了。
Kubernetes 提供了 ConfigMap 来解决“配置与镜像分离”的问题。ConfigMap 本质上是一组键值对,你可以在创建 Pod 时把它作为环境变量注入、作为文件挂载到容器路径、或者作为命令行参数引用。它不负责加密,敏感数据应该用 Secret,不要放进 ConfigMap。
5.2 从命令行创建 ConfigMap
创建 ConfigMap 有好几种方式,我用命令行最顺手的方式是从字面量创建:
kubectl create configmap demo-config --from-literal=APP_ENV=production --from-literal=LOG_LEVEL=info查看 ConfigMap:
kubectl get configmaps kubectl describe configmap demo-config如果你有一份现成的配置文件,也可以直接导入:
kubectl create configmap app-config --from-file=./application.properties--from-file会读取文件内容,默认把文件名当作键名,文件内容当值。你还可以指定键名:--from-file=mykey=./config.txt。多个文件用逗号分隔,实际工作中我经常一条命令导入整个目录下的多个配置文件。
5.3 在 Pod 中使用 ConfigMap 作为环境变量
创建完 ConfigMap,接下来让 Pod 用上它。你可以先写一个 Deployment 的 YAML,也可以用命令行的方式。我这里先展示一种不看 YAML 也能完成的快速验证方法:使用kubectl run加--env参数,但这种写法只能使用普通字面量环境变量,跟 ConfigMap 的联动一般要在 YAML 里通过envFrom或valueFrom实现。所以这一步我建议你接触一下 YAML,至少能看懂结构。
一个最小示例:
apiVersion: v1 kind: Pod metadata: name: config-demo-pod spec: containers: - name: app image: busybox:1.36 command: ["/bin/sh", "-c", "echo $APP_ENV $LOG_LEVEL; sleep 3600"] envFrom: - configMapRef: name: demo-config把上面内容保存为pod-config.yaml,执行:
kubectl apply -f pod-config.yaml然后进入 Pod 查看环境变量:
kubectl exec -it config-demo-pod -- /bin/sh你会看到APP_ENV=production、LOG_LEVEL=info。这里用到的envFrom会把 ConfigMap 里所有键值对注入为环境变量,比较适合配置项较多的场景。
5.4 ConfigMap 挂载成文件:热更新与注意事项
把 ConfigMap 挂载为文件是另一种常见用法。修改上面的 YAML:
spec: containers: - name: app image: busybox:1.36 command: ["/bin/sh", "-c", "cat /etc/config/app.properties; sleep 3600"] volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: app-config这样/etc/config/app.properties就是 ConfigMap 里app.properties键对应的内容。这种做法的好处是:更新 ConfigMap 后,挂载到 Pod 里的文件内容会自动同步(一般几秒到几十秒内),不需要重启 Pod。但要注意,这个“自动更新”只在挂载场景下生效,如果通过环境变量注入,更新 ConfigMap 后 Pod 里的环境变量不会改变,必须重建 Pod。
注意:ConfigMap 挂载有个常见坑:它会覆盖挂载目录的原有内容。比如你把 ConfigMap 挂载到
/etc/nginx/conf.d,这个目录原来是空的还好,如果原有目录本身有文件,就可能被覆盖。解决方法是使用 subPath 挂载指定单文件,或者把 ConfigMap 挂到一个单独的空目录,再用符号链接或修改主配置的方式引用。
6. 暴露服务:从 Pod 到集群内外的访问
6.1 Service 的作用与类型
Pod 的 IP 是临时分配的,Pod 重建后 IP 会变。如果客户端直接访问 Pod IP,一旦 Pod 挂掉重建,连接就断了。Kubernetes 引入 Service 作为稳定的访问入口,它通过标签选择器动态关联一组 Pod,客户端只需访问 Service 的 VIP(虚拟 IP)或 DNS 名称,无需关心后端 Pod 变化。
Service 常见类型:
ClusterIP:默认类型,只能在集群内部访问,适合内部服务调用NodePort:在每个节点上开放一个端口,外部可通过节点IP:端口访问LoadBalancer:云平台或支持 MetalLB 的环境中,自动创建负载均衡器,外部通过负载均衡器 IP 访问
6.2 暴露 Deployment 对应 Service
假设我们已经有了nginx-deploy这个 Deployment,想把它的 80 端口暴露为 Service:
kubectl expose deployment nginx-deploy --type=ClusterIP --port=80 --target-port=80 --name=nginx-service--port是 Service 对外监听的端口,--target-port是后端 Pod 内的容器端口。如果你只想在集群内部测试,ClusterIP就够了:
kubectl get svc nginx-service你会看到类似:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-service ClusterIP 10.96.123.45 <none> 80/TCP 10m在集群内部,业务 Pod 可以直接通过http://nginx-service访问这个服务,不需要带 IP。
如果想让外部访问,可以用 NodePort:
kubectl expose deployment nginx-deploy --type=NodePort --port=80 --target-port=80 --name=nginx-nodeport然后查 Service 分配的端口:
kubectl get svc nginx-nodeport输出里端口部分会显示类似80:31864/TCP,说明外部可以通过任意节点的 IP 加 31864 端口访问这个服务。
6.3 端口转发:临时调试利器
在没有配置 Service 或者不想改动集群内资源的情况下,kubectl port-forward是临时验证 Pod 服务最方便的方式:
kubectl port-forward pod/nginx-pod 8080:80执行后,本机访问http://localhost:8080,流量会转发到 Pod 的 80 端口。port-forward本质是 kubectl 与 API Server 建立一条隧道,数据通过 API Server 转发到节点再进入 Pod。它适合临时调试,不适合生产流量。如果担心安全性,生产环境还是应该依赖 Ingress 或 LoadBalancer,而不是把业务端口直接暴露在节点上。
7. 标签、选择器与批量管理技巧
7.1 标签是资源组织的灵魂
随着集群里资源越来越多,靠“看一眼名字”来管理完全不够。Kubernetes 用标签(Label)来标记资源,键值对形式,比如app=nginx、env=prod、tier=frontend。标签可以加在 Pod、Deployment、Service、Node 等几乎所有资源上。
给 Pod 打标签,最直接的方式是在创建时指定:
kubectl run nginx-lb --image=nginx:1.24 --labels="app=nginx,tier=frontend"查看标签:
kubectl get pods --show-labels如果你想临时给已有的 Pod 加一个标签:
kubectl label pod nginx-lb env=prod7.2 用标签选择器过滤资源
标签选择器最大的用途是在get、delete、logs等命令里精确过滤资源。语法格式:
kubectl get pods -l app=nginx kubectl get pods -l 'tier in (frontend,backend)' kubectl get pods -l 'env!=prod'还可以用组合选择器,多个条件用逗号分隔,相当于 AND:
kubectl get pods -l 'app=nginx,tier=frontend'-l参数支持=、!=、in、notin、exists等多种方式。掌握这个过滤语法后,运维效率会提升不少,尤其在几十上百个 Pod 同时运行的环境里。
7.3 批量操作 Pod 的风险提示
批量删除 Pod 要格外小心,比如:
kubectl delete pods -l app=nginx这个命令会删除所有带app=nginx标签的 Pod。如果你确认这些 Pod 由 Deployment 管理,删除后 Deployment 会根据副本数自动重建,短暂影响服务但不会“消失”;但如果是裸 Pod,删除后就是真的没了。所以我给出的建议是:删除前先执行kubectl get pods -l app=nginx确认范围,最好再配合--dry-run=client预览,不要凭记忆乱删。
8. 常见问题与排查技巧实录
8.1 ImagePullBackOff:镜像拉取失败
这是新手遇到最多的报错。看到ImagePullBackOff或ErrImagePull,第一反应是镜像地址写错、镜像不存在、或者节点无法访问镜像仓库。排查步骤:
kubectl describe pod <pod-name>看 Events 部分,一般会直接显示拉取失败原因。如果提示repository does not exist,检查镜像名称和 tag 是否正确;如果提示超时或 TLS 握手失败,检查节点到镜像仓库的网络连通性以及是否配置了镜像仓库认证(imagePullSecrets)。我遇到过不少次“本地能 pull,节点不能 pull”的情况,原因往往是节点上没有 docker 凭证。解决办法是在集群里创建 Secret,并在 Deployment 的spec.template.spec.imagePullSecrets里引用。
8.2 CrashLoopBackOff:容器起不来
容器反复退出时,kubectl get pods会显示CrashLoopBackOff。排查思路:
- 先看日志:
kubectl logs <pod-name> --previous - 如果日志没有有效输出,用
kubectl describe pod <pod-name>看退出容器的退出码 - 检查启动命令、环境变量、挂载文件是否正确
- 如果涉及数据库等服务,检查依赖是否就绪
常见原因包括:启动命令里依赖的文件不存在、权限不足、配置了错误的环境变量、资源限制过小导致 OOM、容器里没有前台进程导致直接退出。我之前排查过一个案例,容器启动命令写的是sh /opt/app/run.sh,但镜像里实际没有这个脚本,导致启动即退出,CrashLoopBackOff无限循环。这类问题用logs --previous几乎都能看到报错线索。
8.3 Pending 状态:调度不成功
Pod 一直停在Pending,多半是资源不足或存在调度限制。先执行:
kubectl describe pod <pod-name>再看 Events。常见提示:
0/2 nodes are available: 2 Insufficient cpu:节点 CPU 资源不够,需要扩容节点、删除无用 Pod 或调整资源请求0/2 nodes available: 1 node(s) had taint X:节点上有污点,Pod 没有对应容忍0/2 nodes available: 2 node(s) had untolerated taint:同上
如果你确认 Pod 不需要特别调度策略,可以查看节点资源:
kubectl top nodes看 CPU 和内存使用情况。对于本地开发环境,最常见的原因就是笔记本资源不足。
8.4 kubectl cp 拷贝文件失败
如果你执行kubectl cp时报错,优先怀疑容器里没有tar。这时候可以用一个更通用的替代方案:
kubectl exec <pod-name> -- cat /path/to/file > ./local-file.txt把容器内文件内容重定向到本地文件。反过来,往容器里拷文件:
cat ./local-file.txt | kubectl exec -i <pod-name> -- sh -c 'cat > /path/to/file.txt'这种方式不依赖tar,兼容性更好。对于文本和配置类文件,我常用这一套;对于二进制文件或大文件,我会考虑临时挂载 PVC,或者用kubectl cp并提供带tar的调试容器。
8.5 端口转发失效
kubectl port-forward有时会出现“转发没反应”或“连接被拒绝”的情况。排查步骤:
- 确认 Pod 是否 Running:
kubectl get pods - 确认容器内服务是否监听对应端口:
kubectl exec <pod-name> -- netstat -tlnp或ss -tlnp - 确认本地端口是否被占用:
lsof -i:8080 - 确认 kubeconfig 指向的 API Server 可达
port-forward有时会因为长连接空闲断掉,重新执行即可。如果频繁断连,可以考虑用--address 0.0.0.0指定监听地址,但要注意安全性,不要长期暴露在公网网卡上。
9. 速查表:高频 kubectl 命令一页纸
为了方便日常查阅,我把这篇文章涉及的命令整理成一个速查表:
| 目标 | 命令 |
|---|---|
| 查看当前上下文 | kubectl config current-context |
| 切换上下文 | kubectl config use-context <name> |
| 创建命名空间 | kubectl create namespace demo |
| 启动一个测试 Pod | kubectl run nginx-pod --image=nginx:1.24 --port=80 |
| 查看所有 Pod | kubectl get pods -A |
| 查看 Pod 详情 | kubectl describe pod <name> |
| 查看容器日志 | kubectl logs <name> --previous |
| 进入 Pod 执行命令 | kubectl exec -it <name> -- /bin/sh |
| 从 Pod 拷文件 | kubectl cp <pod>:<path> <local-path> |
| 创建 Deployment | kubectl create deployment <name> --image=<image> --replicas=<n> |
| 扩缩容 | kubectl scale deployment <name> --replicas=<n> |
| 更新镜像 | kubectl set image deployment/<name> <container>=<image> |
| 回滚 Deployment | kubectl rollout undo deployment/<name> |
| 创建 ConfigMap | kubectl create configmap <name> --from-literal=<key>=<value> |
| 标签过滤 | kubectl get pods -l app=nginx |
| 端口转发 | kubectl port-forward pod/<name> 8080:80 |
个人建议:先用kubectl api-resources查看当前集群支持的所有资源类型,再用kubectl explain <资源名>查看字段说明。这两个命令是自学的“拐杖”,比死记硬背更高效。
10. 从第一个 Pod 到日常运维的工作流建议
这篇文章从kubectl run建第一个 Pod 起步,一路走到 Deployment 管理、ConfigMap 注入、Service 暴露、以及常见故障排查。其实你会发现,所有操作都围绕一个核心模型:控制面接受你的声明( Pod、Deployment、Service),然后调度器和各类控制器负责让实际状态向声明状态收敛。kubectl只是你跟这个模型对话的翻译官。
按我个人经验,给正在上手 Kubernetes 的朋友一个建议:不要一上来就追求“写一个复杂的编排文件”,先做到能用几条命令完成下面这组动作:
- 创建命名空间
- 用 Deployment 启动一个应用
- 查看 Pod、日志
- 给应用打个标签并按标签过滤
- 创建一个 ConfigMap 并注入到 Pod
- 用 Service 或端口转发访问服务
- 模拟故障,查看 Pod 如何被重建
这一套走完,你对 Pod、Deployment、Service、ConfigMap 这几个核心对象的认识会比看十篇教程都扎实。后续再遇到复杂问题,无非是在这个模型上叠加存储、网络策略、可观测性、弹性伸缩等一层层能力。
最后分享一个我常用的工作流:先在default命名空间临时测试,确认无误后再用-n指定正式命名空间重新部署;所有 YAML 文件尽量用kubectl create --dry-run=client -o yaml生成初始版本,再手工补充字段。这样既能减少手写 YAML 的拼写错误,又保留了对最终文件的控制权。踩过几次坑之后,你会发现,kubectl真正值钱的地方并不在某一条命令,而是你理解 Kubernetes 对象模型之后,能把命令组合成一套解决实际问题的思路。