찾다
운영 및 유지보수DockerDocker 컨테이너에서 신호를 잡는 방법을 알고 있나요?

Docker 컨테이너에서 신호를 잡는 방법을 알고 있나요?

실행 중인 컨테이너를 중지하려면 docker stop 명령을 사용해야 한다고 생각합니다. 때로는 컨테이너를 강제로 닫거나 컨테이너의 프로세스에 신호를 전달하기 위해 docker kill 명령을 사용할 수도 있습니다.

사실 우리가 수행하는 작업은 본질적으로 호스트에서 컨테이너로 신호를 전송하여 호스트와 컨테이너에 있는 프로그램 간의 상호 작용입니다. 예를 들어 컨테이너의 애플리케이션에 다시 로드 신호를 보내면 컨테이너의 애플리케이션은 해당 핸들러를 실행하여 신호를 받은 후 구성 파일을 다시 로드하는 작업을 완료합니다.

신호(linux)

신호는 프로세스 간 통신의 한 형태입니다. 신호는 특정 이벤트가 발생했음을 프로세스에 알리기 위해 커널이 프로세스에 보내는 메시지입니다. 신호가 프로세스에 전송되면 프로세스는 즉시 현재 실행 흐름을 중단하고 신호 처리기 실행을 시작합니다(특정 시간에 신호가 처리된다고 말하는 것은 정확하지 않습니다). 이 신호에 대해 핸들러가 지정되지 않으면 기본 핸들러가 실행됩니다.
프로세스는 관심 있는 신호에 대한 핸들러를 등록해야 합니다. 예를 들어 프로그램이 정상적으로 종료되도록(종료 요청을 받은 후 리소스를 정리하기 위해) 일반적으로 프로그램은 SIGTERM 신호를 처리합니다. SIGTERM 신호와 달리 SIGKILL 신호는 프로세스를 강제로 종료합니다. 따라서 우리 애플리케이션은 프로그램을 정상적으로 종료하기 위해 SIGTERM 신호를 캡처하고 처리하는 디렉터리를 구현해야 합니다. 실패하면 사용자는 최후의 수단으로 SIGKILL 신호를 사용해야 합니다. SIGTERM 및 SIGKILL 외에도 사용자 정의 동작을 특별히 지원하는 SIGUSR1과 같은 신호가 있습니다. 다음 코드는 nodejs에서 신호에 대한 핸들러를 등록하는 방법을 간단히 설명합니다.

process.on('SIGTERM', function() {
  console.log('shutting down...');
});

신호에 대한 자세한 내용은 작성자가 "linux kill 명령" 기사에서 언급했으며 여기서는 반복하지 않습니다.

컨테이너의 신호

Docker의 stop 및 kill 명령은 컨테이너에 신호를 보내는 데 사용됩니다. 컨테이너의 프로세스 1번만 신호를 받을 수 있다는 점에 유의하세요. 이는 매우 중요합니다!
stop 명령은 먼저 SIGTERM 신호를 보내고 애플리케이션이 정상적으로 종료될 때까지 기다립니다. 애플리케이션이 종료되지 않은 것으로 확인되면(사용자가 대기 시간을 지정할 수 있음) 또 다른 SIGKILL 신호를 보내 프로그램을 강제로 종료합니다.
kill 명령은 기본적으로 SIGKILL 신호를 보냅니다. 물론 -s 옵션을 통해 모든 신호를 지정할 수 있습니다.

아래에서는 nodejs 애플리케이션을 사용하여 컨테이너의 신호 작업 프로세스를 보여줍니다. 다음 콘텐츠로 app.js 파일을 만듭니다.

'use strict';

var http = require('http');

var server = http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(3000, '0.0.0.0');

console.log('server started');

var signals = {
  'SIGINT': 2,
  'SIGTERM': 15
};

function shutdown(signal, value) {
  server.close(function () {
    console.log('server stopped by ' + signal);
    process.exit(128 + value);
  });
}

Object.keys(signals).forEach(function (signal) {
  process.on(signal, function () {
    shutdown(signal, signals[signal]);
  });
});

