Tổng quan về khóa học
Trong khóa học này, mình sẽ đi qua một số chủ đề chính như hình bên dưới. Trong những chủ đề này có những chủ đề mới và những chủ đề đã đề cập qua trong khóa học của anh XuanThuLabChanel. Những phần đã nói qua thì sẽ không nói lại mà chỉ ghi chú thêm những mục mới, chưa đề cập ở những phần trước đó.
What is the container
Những khái niệm căn bản về container đã được đề cập khá nhiều ở trong bài docker_overview và ở p1 trong chuỗi bài học từ anh XuanThuLabChanel. Trong phần này chúng ta sẽ đi qua một số khái niệm cũng như một số chủ đề:
namespaces
Khái niệm:
Namespace - không gian tên:
-
Là một trong những thành phần cơ bản của container.
-
giới hạn những gì các process có thể thấy và truy cập trên hệ thống.
-
định nghĩa vị trí inode trên đĩa.
inode là một cấu trúc dữ liệu trong một hệ thống tập tin Unix - phong cách mô tả của một tập tin hệ thống đối tượng như một tập tin hoặc một thư mục. Số lượng nút trong tài khoản bằng với số lượng tệp và thư mục có trên đó. Hay có thể hiểu,inodes = số files + folder
. -
Thông qua một namespace, nhiều process khác nhau có thể chia sẻ, giao tiếp với nhau.
-
Khi một container bắt đầu chạy, nó sẽ tạo ra một namespace mới cho để các process chạy trong hộp cát (sandboxes) chạy. Bằng cách phân bổ namespace dựa trên các pid, tại thời điểm chạy, một process sẽ truy cập vào namespace tương ứng với pid của mình, việc này giúp cho process có cảm giác chỉ một mình nó chạy trên hệ thống.
Một số loại biến thể của namespace
Trong namespace định nghĩa một số biến thể:
Mount (mnt):
mount namespace
điều khiển các mount point
. Khi tạo, các liên kết từ mount namespace
hiện tại được sao chép sang không gian tên mới, nhưng các mount point
được tạo sau đó không truyền giữa mount namespace
. Cờ sao chép được sử dụng để tạo không gian tên mới thuộc loại này là CLONE_NEWNS
- viết tắt của “NEW NameSpace”. Thuật ngữ này không mang tính mô tả (vì nó không cho biết loại không gian tên nào sẽ được tạo) bởi vì mount namespaces là loại namespace đầu tiên và tại thời điểm, các nhà thiết kế không lường trước được sẽ có bất kỳ loại namespaces
nào khác.
Process ID(pid):
PID namespaces
cung cấp những process với tập pid độc lập với những namespace khác. Các PID namespace có thể lồng vào nhau nghĩa là: mỗi process được tạo trong một namespace sẽ có 1 pid, và pid này sẽ được thấy bởi các process ở trong namespace hiện tại ra cho đến namespace đầu tiên. Nghe có vẻ giống như trong công ty, một nhân viên mới vào sẽ có một thông tin và định danh riêng, những thông tin này sẽ được biết bởi sếp anh ta, sếp của sếp, sếp của sếp của sếp 🤣🤣🤣.
Process đầu tiên sẽ được gán PID là 1, nó có vị trí giống như chủ tich hội đồng quản trị của công ty, từ trên nhìn xuống có thể thấy tất cả những process khác, và có quyền “đuổi” tất cả những process dưới trướng của mình.
User ID (user):
User namespace
là một tính năng để cung cấp khả năng phân quyền và phân nhóm người dùng trên nhiều process, khả nằng đã sẵn có từ kernel 3.8. Với quyền admin, có thể xây dựng một container có vẻ như có quyền admin nhưng không thực sự cấp các đặc quyền nâng cao cho các process của người dùng. Giống như PID namespace
, user namespace
dùng được lồng vào nhau và mỗi user namespace mới được coi là con của user namespace đã tạo ra nó.
User namespace
chứa một bảng ánh xạ để chuyển đổi các user ID từ container sang hệ thống. Điều này cho phép, ví dụ, người dùng root có user id 0
trong container nhưng thực sự được hệ thống coi là user id 1.400.000
để kiểm tra quyền sở hữu. Một bảng tương tự được sử dụng để ánh xạ group id
và kiểm tra quyền sở hữu.
Để tạo điều kiện thuận lợi cho việc cô lập đặc quyền của các hành động admin, mỗi loại namespace được coi là thuộc sở hữu của một user namespace dựa trên user namespace đang hoạt động tại thời điểm tạo. Người dùng quyền admin trong user namespace thích hợp sẽ được phép thực hiện các hành động admin trong loại namespace đó. Ví dụ: nếu một process có quyền quản trị để thay đổi địa chỉ IP của giao diện mạng, nó có thể làm như vậy miễn là user namespace của chính nó giống với (hoặc tổ tiên của) user namespace sở hữu network namespace. Do đó user namespace ban đầu có quyền kiểm soát quản trị đối với tất cả các loại user namespace trong hệ thống.
Network (net):
Network namespace
ảo hóa network stack
. Khi được tạo, network namespace
chỉ chứa một loopback interface
. Mỗi network interface (là physical hay virtual) thể hiện chính xác một namespace và có thể di chuyển giữa các namespace với nhau.
Một namespace sẽ có tập các địa chỉ IP riêng, chứa những routing table, socket listing, connection tracking table, firewall, và những resources liên quan tới network khác.
Khi hủy một không gian tên mạng sẽ phá hủy bất kỳ giao diện ảo nào bên trong nó và di chuyển bất kỳ giao diện vật lý nào bên trong nó trở lại không gian tên mạng ban đầu.
Interprocess Communication (ipc):
ipc namespace
dùng để cô lập các process trong giao tiếp. Điều này ngăn không cho các quá trình trong các vùng tên IPC khác nhau sử dụng, chẳng hạn như nhóm hàm SHM để thiết lập phạm vi bộ nhớ dùng chung giữa hai quá trình. Thay vào đó, mỗi quá trình sẽ có thể sử dụng cùng một số nhận dạng cho một vùng bộ nhớ dùng chung và tạo ra hai vùng riêng biệt như vậy.
UTS:
UTS namespace (UNIX Time-Sharing)
cho phép một hệ thống duy nhất có vẻ như có các tên miền và máy chủ lưu trữ khác nhau cho các quá trình khác nhau. “Khi một quy trình tạo một vùng tên UTS mới … tên máy chủ và miền của vùng tên UTS mới được sao chép từ các giá trị tương ứng trong vùng tên UTS của người gọi”.
- Còn nhiều loại biến thể khác, chúng ta có thể xem chúng tại đây.
Unshare tool
- là công cụ giúp chúng ta có thể chạy một process và yêu cầu nó tạo ra một namespace mới.
|
|
What happens when we share a namespace?
Chúng ta có thể liệt kê tất cả những namespace bằng lệnh:
|
|
Một công cụ khác chúng ta có thể dùng đó là nsenter
dùng để gán một process vào một không gian tên đã tồn tại, công cụ này sẽ hữu dụng khi debug.
|
|
Container images
Container images chúng ta đã được học kĩ trong các bài trước, ở đây có một số chú ý nhỏ nhỏ:
- Những images chứa dữ liệu thô (metadata) để làm cơ sở để xây dựng những image khác.
- Chúng ta đã biết, images sẽ có nhiều layer, có 1 layer gốc và những layer sau là quá trình chúng ta cài đặt, thiết lâp thêm môi trường khi chạy contaier được sinh ra từ image ban đầu. Ở đây, mỗi tar file được xem như một layer, và tất cả các tar file được giải nén tới cùng môt vị trí thì
Learn Docker Foundation
Deploying First Docker Container
Phần này chúng ta cũng đã trình bày kĩ ở những phần trước, theo sơ đồ, ta có thể thấy, để build một docker container, chúng ta có 5 bước chính:
Step1:
Tìm kiếm image thích hợp thông qua lệnhdocker search
, tải về bằngdocker pull
và chạy bằngdocker run
Step2:
Kiểm tra những container đang chạy:docker ps
: liệt kê tất cả các container đang chạy và các thông tin về nódocker inspect
: cung cấp thông tin chi tiết về một container đang chạy.docker logs
: những message mà container đã log khi chạy.
Step3:
Truy cập vào container đang chạy. Ở đây, đối với một container đang chạy để lấy port của nó ta có thể dùng một trong 2 lệnh:
|
|
Step 4
: Thiết lập chia sẻ dữ liệu giữa container và host cũng như các container với nhau, đảm bảo dữ liệu cần thiết sẽ được lưu khi container bị xóa.Step 5
: Chạy container, ở đây có một số thiết lập như-d
để chạy nền hay-it
để tương tác với shell.
Những phần này chúng ta đã được học ở những bài trước.
Deploy Static HTML Website as Container
Tóm tắt cho phần này
Create Dockerfile
Docker file là gì?
Dockerfile
là một dạng file text, không có phần đuôi mở rộng, chứa tập các lệnh mô tả các bước để build một docker image.
Cú pháp của một dockerfile.
Cấu trúc chung của một dockerfile có dạng
INSTRUCTION arguments
Trong đó:
INSTRUCTION:
là tên các chỉ thị có trong Dockerfile, mỗi chỉ thị thực hiện một nhiệm vụ nhất định, do dockerfile quy định. Mặc định, lệnh này phải được viết bằng chữ IN HOAarguments
: nội dung mà lệnh thực hiện
Ví dụ:
|
|
Dòng lệnh 1 để định nghĩa base images và dòng lệnh 2 để chỉ thị copy tất cả nội dụng tại vị trí hiện tại vào một địa chỉ cụ thể trên container, ở đây là /usr/share/nginx/html
.
Các chỉ thị chính trong dockerfile
- FROM
Chỉ định rằng image nào sẽ được làm cơ sở trong quá trình build image để thực thi những câu lệnh tiếp theo. Các image này được tải về từ Public Repository hoặc Private Reppository riêng của mỗi người.
Chỉ thị FROM là bắt buộc và phải được đặt trên cùng của Dockerfile
Cú pháp:
|
|
Ví dụ:
|
|
- LABEL
Chỉ thị LABEL được dùng để thêm các thông tin meta vào Docker Image khi chúng được build. Chúng tồn tại dưới dạng cặpkey-value
, lưu dưới dạng chuỗi. Có thể chỉ định nhiều label cho một Docker Image, mỗi cặpkey-value
là duy nhất.
Nếu cùng 1 key mà có nhiều value thì value gần nhất sẽ đè những value trước đó.
Cú pháp:
|
|
Có thể khai báo metadata cho Image theo từng dòng chỉ thị hoặc có thể tách ra khai báo thành từng dòng riêng biệt.
Để xem thông tin meta của một image, ta dùng lệnh docker inspect
|
|
- MAINTAINER
Dùng để khai báo thông tin tác giả của dockerfile
Cú pháp:
|
|
Ví dụ:
|
|
- RUN
Dùng để chạy một lệnh nào đó trong quá trình build image, thường là các câu lệnh Linux. Tùy vào image gốc được khai báo trong FROM thì sẽ có các câu lệnh tương ứng.
Cú pháp:
|
|
Ví dụ
|
|
Ở shell form, có thể thực hiện nhiều câu lệnh bằng dấu \
:
|
|
- ADD
Thực hiện sao chép các tệp, thư mục từ máy đang build hoặc remote file từ src và thêm chúng vào filesystem của image dest
Cú pháp:
|
|
trong đó:
src
có thể là một hoặc nhiều file, thư mụcdest
là địa chỉ tuyệt đối hoặc được chỉ định bởiWORKDIR
Ví dụ:
|
|
- COPY
Giống như ADD là copy file từ thư mụcsrc
đếndest
, khác ở việc COPY không hỗ trợ copy các remote file URLs từ các nguồn trên mạng.
Cú pháp:
|
|
- ENV
Dùng để khai báo các biến môi trường. Các biến được khai báo dưới dạngkey-value
bằng các chuỗi. Chúng sẽ được sử dụng trong các chỉ thị tiếp theo của Dockerfile.
Cú pháp:
|
|
Ví dụ:
|
|
Các biến môi trường có thể thay đổi với lệnh docker run
|
|
Các command được sử dụng ENV:
|
|
- CMD
Dùng để định nghĩa các câu lệnh được chạy sau khi container được khởi động từ image vừa build.
Cú pháp:
|
|
Ví dụ:
|
|
- USER
Thiết lập username hoặc UID để sử dụng khi chạy image và khi chạy các lệnh có trongRUN, CMD, ENTRYPOINT
sau đó.
Cú pháp:
|
|
Ví dụ:
|
|
Build Docker Image
Ta dùng lệnh docker build
để tiến hành build docker image từ Dockerfile vừa tạo.
Cú pháp:
|
|
Ví dụ:
|
|
-t
ở đây cho phép chỉ định tên image và tag của nó.
RUN
Sau khi đã tạo thành image, ta chỉ cần run nó với lệnh docker run
để tiến hành chạy container.
Tổng kết
Phần này chúng ta đi qua 2 nhánh chính là What is the container
và Container images
, ở đó chủ yếu là những kiến thức chúng ta đã thảo luận qua.
Ngoài ra, chúng ta đã đi qua một vài nhánh nhỏ của Docker Foundation
. Vì phần này liên quan đến mục đích công việc của tôi, nên tôi sẽ học kĩ cũng như tìm hiểu kĩ phần này. Bài tiếp theo chúng ta sẽ cùng đi qua những nhánh kế tiếp.