2014-05-16 19 views
46

Tôi đã xây dựng một hình ảnh cơ sở từ Dockerfile có tên là centos + ssh. Trong centos + ssh của Dockerfile, tôi sử dụng CMD để chạy dịch vụ ssh.Tại sao tôi không thể sử dụng Docker CMD nhiều lần để chạy nhiều dịch vụ?

Sau đó, tôi muốn xây dựng một dịch vụ khác hình ảnh chạy tên RabbitMQ, các Dockerfile:

FROM centos+ssh 
EXPOSE 22 
EXPOSE 4149 
CMD /opt/mq/sbin/rabbitmq-server start 

Để bắt đầu chứa RabbitMQ, chạy:

docker run -d -p 222:22 -p 4149:4149 rabbitmq 

nhưng dịch vụ ssh không hoạt động, nó CMD của Dockerfile của CMD có thể thay thế CMD.

  1. CMD hoạt động bên trong hình ảnh docker như thế nào?
  2. Nếu tôi muốn chạy nhiều dịch vụ, làm cách nào? Sử dụng người giám sát?

Trả lời

43

Mặc dù CMD được viết xuống trong Doc kerfile, nó thực sự là thông tin thời gian chạy. Giống như EXPOSE, nhưng trái với ví dụ RUN và ADD. Bằng cách này, tôi có nghĩa là bạn có thể ghi đè lên nó sau này, trong một Dockerfile mở rộng, hoặc đơn giản trong lệnh chạy của bạn, đó là những gì bạn đang gặp phải. Tại mọi thời điểm, chỉ có thể có một CMD.

Nếu bạn muốn chạy nhiều dịch vụ, tôi thực sự sẽ sử dụng người giám sát. Bạn có thể tạo một tập tin cấu hình giám sát cho mỗi dịch vụ, ADD này trong một thư mục, và chạy người giám sát với supervisord -c /etc/supervisor để trỏ đến một tập tin cấu hình giám sát mà tải tất cả các dịch vụ của bạn và trông giống như

[supervisord] 
nodaemon=true 

[include] 
files = /etc/supervisor/conf.d/*.conf 

Nếu bạn muốn biết thêm chi tiết, tôi đã viết một blog về chủ đề này tại đây: http://blog.trifork.com/2014/03/11/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance/

+0

Cảm ơn, giám sát là một ý tưởng tốt, nhưng tôi tự hỏi làm thế nào để CMD làm việc bên trong hình ảnh docker – edwardsbean

+2

Bạn đã hỏi hai câu hỏi, 2. về chạy nhiều dịch vụ. Tự hỏi làm thế nào CMD hoạt động, xin vui lòng xây dựng trên những gì bạn muốn biết cụ thể. Tôi đã đề cập đến nó là thông tin thời gian chạy và bị ghi đè bởi bất kỳ CMD mới nào. – qkrijger

57

Bạn nói đúng, Dockerfile thứ hai sẽ ghi đè lệnh CMD của lệnh đầu tiên. Docker sẽ luôn chạy một lệnh duy nhất, không nhiều hơn. Vì vậy, ở cuối Dockerfile, bạn có thể chỉ định một lệnh để chạy. Không nhiều.

Nhưng bạn có thể thực hiện cả lệnh trong một dòng:

FROM centos+ssh 
EXPOSE 22 
EXPOSE 4149 
CMD service sshd start && /opt/mq/sbin/rabbitmq-server start 

gì bạn cũng có thể làm để làm cho Dockerfile của bạn một chút bụi nhỏ, bạn có thể đặt CMD bạn lệnh để một tập tin thêm:

FROM centos+ssh 
EXPOSE 22 
EXPOSE 4149 
CMD sh /home/centos/all_your_commands.sh 

Và một tập tin như thế này:

service sshd start & 
/opt/mq/sbin/rabbitmq-server start 
+1

cảm ơn, tôi nghĩ rằng giám sát sử dụng tốt hơn. Nhưng tại sao docker chỉ chạy một CMD? Điều gì xảy ra bên trong? – edwardsbean

+0

Tôi không biết điều gì đang xảy ra bên trong. Nhưng tôi nghĩ nó chỉ được thiết kế như thế. Khi bạn có một hình ảnh và chạy một lệnh trong đó (ví dụ: với CMD), nó sẽ bắt đầu một vùng chứa. Các container chạy miễn là lệnh chạy. Và ngay sau khi lệnh kết thúc, container cũng dừng lại. Vì vậy, mỗi vùng chứa đại diện cho một lệnh (chạy) đơn. –

+0

tôi nghĩ có lẽ vì lcx hoặc giới hạn của một cái gì đó – edwardsbean

13

Mặc dù tôi tôn trọng câu trả lời từ qkrijger giải thích cách bạn có thể giải quyết vấn đề này Tôi nghĩ rằng có rất nhiều điều chúng ta có thể tìm hiểu về những gì đang xảy ra ở đây ...

Để thực sự trả lời câu hỏi của bạn về "lý do tại sao "... Tôi nghĩ rằng nó sẽ hữu ích cho bạn để hiểu làm thế nào lệnh docker stop hoạt động và rằng tất cả các quy trình phải được tắt sạch để ngăn chặn các vấn đề khi bạn cố gắng khởi động lại chúng (tệp tham nhũng vv).

Sự cố: Điều gì xảy ra nếu docker đã làm bắt đầu SSH từ lệnh của nó đã bắt đầu RabbitMQ từ tệp Docker của bạn? "The docker stop command attempts to stop a running container first by sending a SIGTERM signal to the root process (PID 1) in the container." Quá trình nào theo dõi docker là PID 1 sẽ nhận được SIGTERM? Nó sẽ là SSH hay Rabbit ?? "According to the Unix process model, the init process -- PID 1 -- inherits all orphaned child processes and must reap them. Most Docker containers do not have an init process that does this correctly, and as a result their containers become filled with zombie processes over time."

Trả lời: Docker chỉ đơn giản là mất rằng CMD cuối cùng là một mà sẽ được đưa ra như quá trình gốc với PID 1 và nhận được SIGTERM từ docker stop.

giải pháp Đề xuất: Bạn nên sử dụng (hoặc tạo) một hình ảnh cơ sở đặc biệt làm cho chạy nhiều hơn một dịch vụ, chẳng hạn như phusion/baseimage

cần biết:

+0

Giải thích và liên kết tuyệt vời về lý do. Cảm ơn! –

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