2016-09-28 23 views
13

Hãy xem xét những điều sau đây, chạy sleep 60 trong nền và sau đó thoát ra:Điều gì xảy ra với các quá trình khác khi PID1 của vùng chứa Docker thoát?

$ cat run.sh 
sleep 60& 
ps 
echo Goodbye!!! 
$ docker run --rm -v $(pwd)/run.sh:/run.sh ubuntu:16.04 bash /run.sh 
    PID TTY   TIME CMD 
    1 ?  00:00:00 bash 
    5 ?  00:00:00 sleep 
    6 ?  00:00:00 ps 
Goodbye!!! 

này sẽ bắt đầu một container Docker, với bash như PID1. Sau đó nó fork/execs một quá trình sleep, và sau đó bash thoát. Khi container Docker chết, quá trình sleep bằng cách nào đó cũng chết.

Câu hỏi của tôi là: cơ chế mà quá trình sleep bị giết là gì? Tôi đã thử bẫy SIGTERM trong một quá trình con và dường như không bị vấp. Giả định của tôi là một cái gì đó (hoặc Docker hoặc hạt nhân Linux) đang gửi SIGKILL khi tắt cgroup container đang sử dụng, nhưng tôi đã không tìm thấy tài liệu nào ở bất cứ nơi nào làm rõ điều này.

EDIT Gần nhất tôi đã đi đến một lời giải thích là đoạn trích sau đây từ baseimage-docker:

Nếu quá trình init của bạn là ứng dụng của bạn, sau đó nó sẽ có lẽ chỉ đóng cửa chính nó, không phải tất cả các các quy trình khác trong vùng chứa. Sau đó, hạt nhân sẽ tiêu diệt các quy trình khác một cách mạnh mẽ, không cho họ cơ hội để tắt trơn tru, có khả năng dẫn đến hỏng tệp, tệp tạm thời cũ, v.v. Bạn thực sự muốn tắt tất cả các quy trình của mình một cách duyên dáng.

Vì vậy, ít nhất theo điều này, hàm ý là khi thùng chứa thoát, hạt nhân sẽ gửi SIGKILL đến tất cả các quy trình còn lại. Nhưng tôi vẫn muốn rõ ràng về cách nó quyết định làm điều đó (tức là, nó là một tính năng của các nhóm?), Và lý tưởng là một nguồn có thẩm quyền hơn sẽ là tốt đẹp.

Trả lời

2

OK, tôi dường như đã đưa ra một số bằng chứng vững chắc hơn rằng đây là, trên thực tế, hạt nhân Linux làm việc chấm dứt. Trong trang clone(2) người đàn ông, có phần hữu ích này:

CLONE_NEWPID (vì Linux 2.6.24)

Quá trình đầu tiên được tạo ra trong một không gian tên mới (ví dụ, quá trình tạo bằng cờ CLONE_NEWPID) có PID 1 và là quy trình "init" cho không gian tên. Trẻ em bị mồ côi trong không gian tên sẽ được sửa lại cho quy trình này thay vì init (8). Không giống như quy trình init truyền thống, quy trình "init" của không gian tên PID có thể chấm dứt, và nếu có, tất cả các quy trình trong không gian tên sẽ bị chấm dứt.

Thật không may điều này vẫn còn mơ hồ về cách chính xác các quy trình trong không gian tên được chấm dứt, nhưng có lẽ đó là vì, không giống như một quá trình thoát bình thường, không có mục nhập trong bảng quy trình. Dù vậy là, có vẻ như rõ ràng rằng:

  • Các hạt nhân chính nó là giết chết các quá trình khác
  • Họ không bị giết trong một cách mà cho phép họ bất kỳ cơ hội để làm sạch, làm cho nó (gần?) Giống với một SIGKILL
+0

Có thể cho dockers 'runc' để làm sạch lên nếu bạn đang [chạy trong các máy chủ tên miền không gian pid] (https://github.com/opencontainers/runc/blob/c4e0d94efacd6f6fb353a538cc01d10792cc3a35 /libcontainer/state_linux.go#L41-L45). – Matt

+0

và hạt nhân gửi 'SIGKILL' để chấm dứt các quá trình. – Matt

+0

@Matt Tốt để biết. Liệu nó có trở thành trách nhiệm của tiến trình 'init' của máy chủ để gặt hái những thứ đó, hay hạt nhân loại bỏ chúng khỏi chính bảng quá trình? –

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