Kubernetes 系列【5】部署一个简单的 Kubernetes 应用
文章目录
1. 前言
本文档整理自 Kubernetes 官方基础教程,目标是帮助初学者理解并完成第一个 Kubernetes 应用部署。
通过本文档,你将学习:
- 使用
kubectl创建Deployment。 - 查看
Pod、Node、Deployment、Service等资源状态。 - 使用
Service对外暴露应用。 - 对应用进行扩容和缩容。
- 使用常用命令排查应用运行问题。
2. 前置条件
开始前需要准备:
- 已有可用
Kubernetes集群,例如minikube、kind、k3s或真实K8S集群。 - 已安装并配置好
kubectl。 - 当前终端可以连接
Kubernetes集群。 - 如果使用
Windows,建议使用WSL或Git Bash。
本文命令采用 POSIX Shell 语法,适用于 Linux、macOS、WSL、Git Bash。
3. kubectl 基础命令
kubectl 命令通用格式:
kubectl <动作> <资源类型> <资源名称>
示例:
# 查看集群中所有节点信息
kubectl get nodes
# 查看所有运行中的Pod资源
kubectl get pods
# 查看指定Pod的详细描述信息,排查事件、配置与异常
kubectl describe pod <pod-name>
# 查看指定Pod的容器日志
kubectl logs <pod-name>
# 删除指定的Deployment控制器
kubectl delete deployment <deployment-name>
查看帮助:
kubectl get nodes --help
验证 kubectl 是否连接到集群:
kubectl version
查看节点:
kubectl get nodes
4. 部署第一个应用
4.1 创建 Deployment
4.1.1 直接创建
本教程使用 NGINX 官方镜像:
kubectl create deployment nginx --image=nginx:latest
该命令会完成:
- 创建
Deployment。 - 创建对应
Pod。 - 将
Pod调度到可用Node。 - 配置异常自动恢复能力。
任意一台能连接 Kubernetes 集群的服务器上执行即可,执行后,本地不会生成文件,是直接把 Deployment 资源创建到 Kubernetes 集群的 etcd 数据库里了。
4.1.2 先创建文件
如果你想把它导出成 YAML 文件,可以执行:
kubectl get deployment nginx -o yaml > nginx-deployment.yaml
或者一开始就生成 YAML 文件而不立即创建:
kubectl create deployment nginx --image=nginx:latest --dry-run=client -o yaml > nginx-deployment.yaml
然后以后用文件部署:
kubectl apply -f nginx-deployment.yaml
文件内容:
# API版本,Deployment资源归属apps/v1分组
apiVersion: apps/v1
# 资源类型:无状态应用控制器
kind: Deployment
metadata:
# 注解,存放描述、版本记录等不可筛选信息
annotations:
# Deployment版本修订号,每次滚动更新自增
deployment.kubernetes.io/revision: "1"
# 资源创建时间戳
creationTimestamp: "2026-06-29T11:18:58Z"
# 资源配置变更次数,每修改spec则+1
generation: 1
# 标签,用于筛选、关联Pod
labels:
app: nginx
# Deployment名称
name: nginx
# 所属命名空间,默认default
namespace: default
# apiserver内部资源版本,用于并发控制
resourceVersion: "427574"
# 全局唯一资源ID
uid: 0a5a8b8f-3975-4d0c-ac89-a73c5e420fdb
spec:
# 滚动更新超时阈值,超过该时间标记更新失败
progressDeadlineSeconds: 600
# 期望运行Pod副本数量
replicas: 1
# 保留历史修订版本数,用于回滚
revisionHistoryLimit: 10
# 标签选择器,匹配管理对应Pod
selector:
matchLabels:
app: nginx
# 更新策略配置
strategy:
# 滚动更新参数
rollingUpdate:
# 更新期间最大可超出期望副本的比例
maxSurge: 25%
# 更新期间最大不可用副本比例
maxUnavailable: 25%
# 更新类型:滚动更新,不中断业务
type: RollingUpdate
# Pod模板,用于创建受控Pod
template:
metadata:
creationTimestamp: null
# Pod自身标签,与selector匹配
labels:
app: nginx
spec:
containers:
- # 容器镜像
image: nginx:latest
# 镜像拉取策略:每次都拉取最新镜像
imagePullPolicy: Always
# 容器名称
name: nginx
# 容器CPU/内存资源配额,此处为空不限制
resources: {}
# 容器终止日志输出路径
terminationMessagePath: /dev/termination-log
# 终止日志读取策略
terminationMessagePolicy: File
# DNS解析策略:优先集群内部DNS
dnsPolicy: ClusterFirst
# Pod重启策略:容器异常始终重启
restartPolicy: Always
# 使用集群默认调度器
schedulerName: default-scheduler
# Pod安全上下文,权限控制配置,此处为空
securityContext: {}
# 容器优雅关闭等待时长,超时强制杀进程
terminationGracePeriodSeconds: 30
4.2 查看 Deployment
kubectl get deployments

