Docker khác với máy ảo như thế nào?


3692

Tôi tiếp tục đọc lại tài liệu Docker để cố gắng hiểu sự khác biệt giữa Docker và VM đầy đủ. Làm thế nào nó quản lý để cung cấp một hệ thống tập tin đầy đủ, môi trường mạng bị cô lập, vv mà không nặng nề?

Tại sao việc triển khai phần mềm lên hình ảnh Docker (nếu đó là thuật ngữ đúng) dễ dàng hơn là triển khai đơn giản đến một môi trường sản xuất nhất quán?


11
Phân tích hiệu suất của Docker vs KVM: bodenr.blogspot.com/2014/05/ từ
HDave

1
Nếu bạn đang tìm kiếm sự khác biệt giữa các hình ảnh của họ - stackoverflow.com/questions/29096967/iêng
devesh-ahuja

21
Docker không phải là một máy ảo - nó là một công cụ quản lý cấu hình.
aaa90210

3
Nói một cách đơn giản: VM -> ba lớp ảo phải chạy để cho phép ứng dụng của bạn chạy, nếu bạn muốn ảo hóa máy chủ thì OK nhưng nếu bạn chỉ muốn chạy một ứng dụng web thì không phải là giải pháp tốt nhất. DOCKER -> Chỉ có một lớp giữa cpu thực của bạn và ứng dụng web của bạn. Nhân bản / phản chiếu mạnh mẽ hơn và tốt hơn nếu bạn chỉ phải chạy ứng dụng web của mình để ảo hóa những ứng dụng mà tôi giới thiệu
Davide Castronovo

6
đừng quên rằng Docker cho Mac và Docker cho Windows sử dụng lớp ảo hóa.
Shapeshifter

Câu trả lời:


3434

Docker ban đầu sử dụng LinuX Container (LXC), nhưng sau đó chuyển sang runC (trước đây gọi là libcontainer ), chạy trong cùng hệ điều hành với máy chủ của nó. Điều này cho phép nó chia sẻ rất nhiều tài nguyên hệ điều hành máy chủ. Ngoài ra, nó sử dụng một hệ thống tập tin lớp ( AuFS ) và quản lý mạng.

AuFS là một hệ thống tệp lớp, vì vậy bạn có thể có một phần chỉ đọc và một phần ghi được hợp nhất với nhau. Người ta có thể có các phần chung của hệ điều hành là chỉ đọc (và được chia sẻ giữa tất cả các container của bạn) và sau đó cung cấp cho mỗi container một giá đỡ riêng để viết.

Vì vậy, giả sử bạn có hình ảnh chứa 1 GB; nếu bạn muốn sử dụng VM đầy đủ, bạn cần có 1 GB x số lượng VM bạn muốn. Với Docker và AuFS, bạn có thể chia sẻ số lượng lớn 1 GB giữa tất cả các container và nếu bạn có 1000 container, bạn vẫn có thể chỉ còn hơn 1 GB dung lượng cho các container của hệ điều hành (giả sử tất cả chúng đều chạy cùng một hình ảnh HĐH) .

Một hệ thống ảo hóa đầy đủ có bộ tài nguyên riêng được phân bổ cho nó và chia sẻ tối thiểu. Bạn bị cô lập nhiều hơn, nhưng nó nặng hơn nhiều (đòi hỏi nhiều tài nguyên hơn). Với Docker bạn sẽ ít bị cô lập hơn, nhưng các container thì nhẹ (yêu cầu ít tài nguyên hơn). Vì vậy, bạn có thể dễ dàng chạy hàng ngàn container trên một máy chủ và nó thậm chí sẽ không nhấp nháy. Hãy thử làm điều đó với Xen, và trừ khi bạn có một máy chủ thực sự lớn, tôi không nghĩ điều đó là có thể.

Một hệ thống ảo hóa đầy đủ thường mất vài phút để bắt đầu, trong khi các container Docker / LXC / runC mất vài giây và thường thậm chí ít hơn một giây.

Có những ưu và nhược điểm đối với từng loại hệ thống ảo hóa. Nếu bạn muốn cách ly hoàn toàn với các tài nguyên được bảo đảm, một VM đầy đủ là cách tốt nhất. Nếu bạn chỉ muốn tách biệt các tiến trình với nhau và muốn chạy một tấn chúng trên một máy chủ có kích thước hợp lý, thì Docker / LXC / runC dường như là cách tốt nhất.

Để biết thêm thông tin, hãy xem tập hợp các bài đăng trên blog này làm tốt công việc giải thích cách thức hoạt động của LXC.

Tại sao việc triển khai phần mềm lên hình ảnh docker (nếu đó là thuật ngữ đúng) dễ dàng hơn là đơn giản triển khai vào một môi trường sản xuất nhất quán?

Triển khai một môi trường sản xuất nhất quán thì nói dễ hơn làm. Ngay cả khi bạn sử dụng các công cụ như ChefPuppet , luôn có các bản cập nhật hệ điều hành và những thứ khác thay đổi giữa máy chủ và môi trường.

Docker cung cấp cho bạn khả năng chụp nhanh HĐH thành hình ảnh được chia sẻ và giúp dễ dàng triển khai trên các máy chủ Docker khác. Tại địa phương, dev, qa, prod, vv.: Tất cả cùng một hình ảnh. Chắc chắn bạn có thể làm điều này với các công cụ khác, nhưng không dễ dàng hay nhanh chóng.

Điều này là tuyệt vời để thử nghiệm; giả sử bạn có hàng ngàn bài kiểm tra cần kết nối với cơ sở dữ liệu và mỗi bài kiểm tra cần một bản sao cơ sở dữ liệu nguyên sơ và sẽ thực hiện thay đổi dữ liệu. Cách tiếp cận cổ điển này là thiết lập lại cơ sở dữ liệu sau mỗi lần kiểm tra bằng mã tùy chỉnh hoặc với các công cụ như Flyway - điều này có thể rất tốn thời gian và có nghĩa là các thử nghiệm phải được chạy một cách an toàn. Tuy nhiên, với Docker, bạn có thể tạo một hình ảnh của cơ sở dữ liệu của mình và chạy một phiên bản cho mỗi thử nghiệm, sau đó chạy song song tất cả các thử nghiệm vì bạn biết rằng tất cả chúng sẽ chạy cùng một ảnh chụp nhanh của cơ sở dữ liệu. Vì các thử nghiệm đang chạy song song và trong các thùng chứa Docker, chúng có thể chạy tất cả trên cùng một hộp cùng một lúc và sẽ hoàn thành nhanh hơn nhiều. Hãy thử làm điều đó với một VM đầy đủ.

Từ ý kiến ​​...

Hấp dẫn! Tôi cho rằng tôi vẫn còn bối rối bởi khái niệm "snapshot [ting] HĐH". Làm thế nào để một người làm điều đó mà không có, làm cho một hình ảnh của hệ điều hành?

Vâng, hãy xem tôi có thể giải thích. Bạn bắt đầu với một hình ảnh cơ bản, sau đó thực hiện các thay đổi của mình và cam kết những thay đổi đó bằng cách sử dụng docker và nó tạo ra một hình ảnh. Hình ảnh này chỉ chứa sự khác biệt từ cơ sở. Khi bạn muốn chạy hình ảnh của mình, bạn cũng cần cơ sở và nó xếp hình ảnh của bạn lên trên cơ sở bằng hệ thống tệp lớp: như đã đề cập ở trên, Docker sử dụng AuFS. AuFS hợp nhất các lớp khác nhau lại với nhau và bạn có được những gì bạn muốn; bạn chỉ cần chạy nó Bạn có thể tiếp tục thêm ngày càng nhiều hình ảnh (lớp) và nó sẽ tiếp tục chỉ lưu các khác biệt. Vì Docker thường xây dựng trên đầu các hình ảnh được tạo sẵn từ sổ đăng ký , nên bạn hiếm khi phải tự "chụp nhanh" toàn bộ HĐH.


239
Ken, ở một số nơi bạn kết nối HĐH với kernel. Tất cả các bộ chứa trên một máy chủ chạy dưới cùng một kernel, nhưng phần còn lại của các tệp OS có thể là duy nhất cho mỗi bộ chứa.
Andy

22
Hấp dẫn! Tôi cho rằng tôi vẫn còn bối rối bởi khái niệm "snapshot [ting] HĐH". Làm thế nào để một người làm điều đó mà không có, làm cho một hình ảnh của hệ điều hành?
zslayton

7
@ murtaza52 họ đang thêm hỗ trợ cho các hệ thống tệp khác nhau để Aufs biến mất không phải là vấn đề. Không chắc chắn khi hỗ trợ 32 bit sẽ được thêm vào, đừng nghĩ rằng đã có nhu cầu mạnh, vì vậy nó nằm trong danh sách ưu tiên thấp, nhưng tôi có thể sai.
Ken Cochrane

21
@Mike: ... chắc chắn được lấy cảm hứng từ các nhà tù FreeBSD HISTORY The jail utility appeared in FreeBSD 4.0.
Stefan Paletta

21
Đối với những người thắc mắc về nhận xét của @ Mike, chúng tôi đang trả lời vì nó dường như đã bị xóa, đó là: <Điều còn thiếu là một tham chiếu đến thực tế rằng Container Linux là bản sao của nguồn cảm hứng thực sự : Container Solaris. Quay trở lại năm 2004 ... Đây là một khái niệm mang tính cách mạng và là một cách tuyệt vời, tuyệt vời để làm các máy ảo được lưu trữ, giá cả phải chăng, thực sự hiệu quả. Joyent là người đầu tiên tôi biết về ...>
Jeffrey 'jf' Lim

