0

0

K8S容器应用优雅关闭-修复5003 Error

蓮花仙者

蓮花仙者

发布时间:2025-07-14 10:20:13

|

834人浏览过

|

来源于php中文网

原创

大家好,我是stanley「史丹利」,今天来谈谈技术:容器优雅关闭方案。

1、遇到的问题 在公司某服务接入效能平台后,发布过程中,页面偶尔会出现5003报错。最初以为是Nacos没有及时将服务反注册,即POD在已经正常关闭的情况下,注册中心依然保留POD信息,导致请求依然发送到已关闭的POD中。

K8S容器应用优雅关闭-修复5003 Error5003报错

K8S容器应用优雅关闭-修复5003 Error5003-error-2

2、问题排查 2.1 首先,我们与开发团队合作,检查了反注册逻辑及相关日志,没有发现任何异常。

2.2 后来偶然发现POD中的主进程PID不为1,而PID为1的进程是shell进程。这会导致容器关闭时,业务进程无法接收到k8s发送的SIGTERM信号,只能在等待15秒后被强行杀死。

K8S容器应用优雅关闭-修复5003 Errorprocess-shell

2.3 我们修改了程序的启动参数,通过EXEC启动模式,使得应用主进程的PID变为1。

K8S容器应用优雅关闭-修复5003 Errorprocess-exec

2.4 重新发布验证后,5003报错问题得到了修复。

3、根因分析 3.1、SHELL 模式和 CMD 模式带来的差异 通常在Dockerfile中使用CMD和ENTRYPOINT来启动应用。启动应用有两种模式:shell模式和exec模式。在shell模式下,PID为1的进程是shell进程;在exec模式下,PID为1的进程是业务本身。

SHELL模式

FROM golang as builder
WORKDIR /go/
COPY app.go    .
RUN go build app.go
FROM ubuntu
WORKDIR /root/
COPY --from=builder /go/app .
CMD ./app

这种方式构建的镜像,应用启动后PID为1的进程是shell进程。

EXEC模式

FlowGPT
FlowGPT

ChatGPT指令大全

下载
FROM golang as builder
WORKDIR /go/
COPY app.go    .
RUN go build app.go
FROM ubuntu
WORKDIR /root/
COPY --from=builder /go/app .
CMD ["./app"]

这种方式构建的镜像,应用启动后PID为1的进程是应用进程。

3.2、直接启动应用和通过脚本启动的区别 在实际生产环境中,由于应用启动命令通常会包含许多启动参数,我们通常会使用一个启动脚本来启动应用,以便管理。相应地,在容器内,PID为1的进程会是shell进程,但shell程序不会转发信号,也不响应退出信号。因此,如果容器应用中启动了shell并占据了PID=1的位置,那么就无法接收到k8s发送的SIGTERM信号,只能在超时后被强行杀死。启动脚本 start.sh 的内容如下:

start.sh

$ cat > start.sh

Dockerfile

FROM golang as builder
WORKDIR /go/
COPY app.go    .
RUN go build app.go
FROM alpine
WORKDIR /root/
COPY --from=builder /go/app .
ADD start.sh /root/
CMD ["/bin/sh","/root/start.sh"]

3.2.1 解决方案 方案一:通过k8s的prestop参数调用容器内进程关闭脚本,实现优雅关闭。在前面脚本启动的Dockerfile基础上,定义一个优雅关闭的脚本,通过k8s-prestop在关闭POD前调用优雅关闭脚本,实现POD优雅关闭。

stop.sh

#!/bin/sh
ps -ef|grep app|grep -v grep|awk '{print $1}'|xargs kill -15

通过yaml部署到k8s中:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-prestop
  labels:
    app: prestop
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prestop
  template:
    metadata:
      labels:
        app: prestop
    spec:
      containers:
      - name: prestop
        image: xx/app:v1.0-prestop
        lifecycle:
          preStop:
            exec:
              command:
              - sh
              - /root/stop.sh

方案二:将shell脚本修改为exec执行。修改start.sh脚本:

#!/bin/sh
exec ./app

在shell中添加一个exec命令即可让应用进程替代当前shell进程,这样可以将SIGTERM信号传递到业务层,让业务实现优雅关闭。

方案三:通过第三方init进程传递SIGTERM到进程中。使用dump-inittini作为容器的主进程,在收到退出信号时,会将退出信号转发给进程组中的所有进程。主要适用于应用本身无关闭信号处理的场景。docker –init本身也是集成的tini

FROM golang as builder
WORKDIR /go/
COPY app.go    .
RUN go build app.go
FROM alpine
WORKDIR /root/
COPY --from=builder /go/app .
ADD start.sh tini /root/
RUN chmod a+x start.sh && apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["/root/tini", "--", /root/start.sh"]

4、总结 1、对于容器化应用启动命令,建议使用EXEC模式。

2、对于已经在代码层面实现了优雅关闭的业务,但有shell启动脚本的,容器化后部署到k8s上,建议使用方案一和方案二。

3、对于代码层面没有实现优雅关闭的业务,建议使用方案三。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

431

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

373

2023.10.25

k8s和docker区别
k8s和docker区别

k8s和docker区别有抽象层次不同、管理范围不同、功能不同、应用程序生命周期管理不同、缩放能力不同、高可用性等等区别。本专题为大家提供k8s和docker区别相关的各种文章、以及下载和课程。

280

2023.07.24

docker进入容器的方法有哪些
docker进入容器的方法有哪些

docker进入容器的方法:1. Docker exec;2. Docker attach;3. Docker run --interactive --tty;4. Docker ps -a;5. 使用 Docker Compose。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

515

2024.04.08

docker容器无法访问外部网络怎么办
docker容器无法访问外部网络怎么办

docker 容器无法访问外部网络的原因和解决方法:配置 nat 端口映射以将容器端口映射到主机端口。根据主机兼容性选择正确的网络驱动(如 host 或 overlay)。允许容器端口通过主机的防火墙。配置容器的正确 dns 服务器。选择正确的容器网络模式。排除主机网络问题,如防火墙或连接问题。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

416

2024.04.08

docker镜像有什么用
docker镜像有什么用

docker 镜像是预构建的软件组件,用途广泛,包括:应用程序部署:简化部署,提高移植性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

450

2024.04.08

Docker容器化部署与DevOps实践
Docker容器化部署与DevOps实践

本专题面向后端与运维开发者,系统讲解 Docker 容器化技术在实际项目中的应用。内容涵盖 Docker 镜像构建、容器运行机制、Docker Compose 多服务编排,以及在 DevOps 流程中的持续集成与持续部署实践。通过真实场景演示,帮助开发者实现应用的快速部署、环境一致性与运维自动化。

37

2026.02.11

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

1

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

35

2026.03.04

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
光速学会docker容器
光速学会docker容器

共33课时 | 2万人学习

Docker 17 中文开发手册
Docker 17 中文开发手册

共0课时 | 0人学习

极客学院Docker视频教程
极客学院Docker视频教程

共33课时 | 18万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号