2013-06-22 46 views
34

Tôi đang thiết lập một hình ảnh đơn giản: một dịch vụ giữ Riak (một cơ sở dữ liệu NoSQL). Hình ảnh bắt đầu dịch vụ Riak với riak start làm CMD. Bây giờ, nếu tôi chạy nó như một daemon với docker run -d quintenk/riak-dev, nó bắt đầu quá trình Riak (tôi có thể thấy rằng trong nhật ký). Tuy nhiên, nó sẽ tự động đóng sau vài giây. Nếu tôi chạy nó bằng cách sử dụng docker run -i -t quintenk/riak-dev /bin/bash quá trình riak không được bắt đầu (UPDATE: xem câu trả lời cho một lời giải thích cho điều này). Trên thực tế, không có dịch vụ nào đang chạy. Tôi có thể bắt đầu nó bằng tay bằng cách sử dụng thiết bị đầu cuối, nhưng tôi muốn Riak bắt đầu tự động. Tôi hình dung hành vi này cũng sẽ xảy ra đối với các dịch vụ khác, Riak chỉ là một ví dụ.Chạy một dịch vụ tự động trong ngăn chứa docker

Vì vậy, chạy/khởi động lại vùng chứa sẽ tự động khởi động Riak. Cách tiếp cận chính xác của thiết lập này là gì?


Để tham khảo, đây là Dockerfile mà hình ảnh có thể được tạo ra (UPDATE: thay đổi bằng cách sử dụng câu trả lời lựa chọn):

FROM ubuntu:12.04 
RUN apt-get update 
RUN apt-get install -y openssh-server curl 
RUN curl http://apt.basho.com/gpg/basho.apt.key | apt-key add - 
RUN bash -c "echo deb http://apt.basho.com precise main > /etc/apt/sources.list.d/basho.list" 
RUN apt-get update 
RUN apt-get -y install riak 
RUN perl -p -i -e 's/(?<=\{http,\s\[\s\{")127\.0\.0\.1/0.0.0.0/g' /etc/riak/app.config 
EXPOSE 8098 
CMD /bin/riak start && tail -F /var/log/riak/erlang.log.1 

EDIT: -f đổi thành -f trong CMD theo để sesm nhận xét của ông


MY ĐÁP rIÊNG

Sau khi làm việc với Docker trong một thời gian tôi chọn thói quen sử dụng người giám sát để điều chỉnh quy trình của tôi. Nếu bạn muốn mã ví dụ cho điều đó, hãy kiểm tra https://github.com/Krijger/docker-cookbooks. Tôi sử dụng hình ảnh giám sát của tôi làm cơ sở cho tất cả các hình ảnh khác của tôi. Tôi đã viết blog bằng cách sử dụng người giám sát here.

+0

Nhân tiện. Tôi bây giờ (cho mục đích phát triển) bằng cách sử dụng container bằng cách bắt đầu nó, gắn vào nó, và sau đó bắt đầu dòng lệnh Riak. – qkrijger

Trả lời

41

Để giữ các vùng chứa docker đang chạy, bạn cần phải giữ một quy trình hoạt động ở nền trước.

Vì vậy, bạn có thể có thể thay thế mà dòng cuối cùng trong Dockerfile của bạn với

CMD /bin/riak console 

Hoặc thậm chí

CMD /bin/riak start && tail -F /var/log/riak/erlang.log.1 

Lưu ý rằng bạn không thể có nhiều dòng lệnh CMD, chỉ có người cuối cùng được chạy.

+0

Tôi hiện đang sử dụng tùy chọn thứ hai. Cảm ơn phản hôi của bạn! – qkrijger

4

Lời giải thích cho:

Nếu tôi chạy nó bằng cách sử docker run -i -t quintenk/riak-dev /bin/bash quá trình riak không bắt đầu

là như sau. Sử dụng CMD trong Dockerfile thực sự là chức năng tương tự như khi bắt đầu vùng chứa sử dụng docker run {image} {command}. Như Gigablah nhận xét chỉ CMD cuối cùng được sử dụng, do đó, một trong những viết trong Dockerfile được ghi đè trong trường hợp này.

Bằng cách sử dụng CMD /bin/riak start && tail -f /var/log/riak/erlang.log.1 trong tệp Buildfile, bạn có thể bắt đầu vùng chứa dưới dạng quá trình nền sử dụng docker run -d {image}, hoạt động như một nét duyên dáng.

+0

Tương tự, tôi đang cố gắng cập nhật CDH. Trong trường hợp đó, tôi đang bắt đầu dịch vụ bằng lệnh RUN. Nó bắt đầu và thoát sau lệnh RUN đó. Điều gì có thể là lý do? –

+0

