一、背景调研

单体架构下,很多研发部门的同事,同时会有很多个项目并行开发,环境的抢占问题严重影响了开发、测试和上线的效率,我们需要给每个项目提供一套开发联调、测试环境,并且随着项目的生命周期开始即结束,项目环境也会随着创建和销毁。运维小伙伴真的苦不堪言~

二、部署上线业务流程

业务部署上线是每个运维都需要面对的问题,接下来针对一个java应用分别从传统运维和K8S运维角度,梳理操作流程:

传统运维:

  1. 安装操作系统;
  2. 初始化系统配置(安全策略、时间同步、yum源……);
  3. 安装配置java环境;
  4. 打jar包并部署服务;
  5. Systemctl添加自定义服务或supervisor进程守护;

K8S运维:

  1. JDK底层镜像选择;
  2. Dockerfile优化配置(应用启动配置,参数等);
  3. CICD流水线交付;
  4. 创建资源清单,完成项目部署;

三、运维成本分析对比

传统运维 K8S运维
部署 上线 配置环境,打包部署服务配置服务管理脚本 镜像选择、封装镜像、创建资源
健康 检查 编写shell脚本或使用守护进程工具 K8S提供就绪、存活探针,支持exec执行命令、HTTP状态码、TCP端口探测
故障 转移 新机器部署服务,修改DNS/LB 解析指向新机器 K8S内部自动实现故障转移
集群 扩容 新机器部署服务,部署负载均衡 服务,配置后端地址 修改K8S pod资源副本数,service自动实现负载均衡
版本 更新 修改负载均衡配置,逐个滚动停止服务,替换jar包,启动服务 更新docker镜像并上传,修改K8S pod资源镜像信息,K8S自动实现滚动更新

四、应用迁移基本流程

4.1 容器有哪些优势?

推广容器的第一步就是能说出容器的优势,我们认为容器有如下优势:

  • 轻量级:容器小、快,能够实现秒级启动。
  • 应用分发:容器使用镜像分发,开发测试容器和部署容器配置完全一致。
  • 弹性:可以根据CPU、内存等资源使用或者QPS、延时等业务指标快速扩容容器, 提升服务能力。

这三个特性的组合,可以给业务带来更大的灵活度和更低的计算成本。

4.2 容器化交付流程是不是很复杂?

容器化交付流程一般包括以下步骤:

  1. 编写Dockerfile文件:编写Dockerfile文件,定义应用程序镜像构建的步骤和命令。
  2. 构建镜像:使用Dockerfile文件构建Docker镜像,生成可移植、可重复部署的应用程序镜像。
  3. 推送镜像:将构建好的Docker镜像推送到Docker镜像仓库中,供其他人或其他环境使用。
  4. 部署应用:基于持续集成和持续交付(CI/CD)流程自动化,部署应用到 Kubernetes平台。
  5. 监控与维护:使用日志和监控工具监控应用容器的运行状态,及时发现并修复问题。同时,定期更新应用程序镜像,保证应用程序的稳定性和安全性。

4.3 应用封装

Aspose.Words.d676e198-7513-4df4-8b3d-e484575af410.003

例如:java程序Dockerfile:

FROM openjdk:19-jdk-alpine3.16 # 使用alpine3.16操作系统,java19运行环境为基础镜像
ADD demo.jar /opt/app.jar      # 复制项目jar包文件到容器/opt/目录下
EXPOSE 8888                    # 声明容器暴露的端口
WORKDIR /opt                   # 指定容器工作目录
CMD ["java","-jar","app.jar"]  # 指定启动命令为java –jar /app.jar

构建镜像:

#docker build -t  harbor.xxxx.com/xxxx/appname:tag

$ docker build -t 仓库名称/项目/appname:tag

推送镜像:

#docker push harbor.xxxx.com/xxxx/appname:tag

$ docker push 仓库名称/项目/appname:tag

4.4 应用部署

Deployment.yaml:封装了Pod的副本管理、部署更新、回滚、扩容、缩容等。

service.yaml:集群内部应用暴露服务的方式。

ingress.yaml:提供外部访问方式。

pv/pvc.yaml:提供持久化数据存储。

configmap.yaml:配置文件的统一管理。

4.5 容器化快速概览

Aspose.Words.d676e198-7513-4df4-8b3d-e484575af410.007

单体应用容器化的过程可以大致分为以下几个步骤:

  1. 分析应用:首先需要对单体应用进行分析,确定应用程序的依赖项、运行环境和整体架构。
  2. 选择容器平台:根据应用程序的需求,选择适合的容器平台。目前比较流行的容器平台有Docker、Kubernetes等。
  3. Docker化应用:将应用程序打包成容器,可以使用Dockerfile来描述容器的构建过程,包括镜像构建、容器启动和应用程序部署。
  4. 镜像管理:存储Docker镜像并管理镜像的版本,可以使用Docker Hub或私有 Harbor等工具来实现。
  5. 部署到Kubernetes:将Docker容器部署到Kubernetes集群,并使用Kubernetes 中的Service、Deployment、Pod等资源管理和扩展应用程序的运行。
  6. 监控和日志记录:使用监控和日志记录工具来监测应用程序的运行状态,包括容器的资源使用情况、日志输出和异常事件等信息。

单体应用容器化需要对应用程序进行分析,选择合适的容器平台,将应用程序打包成 Docker容器,并通过Kubernetes等工具进行部署和管理。

容器化可以提高应用程序的可靠性、弹性和可移植性,方便应用程序在不同平台和环境中快速部署和运行。

五、总结

Aspose.Words.d676e198-7513-4df4-8b3d-e484575af410.008

传统运维和K8S运维的区别如下:

  • 管理方式不同:传统运维主要采用手动操作,而K8S更注重自动化管理。
  • 弹性伸缩不同:传统运维的弹性伸缩较为复杂,需要手动添加或删除节点,而K8S则可以根据负载自动添加或删除Pod。
  • 部署方式不同:传统运维的部署方式较为复杂,需要手动安装依赖库和配置环境, 而K8S则可以通过容器化技术统一打包和部署应用程序,大大简化了部署过程。
  • 安全性不同:传统运维在安全性方面排查问题相对繁琐,K8S则提供了安全策略、网络隔离、访问控制等强大的安全机制。
  • 监控方式不同:传统运维的监控方式相对简单,只能实现简单的监控和日志分析, 而K8S则提供了丰富的监控功能,可以实时监控容器的状态、资源使用情况、日志输出等。
  • 可维护性不同:传统运维中维护一个复杂的架构需要付出较高的成本,而K8S则可以 对应用程序进行管理、监控、伸缩等操作,大大降低了维护成本和难度。

综上所述,使用K8S进行应用程序部署和管理可以大大简化运维工作,提高效率和可靠性。