559

Câu trả lời tốt. Chỉ để có được một đại diện hình ảnh của container so với VM, hãy xem cái bên dưới.

nhập mô tả hình ảnh ở đây

Nguồn


20
<strike> Theo như tôi hiểu, phía trên "công cụ docker" nên có một nhân linux được chia sẻ. Sau đó, thường có thùng / libs chia sẻ. Đầu tiên sau đó là các thùng / lib và ứng dụng dành riêng cho từng container. Vui lòng sửa tôi nếu tôi sai. </ Strike> Tôi đã sai. Hình ảnh Docker chia sẻ kernel với máy chủ, xem superuser.com/questions/889472/ . Tuy nhiên, để minh họa hệ thống tập tin kết hợp của các thùng chứa, có thể có một lớp lib / thùng được chia sẻ ngay phía trên công cụ docker.
Betamos

13
Tôi có một vấn đề với hình ảnh trên, bởi vì Hypervisor có thể được cài đặt trên cơ sở hạ tầng / kim loại trần nhưng Docket không thể (chưa)
reza

@reza, tôi đồng ý Hypervisor có thể được cài đặt trên Bare metal, nhưng vấn đề là Docker được khuyến nghị để chứa các ứng dụng và cách hạn chế hoặc tránh ảo hóa không cần thiết / áp dụng cho một số trường hợp. Ken Cochrane giải thích điều này chi tiết hơn về stackoverflow.com/a/16048353/2478933
manu97

4
Điều này không làm rõ Docker Engine là gì . Hình ảnh rất trừu tượng.
kyb

9
Không có lớp "Docker Engine" giữa container và kernel, container chỉ là một quá trình với các cài đặt đặc biệt trong kernel (không gian tên, cgroups, v.v.)
Paweł Prażak

504

Có thể hữu ích để hiểu làm thế nào ảo hóa và container hoạt động ở mức thấp. Điều đó sẽ làm sáng tỏ rất nhiều thứ.

Lưu ý: Tôi đang đơn giản hóa một chút trong mô tả dưới đây. Xem tài liệu tham khảo để biết thêm thông tin.

Làm thế nào ảo hóa hoạt động ở mức thấp?

Trong trường hợp này, trình quản lý VM chiếm lấy vòng CPU 0 (hoặc "chế độ gốc" trong các CPU mới hơn) và chặn tất cả các cuộc gọi đặc quyền được thực hiện bởi HĐH khách để tạo ảo giác rằng HĐH khách có phần cứng riêng. Sự thật thú vị: Trước năm 1998, người ta cho rằng không thể đạt được điều này trong kiến ​​trúc x86 bởi vì không có cách nào để thực hiện kiểu đánh chặn này. Mọi người tại VMWare là những người đầu tiên có ý tưởng viết lại các byte thực thi trong bộ nhớ cho các cuộc gọi đặc quyền của HĐH khách để đạt được điều này.

Hiệu ứng ròng là ảo hóa cho phép bạn chạy hai hệ điều hành hoàn toàn khác nhau trên cùng một phần cứng. Mỗi hệ điều hành khách trải qua tất cả quá trình bootstrapping, tải kernel, v.v. Bạn có thể có bảo mật rất chặt chẽ, ví dụ, HĐH khách không thể truy cập đầy đủ vào hệ điều hành máy chủ hoặc các khách khác và làm rối tung mọi thứ.

Làm thế nào container hoạt động ở mức thấp?

Khoảng năm 2006 , người trong đó có một số nhân viên tại Google đã triển khai tính năng mức kernel mới được gọi là không gian tên (tuy nhiên ý tưởng từ lâu trước khi tồn tại trong FreeBSD). Một chức năng của HĐH là cho phép chia sẻ tài nguyên toàn cầu như mạng và đĩa cho các quy trình. Điều gì xảy ra nếu các tài nguyên toàn cầu này được bọc trong các không gian tên để chúng chỉ hiển thị với các quy trình chạy trong cùng một không gian tên? Giả sử, bạn có thể lấy một đoạn đĩa và đặt nó vào không gian tên X và sau đó các tiến trình đang chạy trong không gian tên Y không thể nhìn thấy hoặc truy cập vào nó. Tương tự, các quy trình trong không gian tên X không thể truy cập bất cứ thứ gì trong bộ nhớ được phân bổ cho không gian tên Y. Tất nhiên, các quy trình trong X không thể nhìn thấy hoặc nói chuyện với các quy trình trong không gian tên Y. Điều này cung cấp loại ảo hóa và cách ly cho tài nguyên toàn cầu. Đây là cách docker hoạt động: Mỗi container chạy trong không gian tên riêng nhưng sử dụng chính xác như nhaukernel như tất cả các container khác. Sự cô lập xảy ra vì kernel biết không gian tên được gán cho tiến trình và trong các lệnh gọi API, nó đảm bảo rằng tiến trình đó chỉ có thể truy cập tài nguyên trong không gian tên của chính nó.

Hiện tại, giới hạn của container so với VM là rõ ràng: Bạn không thể chạy HĐH hoàn toàn khác trong các container như trong VM. Tuy nhiên, bạn có thể chạy các bản phát hành khác nhau của Linux vì chúng có chung hạt nhân. Mức cô lập không mạnh như trong VM. Trên thực tế, có một cách để container "khách" tiếp quản máy chủ trong các triển khai sớm. Ngoài ra, bạn có thể thấy rằng khi bạn tải container mới, toàn bộ bản sao mới của HĐH sẽ không bắt đầu giống như trong VM. Tất cả các container chia sẻ cùng một kernel. Đây là lý do tại sao container có trọng lượng nhẹ. Ngoài ra, không giống như VM, bạn không phải phân bổ trước bộ nhớ đáng kể cho các bộ chứa vì chúng tôi không chạy bản sao mới của HĐH. Điều này cho phép chạy hàng ngàn container trên một HĐH trong khi sandbox chúng có thể không thực hiện được nếu chúng ta đang chạy bản sao riêng của HĐH trong VM riêng của nó.


26
Wow, cảm ơn vì lời giải thích cấp thấp tuyệt vời (và sự thật lịch sử). Tôi đã tìm kiếm điều đó và không được tìm thấy ở trên. Ý bạn là gì khi "bạn có thể chạy các bản phát hành khác nhau của Linux vì chúng có chung hạt nhân." ? Bạn đang nói rằng một thùng chứa khách phải có cùng phiên bản nhân Linux hay nó không thành vấn đề? Nếu nó không thành vấn đề nếu tôi gọi lệnh OS trên máy khách nhưng chỉ được hỗ trợ trong kernel khách. Hoặc ví dụ một lỗi đã được sửa trong kernel khách nhưng không phải trong kernel host. Tất cả khách sẽ biểu hiện lỗi, đúng không? Mặc dù khách đã được vá.
Jeach

7
@Jeach: các container không có kernel riêng, chúng đang chia sẻ / sử dụng một trong các host. Vì vậy, bạn không thể chạy các container cần các kernel khác nhau trên cùng một máy / VM.
dùng276648

2
Câu hỏi: Bạn viết rằng một số nhân viên của Google đã tham gia vào tính năng nhân không gian tên vào khoảng năm 1996 - nhưng Google vẫn chưa được thành lập cho đến năm 1998. Ý bạn là 'những người sau này sẽ trở thành nhân viên của Google'?
Martin Gjaldbaek

3
@martin - cảm ơn vì đã chú ý đến năm 2006. Ngoài ra tôi nên đề cập rằng các loại không gian tên khác nhau đã tồn tại trong Linux từ năm 2002 nhưng đó là công việc trong năm 2006 đặt nền tảng cho việc đóng gói. Tôi đã cập nhật câu trả lời với tham khảo.
Shital Shah

20
+1 Đây phải là câu trả lời được đánh dấu, trong khi các câu trả lời khác đưa ra một số giải thích rõ ràng, chỉ có giải thích cấp thấp từ dưới lên mới có thể làm rõ cách thức công nghệ này hoạt động, 'các quy trình được nhóm trong không gian tên riêng của họ = container'. Cảm ơn bạn rất nhiều, tôi nhận được nó ngay bây giờ.
Tino Mclaren

328

Tôi thích câu trả lời của Ken Cochrane.

Nhưng tôi muốn thêm quan điểm bổ sung, không được đề cập chi tiết ở đây. Theo tôi thì Docker cũng khác trong toàn bộ quá trình. Trái ngược với VM, Docker không (chỉ) về chia sẻ tài nguyên phần cứng tối ưu, hơn nữa, nó cung cấp một "hệ thống" cho ứng dụng đóng gói (tốt hơn, nhưng không phải là một bộ dịch vụ siêu nhỏ).

Đối với tôi, nó phù hợp với khoảng cách giữa các công cụ hướng nhà phát triển như vòng / phút, gói Debian , Maven , npm + Git ở một bên và các công cụ ops như Puppet , VMware, Xen, bạn đặt tên cho nó ...

Tại sao việc triển khai phần mềm lên hình ảnh docker (nếu đó là thuật ngữ đúng) dễ dàng hơn là đơn giản triển khai vào một môi trường sản xuất nhất quán?

Câu hỏi của bạn giả định một số môi trường sản xuất phù hợp. Nhưng làm thế nào để giữ cho nó phù hợp? Xem xét một số lượng (> 10) máy chủ và ứng dụng, các giai đoạn trong đường ống dẫn.

