服务容器化改造和生产迁移实践

背景:

现在K8s容器化是技术趋势,很多部署在虚拟机上的服务都要迁移到容器化。而迁移到容器化的步骤是要先对服务代码进行容器化改造,之后发布再将生产环境流量从虚拟机切到容器化。 这里以Java服务为例,说下容器化改造需要的准备和流程

配置改动

Java服务接入容器化,需要准备Dockerfile文件,启动脚本,配置文件迁移到Nacos

  • Dockerfile文件:

使用Maven作为项目构建工具

js 复制代码
FROM xxxx/maven:3.8.5-openjdk-17 AS builder
# 设置工作目录
COPY . /app
WORKDIR /app
# 构建项目编译命令
RUN mvn -B -U -f pom.xml -s ./settings.xml clean install -e -Dmaven.test.skip=true -P trait-boot-jar
# 使用  JDK 17 作为运行时镜像
FROM xxxx/openjdk:17
# 设置工作目录
WORKDIR /java
# 从 Maven 镜像中拷贝构建好的 JAR 文件
COPY --from=builder /app/scripts/*.sh ./scripts/
# 这里根据实际生成的制品名称来进行修改拷贝
COPY --from=builder /app/application/target/application-*.jar ./application.jar
COPY --from=builder /app/application/src/main/resources/log4j2.xml ./config/
# 服务端口
EXPOSE 8080
# 监控指标端口
EXPOSE 8082
# 设置容器启动命令
CMD ["/bin/sh", "./scripts/start.sh"]

使用Gradle作为项目构建工具

js 复制代码
FROM gradle:8.4.0-jdk17 as builder  
WORKDIR /app  
COPY . .  
RUN gradle clean bootJar  
FROM xxx/openjdk:17  
WORKDIR /java  
RUN mkdir config \  
&& mkdir scripts \  
&& groupadd -g 5000 java \  
&& useradd -d /java -m -u 5000 -g 5000 -s /bin/sh java \  
&& chown -R java:java /java   

COPY --from=builder /app/application/build/libs/application-*.jar ./application.jar  
COPY --from=builder /app/application/src/main/resources/log4j2.xml ./config/  
COPY --from=builder /app/scripts/start.sh ./scripts/  
  
CMD ["/bin/sh", "./scripts/start.sh"]  
EXPOSE 8080
js 复制代码
#!/bin/sh
java    ${APP_OPTS} \
        -Dspring.cloud.nacos.config.enabled=true \
        -Dspring.cloud.nacos.config.server-addr=${NACOS_HOST}:${NACOS_PORT} \
        -Dspring.cloud.nacos.config.namespace=${NACOS_TENANT} \
        -Dspring.config.import[0]=nacos:${NACOS_DATA_ID} \
        -Dspring.cloud.nacos.config.file-extension=yaml \
        -Dspring.cloud.nacos.config.username=${NACOS_USERNAME} \
        -Dspring.cloud.nacos.config.password=${NACOS_PASSWORD} \
        -Dfile.encoding=UTF-8\
        -server \
        ${JAVA_OPTS} -jar application.jar
  • 容器内环境变量配置
js 复制代码
- name: ENV_NAME
  value: "prod"
- name: JAVA_OPTS
  value: "-XX:InitialRAMPercentage=70.0 
          -XX:MaxRAMPercentage=70.0 
          -XX:+UseZGC 
          -XX:+HeapDumpOnOutOfMemoryError 
          -XX:HeapDumpPath=/java"
- name: APP_OPTS
  value: "-Dreactor.netty.ioWorkerCount=50
          -Dreactor.netty.pool.leasingStrategy=lifo 
          -Dreactor.netty.pool.maxIdleTime=1000"
js 复制代码
NACOS_DATA_ID: xxx
NACOS_HOST: xxx
NACOS_PORT: xxx
NACOS_USERNAME: xxx
NACOS_PASSWORD: xxx 
NACOS_TENANT: xxx
  • 配置文件从本地的application-{env}.yaml迁移到Nacos,定义好NameSpace,Group和Data Id。

预估资源配置

容器化改造需要先预估所需要的生产资源,比如多少核的CPU还有多少G内存,还有副本多少,这涉及到容器的HPA策略,生产一般是横向扩容,比如给定2C4G的资源,副本pod最小2个,最大5个。副本数量会根据生产负载进行扩容

生产迁移

当服务在生产容器化启动成功时,还需要做最后的流量切换,让API网关把流量转发从虚拟机服务转发到容器化服务,因为容器化服务提供出来的域名地址与虚拟机服务的IP地址是不一样。如图所示:

相比于前面配置改造,这个迁移过程更应该注重流程的重要性。这是比较大的变更动作,作为开发,需要提前同步API网关同事,测试同事,运维同事要做这个变更,协调好各位职能的时间来完成这个变更动作。

  • 在服务日志方面,需要配置好日志采集监控,做好接口日志打印,有请求日志后就可以知道已经有流量进来了

  • 在监控方面,需要事先在Grafana上配置服务接口监控,还要对虚拟机的接口监控和容器化的接口监控进行对比,在网关流量切换时可以看到虚拟机的接口监控请求逐渐减少,容器化的接口监控请求逐渐增加,这才是符合预期的变化。常见的接口监控配置有以下两种:

    1. Top5接口QPS监控:展示QPS最高的前5个接口
    js 复制代码
    topk(5, sum(rate(http_server_requests_seconds_count[1m])) by (method, uri))
    1. P95接口监控:展示所有接口的P95响应时间,是个统计值
    js 复制代码
    histogram_quantile(0.95, sum by(method, uri, le) (rate(http_server_requests_seconds_bucket{status="200"}[5m])))
  • 在网关流量切换方面,不能全部切换,可以先切20%的流量到容器化服务,然后观察一段时间,没问题的话就可以切50%,最后100%全部切换。

  • 在测试方面,需要让测试同事回归,确保切换后的服务功能没问题,但可能需要在流量全部切换过去后才能测试,因为不确定测试的账户是否已经切换到新服务。

  • FailOver,在网关流量切换过程中如果有问题,需要把流量重新切换到虚拟机服务。就算切换成功后,原有的虚拟机服务也不能直接下掉,需要保持一段时间,方便后续发现问题可以切换回去,相当于是一个备份副本,这是一种FailOver机制。

相关推荐
你的人类朋友19 分钟前
【Node.js】什么是Node.js
javascript·后端·node.js
David爱编程2 小时前
面试必问!线程生命周期与状态转换详解
java·后端
LKAI.2 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi
Victor3563 小时前
Redis(11)如何通过命令行操作Redis?
后端
Victor3563 小时前
Redis(10)如何连接到Redis服务器?
后端
他日若遂凌云志4 小时前
深入剖析 Fantasy 框架的消息设计与序列化机制:协同架构下的高效转换与场景适配
后端
快手技术4 小时前
快手Klear-Reasoner登顶8B模型榜首,GPPO算法双效强化稳定性与探索能力!
后端
二闹5 小时前
三个注解,到底该用哪一个?别再傻傻分不清了!
后端
用户49055816081255 小时前
当控制面更新一条 ACL 规则时,如何更新给数据面
后端
林太白5 小时前
Nuxt.js搭建一个官网如何简单
前端·javascript·后端