示例字段说明:
| 字段 | 说明 |
|---|---|
| READY | 当前就绪副本数 / 期望副本数 |
| UP-TO-DATE | 已更新到目标版本的副本数 |
| AVAILABLE | 当前可用副本数 |
| AGE | 资源运行时长 |
5. 查看 Pod 和 Node 运行详情
5.1 查看 Pod 列表
部署后 Pod 会被 Kubernetes 调度到某个 Worker/从节点 上运行,默认一般不会运行在 control-plane 节点上,除非 control-plane 节点允许调度。
查看当前命名空间下所有运行的 Pod 资源:
kubectl get pods
返回:
NAME READY STATUS RESTARTS AGE
nginx-64fb578bf4-st6d5 1/1 Running 0 13h
字段说明:
| 字段 | 含义说明 |
|---|---|
| NAME | Pod 的名称 |
| READY | 就绪副本数 / 总副本数,代表容器是否就绪 |
| STATUS | Pod 当前状态:Running 运行中、Pending 调度中、Error 异常、Completed 已完成 |
| RESTARTS | 容器重启次数 |
| AGE | Pod 从创建到现在的运行时长 |
查看更详细信息:
kubectl get pods -o wide
返回:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-64fb578bf4-st6d5 1/1 Running 0 6m24s 100.99.8.46 iz2ze60mcbemirrld91q6rz <none> <none>
字段说明:
| 字段 | 含义说明 |
|---|---|
| NAME | Pod 名称 |
| READY | 就绪容器数量 / 总容器数量,1/1代表正常就绪 |
| STATUS | Pod 当前状态,常见:Running正常运行、Pending调度中、Error异常 |
| RESTARTS | 容器重启次数 |
| AGE | Pod 已经运行多长时间 |
| IP | Pod 内部IP地址 |
| NODE | Pod 被调度到哪一台节点机器 |
| NOMINATED NODE | 临时预留节点,一般为空 |
| READINESS GATES | 就绪准入控制,一般为空 |
5.2 查看 Pod 详细信息
kubectl describe pod $POD_NAME