이 앱은 SIGINT 및 SIGTERM 신호에 등록된 핸들러를 사용하여 포트 3000에서 수신 대기하는 http 서버입니다. 다음으로 컨테이너에서 프로그램을 다양한 방식으로 실행할 때 신호를 처리하는 방법을 소개합니다.

애플리케이션은 컨테이너에서 프로세스 1번 역할을 합니다.

Dockerfile 파일을 생성하고 위 애플리케이션을 이미지에 패키징합니다.

FROM iojs:onbuild
COPY ./app.js ./app.js
COPY ./package.json ./package.json
EXPOSE 3000ENTRYPOINT ["node", "app"]

ENTRYPOINT 명령어 작성에 주의하세요. 이렇게 작성하면 노드가 컨테이너의 1번 프로세스를 실행합니다.

다음으로 이미지 생성:

$ docker build --no-cache -t signal-app -f Dockerfile .

그런 다음 컨테이너를 시작하고 애플리케이션을 실행합니다.

请注意 ENTRYPOINT 指令的写法,这种写法会让 node 在容器中以 1 号进程的身份运行。
接下来创建镜像:
$ docker build --no-cache -t signal-app -f Dockerfile .
然后启动容器运行应用程序:
$ docker run -it --rm -p 3000:3000 --name="my-app" signal-app
此时 node 应用在容器中的进程号为 1:

이때 컨테이너에 있는 노드 애플리케이션의 프로세스 번호는 1입니다.

Docker 컨테이너에서 신호를 잡는 방법을 알고 있나요?

이제 프로그램을 종료합니다.

$ docker container kill --signal="SIGTERM" my-app

이 시점에서 애플리케이션은 예상대로 종료됩니다.

Docker 컨테이너에서 신호를 잡는 방법을 알고 있나요?

애플리케이션은 컨테이너의 1번 프로세스가 아닙니다.

다음을 시작하는 스크립트 파일 app1.sh를 생성합니다.

#!/usr/bin/env bash
node app

그런 다음 Dockerfile1 파일을 생성합니다. 내용은 다음과 같습니다.

FROM iojs:onbuild
COPY ./app.js ./app.js
COPY ./app1.sh ./app1.sh
COPY ./package.json ./package.json
RUN chmod +x ./app1.sh
EXPOSE 3000
ENTRYPOINT ["./app1.sh"]

다음으로 이미지를 생성합니다.

$ docker build --no-cache -t signal-app1 -f Dockerfile1 .

그런 다음 컨테이너를 시작하여 애플리케이션을 실행합니다.

$ docker run -it --rm -p 3000:3000 --name="my-app1" signal-app1

이때, 컨테이너에 있는 노드 애플리케이션의 프로세스 번호가 더 이상 1이 아닙니다:

Docker 컨테이너에서 신호를 잡는 방법을 알고 있나요?

现在给 my-app1 发送 SIGTERM 信号试试,已经无法退出程序了!在这个场景中,应用程序由 bash 脚本启动,bash 作为容器中的 1 号进程收到了 SIGTERM  信号,但是它没有做出任何的响应动作。
我们可以通过:

$ docker container stop my-app1
# or
$ docker container kill --signal="SIGKILL" my-app1

退出应用,它们最终都是向容器中的 1 号进程发送了 SIGKILL 信号。很显然这不是我们期望的,我们希望程序能够收到 SIGTERM  信号优雅的退出。

在脚本中捕获信号

创建另外一个启动应用程序的脚本文件 app2.sh,内容如下:

#!/usr/bin/env bash
set -x

pid=0

# SIGUSR1-handler
my_handler() {
  echo "my_handler"
}

# SIGTERM-handler
term_handler() {
  if [ $pid -ne 0 ]; then
    kill -SIGTERM "$pid"
    wait "$pid"
  fi
  exit 143; # 128 + 15 -- SIGTERM
}
# setup handlers
# on callback, kill the last background process, which is `tail -f /dev/null` and execute the specified handler
trap 'kill ${!}; my_handler' SIGUSR1
trap 'kill ${!}; term_handler' SIGTERM

