docker-compose对比k8s

Kubernetes(k8s)解决了 Docker Compose 在生产环境中无法应对的 7 大核心痛点。


✅ 1. 跨主机(多节点)部署

  • Compose 痛点 :只能在单台机器上运行,无法利用集群资源。
  • k8s 解决 :Pod 可自动调度到任意节点,天然支持多服务器集群

✅ 2. 真正的负载均衡(内置、自动)

  • Compose 痛点 :即使 --scale 启动多个容器,没有自动流量分发,需手动加 Nginx。
  • k8s 解决Service 自动将请求轮询分发到所有健康 Pod,开箱即用。

✅ 3. 自愈能力(Self-healing)

  • Compose 痛点 :容器崩溃后,依赖 restart: always 重启,但不会重建新容器(如镜像损坏就挂了)。
  • k8s 解决 :Pod 挂了 → 自动销毁并创建全新 Pod ,确保副本数始终符合 replicas

✅ 4. 滚动更新 & 回滚(零停机发布)

  • Compose 痛点 :更新镜像需 down + up服务中断;回滚麻烦。
  • k8s 解决
    • kubectl set image deployment/app nginx:v2逐个替换 Pod,零停机
    • kubectl rollout undo一键秒级回滚

✅ 5. 弹性伸缩(自动扩缩容)

  • Compose 痛点 :扩缩容需手动执行 --scale无法根据 CPU/内存自动调整
  • k8s 解决
    • 手动:kubectl scale --replicas=5
    • 自动:HorizontalPodAutoscaler(HPA)根据指标自动扩缩

✅ 6. 服务发现与网络稳定性

  • Compose 痛点 :服务通过容器名通信,但容器 IP 可变,多实例时 DNS 不做 LB。
  • k8s 解决
    • Service 提供永久不变的虚拟 IP 和 DNS 名
    • 流量自动代理到后端动态变化的 Pod,应用完全无感

✅ 7. 有状态应用管理(StatefulSet)

  • Compose 痛点 :MySQL、Redis 主从等有状态服务难以管理(数据卷、启动顺序、固定网络标识)。
  • k8s 解决
    • StatefulSet 提供稳定 Pod 名称、固定存储、有序启停
    • 配合 Headless Service 实现主从发现

docker-compose.yml

javascript 复制代码
version: '3.8'

services:
  # ────────────────────────
  # Java 应用服务
  # ────────────────────────
  app:
    image: my-java-app                     # 你的 Java 镜像(需提前构建或 pull)
    container_name: java-app
    ports:
      - "8080:8080"                        # 主机:容器端口映射
    environment:
      # Spring Boot 推荐的环境变量命名(大写 + 下划线)
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/mydb?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: rootpass
      SPRING_REDIS_HOST: redis
      SPRING_REDIS_PORT: 6379
    depends_on:
      mysql:
        condition: service_healthy         # 等 MySQL 健康后再启动
      redis:
        condition: service_started         # Redis 启动即可(无健康检查)
    networks:
      - app-network
    restart: unless-stopped

  # ────────────────────────
  # MySQL 8.0 服务
  # ────────────────────────
  mysql:
    image: mysql:8.0
    container_name: mysql
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: mydb                 # 自动创建数据库
      MYSQL_USER: appuser                  # 可选:创建普通用户
      MYSQL_PASSWORD: apppass
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql          # 持久化数据
      - ./mysql/conf.d:/etc/mysql/conf.d   # 可选:自定义配置(如时区)
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql  # 初始化脚本(首次启动执行)
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "--password=rootpass"]
      interval: 10s
      timeout: 5s
      retries: 10
    networks:
      - app-network
    restart: unless-stopped

  # ────────────────────────
  # Redis 7 服务
  # ────────────────────────
  redis:
    image: redis:7-alpine
    container_name: redis
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data                   # 持久化 RDB/AOF
      - ./redis/redis.conf:/usr/local/etc/redis/redis.conf  # 可选:自定义配置
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]  # 使用自定义配置
    networks:
      - app-network
    restart: unless-stopped

# ──────────────────────────
# 数据卷(持久化存储)
# ──────────────────────────
volumes:
  mysql_data:
  redis_data:

# ──────────────────────────
# 自定义网络(服务间通过服务名 DNS 通信)
# ──────────────────────────
networks:
  app-network:
    driver: bridge

k8s.yaml