可以看到:
Pod IP。- 所在
Node。 - 容器镜像。
- 端口。
- 启动事件。
- 异常原因。
详细说明:
# Pod名称
Name: nginx-64fb578bf4-st6d5
# 所属命名空间
Namespace: default
# 优先级,数值越高优先级越高,默认0
Priority: 0
# 绑定的服务账号
Service Account: default
# 调度到的节点名称与节点IP
Node: iz2ze60mcbemirrld91q6rz/172.17.172.89
# Pod创建启动时间
Start Time: Mon, 29 Jun 2026 19:48:04 +0800
# Pod标签,用于控制器筛选管理
Labels: app=nginx
pod-template-hash=64fb578bf4
# 注解信息,这里是Calico网络插件写入的网络信息
Annotations: cni.projectcalico.org/containerID: 5f74ae8bcc86ad290009ec7abf27ce13096d7d8cca62b21c9a62450e44812d80
cni.projectcalico.org/podIP: 100.99.87.146/32
cni.projectcalico.org/podIPs: 100.99.87.146/32
# Pod整体运行状态
Status: Running
# Pod内网IP地址
IP: 100.99.87.146
IPs:
IP: 100.99.87.146
# 归属控制器,由ReplicaSet创建管理
Controlled By: ReplicaSet/nginx-64fb578bf4
# 容器配置信息
Containers:
nginx:
# 容器ID
Container ID: docker://8d6394a91483a2642ae6fd0be94afd75ded38261762ae0ea9cca6a518c0945ee
# 容器镜像
Image: nginx:latest
# 镜像唯一ID
Image ID: docker-pullable://swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx@sha256:482d22ab90f2ed6c388907dff6d230c66d7e1a60711ab655b9e00db1cc97b0ac
Port: <none>
Host Port: <none>
# 容器当前状态
State: Running
Started: Mon, 29 Jun 2026 19:48:04 +0800
# 容器是否就绪
Ready: True
# 容器重启次数
Restart Count: 0
Environment: <none>
# 挂载的存储卷,默认挂载serviceaccount证书
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-8zqtf (ro)
# Pod各项就绪条件
Conditions:
Type Status
PodReadyToStartContainers True # 容器可以正常启动
Initialized True # 初始化容器执行完毕
Ready True # Pod整体就绪
ContainersReady True # 业务容器全部就绪
PodScheduled True # Pod已经成功调度到节点
# 数据卷配置
Volumes:
kube-api-access-8zqtf:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
# 资源QoS等级,BestEffort表示无资源配额限制
QoS Class: BestEffort
# 节点亲和选择器
Node-Selectors: <none>
# 容忍度:节点异常时Pod等待300秒再驱逐
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
# 事件日志,此处无异常事件
Events: <none>
5.3 查看容器日志
kubectl logs $POD_NAME

5.4 在容器中执行命令
登录到 nginx 这个 Pod 容器中,输出容器内所有环境变量,常用于排查配置变量、服务账号变量、注入参数是否生效:
kubectl exec $POD_NAME -- env
进入容器:
kubectl exec -ti $POD_NAME -- bash
# 或
kubectl exec -ti $POD_NAME -- sh
在容器内访问 NGINX:
curl http://localhost:80
退出容器:
exit
6. 使用 Service 对外暴露应用
6.1 内部访问
默认情况下,Pod 运行在集群内部网络中,外部不能直接访问,只能通过 kubectl get pods -o wide 中的内部 IP 地址访问:

6.2 创建 NodePort Service
为 nginx 应用创建 NodePort 类型服务:
- 集群内部可直接访问
Service; - 集群外部可以使用任意节点
IP+NodePort端口访问Nginx页面。
kubectl expose deployment/nginx --type="NodePort" --port 80
命令分段解析:
kubectl expose:根据已有控制器自动创建Service对象。deployment/nginx:资源类型为Deployment,资源名称是nginx,Service通过标签自动关联该Deployment下所有Pod。--type="NodePort":Service类型设置为NodePort。集群会在所有节点开放一个随机端口,外部客户端可以通过「节点IP+ 端口」访问服务。--port 80:Service内部端口:Service监听集群内部的80端口,并把流量转发给后端Pod的80端口。
查看生成结果:
kubectl get svc nginx
返回:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.101.223.70 <none> 80:37212/TCP 11s
字段说明:
| 字段 | 说明 |
|---|---|
| NAME | Service资源名称 |
| TYPE | 服务类型,NodePort表示节点端口模式 |
| CLUSTER-IP | Service集群内部虚拟IP,仅集群内可访问 |
| EXTERNAL-IP | 外部IP,NodePort类型为空 |
| PORT(S) | 端口映射:Service端口:NodePort端口/协议 |
| AGE | Service创建时长 |
6.3 查看 Service
查询当前命名空间下所有 Service 资源:
kubectl get services
返回:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.101.223.70 <none> 80:37212/TCP 2m9s
查看详细信息:
kubectl describe service nginx

