Docker Engine
Để sử dụng Docker thì bạn có thể bở qua bài này.Để thực sự master một thứ gì đó, bạn cần hiểu rõ cơ chế hoạt động của nó.
Đây là bài lý thuyết, không có bài tập thực hành.
Docker Engine
- Docker engine là nhân phần mềm để chạy và quản lý container. Nó gần giống với ESXi ở VMware. Docker engine là thiết kế module với nhiều bộ phận có thể thay đổi.
- Docker engine như là một động cơ xe ô tô- đều được tạo bởi nhiều bộ phận chuyên biêt:
- Động cơ ô tô được tạo từ nhiều phần chuyên biệt hoạt động cùng nhau để xe có thể đi đươc - Động cơ xi lanh, Bugi, van, trục cam,….
- Docker engine cũng được tạo từ các tool chuyên biệt mà chạy cùng nhau để chạy và quản lý container - APIs, runtime, shim, …..
- Các thành phần chính cấu tạo nên Docker Engine là : Docker Client, Docker daemon, containerd, runc.
Docker Engine - The Deep Dive
runc
- Docker inc tham gia rất nhiều để xác định các thông số và phát triển runc theo các thông số đó
- runc được coi là một trình command-line wrapper nhỏ, nhẹ cho libcontainer.
- runc dùng để tạo container nhanh, là một công cụ container runtime độc lập. Nó tạo, chạy contaner tốt nhưng lại không có nhiều chức năng.
- runc là low-level container runtime
containerd
- containerd (phát âm container-dee) là một công cụ dùng để quản lý vòng đời của các container:
start | stop | pause | rm ...
.
- containerd có sẵn như một daemon cho Linux và Window.
- containerd nằm giữa Docker daemon và runc trong các tầng OCI.
- containerd không chỉ quản lý vòng đời của container, sau này nó được phát triển để làm được nhiều nhứ khác, như là quản lý image. Lý do là để containerd dễ sử dụng trong các sự án khác. Tuy nhiên, các chức năng khác của containerd là dạng mô đun có thể dùng hoặc không.
- containerd là high-level container runtime
Start một container ( ví dụ).
- Lệnh
docker container run
sau chạy một container từ alpine
image:
docker container run --name vidu -it alpine sh
- Khi bạn gõ lệnh như trên vào Docker CLI, Docker client sẽ convert chúng thành API payload phù hợp và post chúng vào các API endpoint đúng,
- API được triển khai trên Docker daemon sau khi nhận lệnh tạo một container, nó liên hệ đến containerd thông qua CRUD-style API qua gRPC. Lưu ý, Docker daemon không chứa bất kì một đoạn code nào để chạy container.
- containerd không thể tạo container mà nó convert image thành một gói OCI và yêu cầu runc dùng nó để tạo container.
- runc giao tiếp với OS kernel để tập hợp các cấu trúc cần thiết để tạo một container( namespace, cgroup,… ). Container process sẽ khởi động như một process con của runc và ngay sau khi nó hoạt động, runc sẽ thoát.
- quá trình tạo container được tóm tắt ở hình sau.
Lợi ích của mô hình này.
- Container runtime tách biệt với Docker daemon nên có thể bảo trì và nâng cấp Docker daemon mà không ảnh hưởng đến những container đang chạy
- Trước đây khi mà container runtime được triển khai trên daemon thì mỗi khi cập nhật Docker (cập nhật thường xuyên), docker daemon cập nhật sẽ kill hết các container đang chạy.
shim.
- shim quan trọng trong quá trình tách biệt một container đang chạy với daemon.
- Khi tạo một một container nghĩa là tạo ra một runc process mới để chạy container process như process con của runc. Nhưng ngay sau khi container được tạo thì runc process sẽ thoát.
- Khi runc thoát, container shim process thay thế runc trở thành process cha cho container. Nhiệm vụ của shim:
- giữ bất kì STDIN và STDOUT mở cho đến khi daemon khởi động lại, do đó container không bị đóng
- báo cáo trạng thái thoát của container cho daemon
Nó triển khai trên Linux ntn
- dockerd (the Docker daemon)
- docker-containerd (containerd)
- docker-container-shim (shim)
- docker-runc (runc)
Chapter summary
The Docker engine is modular in design and based heavily on open-standards from the OCI.
The Docker daemon implements the Docker API which is currently a rich, versioned, HTTP API that has developed alongside the rest of the Docker project.
Container execution is handled by containerd. containerd was written by Docker, Inc. and contributed to the CNCF. You can think of it as a container supervisor that handles container lifecycle operations. It is small and lightweight and can be used by other projects and third-party tools. For example, it’s poised to become the default, and most common, container runtime in Kubernetes.
containerd needs to talk to an OCI-compliant container runtime to actually create containers. By default, Docker uses runc as its default container runtime. runc is the de facto implementation of the OCI container-runtime-spec and expects to start containers from OCI-compliant bundles. containerd talks to runc and ensures Docker images are presented to runc as OCI-compliant bundles.
runc can be used as a standalone CLI tool to create containers. It’s based on code from libcontainer, and can also be used by other projects and third-party tools.
There is still a lot of functionality implemented in the Docker daemon. More of this may be broken out over time. Functionality currently still inside of the Docker daemon include, but is not limited to: the API, image management, authentication, security features, core networking, and volumes.
The work of modularizing the Docker engine is ongoing