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

背景:

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

相关推荐
小蜗牛慢慢爬行7 分钟前
Java8 Stream编码问题
java·开发语言·后端·面试
豌豆花下猫12 分钟前
Python 潮流周刊#82:美国 CIA 如何使用 Python?(摘要)
后端·python·ai
Q_19284999061 小时前
基于Spring Boot的房屋租赁管理系统
java·spring boot·后端
熬了夜的程序员2 小时前
Go语言封装Cron定时任务
开发语言·后端·golang
王ASC2 小时前
Springboot访问到Controller中不存在的接口BUG
spring boot·后端·mvc
我叫啥都行2 小时前
计算机基础知识复习12.20
java·jvm·笔记·后端·sql
陈大爷(有低保)3 小时前
mybatisPlus使用步骤详解
java·后端·mybatis
水w3 小时前
springBoot Maven 剔除无用的jar引用
开发语言·spring boot·后端·maven·jar
ThetaarSofVenice3 小时前
【Spring框架 三】
java·后端·spring
前端开发熊4 小时前
本地开发遇到强制 HTTPS?快来试试 mkcert 神器!🚀
前端·后端