6.4 访问 NGINX
方式1:集群内部访问
Service 内部虚拟 IP:10.101.223.70,端口:80 。
curl 10.101.223.70:80
只能在集群节点或 Pod内部执行。
方式2:外部访问(NodePort,最常用)
节点端口:37212
格式:任意集群节点 IP:37212
# 把节点IP换成你服务器公网/内网IP
curl http://172.17.172.89:37212
浏览器直接打开:
http://服务器IP:37212
访问失败排查两点:
- 服务器安全组/防火墙放开 37212 端口
- 云服务器开放入站规则,否则外网无法连通
端口说明:
Service端口:80Node对外开放端口:37212Pod容器端口:80
方式3:直接访问 PodIP
Pod 地址:100.99.87.146:80
curl 100.99.87.146:80
7. 使用标签筛选资源
7.1 查看 Deployment 标签
kubectl describe deployment nginx

7.2 根据标签查看 Pod
kubectl get pods -l app=nginx
7.3 根据标签查看 Service
kubectl get services -l app=nginx
7.4 给 Pod 添加标签
kubectl label pods $POD_NAME version=v1
查看标签:
kubectl describe pod $POD_NAME
根据新标签筛选:
kubectl get pods -l version=v1
8. 删除 Service
删除 Service 后,外部访问入口会消失,但 Deployment 和 Pod 仍然运行。
kubectl delete service -l app=nginx
确认删除:
kubectl get services
验证 Pod 内部 NGINX 仍然可用:
kubectl exec -ti $POD_NAME -- curl http://localhost:80
9. NGINX 扩容与缩容
9.1 查看当前 Deployment
kubectl get deployments
9.2 查看 ReplicaSet
kubectl get rs
ReplicaSet 名称通常格式为:
<deployment-name>-<hash>
返回示例:
NAME DESIRED CURRENT READY AGE
nginx-64fb578bf4 1 1 1 13h
字段说明:
| 字段 | 说明 |
|---|---|
| NAME | ReplicaSet控制器名称 |
| DESIRED | 期望副本数 |
| CURRENT | 当前运行副本数 |
| READY | 就绪可用副本数 |
| AGE | 资源运行时长 |
9.3 扩容到 4 个副本
kubectl scale deployment/nginx --replicas=4
查看结果:
kubectl get deployments
kubectl get pods -o wide
9.4 验证负载均衡
如果 Service 仍然存在,可以多次访问:
curl http://<Node节点IP>:$NODE_PORT
多次请求可能会落到不同 Pod,说明 Service 负载均衡生效。
9.5 缩容到 2 个副本
kubectl scale deployment/nginx --replicas=2
查看结果:
kubectl get deployments
kubectl get pods -o wide
10. 常用排障命令
| 命令 | 作用 |
|---|---|
kubectl get pods | 查看 Pod 列表 |
kubectl get pods -o wide | 查看 Pod 所在节点和 IP |
kubectl describe pod <pod> | 查看 Pod 详细状态和事件 |
kubectl logs <pod> | 查看容器日志 |
kubectl exec -ti <pod> -- bash | 进入容器执行命令 |
kubectl get svc | 查看 Service |
kubectl describe svc <svc> | 查看 Service 详细信息 |
kubectl get deployments | 查看 Deployment |
kubectl describe deployment <deployment> | 查看 Deployment 事件和状态 |
11. 清理资源
删除 Service:
kubectl delete service nginx
删除 Deployment:
kubectl delete deployment nginx
确认资源已删除:
kubectl get pods
kubectl get deployments
kubectl get services
更多推荐
所有评论(0)