Để giữ điều này đồng bộ, bạn sẽ bắt đầu sử dụng một cái gì đó như Puppet, Chef hoặc tập lệnh cung cấp của riêng bạn, các quy tắc chưa được công bố và / hoặc nhiều tài liệu ... Trong lý thuyết, các máy chủ có thể chạy vô thời hạn và được cập nhật hoàn toàn nhất quán. Thực tế không thể quản lý hoàn toàn cấu hình của máy chủ, do đó có phạm vi đáng kể cho việc trôi cấu hình và những thay đổi bất ngờ đối với các máy chủ đang chạy.

Vì vậy, có một mô hình đã biết để tránh điều này, cái gọi là máy chủ bất biến . Nhưng mẫu máy chủ bất biến không được yêu thích. Chủ yếu là do những hạn chế của máy ảo đã được sử dụng trước Docker. Xử lý một vài gigabyte hình ảnh lớn, di chuyển những hình ảnh lớn đó xung quanh, chỉ để thay đổi một số lĩnh vực trong ứng dụng, rất tốn công sức. Có thể hiểu được...

Với hệ sinh thái Docker, bạn sẽ không bao giờ phải di chuyển xung quanh gigabyte trên "những thay đổi nhỏ" (cảm ơn aufs và Registry) và bạn không cần lo lắng về việc mất hiệu suất khi đóng gói các ứng dụng vào bộ chứa Docker khi chạy. Bạn không cần phải lo lắng về các phiên bản của hình ảnh đó.

Và cuối cùng, bạn thậm chí sẽ thường xuyên có thể tái tạo các môi trường sản xuất phức tạp ngay cả trên máy tính xách tay Linux của bạn (đừng gọi cho tôi nếu không hoạt động trong trường hợp của bạn;))

Và tất nhiên bạn có thể bắt đầu các Docker container trong VM (đó là một ý tưởng tốt). Giảm việc cung cấp máy chủ của bạn ở cấp VM. Tất cả những điều trên có thể được quản lý bởi Docker.

PS Trong khi đó Docker sử dụng "libcontainer" triển khai riêng của mình thay vì LXC. Nhưng LXC vẫn có thể sử dụng được.


1
Có vẻ kỳ lạ khi bao gồm git trong một nhóm các công cụ như vòng / phút và dpkg. Tôi đề cập đến điều này bởi vì tôi thấy những nỗ lực sử dụng các hệ thống kiểm soát phiên bản như git như một công cụ phân phối / đóng gói là một nguồn gây nhầm lẫn.
blitzen9872

2
Mặc dù vậy, anh ta không sai, git có thể được sử dụng để quản lý gói, ví dụ, bower về cơ bản là một cli ưa thích để tải xuống thẻ git.
roo2

2
ứng dụng đóng gói trong container là một cách tiếp cận thú vị và hợp lệ. Tuy nhiên, nếu bạn đóng gói nó trong docker thì điều này sẽ là quá mức, vì sẽ không có sự hỗ trợ đơn giản cho các phụ thuộc hoặc bất kỳ thư viện chia sẻ nào. Đây chính xác là những gì công nghệ đóng gói mới như Ubuntu Snap và Flatpak cho Redhat đang cố gắng đạt được. Theo tôi, một trong những công nghệ đóng gói này sẽ chiến thắng và trở thành tương lai của bao bì trong linux.
yosefrow

@ blitzen9872 đồng ý về điều này. Nhưng đã được đề cập chính xác bởi vì nó thường được sử dụng cho distributuon trong Praxis, một lần nữa tôi cũng không thích nó.
aholenameich

@yosefrow công phu "quá mức". Kiểm tra ý tưởng và ưu điểm của mẫu "máy chủ bất biến", tất nhiên có một số nhược điểm ... Nếu bạn thấy quá mức cần thiết, đừng sử dụng nó ..
aholenameich

245

Docker không phải là một phương pháp ảo hóa. Nó dựa vào các công cụ khác thực sự thực hiện ảo hóa dựa trên container hoặc ảo hóa cấp hệ điều hành. Do đó, Docker ban đầu sử dụng trình điều khiển LXC, sau đó chuyển sang libcontainer mà giờ được đổi tên thành runc. Docker chủ yếu tập trung vào việc tự động hóa việc triển khai các ứng dụng bên trong các thùng chứa ứng dụng. Các thùng chứa ứng dụng được thiết kế để đóng gói và chạy một dịch vụ, trong khi các thùng chứa hệ thống được thiết kế để chạy nhiều quy trình, như các máy ảo. Vì vậy, Docker được coi là một công cụ triển khai ứng dụng hoặc quản lý container trên các hệ thống được chứa.

Để biết nó khác với các ảo hóa khác như thế nào, chúng ta hãy đi qua ảo hóa và các loại của nó. Sau đó, sẽ dễ dàng hơn để hiểu sự khác biệt ở đó.

Ảo hóa

Ở dạng được hình thành, nó được coi là một phương pháp phân chia logic lớn để cho phép nhiều ứng dụng chạy cùng lúc. Tuy nhiên, kịch bản đã thay đổi mạnh mẽ khi các công ty và cộng đồng nguồn mở có thể cung cấp phương pháp xử lý các hướng dẫn đặc quyền theo cách này hay cách khác và cho phép nhiều hệ điều hành được chạy đồng thời trên một hệ thống dựa trên x86.

Hypervisor

Trình ảo hóa xử lý việc tạo môi trường ảo nơi các máy ảo khách hoạt động. Nó giám sát các hệ thống của khách và đảm bảo rằng các tài nguyên được phân bổ cho khách khi cần thiết. Trình ảo hóa nằm ở giữa máy vật lý và máy ảo và cung cấp dịch vụ ảo hóa cho các máy ảo. Để nhận ra điều đó, nó chặn các hoạt động của hệ điều hành khách trên các máy ảo và mô phỏng hoạt động trên hệ điều hành của máy chủ.

Sự phát triển nhanh chóng của các công nghệ ảo hóa, chủ yếu là trên đám mây, đã thúc đẩy việc sử dụng ảo hóa hơn nữa bằng cách cho phép nhiều máy chủ ảo được tạo trên một máy chủ vật lý duy nhất với sự trợ giúp của các trình ảo hóa, như Xen, VMware Player, KVM, v.v., và kết hợp hỗ trợ phần cứng trong các bộ xử lý hàng hóa, như Intel VT và AMD-V.

Các loại ảo hóa

Phương pháp ảo hóa có thể được phân loại dựa trên cách nó bắt chước phần cứng với hệ điều hành khách và mô phỏng môi trường vận hành khách. Chủ yếu, có ba loại ảo hóa:

  • Thi đua
  • Paravirtualization
  • Ảo hóa dựa trên container

Thi đua

Giả lập, còn được gọi là ảo hóa hoàn toàn chạy nhân hệ điều hành máy ảo hoàn toàn trong phần mềm. Trình ảo hóa được sử dụng trong loại này được gọi là hypanneror Loại 2. Nó được cài đặt trên đỉnh của hệ điều hành máy chủ có trách nhiệm dịch mã nhân hệ điều hành khách sang hướng dẫn phần mềm. Bản dịch được thực hiện hoàn toàn trong phần mềm và không yêu cầu sự tham gia của phần cứng. Thi đua cho phép chạy bất kỳ hệ điều hành không sửa đổi nào hỗ trợ môi trường được mô phỏng. Nhược điểm của loại ảo hóa này là chi phí tài nguyên hệ thống bổ sung dẫn đến giảm hiệu suất so với các loại ảo hóa khác.

Thi đua

Ví dụ trong danh mục này bao gồm VMware Player, VirtualBox, QEMU, Bochs, Parallels, v.v.

Paravirtualization

Paravirtualization, còn được gọi là hypanneror Loại 1, chạy trực tiếp trên phần cứng, hoặc trần kim loại trần, và cung cấp dịch vụ ảo hóa trực tiếp cho các máy ảo chạy trên nó. Nó giúp hệ điều hành, phần cứng ảo hóa và phần cứng thực sự hợp tác để đạt được hiệu suất tối ưu. Các siêu giám sát này thường có dấu chân khá nhỏ và bản thân chúng không yêu cầu nhiều tài nguyên.

Ví dụ trong danh mục này bao gồm Xen, KVM, v.v.

Paravirtualization

Ảo hóa dựa trên container

Ảo hóa dựa trên container, còn được gọi là ảo hóa cấp hệ điều hành, cho phép thực thi nhiều cách ly trong một nhân hệ điều hành. Nó có hiệu suất và mật độ tốt nhất có thể và có tính năng quản lý tài nguyên động. Môi trường thực thi ảo bị cô lập được cung cấp bởi loại ảo hóa này được gọi là một thùng chứa và có thể được xem như là một nhóm các quy trình.

Ảo hóa dựa trên container

Khái niệm về một container được thực hiện nhờ tính năng không gian tên được thêm vào nhân Linux phiên bản 2.6.24. Container thêm ID của nó vào mọi quy trình và thêm kiểm tra kiểm soát truy cập mới vào mỗi cuộc gọi hệ thống. Nó được truy cập bằng lệnh gọi hệ thống clone () cho phép tạo các thể hiện riêng biệt của các không gian tên toàn cầu trước đó.

