2015-01-15 15 views
6

Tôi muốn có thể chạy nút bên trong vùng chứa docker và sau đó có thể chạy docker stop <container>. Điều này sẽ dừng vùng chứa trên SIGTERM thay vì định thời gian và thực hiện SIGKILL. Thật không may, tôi dường như thiếu một cái gì đó, và các thông tin tôi đã tìm thấy dường như mâu thuẫn với các bit khác.điểm dừng chân đế không hoạt động đối với quy trình nút

Đây là một Dockerfile kiểm tra:

FROM ubuntu:14.04 
RUN apt-get update && apt-get install -y curl 
RUN curl -sSL http://nodejs.org/dist/v0.11.14/node-v0.11.14-linux-x64.tar.gz | tar -xzf - 
ADD test.js/
ENTRYPOINT ["/node-v0.11.14-linux-x64/bin/node", "/test.js"] 

Đây là test.js gọi trong Dockerfile:

var http = require('http'); 

var server = http.createServer(function (req, res) { 
    console.log('exiting'); 
    process.exit(0); 
}).listen(3333, function (err) { 
    console.log('pid is ' + process.pid) 
}); 

tôi xây dựng nó như vậy:

$ docker build -t test . 

tôi chạy nó như vậy:

$ docker run --name test -p 3333:3333 -d test 

Sau đó, tôi chạy:

$ docker stop test 

Nhân đó các SIGTERM dường như không hoạt động, làm cho nó thời gian chờ 10 giây sau đó và sau đó chết.

Tôi đã phát hiện ra rằng nếu tôi bắt đầu nhiệm vụ nút thông qua sh -c sau đó tôi có thể giết chết nó với ^C từ một tương tác (-it) container, nhưng tôi vẫn không thể có được docker stop để làm việc. Điều này mâu thuẫn với các nhận xét tôi đã đọc nói rằng sh không truyền tín hiệu nhưng có thể đồng ý với các nhận xét khác mà tôi đã đọc nói rằng PID 1 không nhận được SIGTERM (vì nó bắt đầu qua sh, nó sẽ là PID 2).

Mục tiêu cuối cùng là có thể chạy docker start -a ... trong một công việc mới nổi và có thể dừng dịch vụ và thực sự thoát khỏi vùng chứa.

Trả lời

1

Ok, tôi đã tự mình tìm ra cách giải quyết khác, mà tôi sẽ mạo hiểm như một câu trả lời với hy vọng nó sẽ giúp người khác. Nó không hoàn toàn trả lời tại sao các tín hiệu không hoạt động trước đây, nhưng nó cho tôi hành vi mà tôi muốn.

Sử dụng baseimage-docker dường như giải quyết được vấn đề. Dưới đây là những gì tôi đã làm để làm việc này với ví dụ thử nghiệm tối thiểu ở trên:

Giữ test.js như hiện tại.

Sửa Dockerfile để trông giống như sau:

FROM phusion/baseimage:0.9.15 

# disable SSH 
RUN rm -rf /etc/service/sshd /etc/my_init.d/00_regen_ssh_host_keys.sh 

# install curl and node as before 
RUN apt-get update && apt-get install -y curl 
RUN curl -sSL http://nodejs.org/dist/v0.11.14/node-v0.11.14-linux-x64.tar.gz | tar -xzf - 

# the baseimage init process 
CMD ["/sbin/my_init"] 

# create a directory for the runit script and add it 
RUN mkdir /etc/service/app 
ADD run.sh /etc/service/app/run 

# install the application 
ADD test.js/

baseimage-Docker bao gồm một quá trình init (/sbin/my_init) mà xử lý bắt đầu quá trình khác và đối phó với zombie processes. Nó sử dụng runit để giám sát dịch vụ. Dockerfile do đó đặt quá trình my_init làm lệnh để chạy khi khởi động và thêm một tập lệnh /etc/service cho runit để nhặt nó lên.

Kịch bản run.sh rất đơn giản:

#!/bin/sh 
exec /node-v0.11.14-linux-x64/bin/node /test.js 

Đừng quên chmod +x run.sh!

Theo mặc định, runit sẽ tự động khởi động lại dịch vụ nếu nó ngừng hoạt động.

Làm theo các bước sau (và xây dựng, chạy và dừng như trước), vùng chứa phản hồi đúng cách các yêu cầu tắt máy theo đúng thời điểm.

Các vấn đề liên quan