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

背景:

现在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机制。

相关推荐
猿究院_夏燊5 小时前
Spring Bean 生命周期
java·后端·spring
CCblandy7 小时前
雪花 ID 四个边界实测:时钟回拨重号 500 个,前端 JSON.parse 直接丢精度
后端·python·算法·性能优化·架构
我是人✓7 小时前
SpringBoot项目的五种创建方式
java·spring boot·后端
念念清晰8 小时前
000-OpenJDK17 源码构建:MacOS环境(M芯片)
java·后端
来福猿8 小时前
SpringCloud Config 源码分析:配置拉取、刷新与多环境管理
后端·spring·spring cloud
IT_陈寒10 小时前
React组件莫名重渲染?你可能忘了这个小细节
前端·人工智能·后端
用户98883218717411 小时前
给 .NET 网络调用设定“预算”:用 CancellationTokenSource.CancelAfter 处理超时取消
后端
清风儿32911 小时前
一块不会说话的电表,把我们折腾了半个月
后端
预知同行11 小时前
深入解析 MoE 混合专家模型:从 Router 到 All-to-All 的架构全景与生产实践
后端·架构
upala11 小时前
【仓颉语言入门 · 第二篇 第 8 课】
后端