引言
随着微服务和容器化的普及,传统的应用部署方式正被颠覆。如何统一管理成百上千的容器实例,实现自动扩缩、服务发现与负载均衡?这就不得不提云原生的核心——Kubernetes(K8s)。不过,入门Kubernetes常因概念繁杂、命令众多而让人望而却步。本文不会堆砌理论,而是用一个完整的实战项目,带你从零搭建集群(Minikube)、编写部署清单,最终让一个可水平扩展的Web应用真正跑起来。读完你会发现,Kubernetes没有想象中那么难。
1. 先理解几个核心概念
如果只是敲命令,你很快会迷失方向。我们先梳理最重要的三大资源对象,后续操作都会围绕它们展开。
1.1 Pod——最小的调度单元
Pod是Kubernetes里最小、最简单的部署单位。一个Pod可以包含一个或多个紧密共享网络和存储的容器。在生产中,我们通常不在Pod里直接运行多个复杂服务,而是让一个Pod只跑一个应用实例。
1.2 Deployment——管理Pod的控制器
你很少会直接创建裸Pod。Deployment负责声明式地管理Pod的期望副本数、更新策略等。一旦某个Pod挂了,Deployment会自动重建并恢复到声明状态,它也是实现滚动更新的基础。
1.3 Service——稳定的访问入口
Pod IP是易变的,每次重建都会改变。Service为一组Pod提供一个固定的虚拟IP(集群内)和DNS名,并通过标签选择器找到后端的Pod。Service类型包括ClusterIP(内部访问)、NodePort(物理节点端口)和LoadBalancer(云负载均衡)。
这三个对象的关系可以用下图理解:
[Deployment] -- 管理 --> [Pod集合] -- 暴露 --> [Service]
下面,我们马上动手实践。
2. 环境准备:启动本地Kubernetes集群
为了让所有人都能复现,我们使用Minikube在本地运行一套单节点K8s集群。如果你的机器已安装Docker Desktop等内置K8s,也可以直接使用。
2.1 安装Minikube
- macOS:
bash brew install minikube - Windows (使用Chocolatey):
powershell choco install minikube - Linux:
bash curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 sudo install minikube-linux-amd64 /usr/local/bin/minikube
详细说明可参考官方文档。
2.2 启动集群并验证
minikube start --driver=docker # 使用docker驱动
kubectl cluster-info # 查看集群信息
kubectl get nodes # 应能看到一个Ready节点
如果没有kubectl,可通过
minikube kubectl -- get pods替代,或单独安装kubectl。
3. 实战:部署一个可伸缩的Nginx应用
我们将执行一套完整的部署流水线:创建Deployment → 暴露Service → 验证连通性 → 演示扩缩容。
3.1 编写Deployment清单
新建文件 nginx-deployment.yaml,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment # Deployment名称
labels:
app: nginx # 可选的标签
spec:
replicas: 3 # 期望副本数
selector:
matchLabels:
app: nginx # 必须与Pod模板的标签一致
template: # Pod模板
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25.3 # 指定镜像版本
ports:
- containerPort: 80 # 容器监听端口
resources: # 资源限制(生产必备)
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
readinessProbe: # 就绪探针,确保Pod准备好后才接收流量
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe: # 存活探针,容器不正常时自动重启
httpGet:
path: /
port: 80
initialDelaySeconds: 15
periodSeconds: 20
replicas: 3:我们一开始就部署3个副本,体现高可用。resources:设置了最少100m CPU、128Mi内存,最大200m CPU、256Mi内存。readinessProbe:只有在http://:80/返回成功时,才将Pod标记为Ready并加入Service端点。livenessProbe:持续检查健康状态,异常时重启容器。
3.2 应用Deployment
kubectl apply -f nginx-deployment.yaml
# 输出:deployment.apps/nginx-deployment created
# 查看Deployment状态
kubectl get deployments
# NAME READY UP-TO-DATE AVAILABLE AGE
# nginx-deployment 3/3 3 3 10s
# 查看Pod(由于是3副本,你会看到3个Pod)
kubectl get pods -o wide
# 输出三个状况为Running的Pod
3.3 创建Service暴露应用
Pod运行在集群内部,外部无法直接访问。我们需要创建一个 NodePort 类型的Service(Minikube不支持直接LoadBalancer,但可用NodePort或minikube tunnel模拟LoadBalancer)。
新建 nginx-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort # 也可设为ClusterIP(仅集群内),这里为了方便演示选NodePort
selector:
app: nginx # 与Pod标签匹配
ports:
- protocol: TCP
port: 80 # Service自己的端口
targetPort: 80 # 容器端口
nodePort: 30080 # 节点上暴露的端口(范围30000-32767)
执行创建:
kubectl apply -f nginx-service.yaml
# 输出:service/nginx-service created
# 查看Service详情
kubectl get svc nginx-service
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# nginx-service NodePort 10.100.200.50 <none> 80:30080/TCP 5s
3.4 验证服务可访问性
Minikube环境下,获取节点的IP地址:
minikube ip
# 假设输出 192.168.49.2
然后在浏览器访问 http://192.168.49.2:30080,你会看到Nginx的欢迎页面。或者在终端用curl测试:
curl http://$(minikube ip):30080
# 返回HTML内容,证明成功
如果你用的是Docker Desktop内置K8s,则直接访问 http://localhost:30080 即可。
3.5 实操:水平扩缩容
假设流量激增,我们需要将副本数从3扩展到5:
kubectl scale deployment nginx-deployment --replicas=5
# 查看Pod数量变化
kubectl get pods
# 你会看到新增两个Pod正在启动
之后若想缩容回3个,只需执行:
kubectl scale deployment nginx-deployment --replicas=3
所有变化都由控制器异步完成,保证最终状态符合期望。
4. 深入理解:资源清单与常用命令
4.1 管理工具的黄金组合
kubectl apply -f <file>:声明式部署,推荐使用。kubectl delete -f <file>:删除对应资源。kubectl describe pod <pod-name>:查看Pod事件与详情,排错利器。kubectl logs <pod-name>:查看容器日志,可加-f实时跟踪。kubectl exec -it <pod-name> -- /bin/bash:进入容器交互式命令行。
4.2 为什么要使用 requests 和 limits
- requests 告诉调度器Pod需要的最小资源量,调度器会保证节点上有足量资源。
- limits 防止单个Pod消耗过多资源影响同一节点上的其他Pod。超过limit时,CPU会被节流,而内存超出则会被OOM Killer杀掉。
4.3 探针的正确设置
探针配置不当会导致容器频繁重启或永远不能就绪。建议:
- initialDelaySeconds 设得比应用启动到完全运行所需时间稍长。
- 生产环境一定要配置 readinessProbe,因为Pod Running不代表服务已ready。
- 探针路径尽量简单高效,避免占用过多资源。
5. 常见问题与注意事项
-
镜像拉取失败
如果使用本地私有镜像或命名空间错误,查看Pod事件:kubectl describe pod <pod>。常见错误有ImagePullBackOff,这时要检查镜像名、仓库凭证(imagePullSecrets)。 -
Service无法访问
先检查Service的selector与Pod标签是否一致:kubectl get endpoints nginx-service,若无端点,说明label没有匹配到任何Pod。接着用kubectl port-forward直接转发Pod端口测试Pod本身服务是否正常。 -
Minikube资源不足
默认Minikube只分配2GB内存。如需更多,启动时指定:minikube start --memory=4096。生产环境推荐的多节点集群不应使用Minikube。 -
配置文件版本问题
apiVersion必须与集群K8s版本兼容。例如apps/v1适用于1.9以后的版本。可先用kubectl api-versions查看支持的API组。 -
敏感信息处理
不要在YAML中硬编码密码等,应使用Secret对象,并通过环境变量或卷挂载到Pod。
6. 总结
通过这个实战,我们完整经历了:搭建K8s环境 → 编写Deployment清单 → 部署多副本应用 → 暴露Service → 测试验证 → 动态扩缩容。这些是生产级应用最基础的技能。
Kubernetes的门槛并不在于敲几条命令,而在于理解声明式设计的哲学。当你习惯描述“我想要什么状态”,而不是“如何一步步达到”时,就真正迈入了云原生的大门。
下一步,你可以尝试:
- 添加Ingress资源,实现基于域名的路由。
- 使用ConfigMap和Secret配置应用环境。
- 学习Helm,将复杂应用打包实现一键部署。
- 引入CI/CD流程,自动化构建和发布。
动手是最好的学习方式,建议你亲自敲完上面的所有命令,遇到问题多查看 describe 和 logs。Kubernetes生态广阔,但基础牢固后,进阶之路就会越走越宽。希望本文能为你打开一扇窗,让容器编排变得亲切起来。
2396

被折叠的 条评论
为什么被折叠?



