传统应用迁移

传统应用迁移

迁移的挑战

将传统应用迁移到 Docker 容器并不是简单的”把二进制文件塞进镜像”,需要面对:

  • 配置管理方式的改变
  • 日志处理方式的改变
  • 进程管理方式的改变
  • 数据持久化的处理
  • 网络访问方式的改变

迁移步骤

第一步:应用梳理

# 了解当前运行环境
# 1. 操作系统版本和依赖
cat /etc/os-release
ldd /path/to/binary

# 2. 运行时依赖
which java python node
java -version
python --version

# 3. 配置文件和路径
ls /etc/myapp/
ls /var/log/myapp/
ls /opt/myapp/

# 4. 端口和服务
netstat -tulpn | grep myapp

第二步:创建 Dockerfile

# 传统 Java 应用迁移
FROM eclipse-temurin:17-jre

# 应用文件
WORKDIR /opt/myapp
COPY target/myapp.jar .
COPY config/ ./config/

# 日志目录
RUN mkdir -p /var/log/myapp

# 环境变量(替代传统配置文件)
ENV APP_ENV=production
ENV DB_HOST=database
ENV DB_PORT=3306

# 暴露端口
EXPOSE 8080

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:8080/health || exit 1

# 启动命令(替代 init.d/systemd)
CMD ["java", "-jar", "myapp.jar"]

第三步:配置管理

传统方式:配置文件在 /etc/myapp/config.ini

Docker 方式:环境变量 + Config

# docker-compose.yml
version: '3.8'
services:
  myapp:
    image: myapp:latest
    environment:
      - DB_HOST=postgres
      - DB_PORT=5432
      - DB_USER=myapp
      - DB_PASSWORD=${DB_PASSWORD}  # 从 .env 文件读取
      - LOG_LEVEL=info
    volumes:
      # 配置文件映射
      - ./config/custom.conf:/opt/myapp/config/custom.conf
      # 日志持久化
      - logs:/var/log/myapp

第四步:日志处理

# 传统:日志写入文件
# Docker:日志输出到 stdout/stderr
FROM myapp

# ✅ 方案一:修改应用日志到 stdout
# 在代码中将日志输出到 console

# ✅ 方案二:使用软链接
RUN ln -sf /dev/stdout /var/log/myapp/app.log
RUN ln -sf /dev/stderr /var/log/myapp/error.log

第五步:进程管理

# 传统应用可能依赖 supervisord 管理多进程
FROM ubuntu:22.04

# 多进程管理方案

# 方案一:使用 supervisord(不推荐)
RUN apt-get update && apt-get install -y supervisor
COPY supervisord.conf /etc/supervisor/conf.d/

# 方案二:拆分为多个容器(推荐)
# 每个容器只运行一个进程

常见迁移模式

模式一:直接打包

# 适用:无状态应用,简单的二进制
FROM ubuntu:22.04
COPY myapp /usr/local/bin/
CMD ["myapp"]

模式二:包装迁移

# 适用:依赖较复杂的传统应用
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y libssl-dev libcurl4

# 保留原有目录结构
COPY --from=original /opt/myapp /opt/myapp
COPY --from=original /etc/myapp /etc/myapp

# 添加 Docker 适配层
COPY docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]

模式三:渐进式迁移

# 先容器化无状态部分,有状态部分逐步迁移
services:
  # Step 1: 先迁移 web 层
  web:
    image: myapp-web:latest
    ports:
      - "80:80"

  # Step 2: 处理缓存
  redis:
    image: redis:7

  # Step 3: 最后迁移数据库
  db:
    image: postgres:15
    volumes:
      - db-data:/var/lib/postgresql/data

迁移检查清单

  • [ ] 应用是无状态的还是需要持久化?
  • [ ] 配置文件是否可以改为环境变量?
  • [ ] 日志是否输出到 stdout/stderr?
  • [ ] 是否有 init.d/systemd 依赖?
  • [ ] 是否依赖宿主机特定的硬件或内核模块?
  • [ ] 服务的启动顺序是否有要求?
  • [ ] 是否需要特权模式?

面试要点

  1. 传统应用迁移到 Docker 的三大变化:配置、日志、进程管理
  2. 日志从文件改为 stdout/stderr 是最常见的改造点
  3. 渐进式迁移比”大爆炸”迁移更安全
  4. 多进程应用应拆分为多个容器
  5. 迁移后要验证功能、性能、配置三方面

面试官常问:你们迁移过程中遇到的最大困难是什么?怎么评估一个应用是否适合容器化?

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容