Không gian tên có thể được sử dụng theo nhiều cách khác nhau, nhưng cách tiếp cận phổ biến nhất là tạo ra một container bị cô lập không có khả năng hiển thị hoặc truy cập vào các đối tượng bên ngoài container. Các tiến trình chạy bên trong container dường như đang chạy trên một hệ thống Linux bình thường mặc dù chúng đang chia sẻ kernel bên dưới với các tiến trình nằm trong các không gian tên khác, tương tự cho các loại đối tượng khác. Chẳng hạn, khi sử dụng các không gian tên, người dùng root bên trong container không được coi là root bên ngoài container, thêm bảo mật bổ sung.

Hệ thống con Linux Control Groups (cgroups), thành phần chính tiếp theo để cho phép ảo hóa dựa trên container, được sử dụng để nhóm các quy trình và quản lý mức tiêu thụ tài nguyên tổng hợp của chúng. Nó thường được sử dụng để hạn chế mức tiêu thụ bộ nhớ và CPU của các container. Vì một hệ thống Linux được chứa chỉ có một kernel và kernel có khả năng hiển thị đầy đủ vào các container, nên chỉ có một cấp độ phân bổ và lập lịch tài nguyên.

Một số công cụ quản lý có sẵn cho các bộ chứa Linux, bao gồm LXC, LXD, systemd-nspawn, lmctfy, Warden, Linux-VServer, OpenVZ, Docker, v.v.

Container vs Máy ảo

Không giống như một máy ảo, một container không cần phải khởi động kernel hệ điều hành, vì vậy các container có thể được tạo trong chưa đầy một giây. Tính năng này làm cho ảo hóa dựa trên container trở nên độc đáo và đáng mong đợi hơn các phương pháp ảo hóa khác.

Do ảo hóa dựa trên container thêm ít hoặc không có chi phí cho máy chủ, nên ảo hóa dựa trên container có hiệu năng gần như nguyên gốc

Đối với ảo hóa dựa trên container, không yêu cầu phần mềm bổ sung, không giống như các ảo hóa khác.

Tất cả các container trên máy chủ chia sẻ bộ lập lịch của máy chủ lưu trữ cần thêm tài nguyên.

Các trạng thái vùng chứa (hình ảnh Docker hoặc LXC) có kích thước nhỏ so với hình ảnh máy ảo, vì vậy hình ảnh container rất dễ phân phối.

Quản lý tài nguyên trong các container được thực hiện thông qua các nhóm. Các nhóm không cho phép các container tiêu thụ nhiều tài nguyên hơn so với phân bổ cho chúng. Tuy nhiên, cho đến nay, tất cả tài nguyên của máy chủ đều có thể nhìn thấy trong các máy ảo, nhưng không thể sử dụng được. Điều này có thể được nhận ra bằng cách chạy tophoặc htoptrên các container và máy chủ cùng một lúc. Đầu ra trên tất cả các môi trường sẽ trông tương tự nhau.

Cập nhật:

Làm thế nào để Docker chạy container trong các hệ thống không phải là Linux?

Nếu các bộ chứa có thể là do các tính năng có sẵn trong nhân Linux, thì câu hỏi rõ ràng là làm thế nào để các hệ thống không phải Linux chạy các bộ chứa. Cả Docker cho Mac và Windows đều sử dụng máy ảo Linux để chạy các thùng chứa. Docker Toolbox được sử dụng để chạy các container trong máy ảo Virtual Box. Nhưng, Docker mới nhất sử dụng Hyper-V trong Windows và Hypervisor.framework trong Mac.

Bây giờ, hãy để tôi mô tả cách Docker cho Mac chạy container chi tiết.

Docker cho Mac sử dụng https://github.com/moby/hyperkit để mô phỏng các khả năng của trình ảo hóa và Hyperkit sử dụng hypanneror.framework trong lõi của nó. Hypervisor.framework là giải pháp hypanneror riêng của Mac. Hyperkit cũng sử dụng VPNKit và DataKit để tương ứng với không gian mạng và hệ thống tệp.

Máy ảo Linux mà Docker chạy trong Mac là chỉ đọc. Tuy nhiên, bạn có thể bash vào nó bằng cách chạy:

screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty.

Bây giờ, chúng ta thậm chí có thể kiểm tra phiên bản Kernel của VM này:

# uname -a Linux linuxkit-025000000001 4.9.93-linuxkit-aufs #1 SMP Wed Jun 6 16:86_64 Linux.

Tất cả các container chạy bên trong VM này.

Có một số hạn chế đối với hypanneror.framework. Do đó Docker không lộ docker0giao diện mạng trong Mac. Vì vậy, bạn không thể truy cập các container từ máy chủ lưu trữ. Đến bây giờ, docker0chỉ có sẵn trong VM.

Hyper-v là trình ảo hóa tự nhiên trong Windows. Họ cũng đang cố gắng tận dụng các khả năng của Windows 10 để chạy các hệ thống Linux nguyên bản.


1
Bài viết rất hay. Cảm ơn bạn rất nhiều! Một câu hỏi khác mà tôi có là tôi có thể xây dựng docker arm7v hình ảnh 32 bit trên máy Mac x86_64. Tuy nhiên, tôi không thể xây dựng hình ảnh tương tự trên Ubuntu được cài đặt trên máy x86_64. Điều này có liên quan đến giải pháp của Mac hypanneror mà bạn đã đề cập không?
jiashenC

1
Câu trả lời của bạn là người duy nhất giải quyết "Làm thế nào Docker chạy container trong các hệ thống không phải là Linux?" Thông tin này rất khó tìm thấy ở bất cứ đâu. Mọi thứ đều nhấn mạnh rằng "các thùng chứa hoàn toàn khác với VM!", Nhanh hơn, trọng lượng nhẹ hơn, v.v., nhưng cách duy nhất để chạy một container trên hệ thống không phải là linux là ...
Bogatyr

@Bogatyr IINM, nó -one- VM cho tất cả các container.
dstromberg

147

Thông qua bài viết này, chúng tôi sẽ rút ra một số dòng khác biệt giữa VM và LXC. Trước tiên hãy xác định chúng.

VM :

Một máy ảo mô phỏng môi trường máy tính vật lý, nhưng các yêu cầu về CPU, bộ nhớ, đĩa cứng, mạng và các tài nguyên phần cứng khác được quản lý bởi một lớp ảo hóa giúp chuyển các yêu cầu này sang phần cứng vật lý bên dưới.

Trong bối cảnh này, VM được gọi là Khách trong khi môi trường mà nó chạy được gọi là máy chủ.

LXC s:

Các bộ chứa Linux (LXC) là các khả năng ở cấp hệ điều hành, cho phép chạy nhiều bộ chứa Linux bị cô lập, trên một máy chủ điều khiển (máy chủ LXC). Các bộ chứa Linux hoạt động như một giải pháp thay thế nhẹ cho máy ảo vì chúng không yêu cầu các trình ảo hóa. Hộp ảo, KVM, Xen, v.v.

Bây giờ trừ khi bạn bị Alan (Zach Galifianakis- từ loạt Hangover) đánh thuốc mê và đã ở Vegas trong năm ngoái, bạn sẽ nhận thức được rất nhiều về sự quan tâm to lớn của công nghệ container Linux, và nếu tôi sẽ là một container cụ thể Dự án đã tạo ra tiếng vang trên toàn thế giới trong vài tháng qua là - Docker dẫn đến một số ý kiến ​​trái chiều rằng môi trường điện toán đám mây nên từ bỏ các máy ảo (VM) và thay thế chúng bằng các thùng chứa do chi phí thấp hơn và có khả năng hoạt động tốt hơn.

Nhưng câu hỏi lớn là nó có khả thi không?, Liệu nó có hợp lý không?

a. Các LXC nằm trong phạm vi của Linux. Nó có thể là các hương vị khác nhau của Linux (ví dụ: thùng chứa Ubuntu trên máy chủ CentOS nhưng vẫn là Linux.) Tương tự, các thùng chứa dựa trên Windows bây giờ nằm ​​trong một phiên bản của Windows nếu chúng ta nhìn vào VM chúng có phạm vi khá rộng hơn và sử dụng nhà ảo thuật bạn không bị giới hạn trong các hệ điều hành Linux hoặc Windows.

b. LXC có tổng phí thấp và có hiệu suất tốt hơn so với VM. Công cụ viz. Docker được xây dựng trên vai công nghệ LXC đã cung cấp cho các nhà phát triển một nền tảng để chạy các ứng dụng của họ, đồng thời đã trao quyền cho mọi người hoạt động với một công cụ cho phép họ triển khai cùng một container trên các máy chủ sản xuất hoặc trung tâm dữ liệu. Nó cố gắng tạo trải nghiệm giữa nhà phát triển chạy ứng dụng, khởi động và kiểm tra ứng dụng và người vận hành triển khai ứng dụng đó một cách liền mạch, bởi vì đây là nơi mà tất cả ma sát nằm trong mục đích của DevOps là phá vỡ các silo đó.

Vì vậy, cách tiếp cận tốt nhất là các nhà cung cấp cơ sở hạ tầng đám mây nên ủng hộ việc sử dụng VM và LXC thích hợp, vì chúng đều phù hợp để xử lý các khối lượng công việc và kịch bản cụ thể.

Từ bỏ máy ảo là không thực tế như bây giờ. Vì vậy, cả VM và LXC đều có sự tồn tại và tầm quan trọng riêng của chúng.


4
Phần "b" của bạn ở trên chính xác là những gì người dân Docker đã nói về công nghệ. Nó có nghĩa là để làm cho các nhiệm vụ phát triển triển khai dễ dàng hơn. Và dựa trên kinh nghiệm của tôi là một dev và là một sysop, tôi phải đồng ý.
WineSoakes

