Gần đây cả Docker và M$ đều thông báo là có thể chạy Docker Container trên Windows Server. Với mình đây là tin khá là shock vì trước giờ mình luôn cho rằng việc chạy docker engine trực tiếp trên Windows (không thông qua máy ảo Linux) hoặc tạo một container với OS không phải là Linux là điều không thể. Thế nên mình quyết định là tìm hiểu xem nó là cái gì.
Trước khi bắt đầu thì quay ngược trở lại các phiên bản trước đây của docker và xem thử một số mối liên hệ giữa docker với Windows như thế nào.
1. Năm phút giới thiệu
Về container thì nó không phải là một công nghệ mới (không phải do Docker phát minh ra mà nó đã có từ trước đó khá lâu rồi với các ứng dụng như chroot trên Linux, jails trên BSD, zone trên Solaris hoặc một công nghệ khá phổ biến là OpenVZ. Đặc điểm của container là share kernel giữa guest (container) và host (máy thật) nên tất nhiên OS của container và máy thật phải giống nhau.
Để có thể tạo ra container với đặc tính như: (thực ra các công nghệ ảo hóa cũng tương tự)
- Isolation (user, process, filesystem …)
- Limit resource (memory, cpu, I/O …)
- Security
- …
Trước phiên bản 0.9, Docker (engine) sử dụng LXC như một layer trung gian để giao tiếp với Kernel Linux. Kernel của Linux cung cấp một số tính năng giúp tạo container với các đặc tính trên như namespace, cgroups, Apparmor, SELinux … Kể từ sau phiên bản 0.9, Docker cung cấp một driver là libcontainer cho phép Docker engine giao tiếp trực tiếp xuống kernel của Linux mà không cần thông qua LXC (LXC là một tùy chọn)
Như ta thấy là để có thể tạo ra một container có khả năng độc lập với máy thật, có thể giới hạn được tài nguyên và cung cấp tính bảo mật thì Docker cần Linux (cần các đặc tính của nhân Linux)
2. Docker với Windows
Ta sẽ nói về 2 component cụ thể đó là docker client và docker engine.
2.1 Docker client
Với docker client, có một bài blog vào năm 2014. Bài này nói rằng có thể chạy docker cli (docker client) trên Windows.
Trong bài mình có giới thiệu là docker sử dụng kiến trúc client-server.
Docker Client sẽ nói chuyện với Docker Engine thông qua một RESTful API, để thực thi các lệnh như build, ship và run một container.
Nên bản chất là docker client hoàn toàn không phụ thuộc vào Linux. Mã nguồn của docker viết bằng Go, có thể compile ra binary và chạy trên Windows bình thường, xem thêm pull request
2.2 Docker engine
Ở những phiên bản đầu tiên, để có thể chạy docker engine trên Windows bạn có thể sử dụng 2 cách
- Tự cài virtualbox, vmware, sau đó cài một máy ảo Linux (Ubuntu, CentOS) và cài docker engine lên máy ảo này
- Sử dụng boot2docker (tinycore), boot2docker sẽ làm hết cho bạn, kể cả việc giao tiếp từ Windows vào VM rồi vào trong container luôn
Ở phiên bản sau này (1.12) docker cung cấp Docker for Mac and Docker for Windows
Điểm khác biệt là bạn không nhất thiết phải dùng VirtualBox. Đối với Mac thì Docker Engine sẽ chạy trên xhyve Virtual Machine (VM), xhyve là một giải pháp ảo hóa lightweight trên OSX. Đối với Windows thì Docker Engine chạy trên công nghệ ảo hóa của Windows là Hyper-V. Cả 2 đều dùng Alpine Linux, một distribution vô cùng nhỏ ngọn.
Tóm lại, để chạy docker engine với container là Linux trên Windows thì kiểu gì ta cũng phải chạy qua máy ảo.
3. Windows Container vs Docker
Bắt nguồn từ 2 bài này Windows Containers on Windows Server và Build And Run Your First Docker Windows Server Container. Mình muốn giải quyết và trả lời 3 vấn đề:
- Windows Container là gì?
- Làm thế nào có thể tạo ra một container Windows (không phải là Linux như ở đầu bài nói).
- Làm thế nào để có thể sử dụng Docker Engine trên Windows (Docker engine có thể quản lý các Windows Container)
3.1 Windows Container
Trong phần quick_start, M$ giới thiệu Windows container tương tự các đặc tính của container ở trên mục [1], nghĩa là nó cũng isolated, cũng limit resource và tạo ra một môi trường portable.
Windows Container được chia làm 2 loại:
- Windows Server Containers: Cung cấp một môi trường độc lập cho ứng dụng với kĩ thuật namespace isolation. Windows Server Container sẽ share kernel với máy thật (host) và với tất cả các container khác
- Hyper-V Containers: mở rộng cơ chế isolation được cung cấp bởi Windows Server Containers bằng cách chạy mỗi container trên một máy ảo (VM) được tối ưu. Tất nhiên khi đã chạy container trên máy ảo thì kernel của Hyper-V Container không nhất thiết phải share với máy thật. (Mỗi hyper-v container sẽ được chạy trên một máy ảo, 10 container thì có 10 máy ảo, chưa rõ là OS cho máy ảo là gì)
Tóm lại: Windows Container mang đặc tính của container, và tất nhiên container guest và host phải share kernel với nhau. Windows Container sẽ chạy OS là Windows và đồng nghĩa là nó share kernel Windows với máy chủ.
3.2 Làm thế nào có thể tạo ra một container Windows
Để có thể chạy một container Windows thì OS của container và OS của host phải giống nhau. Ở đây tất nhiên OS của cả hai đều là Windows.
Nhưng vấn đề là để có thể cung cấp khả năng isolated và limit resource thì ta cần ít nhất 2 tính năng được hỗ trợ bởi kernel Linux đó là namespace và cgroups HOẶC Windows phải làm cách nào đó để hỗ trợ tính năng nào đó có chức năng tương tự vào kernel của mình.
Theo tài liệu của M$ thì khả năng là các tính năng này mới được thêm vào từ phiên bản Windows 10 và Windows Server 2016
Ngoài ra mình có tìm được một hình minh họa
Từ hình này mình đoán rằng M$ đã phát triển thêm một số tính năng cho kernel Windows tương tự kernel Linux để hỗ trợ việc tạo Container. Job object có chức năng tương tự cgroups cho việc giới hạn tài nguyên, Object Namespace, Process Table, Networking tương tự với namespace cho việc isolation ….
3.3 Làm thế nào để có thể sử dụng Docker Engine trên Windows
Docker Engine sẽ giúp chúng ta các tác vụ liên quan đến việc quản lý các đối tượng trong hệ sinh thái container như container, image, volume, network. Nói chung khi tay chạy các lệnh docker run, docker build, docker ps thì docker client sẽ giao tiếp với docker engine để trả về cho ta các tác vụ tương ứng.
docker engine viết bằng Go, nên cũng có thể build ra binary và chạy trên Windows được. Vấn đề là chỉ cần Kernel hỗ trợ các tính năng tương tự Linux là được. Vấn đề này đã được M$ chủ động giải quyết trong kernel của họ, như mục 3.2 mình có giải thích. Đây là commercial partnership giữa Docker Inc và M$
Đến đây thì phát sinh một số câu hỏi:
- Docker engine cho Linux và Windows là chung một source code hay là hai dự án độc lập.
- Kernel Windows đã hỗ trợ tốt các tính năng cgroup, namespace, unionfs như Linux chưa. Nếu docker engine chung source code thì liệu code có phình ra thêm hay không?
Mình không tìm được câu trả lời nhưng cá nhân mình nghĩ khả năng cao là docker engine cho 2 platform này đều dùng chung source code. Nếu chung source code thì sẽ có thể phát sinh các vấn đề như:
- Hai nền tảng khác nhau, nên khả năng không thể hỗ trợ tốt cả 2 nền tảng như nhau được
- Code phình ra và có thể không handle tốt vì M$ mới phát triển các tính năng để hỗ trợ container
4. Kết luận
- Container là công nghệ mà container guest và container host phải share kernel với nhau. Nên dù là Windows Container hay Linux Container thì guest và host phải giống nhau về OS. Nghĩa là Windows container chỉ chạy trên host Windows, Linux container chỉ chạy trên host Linux.
- Việc Docker hỗ trợ Windows Container làm phong phú thêm hệ sinh thái Container. Tuy nhiên nếu tích hợp chung codebase thì có thể làm mọi thứ trở nên phức tạp hơn
- Từ phiên bản 1.12 với việc tích hợp sắn tính năng orchestration vào Docker Engine, docker gặp khá nhiều phản ứng không tốt từ cộng đồng. Nên quan điểm cá nhân của mình là không đánh giá cao việc này.
PS: Phần Windows Container mình không có thử nghiệm việc tạo và chạy, vì mình không xài Windows. Nên có nhiều nhận định là dựa trên những tài liệu của M$ và Docker.
Techtalk via Kipalog