Cách đúng để giữ container docker bắt đầu khi nó được sử dụng cho các nhiệm vụ định kỳ


41

Tôi có container docker với phần mềm được cài đặt và cấu hình.

Không có bất kỳ chương trình nào được cho là bắt đầu / chạy mọi lúc.

Những gì tôi muốn - khả năng của nó để bắt đầu một số lệnh tùy thuộc vào các sự kiện bên ngoài. như:

docker exec mysupercont /path/to/mycommand -bla -for

docker exec mysupercont /path/to/myothercommand 

Nhưng "exec" không thể khi container bị dừng và container này cũng có một số dữ liệu "hoạt động" bên trong, được sử dụng cho các lệnh đó, vì vậy tôi không thể sử dụng

docker run ...

mỗi lần, vì nó tạo lại container từ hình ảnh và phá hủy dữ liệu của tôi.

Cách "đúng" và "tốt nhất" để giữ cho container như vậy được chạy là gì? Lệnh nào tôi có thể bắt đầu bên trong?


Đây là một câu hỏi được giải thích rất tốt. Xem một bài tương tự ở đây .
Cấp Li

1
docker run -d --name=name container tail -f /dev/null
steampowered

Câu trả lời:


46

Bạn không cần phải thực hiện mỗi lần docker run.

docker run thực sự là một chuỗi gồm hai lệnh: "tạo" và "bắt đầu".

Khi bạn chạy container, bạn phải chỉ định " -it":

-i, --interactive = false Giữ STDIN mở ngay cả khi không được đính kèm
-t, --tty = false Phân bổ giả giả TTY

Thí dụ:

docker run -it debian:stable bash

Sau khi hoàn thành công việc, lệnh được chỉ định khi khởi động (trong ví dụ bash của tôi). Ví dụ: bạn thực hiện "thoát". Container dừng lại:

CONTAINER ID        IMAGE                      COMMAND                CREATED             STATUS                     PORTS               NAMES
1329c99a831b        debian:stable              "bash"                 51 seconds ago      Exited (0) 1 seconds ago                       goofy_bardeen

Bây giờ bạn có thể bắt đầu lại

docker start 1329c99a831b

Container được khởi động và một lần nữa thực thi lệnh "bash".
Kết nối với phiên này "bash" bằng lệnh

docker attach 1329c99a831b

Tóm lại : bạn phải hiểu sự khác biệt giữa runstartcontainer.
Bên cạnh đó, hãy xem tài liệu về vai trò của các tham số " -i t" và " -d" cho "Chạy"


1
aha, tôi hiểu điều này Câu hỏi là: Tôi không có gì để chạy bên trong container, nhưng tôi cần giữ nó ở trạng thái "chạy" Vì vậy, câu trả lời của bạn là - sử dụng bash để giữ container ở trạng thái chạy?
Korjavin Ivan

Có. Quá trình mà bạn đã chỉ định trong thời gian chạy phải được chạy để container tiếp tục hoạt động. Ví dụ đơn giản nhất là bash. Có lẽ bạn sẽ là cách dễ nhất để khởi động container với "-d" và kết nối với nó khi cần bằng cách sử dụng docker attach ID. Thoát khỏi phiên này mà không kết thúc bash, bạn có thể sử dụngCTRL-p CTRL-q
MSemochkin

Quá trình mà bạn chỉ định trong quá trình chạy container nhận được PID 1. Theo đó, container chỉ đơn giản là không thể hoạt động mà không có nó ☺
MSemochkin

Kinh nghiệm của tôi khi bắt đầu và đính kèm (hoặc bắt đầu bằng -ai) là lời nhắc và chỉnh sửa tương tác của dòng lệnh của bạn không hiển thị. EG tty không kết xuất hoặc lặp lại.
dlamblin

1
Đây là tiện lợi. Lưu ý rằng nếu bạn muốn khởi động vùng chứa trong nền mà không phải khởi động lại thủ công (giả sử nếu bạn đang chạy dịch vụ web), hãy sử dụng tham số '-itd' và CTRL-p CTRL-q để tách ra mà không dừng thùng đựng hàng.
taranaki

6

Toàn bộ hoạt động kinh doanh này về việc bạn có thể bắt đầu một container bị dừng hay không, phụ thuộc vào cách container được tạo ban đầu, tức là chạy. Nếu bạn đã chạy một lệnh kết thúc hoặc bạn thoát một lệnh tương tác, ví dụ bash, bạn không thể bắt đầu, khởi động lại hoặc thực thi container bị dừng. Tất cả những gì bạn có thể làm là loại bỏ nó. Đó là rác.

Nhưng bình luận cuối cùng của taranaki, sử dụng '-itd', dường như là những gì docker đã ra lệnh.

Container tiếp tục chạy và bạn có thể thực thi bất cứ điều gì bạn muốn và bạn có thể dừng, bắt đầu hoặc khởi động lại container. Tất nhiên, đây chỉ là một phát hiện sơ bộ dựa trên hình ảnh núi cao. Lưu ý, nếu bạn gắn vào container, nó sẽ dừng khi bạn thoát, nhưng bạn có thể bắt đầu lại.


2
+1 "dường như là những gì các docker đã ra lệnh" :-)
Matt Alexander

5

Vì bạn đã đề cập đến các nhiệm vụ định kỳ và có lẽ bạn đang sử dụng một cái gì đó như cron vì cách bạn muốn sử dụng docker exec, tôi chỉ có thuốc cho bạn. Ít nhất tôi đã kết thúc việc làm một cái gì đó như thế này.

  1. Dockerfile

    FROM <some base>
    CMD tail -f /dev/null
    
  2. Chạy với thông thường docker run -d ....(tôi đã sử dụng docker-compose)

  3. Thiết lập máy chủ crontab, ví dụ:

    * * * * * docker exec mysupercont foo >> /var/log/foo.log 2>&1
    * * * * * docker exec mysupercont bar >> /var/log/bar.log 2>&1
    

Tôi thấy giải pháp này rất hay khi chúng ta dựa vào crontab cổ xưa và đã được chứng minh trong một môi trường linux mặc định, trong khi Docker xử lý các biến môi trường và các biến môi trường kỳ lạ hơn. Bạn cũng có thể đặt một số giới hạn nếu các tác vụ định kỳ của bạn bị kẹt và bị rò rỉ bộ nhớ hoặc bất cứ điều gì.


0

Tail vẫn sẽ gây ra một số hoạt động tập tin theo thời gian.

Đây là giải pháp của tôi để ngủ mãi mãi, không có tác dụng phụ.

# Ah, ha, ha, ha, stayin' alive...
while true; do :; done & kill -STOP $! && wait $!

Làm thế nào nó hoạt động

while true; do :; done & # do nothing(:) in background, in an endless loop
kill -STOP $!            # stop the background process of doing nothing
wait $!                  # wait forever, because doing nothing process is stopped

1
khó hiểu những gì nó làm. Tại sao không ngủ 3650d
Pieter

1
Bạn nói đúng, giấc ngủ có thể hoạt động tốt như giải pháp của tôi, tuy nhiên cuối cùng thì giấc ngủ cũng sẽ hết :-D PS: Tôi sẽ thêm một số nhận xét, để giải pháp của tôi dễ hiểu.
qoomon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.