3
Đó là câu trả lời khá trừu tượng. Chúng ta cần các trường hợp sử dụng khi sử dụng / không sử dụng Docker. Đó là câu hỏi. Mọi người đều có thể tìm thấy Docker là như thế nào nhưng chỉ một số ít có thể giải thích về các tình huống thực tế.
Ivan Voroshilin

1
Docker hiện đang được đưa vào thế giới windows, vì nó không còn phụ thuộc vào LXC: blog.msdn.com/b/nzdev/archive/2015/06/02/ Hãy làm ơn sửa cho tôi nếu tôi hiểu nhầm câu trả lời ở đây
bubakazouba

6
Tôi có một thời gian khó hiểu phần "(ví dụ: bộ chứa Ubuntu trên máy chủ Centos nhưng vẫn là Linux)" của bộ chứa. Theo cách tôi hiểu, đó là các container chia sẻ kernel host. Ví dụ, nếu tôi có một máy chủ VM chạy Linux kernel 4.6, có một số máy khách VM đang chạy các nhân Linux 2.4, 2.6, 3.2, 4.1 và 4.4. Nếu tôi thực thi các lệnh cụ thể cho kernel đó, tôi sẽ nhận được hành vi của kernel khách (chứ không phải máy chủ). Nhưng nếu bây giờ VM máy khách của tôi là các thùng chứa, lệnh thực thi có được xác định bởi hạt nhân máy chủ không?
Jeach

@bubakazouba vâng. bạn nói đúng. Bây giờ họ sử dụng runC
Rumesh Eranga Hapuarachchi

140

Hầu hết các câu trả lời ở đây nói về máy ảo. Tôi sẽ cung cấp cho bạn câu trả lời một câu hỏi cho câu hỏi này đã giúp tôi nhiều nhất trong vài năm qua khi sử dụng Docker. Đây là:

Docker chỉ là một cách ưa thích để chạy một quy trình, không phải là một máy ảo.

Bây giờ, hãy để tôi giải thích thêm một chút về điều đó có nghĩa là gì. Máy ảo là con thú riêng của họ. Tôi cảm thấy như giải thích Docker là gì sẽ giúp bạn hiểu điều này hơn là giải thích máy ảo là gì. Đặc biệt bởi vì có nhiều câu trả lời hay ở đây cho bạn biết chính xác ý nghĩa của ai đó khi họ nói "máy ảo". Vì thế...

Một thùng chứa Docker chỉ là một quá trình (và con của nó) được ngăn cách bằng cách sử dụng các nhóm bên trong nhân của hệ thống máy chủ từ phần còn lại của các quy trình. Bạn thực sự có thể thấy các quá trình chứa Docker của bạn bằng cách chạy ps auxtrên máy chủ. Ví dụ: bắt đầu apache2"trong một container" chỉ bắt đầu apache2như một quy trình đặc biệt trên máy chủ. Nó chỉ được ngăn cách từ các quy trình khác trên máy. Điều quan trọng cần lưu ý là các thùng chứa của bạn không tồn tại bên ngoài vòng đời của quá trình được đóng gói của bạn. Khi quá trình của bạn chết, container của bạn chết. Đó là bởi vì Docker thay thế pid 1bên trong container của bạn bằng ứng dụng của bạn ( pid 1thường là hệ thống init). Điểm cuối cùng này pid 1là rất quan trọng.

Theo như hệ thống tập tin được sử dụng bởi mỗi người trong số các quy trình container, Docker sử dụng UnionFS -backed hình ảnh, đó là những gì bạn đang tải khi bạn làm một docker pull ubuntu. Mỗi "hình ảnh" chỉ là một chuỗi các lớp và siêu dữ liệu liên quan. Khái niệm layering rất quan trọng ở đây. Mỗi lớp chỉ là một sự thay đổi từ lớp bên dưới nó. Ví dụ: khi bạn xóa một tệp trong Dockerfile trong khi xây dựng bộ chứa Docker, thực tế bạn chỉ đang tạo một lớp ở trên cùng của lớp cuối cùng có nội dung "tệp này đã bị xóa". Ngẫu nhiên, đây là lý do tại sao bạn có thể xóa một tệp lớn khỏi hệ thống tệp của mình, nhưng hình ảnh vẫn chiếm cùng một dung lượng đĩa. Các tập tin vẫn còn đó, trong các lớp bên dưới lớp hiện tại. Bản thân các lớp chỉ là tarball của các tập tin. Bạn có thể kiểm tra điều này vớidocker save --output /tmp/ubuntu.tar ubuntuvà sau đó cd /tmp && tar xvf ubuntu.tar. Sau đó, bạn có thể nhìn xung quanh. Tất cả những thư mục trông giống như băm dài thực sự là các lớp riêng lẻ. Mỗi cái chứa tệp ( layer.tar) và siêu dữ liệu (json) với thông tin về lớp cụ thể đó. Các lớp đó chỉ mô tả các thay đổi đối với hệ thống tệp được lưu dưới dạng một lớp "trên đầu trang" trạng thái ban đầu của nó. Khi đọc dữ liệu "hiện tại", hệ thống tập tin đọc dữ liệu như thể nó chỉ nhìn vào các lớp thay đổi trên cùng. Đó là lý do tại sao tệp dường như bị xóa, mặc dù nó vẫn tồn tại trong các lớp "trước đó", bởi vì hệ thống tệp chỉ nhìn vào các lớp trên cùng. Điều này cho phép các thùng chứa hoàn toàn khác nhau để chia sẻ các lớp hệ thống tệp của chúng, mặc dù một số thay đổi quan trọng có thể đã xảy ra với hệ thống tệp trên các lớp trên cùng trong mỗi thùng chứa. Điều này có thể giúp bạn tiết kiệm rất nhiều dung lượng đĩa, khi các thùng chứa của bạn chia sẻ các lớp hình ảnh cơ sở của chúng. Tuy nhiên,

Kết nối mạng trong Docker đạt được bằng cách sử dụng cầu ethernet (được gọi docker0trên máy chủ) và giao diện ảo cho mọi vùng chứa trên máy chủ. Nó tạo ra một mạng con ảo docker0để các container của bạn giao tiếp "giữa" với nhau. Có nhiều tùy chọn để kết nối mạng ở đây, bao gồm tạo các mạng con tùy chỉnh cho các thùng chứa của bạn và khả năng "chia sẻ" ngăn xếp mạng của máy chủ để container của bạn truy cập trực tiếp.

Docker đang di chuyển rất nhanh. Tài liệu của nó là một số tài liệu tốt nhất tôi từng thấy. Nó thường được viết tốt, súc tích và chính xác. Tôi khuyên bạn nên kiểm tra tài liệu có sẵn để biết thêm thông tin và tin tưởng tài liệu này hơn bất kỳ thứ gì bạn đọc trực tuyến, bao gồm cả Stack Overflow. Nếu bạn có câu hỏi cụ thể, tôi khuyên bạn nên tham gia #dockervào Freenode IRC và hỏi ở đó (thậm chí bạn có thể sử dụng webchat của Freenode cho điều đó!).


12
"Docker chỉ là một cách ưa thích để chạy một quy trình, không phải là một máy ảo." Đây là một bản tóm tắt tuyệt vời, cảm ơn!
mkorman

Cảm ơn! Khoản tín dụng dành cho lập trình viên từ #dockerkênh trên Freenode IRC.
L0j1k

Điều này rõ ràng hơn nhiều so với các câu trả lời khác. Tôi đoán đó là sự tương tự quá trình làm điều đó cho tôi. Nó chỉ làm giảm mức độ trừu tượng.
Mate Mrše

Tôi sẽ nói thêm: "Docker chỉ là một cách ưa thích để chạy một quy trình, theo cách cô lập, được bảo vệ, đóng gói, không phải là một máy ảo." Hệ thống máy chủ có khả năng hiển thị (qua các quy trình và tài nguyên) của hệ thống con nhưng hệ thống bị cô lập không có khả năng hiển thị (qua các quy trình và tài nguyên) trong hệ thống máy chủ.
Sohail Si

87

Docker đóng gói một ứng dụng với tất cả các phụ thuộc của nó.

Một trình ảo hóa đóng gói một HĐH có thể chạy bất kỳ ứng dụng nào mà nó thường có thể chạy trên một máy kim loại trần.


1
Tôi đang tìm hiểu về LXC, sửa tôi nếu tôi sai, nhưng nó có thể là một loại virtualenv? nhưng rõ ràng là rộng hơn, không chỉ được lưu lại thành con trăn để nói
NeoVe

2
Tôi thích câu trả lời này tốt nhất. Nó đơn giản và đi thẳng vào điểm. Bây giờ người ta đã hiểu cơ bản về những gì LXC và Virtualators có thể làm, các chi tiết từ cách đọc khác sẽ có ý nghĩa.
Phil

2
@Phil Nó đã làm sau khi tôi đọc câu trả lời chi tiết ở trên đầu tiên.
johnny

Tôi giả sử họ muốn biết cách gói gọn. Đó là phần lớn sẽ cho thấy sự khác biệt giữa họ nhưng bạn không trả lời.
Ánh sáng.G

60

Cả hai đều rất khác nhau. Docker rất nhẹ và sử dụng LXC / libcontainer (dựa trên không gian tên và nhóm nhân) và không có mô phỏng máy / phần cứng như hypanneror, KVM. Xen mà nặng.

Docker và LXC có nghĩa là nhiều hơn cho hộp cát, container và cách ly tài nguyên. Nó sử dụng API nhân bản của hệ điều hành máy chủ (hiện chỉ là nhân Linux), cung cấp không gian tên cho IPC, NS (mount), mạng, PID, UTS, v.v.