@GopsAB có thể có một số loại lỗi ngăn cản quá trình chính từ (giữ) đang chạy. Kiểm tra nhật ký của bạn hoặc thử CMD của bạn theo cách thủ công bằng cách bắt đầu vùng chứa bằng/bin/bash và xem điều gì xảy ra – qkrijger

+0

Nếu quá trình bị lỗi, đuôi tiếp tục chạy. Câu chuyện giống như @damick –

31

Sử dụng đuôi để giữ vùng chứa còn sống là một hack. Ngoài ra, lưu ý rằng với vùng chứa tùy chọn -f sẽ chấm dứt khi xoay vòng nhật ký xảy ra (điều này có thể tránh được bằng cách sử dụng -F thay thế).

Giải pháp tốt hơn là sử dụng supervisor. Hãy xem điều này tutorial về việc chạy Riak trong vùng chứa Docker.

+3

Điều đó có vẻ đầy hứa hẹn. Nếu bạn đã có kinh nghiệm sử dụng kết hợp với docker, bạn có muốn chia sẻ một ví dụ ngắn ở đây không? – qkrijger

3

Vì tôi muốn một cách rõ ràng để thoát khỏi quá trình sau, tôi thực hiện lệnh cuối cùng để gọi đến số read của vỏ đó làm cho quá trình đó bị chặn cho đến khi tôi đính kèm nó và nhấn enter.

[email protected]:~/docker$ sudo docker run -d -t -i -v /raid:/raid -p 4040:4040 subsonic /bin/bash -c 'service subsonic start && read -p "waiting"' 
WARNING: Docker detected local DNS server on resolv.conf. Using default external servers: [8.8.8.8 8.8.4.4] 
f27229a260c9 

[email protected]:~/docker$ sudo docker ps                                  
[sudo] password for arthur: 
ID     IMAGE    COMMAND    CREATED    STATUS    PORTS 
35f253bdf45a  subsonic:latest  /bin/bash -c service 2 days ago   Up 2 days   4040->4040 

[email protected]:~/docker$ sudo docker attach 35f253bdf45a 

[email protected]:~/docker$ sudo docker ps                                  
ID     IMAGE    COMMAND    CREATED    STATUS    PORTS 

vì bạn có thể thấy các thùng chứa thoát sau khi đính kèm và bỏ chặn phần đọc. Bạn có thể sử dụng tất nhiên một kịch bản tinh vi hơn read -p nếu bạn cần phải làm khác dọn dẹp, chẳng hạn như ngăn chặn các dịch vụ và tiết kiệm các bản ghi, vv

4

"Nếu tôi chạy nó bằng cách sử Docker chạy -i -t quintenk/riak-dev/bin/bash quy trình riak chưa được bắt đầu "

Có vẻ như bạn chỉ muốn có thể theo dõi nhật ký khi bạn đính kèm vào vùng chứa. Trường hợp sử dụng của tôi hơi khác một chút ở chỗ tôi muốn lệnh bắt đầu tự động, nhưng tôi muốn có thể đính kèm vào vùng chứa và nằm trong bash shell. Tôi đã có thể giải quyết cả hai vấn đề của chúng tôi như sau:

Trong hình ảnh/vùng chứa, thêm các lệnh bạn muốn tự động bắt đầu vào cuối tệp /etc/bash.bashrc.

Trong trường hợp của bạn, chỉ cần thêm dòng /bin/riak start && tail -F /var/log/riak/erlang.log.1 hoặc đặt /bin/riak starttail -F /var/log/riak/erlang.log.1 trên các dòng riêng biệt tùy thuộc vào chức năng mong muốn.

Bây giờ, hãy cam kết thay đổi đối với vùng chứa của bạn và chạy lại với: docker run -i -t quintenk/riak-dev /bin/bash. Bạn sẽ tìm thấy các lệnh bạn đặt trong bashrc đang chạy khi bạn đính kèm.

+3

Đó thực sự là một giải pháp rất tốt đẹp :) Lưu ý rằng 0.6.5 thêm rằng tùy chọn 'docker run -a' cho khả năng tương thích của người giám sát. Bạn cũng có thể muốn điều đó. – qkrijger

+0

Không phải là một giải pháp tốt. Bạn sẽ làm gì nếu quá trình thoát, tailf sẽ tiếp tục chạy, vùng chứa sẽ không thoát. –

+0

@ MincăDanielAndrei Bạn nói đúng một phần. Đây không phải là một giải pháp sản xuất đã sẵn sàng, nó không bền vững vì lý do bạn đề cập đến. Tốt nhất là nếu có thể có 'entrypoint' hoặc' cmd' của hình ảnh là quá trình bạn muốn tự chạy. Thường thì điều này có nghĩa là bạn cần phải tìm tùy chọn '--no-daemon' cho quá trình nói để giữ cho vùng chứa thoát khỏi khi xuất cảnh điểm gốc và thoát, và để làm cho nó đăng nhập vào stderr/stdout. – damick

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