# run application
node app &
pid="$!"

# wait forever
while true
do
  tail -f /dev/null & wait ${!}
done

这个脚本文件在启动应用程序的同时可以捕获发送给它的 SIGTERM 和 SIGUSR1 信号,并为它们添加了处理程序。其中 SIGTERM 信号的处理程序就是向我们的 node 应用程序发送 SIGTERM 信号。

然后创建 Dockerfile2 文件,内容如下:

FROM iojs:onbuild
COPY ./app.js ./app.js
COPY ./app2.sh ./app2.sh
COPY ./package.json ./package.json
RUN chmod +x ./app2.sh
EXPOSE 3000
ENTRYPOINT ["./app2.sh"]

接下来创建镜像:

$ docker build --no-cache -t signal-app2 -f Dockerfile2 .

然后启动容器运行应用程序:

$ docker run -it --rm -p 3000:3000 --name="my-app2" signal-app2

此时 node 应用在容器中的进程号也不是 1,但是它却可以接收到 SIGTERM 信号并优雅的退出了:

Docker 컨테이너에서 신호를 잡는 방법을 알고 있나요?

结论

容器中的 1 号进程是非常重要的,如果它不能正确的处理相关的信号,那么应用程序退出的方式几乎总是被强制杀死而不是优雅的退出。究竟谁是 1 号进程则主要由 EntryPoint, CMD, RUN 等指令的写法决定,所以这些指令的使用是很有讲究的。

相关推荐:docker入门教程

위 내용은 Docker 컨테이너에서 신호를 잡는 방법을 알고 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
이 기사는 博客园에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
Linux와 함께 Docker 사용 : 포괄적 인 가이드Linux와 함께 Docker 사용 : 포괄적 인 가이드Apr 12, 2025 am 12:07 AM

Linux에서 Docker를 사용하면 개발 및 배포 효율성을 향상시킬 수 있습니다. 1. Docker 설치 : 스크립트를 사용하여 Ubuntu에 Docker를 설치하십시오. 2. 설치 확인 : Sudodockerrunhello-World를 실행하십시오. 3. 기본 사용 : Nginx 컨테이너 생성 Dockerrun-Namemy-Nginx-P8080 : 80-Dnginx. 4. 고급 사용 : DockerFile을 사용하여 사용자 정의 이미지를 만들고 빌드 및 실행하십시오. 5. 최적화 및 모범 사례 : 다단계 빌드 및 dockercompose를 사용하여 Dockerfiles를 작성하기위한 모범 사례를 따르십시오.

도커 모니터링 : 메트릭 수집 및 컨테이너 건강 추적도커 모니터링 : 메트릭 수집 및 컨테이너 건강 추적Apr 10, 2025 am 09:39 AM

Docker 모니터링의 핵심은 주로 CPU 사용, 메모리 사용, 네트워크 트래픽 및 디스크 I/O와 같은 지표를 포함하여 컨테이너의 작동 데이터를 수집하고 분석하는 것입니다. Prometheus, Grafana 및 Cadvisor와 같은 도구를 사용하면 컨테이너의 포괄적 인 모니터링 및 성능 최적화를 달성 할 수 있습니다.

Docker Swarm : 확장 가능하고 탄력적 인 컨테이너 클러스터 구축Docker Swarm : 확장 가능하고 탄력적 인 컨테이너 클러스터 구축Apr 09, 2025 am 12:11 AM

Dockerswarm은 확장 가능한 고도로 컨테이너 클러스터를 구축하는 데 사용될 수 있습니다. 1) Dockers -Warminit을 사용하여 떼 클러스터를 초기화하십시오. 2) Swarm 클러스터에 가입하여 Dockers-Warmjoin-Token을 사용하십시오. 3) DockerserviceCreate-namemy-nginx-replicas3nginx를 사용하여 서비스를 만듭니다. 4) DockerstackDeploy-Cdocker-Compose.ymlmyapp을 사용하여 복잡한 서비스를 배포합니다.

