跳到主要内容

容器化部署

问题

微服务如何使用 Docker 和 Kubernetes 进行容器化部署?Docker 和 K8s 的核心概念是什么?

答案

Docker 基础

Docker 将应用和依赖打包成容器镜像,保证在任何环境中运行一致。

Spring Boot Dockerfile(多阶段构建)
# 构建阶段
FROM maven:3.9-eclipse-temurin-17 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

# 运行阶段
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar

# 非 root 用户运行
RUN addgroup -S spring && adduser -S spring -G spring
USER spring

EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
docker-compose.yml(本地开发环境)
version: '3.8'
services:
order-service:
build: ./order-service
ports:
- "8081:8080"
environment:
- SPRING_PROFILES_ACTIVE=dev
- NACOS_SERVER=nacos:8848
depends_on:
- mysql
- redis
- nacos

mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: order_db
volumes:
- mysql_data:/var/lib/mysql

redis:
image: redis:7-alpine

nacos:
image: nacos/nacos-server:v2.2.3
environment:
MODE: standalone

volumes:
mysql_data:

Kubernetes 核心概念

概念说明
Pod最小部署单元,包含一个或多个容器
Deployment管理 Pod 的副本数、滚动更新
Service为 Pod 提供稳定的网络访问入口
IngressHTTP 路由入口(类似 Nginx 反向代理)
ConfigMap配置数据(环境变量、配置文件)
Secret敏感数据(密码、证书)
Namespace资源隔离(dev/staging/prod)
HPA水平自动扩缩容

K8s 部署配置

deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service
image: registry.example.com/order-service:v1.2.0
ports:
- containerPort: 8080
resources:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "500m"
memory: "1Gi"
readinessProbe: # 就绪探针
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
livenessProbe: # 存活探针
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 30
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 滚动更新时最多多 1 个 Pod
maxUnavailable: 0 # 更新时不允许不可用
service.yaml + HPA
apiVersion: v1
kind: Service
metadata:
name: order-service
spec:
selector:
app: order-service
ports:
- port: 80
targetPort: 8080
type: ClusterIP
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: order-service-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: order-service
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70

部署策略

策略说明适用场景
滚动更新逐步替换旧 Pod默认策略,零停机
蓝绿部署两套环境切换需要快速回滚
金丝雀发布小比例流量先灰度高风险变更

常见面试问题

Q1: Docker 和虚拟机有什么区别?

答案

对比Docker 容器虚拟机
隔离级别进程级(共享内核)操作系统级(独立内核)
启动速度秒级分钟级
资源占用MB 级GB 级
性能接近原生有虚拟化开销
镜像大小几十 MB几 GB

Docker 更轻量,适合微服务部署。

Q2: K8s 的 Pod 和 Container 的关系?

答案

  • Pod 是 K8s 最小调度单元,可以包含多个 Container
  • 同一 Pod 内的容器共享网络和存储(localhost 通信)
  • 通常一个 Pod 运行一个主容器(业务应用),可加 Sidecar(如日志采集、Service Mesh 代理)

Q3: 如何实现零停机部署?

答案

  1. 滚动更新:K8s Deployment 默认策略,逐步替换 Pod
  2. 就绪探针:新 Pod 通过健康检查后才接收流量
  3. 优雅停机:Spring Boot 配置 server.shutdown=graceful,处理完正在执行的请求再关闭
  4. preStop Hook:Pod 删除前等待一段时间,让负载均衡感知到
lifecycle:
preStop:
exec:
command: ["sleep", "10"] # 等待 10s 让流量切走

相关链接