Docker 作为容器技术的基石,解决了应用打包和环境隔离的难题。然而,当应用进入生产环境,对稳定性、伸缩性和可管理性提出要求时,仅靠 Docker CLI 或 Docker Compose 就显得力不从心。这就是为什么 Docker 之后必然是 K8s(Kubernetes)的原因——K8s 解决的是单机容器化无法应对的「分布式生产级部署」的痛点。
生产痛点一:单点故障与弹性伸缩(Scaling and Reliability)
在使用 Docker 部署应用时,如果运行应用的宿主机发生故障,该应用服务将完全中断。此外,流量高峰时,手动启动多个容器副本非常低效,且难以确保这些副本均匀分布到集群中的不同机器上。
K8s 的解决方案:Deployment
Kubernetes 的 Deployment 对象允许你声明性地定义应用程序的期望状态。K8s 持续监控集群状态,确保运行中的 Pod(K8s 最小调度单元,包含一个或多个容器)数量始终等于你定义的 replicas 数量。
生产痛点二:容器间的服务发现(Service Discovery)
在一个微服务架构中,前端服务需要知道后端服务的 IP 地址,数据库服务需要知道缓存服务的地址。然而,容器的 IP 地址是短暂且动态变化的。如果后端容器重启,其 IP 地址可能会改变,导致前端服务调用失败。
K8s 的解决方案:Service
K8s 的 Service 对象提供了一个稳定、持久的访问入口(虚拟 IP,ClusterIP),用于暴露一组 Pod。无论 Pod 如何创建、销毁或迁移,Service 的 ClusterIP 保持不变,并自动在后端的 Pod 之间进行负载均衡。
实践示例:通过 Deployment 和 Service 实现高可用与服务发现
下面是一个标准的 K8s 部署文件,它定义了一个高可用的 Web 应用(3个副本)和为它提供稳定访问入口的服务。
步骤 1: 创建 Deployment 文件 (webapp.yaml)
该文件定义了应用(使用 nginx 镜像作为示例)需要运行 3 个副本,确保了基础的容错能力。
# webapp.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-deployment
spec:
replicas: 3 # 定义期望的副本数量
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp-container
image: nginx:latest
ports:
- containerPort: 80
---
# 定义 Service,用于服务发现和负载均衡
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
selector:
app: webapp # Service 关联到所有带有 app: webapp 标签的 Pod
ports:
- protocol: TCP
port: 80 # Service 暴露的端口
targetPort: 80 # 容器内部的端口
type: LoadBalancer # 如果在云环境中,会创建一个外部负载均衡器
步骤 2: 应用配置到 K8s 集群
只需一个命令,K8s 就会自动完成所有任务:在集群节点上拉取镜像,启动 3 个副本,并配置内部负载均衡。
kubectl apply -f webapp.yaml
步骤 3: 验证服务发现和高可用
现在,集群内的其他 Pod 或外部用户可以直接通过稳定的 webapp-service 名称或 IP 访问该应用,而无需关心后端 3 个 Pod 的具体位置或状态。
# 检查 Deployment 状态,确认 3 个副本已运行
kubectl get deployment webapp-deployment
# 检查 Service 状态,获取稳定访问 IP/DNS
kubectl get service webapp-service
总结
Docker 是容器化的载体,而 Kubernetes 则是生产级的容器操作系统。K8s 通过引入 Deployment 和 Service 等抽象层,彻底解决了 Docker 在集群环境中的两大核心痛点:通过声明式配置保证应用的弹性伸缩与容错性,以及通过稳定 IP 机制解决动态服务发现的复杂性,从而实现了真正意义上的分布式高可用部署。
汤不热吧