Còn bộ nhớ, I / O, CPU, v.v? Điều đó được kiểm soát bằng cách sử dụng các nhóm trong đó bạn có thể tạo các nhóm với đặc tả / hạn chế tài nguyên nhất định (CPU, bộ nhớ, v.v.) và đưa các quy trình của bạn vào đó. Trên LXC, Docker cung cấp một phụ trợ lưu trữ ( http://www.projectatomic.io/docs/filesystems/ ), ví dụ: hệ thống tập tin gắn kết liên kết nơi bạn có thể thêm các lớp và chia sẻ các lớp giữa các không gian tên gắn kết khác nhau.

Đây là một tính năng mạnh mẽ trong đó các hình ảnh cơ bản thường chỉ đọc và chỉ khi vùng chứa sửa đổi một cái gì đó trong lớp thì nó mới ghi một cái gì đó vào phân vùng đọc-ghi (còn gọi là sao chép trên ghi). Nó cũng cung cấp nhiều trình bao bọc khác như đăng ký và phiên bản hình ảnh.

Với LXC bình thường, bạn cần đi kèm với một số rootfs hoặc chia sẻ rootfs và khi chia sẻ, và những thay đổi được phản ánh trên các container khác. Do nhiều tính năng được thêm vào này, Docker phổ biến hơn LXC. LXC phổ biến trong các môi trường nhúng để thực hiện bảo mật xung quanh các quy trình tiếp xúc với các thực thể bên ngoài như mạng và giao diện người dùng. Docker là phổ biến trong môi trường nhiều người thuê đám mây nơi môi trường sản xuất phù hợp được mong đợi.

Một VM bình thường (ví dụ VirtualBox và VMware) sử dụng một trình ảo hóa và các công nghệ liên quan có phần sụn chuyên dụng trở thành lớp đầu tiên cho HĐH đầu tiên (HĐH máy chủ hoặc HĐH khách 0) hoặc phần mềm chạy trên HĐH máy chủ cung cấp mô phỏng phần cứng như CPU, USB / phụ kiện, bộ nhớ, mạng, v.v., cho các HĐH khách. Máy ảo vẫn còn (tính đến năm 2015) phổ biến trong môi trường nhiều người thuê bảo mật cao.

Docker / LXC gần như có thể chạy trên bất kỳ phần cứng giá rẻ nào (bộ nhớ dưới 1 GB cũng không sao miễn là bạn có kernel mới hơn) so với các máy ảo bình thường cần ít nhất 2 GB bộ nhớ, v.v., để làm bất cứ điều gì có ý nghĩa với nó . Nhưng hỗ trợ Docker trên HĐH máy chủ không có sẵn trong HĐH như Windows (kể từ tháng 11 năm 2014) trong đó các loại máy ảo có thể chạy trên windows, Linux và Mac.

Đây là một hình ảnh từ docker / Rightscale: Đây là một bức ảnh từ Rightscale


34

1. Nhẹ

Đây có lẽ là ấn tượng đầu tiên đối với nhiều người học docker.

Đầu tiên, hình ảnh docker thường nhỏ hơn hình ảnh VM, giúp dễ dàng xây dựng, sao chép, chia sẻ.

Thứ hai, các container Docker có thể bắt đầu trong vài mili giây, trong khi VM bắt đầu sau vài giây.

2. Hệ thống tập tin lớp

Đây là một tính năng quan trọng khác của Docker. Hình ảnh có các lớp và các hình ảnh khác nhau có thể chia sẻ các lớp, làm cho nó tiết kiệm không gian hơn và nhanh hơn để xây dựng.

Nếu tất cả các bộ chứa sử dụng Ubuntu làm hình ảnh cơ sở của chúng, thì không phải mọi hình ảnh đều có hệ thống tệp riêng, nhưng chia sẻ cùng một tệp ub Ubuntu và chỉ khác nhau trong dữ liệu ứng dụng của chúng.

3. Nhân hệ điều hành dùng chung

Hãy nghĩ về container như các quá trình!

Tất cả các container chạy trên một máy chủ thực sự là một loạt các quy trình với các hệ thống tệp khác nhau. Chúng chia sẻ cùng một nhân hệ điều hành, chỉ gói gọn thư viện hệ thống và các phụ thuộc.

Điều này tốt cho hầu hết các trường hợp (không có nhân hệ điều hành bổ sung duy trì) nhưng có thể là một vấn đề nếu cần cách ly nghiêm ngặt giữa các container.

Tại sao nó quan trọng?

Tất cả những điều này có vẻ như cải tiến, không phải là cách mạng. Vâng, tích lũy định lượng dẫn đến chuyển đổi định tính .

Hãy suy nghĩ về việc triển khai ứng dụng. Nếu chúng tôi muốn triển khai một phần mềm (dịch vụ) mới hoặc nâng cấp một phần mềm, tốt hơn là thay đổi các tệp cấu hình và quy trình thay vì tạo một VM mới. Bởi vì Tạo một VM với dịch vụ cập nhật, thử nghiệm nó (chia sẻ giữa Dev & QA), việc triển khai vào sản xuất mất nhiều giờ, thậm chí vài ngày. Nếu có gì sai, bạn phải bắt đầu lại, lãng phí nhiều thời gian hơn. Vì vậy, sử dụng công cụ quản lý cấu hình (con rối, Saltstack, đầu bếp, v.v.) để cài đặt phần mềm mới, tải xuống các tệp mới được ưu tiên.

Khi nói đến docker, không thể sử dụng một container docker mới được tạo để thay thế cái cũ. Bảo trì dễ dàng hơn nhiều! Xây dựng hình ảnh mới, chia sẻ nó với QA, thử nghiệm nó, triển khai nó chỉ mất vài phút (nếu mọi thứ được tự động hóa), hàng giờ trong trường hợp xấu nhất. Đây được gọi là cơ sở hạ tầng bất biến : không duy trì (nâng cấp) phần mềm, thay vào đó hãy tạo một phần mềm mới.

Nó biến đổi cách thức cung cấp dịch vụ. Chúng tôi muốn các ứng dụng, nhưng phải duy trì máy ảo (đây là một vấn đề khó khăn và ít liên quan đến các ứng dụng của chúng tôi). Docker làm cho bạn tập trung vào các ứng dụng và làm trơn tru mọi thứ.


27

Docker, về cơ bản là các container, hỗ trợ ảo hóa hệ điều hành, tức là ứng dụng của bạn cảm thấy rằng nó có phiên bản hoàn chỉnh của HĐH trong khi VM hỗ trợ ảo hóa phần cứng . Bạn cảm thấy như nó là một cỗ máy vật lý mà bạn có thể khởi động bất kỳ HĐH nào.

Trong Docker, các container đang chạy chia sẻ kernel hệ điều hành máy chủ, trong khi đó trong VM họ có các tệp OS riêng. Môi trường (HĐH) mà bạn phát triển một ứng dụng sẽ giống nhau khi bạn triển khai nó đến các môi trường phục vụ khác nhau, chẳng hạn như "thử nghiệm" hoặc "sản xuất".

Ví dụ: nếu bạn phát triển một máy chủ web chạy trên cổng 4000, khi bạn triển khai nó đến môi trường "thử nghiệm" của mình, cổng đó đã được một số chương trình khác sử dụng, vì vậy nó sẽ ngừng hoạt động. Trong các thùng chứa có các lớp; tất cả các thay đổi bạn đã thực hiện cho HĐH sẽ được lưu trong một hoặc nhiều lớp và các lớp đó sẽ là một phần của hình ảnh, do đó, bất cứ nơi nào hình ảnh đi cũng sẽ xuất hiện các phụ thuộc.

Trong ví dụ hiển thị bên dưới, máy chủ có ba VM. Để cung cấp các ứng dụng trong VM cách ly hoàn toàn, mỗi máy đều có các bản sao tệp, thư viện và mã ứng dụng riêng, cùng với một phiên bản đầy đủ trong bộ nhớ của HĐH.Không có container Trong khi hình dưới đây cho thấy kịch bản tương tự với các container. Ở đây, các container chỉ chia sẻ hệ điều hành máy chủ, bao gồm kernel và thư viện, vì vậy chúng không cần phải khởi động HĐH, tải thư viện hoặc trả chi phí bộ nhớ riêng cho các tệp đó. Không gian gia tăng duy nhất họ có là bất kỳ bộ nhớ và dung lượng đĩa cần thiết để ứng dụng chạy trong vùng chứa. Mặc dù môi trường của ứng dụng có cảm giác như một HĐH chuyên dụng, nhưng ứng dụng triển khai giống như trên một máy chủ chuyên dụng. Ứng dụng được đóng gói bắt đầu sau vài giây và nhiều phiên bản khác của ứng dụng có thể vừa với máy hơn trong trường hợp VM. nhập mô tả hình ảnh ở đây

Nguồn: https://azure.microsoft.com/en-us/blog/containers-docker-windows-and-trends/


Tôi rất thích đoạn đầu tiên.
Ánh sáng.G

23

Có ba thiết lập khác nhau cung cấp ngăn xếp để chạy ứng dụng (Điều này sẽ giúp chúng tôi nhận ra container là gì và điều gì làm cho nó mạnh hơn nhiều so với các giải pháp khác):

1) Traditional Servers(bare metal)
2) Virtual machines (VMs)
3) Containers