Kubernetes와 Docker : 엔터프라이즈 애플리케이션을위한 컨테이너 오케스트레이션Kubernetes와 Docker : 엔터프라이즈 애플리케이션을위한 컨테이너 오케스트레이션Apr 08, 2025 am 12:07 AM

Docker 및 Kubernetes를 사용하여 Enterprise Applications의 컨테이너 오케스트레이션을 수행하는 방법은 무엇입니까? 다음 단계를 통해 구현하십시오. Docker 이미지를 만들고 DockerHub로 푸시하십시오. Kubernetes에서 배포 및 서비스를 작성하여 응용 프로그램을 배포하십시오. 외부 액세스를 관리하기 위해 Insress를 사용하십시오. 성능 최적화 및 다단장 구성 및 자원 제약과 같은 모범 사례를 적용하십시오.

도커 문제 해결 : 일반적인 문제를 진단하고 해결합니다도커 문제 해결 : 일반적인 문제를 진단하고 해결합니다Apr 07, 2025 am 12:15 AM

Docker FAQ는 다음 단계를 통해 진단 및 해결할 수 있습니다. 1. 컨테이너 상태 및 로그보기, 2. 네트워크 구성 확인, 3. 볼륨이 올바르게 장착되도록하십시오. 이러한 방법을 통해 Docker의 문제는 빠르게 위치하고 고정되어 시스템 안정성과 성능을 향상시킬 수 있습니다.

Docker 인터뷰 질문 : Ace Your DevOps 엔지니어링 인터뷰Docker 인터뷰 질문 : Ace Your DevOps 엔지니어링 인터뷰Apr 06, 2025 am 12:01 AM

Docker는 DevOps 엔지니어에게 필수 기술입니다. 1. Docker는 포장 애플리케이션 및 컨테이너에 대한 종속성을 통해 격리 및 휴대 성을 달성하는 오픈 소스 컨테이너화 플랫폼입니다. 2. Docker는 네임 스페이스, 제어 그룹 및 연합 파일 시스템과 함께 작동합니다. 3. 기본 사용에는 컨테이너 생성, 실행 및 관리가 포함됩니다. 4. 고급 사용법에는 DockerCompose를 사용하여 다중 컨테이너 응용 프로그램을 관리하는 것이 포함됩니다. 5. 일반적인 오류에는 컨테이너 고장, 포트 매핑 문제 및 데이터 지속성 문제가 포함됩니다. 디버깅 기술에는 로그보기, 컨테이너 입력 및 자세한 정보보기가 포함됩니다. 6. 성능 최적화 및 모범 사례에는 이미지 최적화, 리소스 제약 조건, 네트워크 최적화 및 Dockerfile 사용을위한 모범 사례가 포함됩니다.

Docker Security Hardening : 컨테이너를 취약성으로부터 보호합니다Docker Security Hardening : 컨테이너를 취약성으로부터 보호합니다Apr 05, 2025 am 12:08 AM

Docker Security 향상 방법에는 다음이 포함됩니다. 1.-캡 드롭 매개 변수를 사용하여 Linux 기능을 제한, 2. 읽기 전용 컨테이너 생성, 3. Selinux 태그 설정. 이러한 전략은 취약성 노출을 줄이고 공격자 기능을 제한함으로써 컨테이너를 보호합니다.

Docker Volumes : 컨테이너의 지속적인 데이터 관리Docker Volumes : 컨테이너의 지속적인 데이터 관리Apr 04, 2025 am 12:19 AM

DockErvolumes는 컨테이너가 다시 시작, 삭제 또는 마이그레이션 될 때 데이터가 안전하게 유지되도록합니다. 1. 볼륨 생성 : dockervolumecreatemydata. 2. 컨테이너를 실행하고 볼륨을 장착하십시오 : Dockerrun-it-vmydata :/app/dateubuntubash. 3. 고급 사용에는 데이터 공유 및 백업이 포함됩니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

Dreamweaver Mac版

Dreamweaver Mac版

시각적 웹 개발 도구

SublimeText3 Linux 새 버전

SublimeText3 Linux 새 버전

SublimeText3 Linux 최신 버전