javascript 复制代码
# ==============================
# 第一部分:Java 应用的 Deployment(负责创建和管理 Pod 副本)
# ==============================
apiVersion: apps/v1          # 使用 apps/v1 API 版本(Deployment 所属的 API 组)
kind: Deployment             # 资源类型:Deployment(用于管理无状态应用的副本)
metadata:
  name: java-app             # Deployment 的名称,在命名空间内必须唯一
spec:
  replicas: 1                # 期望运行的 Pod 副本数量(这里只起 1 个)
  selector:
    matchLabels:
      app: java-app         # 通过标签选择器,关联由该 Deployment 管理的 Pod
                            # 必须与 template.metadata.labels 一致!

  # 关键:Pod 模板(Template)------ 这是嵌套的核心原因
  template:                 # 定义"如何创建每一个 Pod"的模板
    metadata:
      labels:
        app: java-app       # 给每个 Pod 打上标签,必须匹配上面的 selector
                            # 这样 Service 和 Deployment 才能找到它
    spec:                   # ← 这是 Pod 的 spec!不是 Deployment 的 spec!
                            #   它描述了容器运行时的具体配置
      containers:
      - name: app           # 容器名称(在一个 Pod 内必须唯一)
        image: my-java-app  # 镜像名称(需提前推送到镜像仓库或本地存在)
        ports:
        - containerPort: 8080  # 容器监听的端口(仅声明,不暴露到宿主机)
        env:                  # 环境变量(供应用读取)
        - name: SPRING_DATASOURCE_URL
          value: "jdbc:mysql://mysql:3306/mydb"  # 注意:mysql 是 Service 名称!
        - name: SPRING_REDIS_HOST
          value: "redis"     # redis 是另一个 Service 的名称

---
# ==============================
# 第二部分:Java 应用的 Service(负责网络访问)
# ==============================
apiVersion: v1              # Service 属于 core/v1 API 组,简写为 v1
kind: Service               # 资源类型:Service(提供稳定的网络入口)
metadata:
  name: java-app            # Service 名称(在集群内可通过 DNS 访问:java-app.namespace.svc.cluster.local)
spec:
  selector:
    app: java-app           # 选择带有此标签的 Pod,将流量转发给它们
                            # 必须与 Deployment 中 Pod 的 labels 一致!
  ports:
    - protocol: TCP
      port: 8080            # Service 监听的端口(其他 Pod 访问 java-app:8080 即可)
      targetPort: 8080      # 流量转发到 Pod 的 containerPort(即上面定义的 8080)
  type: ClusterIP           # 默认类型:仅集群内部可访问
                            # 其他选项:
                            #   NodePort  → 通过宿主机 IP:端口 访问
                            #   LoadBalancer → 云厂商分配公网 IP

如何使用这个 YAML?

javascript 复制代码
# 1. 保存为 app.yaml
# 2. 应用到集群
kubectl apply -f app.yaml

# 3. 查看状态
kubectl get pods      # 看 Pod 是否 Running
kubectl get svc       # 看 Service 是否创建成功
相关推荐
旅僧几秒前
Ubantu docker环境配置(前置)
运维·docker·容器
正经教主2 小时前
【docker基础】第六课:Web应用与数据库容器部署
网络·docker·容器
Shacoray2 小时前
K8s 中 Ingress 的 HTTPS 证书 如何生成?
容器·https·kubernetes
开发者联盟league2 小时前
使用Jenkins整合Sonarqube/Gitlab/Harbor/Kubernetes的Demo工程
kubernetes·gitlab·jenkins
Patrick_Wilson2 小时前
Node.js SSR 内存治理:为什么 --max-old-space-size 不等于进程内存
kubernetes·node.js·v8
开发者联盟league2 小时前
使用k8s安装Jenkins
容器·kubernetes·jenkins
正经教主3 小时前
【docker基础】 第七课:Docker Compose 多容器实战
运维·docker·容器
正经教主3 小时前
【docker基础】Redis的docker部署
redis·docker·容器
DolphinScheduler社区3 小时前
Apache DolphinScheduler 3.4.2 正式发布!新增 Amazon EMR Serverless 插件,增强监控与补数据能力
大数据·云原生·serverless·apache·海豚调度·版本发版
成为你的宁宁3 小时前
【基于 Prometheus Operator 实现 K8s 环境下 Redis Cluster 集群监控部署】
redis·kubernetes·prometheus