1) Ngăn xếp máy chủ truyền thống bao gồm một máy chủ vật lý chạy hệ điều hành và ứng dụng của bạn.

Ưu điểm:

  • Sử dụng tài nguyên thô

  • Sự cách ly

Nhược điểm:

  • Thời gian triển khai rất chậm
  • Đắt
  • Tài nguyên lãng phí
  • Khó mở rộng
  • Khó di cư
  • Cấu hình phức tạp

2) Ngăn xếp VM bao gồm một máy chủ vật lý chạy hệ điều hành và trình ảo hóa quản lý máy ảo, tài nguyên dùng chung và giao diện mạng của bạn. Mỗi Vm chạy Hệ điều hành khách, một ứng dụng hoặc bộ ứng dụng.

Ưu điểm:

  • Sử dụng tốt tài nguyên
  • Dễ dàng để quy mô
  • Dễ dàng sao lưu và di chuyển
  • Hiệu quả chi phí
  • Uyển chuyển

Nhược điểm:

  • Phân bổ nguồn lực có vấn đề
  • Nhà cung cấp lockin
  • Cấu hình phức tạp

3) Thiết lập Container , điểm khác biệt chính với ngăn xếp khác là ảo hóa dựa trên container sử dụng kernel của HĐH máy chủ để rum nhiều trường hợp khách bị cô lập. Những trường hợp khách này được gọi là container. Máy chủ có thể là máy chủ vật lý hoặc VM.

Ưu điểm:

  • Sự cách ly
  • Nhẹ
  • Tài nguyên hiệu quả
  • Dễ dàng di chuyển
  • Bảo vệ
  • Chi phí thấp
  • Môi trường sản xuất và phát triển gương

Nhược điểm:

  • Kiến trúc tương tự
  • Tài nguyên ứng dụng nặng
  • Các vấn đề về mạng và bảo mật.

Bằng cách so sánh thiết lập vùng chứa với các thiết bị tiền nhiệm, chúng ta có thể kết luận rằng việc đóng gói là thiết lập nhanh nhất, hiệu quả nhất về tài nguyên và an toàn nhất mà chúng ta biết cho đến nay. Các thùng chứa là các trường hợp riêng biệt chạy ứng dụng của bạn. Docker quay vòng container theo cách, các lớp lấy bộ nhớ thời gian chạy với trình điều khiển lưu trữ mặc định (Trình điều khiển lớp phủ) chạy trong vài giây và lớp sao chép được tạo trên đầu trang sau khi chúng tôi cam kết vào vùng chứa, hỗ trợ thực thi hộp đựng.Trong trường hợp VM sẽ mất khoảng một phút để tải mọi thứ vào môi trường ảo hóa. Những trường hợp nhẹ này có thể được thay thế, xây dựng lại và di chuyển dễ dàng. Điều này cho phép chúng tôi phản ánh môi trường sản xuất và phát triển và giúp đỡ rất nhiều trong các quy trình CI / CD. Những lợi thế mà container có thể cung cấp rất hấp dẫn mà chắc chắn họ sẽ ở đây.


Vui lòng cho biết lý do tại sao đây phải là "thiết lập an toàn nhất" so với máy ảo.
MKesper

@MKesper: Khi bạn di chuyển từ môi trường cũ sang môi trường container, bạn có nhiều cách khác nhau để xây dựng mô hình bảo mật, một cách dựa trên phương pháp chủ động thay vì phản ứng để ngăn chặn sự xâm nhập. Nó cho phép bạn bảo mật ứng dụng và thời gian chạy của mình ở mức độ chi tiết và sắc thái hơn. Họ cũng trao quyền để xác định và giải quyết các mối đe dọa bảo mật tiềm ẩn trước khi chúng phá vỡ quy trình công việc của bạn. Và, có thể kết hợp phân tích tĩnh với ML để tự động hóa bảo vệ thời gian chạy và thực thi các chính sách trên môi trường của bạn. Do đó, dòng "thiết lập an toàn nhất".
mohan08p

18

Liên quan đến:-

"Tại sao việc triển khai phần mềm lên hình ảnh docker dễ dàng hơn là chỉ đơn giản là triển khai vào một môi trường sản xuất nhất quán?"

Hầu hết các phần mềm được triển khai cho nhiều môi trường, thường là tối thiểu ba trong số các điều sau:

  1. PC nhà phát triển cá nhân
  2. Môi trường phát triển dùng chung
  3. PC thử nghiệm cá nhân
  4. Môi trường kiểm tra dùng chung
  5. Môi trường QA
  6. Môi trường UAT
  7. Kiểm tra tải / hiệu suất
  8. Dàn dựng trực tiếp
  9. Sản xuất
  10. Lưu trữ

Ngoài ra còn có các yếu tố sau để xem xét:

  • Các nhà phát triển, và thực sự là những người thử nghiệm, tất cả sẽ có cấu hình PC tinh tế hoặc khác biệt rất lớn, bởi bản chất của công việc
  • Các nhà phát triển thường có thể phát triển trên PC ngoài tầm kiểm soát của các quy tắc tiêu chuẩn hóa doanh nghiệp hoặc doanh nghiệp (ví dụ: những người làm việc tự do phát triển trên máy của họ (thường là từ xa) hoặc người đóng góp cho các dự án nguồn mở không được 'thuê' hoặc 'ký hợp đồng' để cấu hình PC của họ một cách chắc chắn đường)
  • Một số môi trường sẽ bao gồm một số lượng cố định của nhiều máy trong cấu hình cân bằng tải
  • Nhiều môi trường sản xuất sẽ có các máy chủ dựa trên đám mây một cách linh hoạt (hoặc 'co giãn') được tạo và hủy tùy thuộc vào mức lưu lượng

Như bạn có thể thấy tổng số máy chủ ngoại suy cho một tổ chức hiếm khi ở các số liệu đơn lẻ, rất thường là trong ba số liệu và có thể dễ dàng cao hơn đáng kể.

Tất cả điều này có nghĩa là việc tạo ra các môi trường nhất quán ở nơi đầu tiên đủ khó chỉ vì âm lượng lớn (ngay cả trong kịch bản trường xanh), nhưng giữ cho chúng nhất quán là tất cả nhưng không thể có số lượng máy chủ cao, thêm máy chủ mới (tự động hoặc thủ công), cập nhật tự động từ nhà cung cấp o, nhà cung cấp chống vi-rút, nhà cung cấp trình duyệt và tương tự, cài đặt phần mềm thủ công hoặc thay đổi cấu hình được thực hiện bởi nhà phát triển hoặc kỹ thuật viên máy chủ, v.v. Hãy để tôi nhắc lại - hầu như không thể (không có ý định chơi chữ) để giữ cho môi trường nhất quán (được, đối với người theo chủ nghĩa thuần túy, có thể thực hiện được, nhưng nó đòi hỏi một lượng lớn thời gian, công sức và kỷ luật, đó chính là lý do tại sao VM và container (ví dụ Docker) được nghĩ ra ngay từ đầu).

Vì vậy, hãy nghĩ về câu hỏi của bạn giống như thế này "Với khó khăn cực lớn trong việc giữ tất cả các môi trường nhất quán, việc triển khai phần mềm lên hình ảnh docker có dễ dàng hơn không, ngay cả khi tính đến đường cong học tập?" . Tôi nghĩ bạn sẽ luôn tìm thấy câu trả lời là "có" - nhưng chỉ có một cách để tìm hiểu, hãy đăng câu hỏi mới này lên Stack Overflow.


Vì vậy, nếu tôi triển khai hình ảnh docker của mình với 15 hộp khác nhau có tất cả các kết hợp hệ điều hành / phiên bản khác nhau, tất cả hình ảnh docker của tôi sẽ chạy giống nhau?
Teoman shipahi

@Teomanshipahi Nếu tất cả các container này có thể sử dụng cùng một kernel được cung cấp bởi máy chủ, vâng, tất cả chúng sẽ chạy thành công.
Ánh sáng.G

Nếu tôi sử dụng docker cho windows trên local, tôi có thể triển khai và chạy tương tự trong linux / mac không?
Teoman shipahi

Điều dường như luôn bị che lấp là vẫn còn phụ thuộc phiên bản: 1) Nhà phát triển phải phát triển trên cùng một môi trường mà hình ảnh chứa; 2) Môi trường dev và môi trường thử nghiệm cần phải chạy cùng một phiên bản (hoặc tương thích) của cả kernel linux và docker ... đúng không?
Bogatyr

18

Có nhiều câu trả lời giải thích chi tiết hơn về sự khác biệt, nhưng đây là lời giải thích rất ngắn gọn của tôi.

Một điểm khác biệt quan trọng là VM sử dụng kernel riêng để chạy HĐH . Đó là lý do nó nặng và mất thời gian để khởi động, tiêu tốn nhiều tài nguyên hệ thống hơn.

Trong Docker, các container chia sẻ kernel với máy chủ; do đó nó rất nhẹ và có thể bắt đầu và dừng lại nhanh chóng.

Trong ảo hóa, các tài nguyên được phân bổ khi bắt đầu thiết lập và do đó tài nguyên không được sử dụng đầy đủ khi máy ảo không hoạt động trong nhiều thời gian. Trong Docker, các thùng chứa không được phân bổ với lượng tài nguyên phần cứng cố định và được sử dụng miễn phí các tài nguyên tùy theo yêu cầu và do đó nó có khả năng mở rộng cao.

Docker sử dụng hệ thống tệp UNION .. Docker sử dụng công nghệ sao chép ghi để giảm dung lượng bộ nhớ được sử dụng bởi các container. Đọc thêm tại đây


