概述
你已经知道 Kubernetes(K8s)能自动管理容器,但什么是 Pod、Deployment、Service、Namespace......其实,90% 的日常操作,只用掌握三个核心对象就够了
Pod:K8s 中最小的调度单元
- 一个 Pod 可以运行 1 个或多个容器
- 这些容器共享网络、存储、IP 地址
- 它们就像合租室友,住在一起,互相配合
绝大多数情况下,一个 Pod 只放一个主容器(比如你的微服务),这是最佳实践。
为什么需要 Pod而不直接调度容器
因为有些场景需要协作的容器:
- 主应用 + 日志收集器
- Web 服务器 + 缓存代理
K8s 用 Pod 把它们绑在一起,保证部署在同一台机器上。
查看 Pod
bash
kubectl get pods
输出示例:
NAME READY STATUS RESTARTS AGE
user-service-7d5b8c6f9-xk2vq 1/1 Running 0 2m
Deployment
你告诉Deployment:"我要 3 个 user-service 实例",它就会:
- 启动 3 个 Pod
- 如果某个 Pod 挂了,自动重建
- 升级时,平滑替换旧版本(滚动更新)
- 扩容缩容一键搞定
示例:创建一个 Deployment
创建文件 deployment.yaml:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
spec:
replicas: 3 # 我要 3 个副本
selector:
matchLabels:
app: user # 选中带这个标签的 Pod
template:
metadata:
labels:
app: user # 给 Pod 打标签
spec:
containers:
- name: user-app
image: my-user-service:1.0
ports:
- containerPort: 3000
应用配置:
bash
kubectl apply -f deployment.yaml
查看:
bash
kubectl get deployments
kubectl get pods
你会看到 3 个 Pod 自动创建!
常用操作
bash
# 扩容到 5 个实例
kubectl scale deployment/user-service --replicas=5
# 更新镜像(触发滚动更新)
kubectl set image deployment/user-service user-app=my-user-service:1.1
# 查看更新历史
kubectl rollout history deployment/user-service
# 回滚到上一版
kubectl rollout undo deployment/user-service
Service
问题:
- Pod 是临时的,IP 会变(重启就换)
- 其他服务怎么访问它?
答案:不要直接连 Pod,而是连 Service!
Service 会给一组 Pod 提供一个固定的虚拟 IP 和 DNS 名称,即使后端 Pod 换了,地址不变。
示例:创建一个 Service
创建 service.yaml:
yaml
apiVersion: v1
kind: Service
metadata:
name: user-service # 服务名 → 其他服务可通过 http://user-service 访问
spec:
selector:
app: user # 选中所有带 app=user 标签的 Pod
ports:
- protocol: TCP
port: 80 # Service 监听的端口
targetPort: 3000 # 转发到 Pod 的 3000 端口
type: ClusterIP # 默认类型:集群内部访问
应用:
bash
kubectl apply -f service.yaml
现在,在集群内任何地方,你都可以通过:
bash
curl http://user-service/api/users
Service 的三种常用类型
| 类型 | 用途 | 是否暴露到外网 |
|---|---|---|
| ClusterIP(默认) | 集群内部服务通信 | ❌ |
| NodePort | 通过节点 IP + 高端口访问 | ✅(如 http://<节点IP>:30001) |
| LoadBalancer | 云厂商提供公网 IP(如 AWS ELB) | ✅ |
三者的关系
[其他服务]
│
▼
[Service: user-service] ← 固定入口(DNS 名)
│
▼(负载均衡)
┌─────────────┐
│ Pod 1 │ ← 由 Deployment 创建和管理
│ (IP: 10.1.0.5) │
└─────────────┘
┌─────────────┐
│ Pod 2 │
│ (IP: 10.1.0.6) │
└─────────────┘
┌─────────────┐
│ Pod 3 │
│ (IP: 10.1.0.7) │
└─────────────┘
最佳实践
假设你已有一个 Docker 镜像 my-user-service:1.0
步骤 1:创建 Deployment
bash
kubectl create deployment user-svc --image=my-user-service:1.0 --port=3000
步骤 2:暴露为 Service(NodePort 方式)
bash
kubectl expose deployment user-svc --type=NodePort --port=80 --target-port=3000
步骤 3:查看访问地址
bash
kubectl get service user-svc
输出:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
user-svc NodePort 10.96.123.45 <none> 80:32145/TCP 10s
在本地访问(Minikube 用户需用 minikube ip):
bash
curl http://localhost:32145/api/users
# 或
curl http://$(minikube ip):32145/api/users
至此你已用 K8s 三剑客部署了一个完整微服务
注意事项
| 误区 | 正确做法 |
|---|---|
| ❌ 直接创建 Pod | ✅ 总是通过 Deployment 管理 |
| ❌ 用 Pod IP 直接通信 | ✅ 永远通过 Service 访问 |
| ❌ 不打标签(labels) | ✅ 所有资源都要有清晰标签(如 app=user, env=prod) |
| ❌ 在 Pod 里存重要数据 | ✅ 用 PersistentVolume 存持久化数据 |
总结
| 对象 | 角色 | 关键词 |
|---|---|---|
| Pod | 最小运行单元 | "装容器的盒子" |
| Deployment | Pod 管理器 | "自愈、扩缩容、滚动更新" |
| Service | 网络入口 | "固定地址、负载均衡" |
记住这个流程 :
写代码 → 打包镜像 → 用 Deployment 启动 Pod → 用 Service 暴露服务