Có thể chạy docker từ bên trong docker không?


185

Tôi đang chạy Jenkins trong một container Docker. Tôi tự hỏi liệu có ổn không khi container Jenkins cũng là máy chủ Docker? Những gì tôi nghĩ là bắt đầu một container docker mới cho mỗi bản dựng thử nghiệm tích hợp từ bên trong Jenkins (để bắt đầu cơ sở dữ liệu, môi giới tin nhắn, v.v.). Do đó, các container nên được tắt sau khi hoàn thành các bài kiểm tra tích hợp. Có một lý do để tránh chạy các container docker từ bên trong một container docker khác theo cách này?


11
Một khả năng khác là gắn ổ cắm docker từ máy chủ dưới dạng âm lượng trong container. Điều đó cho phép bạn tạo các thùng chứa "anh chị em" và có lợi thế là có thể sử dụng lại bộ đệm.
Adrian Mouat

4
Tôi đã thấy rằng khi sử dụng ổ cắm docker từ máy chủ mà trong trường hợp tôi muốn gắn âm lượng bên ngoài, cần phải đặt đường dẫn âm lượng liên quan đến máy chủ vì đó là nơi trình nền của docker chạy. Đặt nó liên quan đến container bắt đầu các container sẽ không nhất thiết phải hoạt động trừ khi các đường dẫn trùng khớp.
Jakob Runge

Câu trả lời:


224

Chạy Docker bên trong Docker (còn gọi là dind ), trong khi có thể, nên tránh, nếu có thể. (Nguồn được cung cấp dưới đây.) Thay vào đó, bạn muốn thiết lập một cách để thùng chứa chính của bạn sản xuất và liên lạc với các thùng chứa anh chị em .

Jérôme Petazzoni - tác giả của tính năng giúp Docker có thể chạy bên trong một container Docker - thực sự đã viết một bài đăng trên blog nói rằng không nên làm điều đó . Trường hợp sử dụng mà anh mô tả khớp với trường hợp sử dụng chính xác của OP của bộ chứa CI Docker cần chạy các công việc bên trong các bộ chứa Docker khác.

Petazzoni liệt kê hai lý do tại sao dind gây rắc rối:

  1. Nó không hợp tác tốt với Mô-đun bảo mật Linux (LSM).
  2. Nó tạo ra một sự không phù hợp trong các hệ thống tệp tạo ra các vấn đề cho các thùng chứa được tạo bên trong các thùng chứa cha.

Từ bài đăng trên blog, ông mô tả các phương án sau,

[Cách] đơn giản nhất là chỉ để lộ ổ cắm Docker vào thùng chứa CI của bạn, bằng cách gắn kết nó với -vcờ.

Nói một cách đơn giản, khi bạn khởi động thùng chứa CI của mình (Jenkins hoặc loại khác), thay vì hack một cái gì đó cùng với Docker-in-Docker, hãy khởi động nó bằng:

docker run -v /var/run/docker.sock:/var/run/docker.sock ...

Bây giờ container này sẽ có quyền truy cập vào ổ cắm Docker, và do đó sẽ có thể bắt đầu các container. Ngoại trừ việc thay vì bắt đầu các container "con", nó sẽ bắt đầu các container "anh chị em".


1
Làm thế nào để chạy các lệnh docker mà không cần sudolàm như thế này? Cảm ơn
c4k

3
Bạn cần thêm người dùng vào dockernhóm : sudo usermod -aG docker $USER. Bạn sẽ cần phải đăng nhập lại sau đó.
premijat

2
Làm thế nào để đăng nhập lại từ bên trong một cointainer?
thiagowfx

1
@AlexanderMills Cũng tương tự vì ổ cắm /var/run/docker.sockdocker của bạn cũng được đặt tại khi bạn chạy docker cho mac trên máy macos của bạn.
Bruce Sun

1
Còn cửa sổ thì sao? tôi không có/var/run/docker.sock
Abdelhafid

54

Tôi đã trả lời một câu hỏi tương tự trước đây về cách chạy một Docker container bên trong Docker .

Để chạy docker bên trong docker là chắc chắn có thể. Điều chính là bạn runchứa container bên ngoài với các đặc quyền bổ sung (bắt đầu bằng --privileged=true) và sau đó cài đặt docker trong container đó.

Kiểm tra bài đăng trên blog này để biết thêm thông tin: Docker-in-Docker .

Một trường hợp sử dụng tiềm năng cho điều này được mô tả trong mục này . Blog mô tả cách xây dựng các container docker trong container docker Jenkins.

Tuy nhiên, Docker bên trong Docker không phải là cách tiếp cận được đề xuất để giải quyết loại vấn đề này. Thay vào đó, cách tiếp cận được đề xuất là tạo các thùng chứa "anh chị em" như được mô tả trong bài viết này

Vì vậy, chạy Docker bên trong Docker được nhiều người coi là một giải pháp tốt cho loại vấn đề này. Bây giờ, xu hướng là sử dụng các container "anh chị em" thay thế. Xem câu trả lời của @predmijat trên trang này để biết thêm.


Xem bình luận dưới đây về việc tránh docker trong docker.
Dan Poltawski

6

Bạn có thể chạy Docker-in-Docker (DinD) và trên thực tế Docker (công ty) có hình ảnh DinD chính thức cho việc này.

Tuy nhiên, sự cảnh báo là nó yêu cầu một thùng chứa đặc quyền, tùy thuộc vào nhu cầu bảo mật của bạn có thể không phải là một sự thay thế khả thi.

Giải pháp thay thế cho việc chạy Docker bằng cách sử dụng các bộ chứa anh chị em (còn gọi là Docker-out-of-Docker hoặc DooD) không yêu cầu một bộ chứa đặc quyền, nhưng có một vài nhược điểm xuất phát từ việc bạn đang khởi chạy bộ chứa trong bối cảnh đó là khác với cái mà nó đang chạy (nghĩa là bạn khởi chạy container từ bên trong một container, nhưng nó đang chạy ở cấp độ của máy chủ chứ không phải bên trong container).

Tôi đã viết một blog mô tả những ưu / nhược điểm của DinD vs DooD tại đây .

Phải nói điều này, Nestybox (một startup tôi mới thành lập) đang nghiên cứu một giải pháp chạy Docker-in-Docker thực sự một cách an toàn (không sử dụng các container đặc quyền). Bạn có thể kiểm tra nó tại www.nestybox.com .


0

Có, chúng tôi có thể chạy docker trong docker, chúng tôi sẽ cần đính kèm sockeet unix "/var/run/docker.sock" mà trình nền của docker nghe theo mặc định là âm lượng cho docker cha mẹ bằng cách sử dụng "-v / var / run /docker.sock:/var/run/docker.sock ". Đôi khi, các vấn đề về quyền có thể phát sinh đối với ổ cắm docker daemon mà bạn có thể viết "sudo chmod 757 /var/run/docker.sock".

Và cũng cần phải chạy docker ở chế độ đặc quyền, vì vậy các lệnh sẽ là:

sudo chmod 757 /var/run/docker.sock

docker chạy --privileged = true -v /var/run/docker.sock:/var/run/docker.sock -it ...

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.