1
"Trong ảo hóa, các tài nguyên được phân bổ khi bắt đầu thiết lập và do đó tài nguyên không được sử dụng hết khi máy ảo không hoạt động trong nhiều lần" Hyper-V có khái niệm về Bộ nhớ động trong đó bạn có thể chỉ định Tối thiểu, Tối đa và RAM khởi động.
Mariusz

15

Với một máy ảo , chúng tôi có một máy chủ, chúng tôi có một hệ điều hành máy chủ trên máy chủ đó và sau đó chúng tôi có một trình ảo hóa. Và sau đó chạy trên trình ảo hóa đó, chúng tôi có bất kỳ số lượng hệ điều hành khách nào với một ứng dụng và các nhị phân phụ thuộc của nó và các thư viện trên máy chủ đó. Nó mang lại một hệ điều hành khách với nó. Nó khá nặng. Ngoài ra, có một giới hạn về số lượng bạn thực sự có thể đặt trên mỗi máy vật lý.

Nhập mô tả hình ảnh ở đây

Docker container mặt khác, hơi khác nhau. Chúng tôi có máy chủ. Chúng tôi có hệ điều hành máy chủ. Nhưng thay vì một trình ảo hóa , chúng ta có công cụ Docker , trong trường hợp này. Trong trường hợp này, chúng tôi sẽ không mang theo toàn bộ hệ điều hành khách. Chúng tôi đang mang một lớp rất mỏng của hệ điều hành và container có thể nói chuyện với hệ điều hành máy chủ để có được chức năng kernel ở đó. Và điều đó cho phép chúng ta có một container rất nhẹ.

Tất cả những gì nó có trong đó là mã ứng dụng và bất kỳ nhị phân và thư viện nào mà nó yêu cầu. Và những nhị phân và thư viện đó thực sự có thể được chia sẻ trên các container khác nhau nếu bạn muốn chúng cũng như vậy. Và điều này cho phép chúng ta làm, là một số thứ. Họ có thời gian khởi động nhanh hơn nhiều . Bạn không thể đứng lên một VM trong vài giây như thế. Và cũng như vậy, hạ chúng xuống nhanh chóng .. vì vậy chúng ta có thể tăng quy mô lên xuống rất nhanh và chúng ta sẽ xem xét điều đó sau.

Nhập mô tả hình ảnh ở đây

Mọi container đều nghĩ rằng nó đang chạy trên bản sao riêng của hệ điều hành. Nó có hệ thống tệp riêng, sổ đăng ký riêng, v.v ... đó là một loại lời nói dối. Nó thực sự được ảo hóa.



11

Tôi đã sử dụng Docker trong môi trường sản xuất và dàn dựng rất nhiều. Khi bạn đã quen với nó, bạn sẽ thấy nó rất mạnh mẽ để xây dựng một container đa và môi trường biệt lập.

Docker đã được phát triển dựa trên LXC (Linux Container) và hoạt động hoàn hảo trong nhiều bản phân phối Linux, đặc biệt là Ubuntu.

Docker container là môi trường bị cô lập. Bạn có thể thấy nó khi bạn phát toplệnh trong bộ chứa Docker đã được tạo từ hình ảnh Docker.

Bên cạnh đó, chúng rất nhẹ và linh hoạt nhờ cấu hình dockerFile.

Ví dụ: bạn có thể tạo hình ảnh Docker và định cấu hình DockerFile và nói rằng ví dụ khi nó đang chạy thì hãy quên 'this', apt-get 'that', chạy 'some shell script', đặt các biến môi trường, v.v.

Trong các dự án dịch vụ vi mô và kiến ​​trúc Docker là một tài sản rất khả thi. Bạn có thể đạt được khả năng mở rộng, khả năng phục hồi và độ đàn hồi với Docker, Docker swarm, Kubernetes và Docker Compose.

Một vấn đề quan trọng khác liên quan đến Docker là Docker Hub và cộng đồng của nó. Ví dụ, tôi đã triển khai một hệ sinh thái để theo dõi kafka bằng Prometheus, Grafana, Prometheus-JMX-Exporter và Docker.

Để làm điều đó, tôi đã tải xuống các bộ chứa Docker được cấu hình cho zookeeper, kafka, Prometheus, Grafana và jmx-collector sau đó gắn cấu hình của riêng tôi cho một số trong số chúng bằng các tệp YAML hoặc cho những người khác, tôi đã thay đổi một số tệp và cấu hình trong bộ chứa Docker và tôi xây dựng toàn bộ hệ thống để giám sát kafka bằng cách sử dụng Docker đa container trên một máy duy nhất với khả năng cách ly và khả năng mở rộng và khả năng phục hồi mà kiến ​​trúc này có thể dễ dàng di chuyển vào nhiều máy chủ.

Bên cạnh trang web Docker Hub còn có một trang web khác gọi là quay.io mà bạn có thể sử dụng để có bảng điều khiển hình ảnh Docker của riêng mình ở đó và kéo / đẩy đến / từ đó. Bạn thậm chí có thể nhập hình ảnh Docker từ Docker Hub để quay sau đó chạy chúng từ quay trên máy của riêng bạn.

Lưu ý: Học Docker ở nơi đầu tiên có vẻ phức tạp và khó khăn, nhưng khi bạn đã quen với nó thì bạn không thể làm việc mà không có nó.

Tôi nhớ những ngày đầu tiên làm việc với Docker khi tôi phát lệnh sai hoặc xóa các thùng chứa của tôi và tất cả dữ liệu và cấu hình nhầm.


6

Đây là cách Docker tự giới thiệu:

Docker là công ty thúc đẩy phong trào container và là nhà cung cấp nền tảng container duy nhất để giải quyết mọi ứng dụng trên đám mây lai. Các doanh nghiệp ngày nay chịu áp lực chuyển đổi kỹ thuật số nhưng bị hạn chế bởi các ứng dụng và cơ sở hạ tầng hiện có trong khi hợp lý hóa một danh mục ngày càng đa dạng của các đám mây, trung tâm dữ liệu và kiến ​​trúc ứng dụng. Docker cho phép sự độc lập thực sự giữa các ứng dụng và cơ sở hạ tầng và các nhà phát triển và các chuyên gia CNTT để mở khóa tiềm năng của họ và tạo ra một mô hình cho sự hợp tác và đổi mới tốt hơn.

Vì vậy, Docker là dựa trên container, có nghĩa là bạn có hình ảnh và container có thể chạy trên máy hiện tại của bạn. Nó không bao gồm hệ điều hành như VM , mà giống như một gói các gói làm việc khác nhau như Java, Tomcat, v.v.

Nếu bạn hiểu các container, bạn sẽ hiểu Docker là gì và nó khác với VM như thế nào ...

Vì vậy, những gì một container?

Một hình ảnh container là một gói phần mềm nhẹ, độc lập, có thể thực hiện được của một phần mềm bao gồm mọi thứ cần thiết để chạy nó: mã, thời gian chạy, công cụ hệ thống, thư viện hệ thống, cài đặt. Có sẵn cho cả ứng dụng dựa trên Linux và Windows, phần mềm được chứa sẽ luôn chạy giống nhau, bất kể môi trường. Các container cách ly phần mềm với môi trường xung quanh, ví dụ như sự khác biệt giữa môi trường phát triển và dàn dựng và giúp giảm xung đột giữa các nhóm chạy phần mềm khác nhau trên cùng một cơ sở hạ tầng.

Docker

Vì vậy, như bạn thấy trong hình bên dưới, mỗi container có một gói riêng và chạy trên một máy duy nhất chia sẻ hệ điều hành của máy đó ... Chúng an toàn và dễ vận chuyển ...


4

Có rất nhiều câu trả lời kỹ thuật hay ở đây thảo luận rõ ràng về sự khác biệt giữa VM và container cũng như nguồn gốc của Docker.

Đối với tôi, sự khác biệt cơ bản giữa VM và Docker là cách bạn quản lý việc quảng bá ứng dụng của mình.

Với VM, bạn quảng bá ứng dụng của mình và các phụ thuộc của nó từ một VM sang DEV tiếp theo sang UAT sang PRD.

  1. Thường thì các VM này sẽ có các bản vá và thư viện khác nhau.
  2. Không có gì lạ khi nhiều ứng dụng chia sẻ VM. Điều này đòi hỏi phải quản lý cấu hình và phụ thuộc cho tất cả các ứng dụng.
  3. Backout yêu cầu hoàn tác các thay đổi trong VM. Hoặc khôi phục nó nếu có thể.

Với Docker, ý tưởng là bạn gói ứng dụng của mình bên trong thùng chứa của chính nó cùng với các thư viện cần thiết và sau đó quảng bá toàn bộ vùng chứa dưới dạng một đơn vị.

  1. Ngoại trừ kernel, các bản vá và thư viện giống hệt nhau.
  2. Theo nguyên tắc chung, chỉ có một ứng dụng cho mỗi container giúp đơn giản hóa cấu hình.
  3. Backout bao gồm dừng và xóa container.

Vì vậy, ở cấp độ cơ bản nhất với máy ảo, bạn quảng bá ứng dụng và các phụ thuộc của nó dưới dạng các thành phần riêng biệt trong khi với Docker, bạn quảng bá mọi thứ trong một lần nhấn.

Và vâng, có vấn đề với các container bao gồm cả việc quản lý chúng mặc dù các công cụ như Kubernetes hoặc Docker Swarm đơn giản hóa rất nhiều nhiệm vụ.

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.