2015-07-22 33 views
7

Tôi đang cố gắng chạy tập lệnh shell trong vùng chứa docker của mình. Vấn đề là kịch bản lệnh shell sinh ra một tiến trình khác và nó sẽ tiếp tục chạy trừ khi một kịch bản tắt khác được sử dụng để chấm dứt các tiến trình được sinh ra bởi tập lệnh khởi động.docker chạy tập lệnh shell trong nền mà không thoát khỏi vùng chứa

Khi tôi chạy lệnh dưới đây,

docker run image:tag /bin/sh /root/my_script.sh 

và sau đó,

docker ps -a 

Tôi thấy rằng lệnh đã kết thúc. Nhưng đây không phải là điều tôi muốn. Câu hỏi của tôi là làm thế nào để lệnh chạy trong nền mà không thoát?

Trả lời

3

Bạn chưa giải thích lý do bạn muốn xem vùng chứa của mình chạy sau khi tập lệnh của bạn đã thoát hoặc có hoặc không mong đợi tập lệnh của bạn để thoát.

Hộp chứa đế lót sẽ thoát ngay sau khi lối ra của vùng chứa là CMD. Nếu bạn muốn vùng chứa của mình tiếp tục chạy, bạn sẽ cần một quá trình sẽ tiếp tục chạy. Một tùy chọn chỉ đơn giản là đặt một vòng lặp while ở cuối tập lệnh của bạn:

while :; do 
    sleep 300 
done 

Tập lệnh của bạn sẽ không bao giờ thoát để vùng chứa của bạn tiếp tục chạy. Nếu vùng chứa của bạn lưu trữ một dịch vụ mạng (máy chủ web, máy chủ cơ sở dữ liệu, v.v.), thì đây thường là quá trình chạy trong vòng đời của vùng chứa.

Nếu thay vào đó tập lệnh của bạn thoát đột ngột, có thể bạn sẽ cần phải xem nhật ký vùng chứa của mình (docker logs <container>) và có thể thêm một số gỡ lỗi vào tập lệnh của bạn.

Nếu bạn đơn giản hỏi, "làm cách nào để chạy vùng chứa trong nền?", Thì câu trả lời của Emil (chuyển cờ -d tới docker run) sẽ giúp bạn.

1

Gói chương trình bằng tập lệnh bash docker-entrypoint.sh để chặn quá trình chứa và có thể bắt ctrl-c. Ví dụ bash này sẽ giúp: https://rimuhosting.com/knowledgebase/linux/misc/trapping-ctrl-c-in-bash

Tập lệnh sẽ tắt quá trình này khi tín hiệu thoát được gửi bởi Docker.

Bạn cũng có thể thêm vòng lặp bên trong tập lệnh liên tục kiểm tra quy trình đang chạy.

1

Run bạn container với kịch bản của bạn ở chế độ nền với bên dưới lệnh

docker run -i -t -d image:tag /bin/sh /root/my_script.sh 

Kiểm tra id chứa bởi docker ps lệnh

Sau đó kiểm tra kịch bản của bạn được thực hiện hay không trên thùng chứa

docker exec <id> /bin/sh -l -c "ps aux" 
4

Quá trình mà docker chạy mất vị trí của init trong cây quá trình UNIX. init là quy trình cấp cao nhất của phụ huynh và sau khi thoát khỏi vùng chứa docker. Bất kỳ quy trình con nào (hiện tại là orphan process) cũng sẽ bị dừng.

$ docker pull busybox >/dev/null 
$ time docker run --rm busybox sleep 3 

real 0m3.852s 
user 0m0.179s 
sys 0m0.012s 

Vì vậy, bạn không thể cho phép cha mẹ trốn thoát nhưng bạn có hai tùy chọn. Bạn có thể để lại quá trình cha mẹ tại chỗ và cho phép nó để quản lý con của nó (ví dụ, bằng cách nói với nó để wait đến khi tất cả các tiến trình con đã thoát)

$ time docker run --rm busybox sh -c 'sleep 3 & wait' 

real 0m3.916s 
user 0m0.178s 
sys 0m0.013s 

... hoặc bạn có thể thay thế quá trình cha mẹ với quá trình con sử dụng exec. Điều này có nghĩa rằng các lệnh mới đang được thực hiện trong không gian quá trình cha mẹ của ...

$ time docker run --rm busybox sh -c 'exec sleep 3' 

real 0m3.886s 
user 0m0.173s 
sys 0m0.010s 

tiếp cận thứ hai này có thể phức tạp tùy theo tính chất của quá trình đứa trẻ, nhưng có ít không cần thiết tiến trình đang chạy là idiomatically hơn Docker. (Điều này không có nghĩa là bạn chỉ nên có một quy trình.)

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