Khi mà kỷ nguyên điện toán đám mây trở nên phổ biến, các doanh nghiệp bắt đầu thực hiện một cuộc di dời cơ sở hạ tầng và kiến trúc của họ sang các nền tảng này, và cũng là lúc phải quan tâm đến các vấn đề container hoá và điều phối container. Khi xu hướng này ngày càng phát triển mạnh mẽ, những cái tên lớn xuất hiện để làm tiêu chuẩn chung tiêu biểu như Docker và Kubernetes, đã tạo nên một cuộc cách mạng cho phát triển phần mềm trên quy mô lớn.
Bất kể bạn đang là một dev web, phân tích dữ liệu, quản lý sản phẩm hay gì nữa thì bạn cũng cần đến kiến thức về Docker và Kubernetes.
Docker là một nền tảng cho container hoá, còn Kubernetes là nền tảng cho điều phối container, cả hai đều là những công cụ cơ bản cho phát triển phần mềm.
Hôm nay ta sẽ tìm hiểu về:
- Docker là gì, container là gì và tại sao phải dùng chúng?
- Kubernetes là gì và tại sao phải dùng nó?
- Sự khác biệt giữa Docker và Kubernetes
- Docker và Kubernetes: Tốt hơn khi kết hợp với nhau
- Sử dụng Docker
- Sử dụng Kubernetes
Docker là gì và tại sao phải dùng nó
Dễ hiểu thì, Docker giúp mọi người dễ dàng triển khai một ứng dụng trên cùng một môi trường mà không cần lo về các phụ thuộc (dependencies) hay các vấn đề về hệ điều hành vì Docker cung cấp hệ điều hành của riêng nó. Ví dụ:
- Trước khi có Docker: bạn xây dựng một trang web Laravel + Vue + MySQL, thì khi phía tester muốn kiểm thử ứng dụng này, họ phải cài đặt PHP, node.js và MySQL. Nếu không ứng dụng sẽ không hoạt động.
- Sử dụng Docker: lúc này tester sẽ chạy trên container của Docker, nó sẽ tải tất các phụ thuộc cần thiết để ứng dụng hoạt động, tuy nhiên nó làm điều đó trên Docker chứ không phải hệ điều hành máy của bạn.
Có thể nói Docker hoạt động giống như một VM nhưng gọn nhẹ và linh hoạt hơn.
Chi tiết hơn
Docker là một nền tảng container hoá, nó đóng gói ứng dụng của bạn và tất cả phụ thuộc của nó thành một docker container. Nó là một tập hợp các sản phẩm platform-as-a-service được thiết kế để giải quyết các vấn đề trong xu hướng phát triển DevOps. Docker giúp dễ dàng tạo, triển khai và chạy ứng dụng bằng cách dụng container.
Container là thứ giúp Docker trở nên phổ biến với các dev. Nó tạo ra một lớp ứng dụng trừu tượng đóng gói ứng dụng và tất cả phụ thuộc cần thiết để chạy nó: hệ điều hành, công cụ, thư viện hệ thống, runtime, …
Container chiếm ít dung lượng hơn so với VM, nhưng có thể xử lý nhiều ứng dụng và yêu cầu ít VM và hệ điều hành hơn.
Kubernetes là gì và tại sao phải dùng nó
Kubernetes(k8’s) là một làn sóng mới trong điện toán đám mây, nó là một công cụ quản lý container mạnh mẽ có thể tự động triển khai và quản lý container.
Khi nói đến việc vận hành các container trong thực tế, bạn có thể làm việc với hàng chục, thậm chí hàng nghìn container. Các container này cần được triển khai, quản lý, kết nối và cập nhật; nếu bạn phải làm điều này theo cách thủ công, sẽ phải cần có cả một nhóm chuyên trách việc này.
Và để chạy được các container, bạn cần có khả năng:
- Tích hợp và sắp xếp các phần module.
- Mở rộng hay thu hẹp quy mô dựa trên yêu cầu.
- Tạo dung sai phân vùng.
- Cung cấp khả năng giao tiếp trên cụm.
Ở đây ta có thể hỏi: không phải một container sẽ làm tất cả những điều đó sao? Câu trả lời là các container chỉ là một phần nhỏ của toàn bộ. Những lợi ích thực sự đạt được nhờ vào các công cụ được đặt trên các container đó - như Kubernetes. Những công cụ này ngày nay được gọi là container schedulers.
Sự khác biệt giữa Docker và Kubernetes
Điều đầu tiên cần phải làm rõ rằng chúng là hai công nghệ khác nhau được thiết kế để hoạt động cùng nhau. Chúng không phải là những công cụ cạnh tranh vì vậy không nên có nhầm lẫn rằng “tôi có nên dùng cái này thay cho cái kia” hay “cái nào tốt hơn”. Cả hai đều có vai trò riêng biệt trong DevOps và thường được kết hợp sử dụng cùng nhau:
- Docker được dùng để truyển đổi ứng dụng của bạn thành container. Nó dùng cho đóng gói và gửi ứng dụng.
- Kubernetes mặt khác dùng như một container scheduler. Được sử dụng để triển khai và tuỳ chỉnh quy mô ứng dụng.
Docker và Kubernetes: tốt hơn khi đi cùng nhau
Hai công nghệ được thiết kế để hoạt động cùng nhau và khi chúng làm điều đó thì đấy chính là giấc mơ của các DevOps. Như đã đề cập trước đó, chỉ chạy các contaienr trong quá trình production là chưa đủ, chúng cần phải được quản lý và Kubernetes cung cấp một số tính năng tuyệt vời giúp làm việc với các container dễ dàng hơn. Kubernetes cung cấp những thứ như tự động mở rộng quy mô, kiểm tra tình trạng và cân bằng tải, những thứ rất quan trọng để quản lý vòng đời của container.
Điều quan trọng là ứng dụng của bạn phải trở thành container, nhưng đừng quên bước tiếp theo; bạn sẽ vận hành các container của mình ở quy mô như thế nào trong quá trình production? Nếu câu trả lời Kubernetes, thì tuyệt vời rồi đấy.
Bắt đầu với Docker
Các khái niệm cơ bản trong Docker
Có một vài khái niệm cơ bạn mà bạn cần học trong Docker:
- Container
- Image
- Registry
Containers
Một container là thứ cuối cùng mà bạn muốn chạy và lưu trữ trong Docker. Bạn có thể xen nó như một máy ảo nếu bạn muốn.
Từ quan điểm chung, một container chạy bên trong máy chủ Docker tách biệt với các container khác và thậm chí cả hệ điều hành máy chủ. Nó không thể nhìn thấy các container khác, bộ nhớ vật lý hoặc nhận các kết nối đến trừ khi được bạn thiết lập. Nó chứa mọi thứ cần thiết để chạy ứng dụng của bản: thông tin về hệ điều hành, package, runtime, file, biến môi trường, đầu vào và đầu ra tiêu chuẩn.
Máy chủ Docker thông thường của bạn sẽ trông giống như thế này - một máy chủ cho nhiều container:
Như trên hình, việc có có hai container app2
là bình thường; trường hợp này thường là khi máy chủ lưu trữ một bản phát hành (release) và một phiên bản thử nghiệm (dev). Có nghĩa là bạn có thể lưu trữ cả hai phiên bản trên cùng một máy chủ.
Images
Bất kỳ container nào đang chạy đều được tạo từ một image. Image mô tả mọi thứ cần thiết để tạo container; nó là một mẫu cho các container. Bạn có thể tạo nhiều container nếu cần từ một image duy nhất.
Registries
Image được lưu trữ trong một registry. Trong ví dụ trên, image app2
được sử dụng để tạo hai container. Mỗi container có vòng đời riêng và cả hai đều có chung một gốc: image của chúng từ registry. Bức tranh tổng quan như sau:
Thiết lập và chạy Docker
Chọn Docker dựa trên yêu cầu
Trong môi trường production chạy các container lưu trữ các ứng dụng quan trọng, bạn muốn các quản trị viên của mình cài đặt Docker Enterprise.
Tuy nhiên, trên máy dev của bạn hoặc máy CD/CI, bạn có thể sử dụng Docker Engine Community hoặc Docker Desktop miễn phí tùy thuộc vào loại máy của bạn. Nói ngắn gọn:
Sử dụng | Sản phẩm |
---|---|
Máy dev | Docker Engine Community/Docker Desktop |
Server nhỏ | Docker Engine Community |
Ứng dụng quan trọng/cốt lõi | Docker Engine Enterprise/Kubernetes |
Hello World
Dù bạn cài đặt phiên bản nào, bạn cũng có thể kiểm tra cài đặt của mình bằng cách chạy lệnh sau trong một dòng lệnh (terminal của bạn trên Linux hoặc PowerShell trên Windows):
docker run hello-world
Nó sẽ pull một image và hiển thị văn bản output như sau:
Hello from Docker!
This message shows that your installation appears to be working correctly.
Cài đặt Docker - Window, Linux, Mac
Thiết lập Docker trên Windows 10
Docker Desktop yêu cầu phiên bản Windows 10 64-bit Professional hoặc Enterprise, vì nó dựa trên Hyper-V. Nếu bạn có phiên bản Windows dành cho máy tính để bàn không đáp ứng các yêu cầu, bạn có thể sử dụng Docker Toolbox cũ hơn dựa trên VirtualBox. Trước khai cài đặt Docker Desktop cần nhớ các điều quan chạy:
- enable Hyper-V
- enable ảo hoá phần cứng trên BIOS
- Sau đó thực hiện theo đường link dưới đây
Trong khi cài đặt, bạn sẽ được nhắc sử dụng Windows hay Linux container. Nên dùng các Linux container vì:
- Bạn có thể thay đổi quyết định của mình bất kỳ lúc nào sau đó, chỉ cần click chuột phải vào biểu tượng Docker trên thanh công cụ và chọn “Switch to Windows containers…”
- Hiện tại, hầu hết các container image đều dựa trên Linux.
Thiết lập Docker trên Linux
Ở đây có nhiều Docker package khả dụng khác nhau mà bạn có thể cài đặt:
Dù bạn sử dụng hệ điều hành Linux nào thì cũng có các bước sau cài đặt phổ biến ở đây. Hãy chắc chắn rằng bạn đọc chúng một cách cẩn thận. Kiểm tra kỹ chúng nếu bạn không thể chạy thử nghiệm hello-world thành công.
Thiết lập Docker trên Mac
Docker Desktop yêu cầu Mac OS Sierra 10.12 trở lên. Nếu bạn có phiên bản macOS cũ hơn, bạn có thể sử dụng Docker Toolbox cũ hơn dựa trên VirtualBox.
Tạo Docker image đầu tiên
Như chúng ta đã nói trước đó, các container được tạo từ các image. Hãy cùng khám phá cách bạn có thể tạo container cho riêng mình. Bên trong image, chúng ta có thể đặt các chương trình của mình và các phụ thuộc của chúng để có thể tạo ra nhiều container từ những image đó.
Tạo một Docker image đơn giản
Dockerfile
Docker Image được tạo bằng lệnh docker build
và file Dockerfile. Dockerfile chứa các hướng dẫn về cách tạo image.
Dockerfile có thể có bất kỳ cái tên nào. Đặt tên cho nó là Dockerfile giúp người khác hiểu mục đích của nó dễ dàng hơn khi họ nhìn thấy file đó trong dự án của bạn. Điều đó cũng có nghĩa là bạn không cần phải nêu tên file khi sử dụng lệnh docker build
.
Bây giờ, hãy tạo image cơ bản cho container hiển thị thông báo “hello world” khi container chạy.
Trước tiên, hãy tạo một file có tên Dockerfile mô tả cách image của bạn sẽ được tạo. Dockerfile luôn bắt đầu bằng lệnh FROM
vì mọi image đều dựa trên một image cơ sở khác. Đây là một tính năng mạnh mẽ vì nó cho phép bạn mở rộng các image có thể đã phức tạp.
Vì ở đây chỉ cần một kết xuất văn bản đơn giản, ta có thể sử dụng image Debian Linux. Đây là Dockerfile:
FROM debian:8
Nó chưa đủ. Mặc dù ta đã có được nền tảng Debian Linux, nhưng ta chưa chạy bất kỳ lệnh nào có thể hiển thị “hello world”. Điều này có thể thực hiện bằng cách sử dụng lệnh CMD
. Lệnh CMD
chỉ định file thực thi nào được chạy khi một container được tạo bằng image của bạn và cung cấp các đối số tùy chọn.
Dưới đây là một Dockerfile được cải tiến tạo image dựa trên Debian Linux và hướng dẫn nó chào người dùng của khi một container được tạo:
FROM debian:8
CMD ["echo", 'Hello world']
Lưu ý rằng cả chương trình sẽ chạy và các đối số của nó đều được cung cấp dưới dạng một mảng chuỗi JSON. Để tạo image từ Dockerfile, ta cần chạy lệnh docker build
. Để thực hiện việc này, tôi nhập lệnh sau vào terminal của mình trong thư mục chứa Dockerfile:
docker build -t hello .
Ở đây -t
được sử dụng ở phía trước của image mong muốn. Một image có thể được tạo mà không có tên, nó sẽ có một ID duy nhất được tạo tự động, vì vậy nó là một tham số tùy chọn trên lệnh docker build
.
Lưu ý dấu chấm ở cuối lệnh trên. Nó chỉ định đường dẫn nào được sử dụng làm bối cảnh để build (sẽ nói thêm về điều này ở phần sau) và nơi dự kiến sẽ tìm thấy Dockerfile. Nếu Dockerfile của chúng ta có tên khác hoặc ở ở nơi khác, ta có thể thêm chuyển đổi -f
để cung cấp đường dẫn.
Lệnh docker build
vừa tạo một image có tên là hello. Image đó được lưu trữ cục bộ trên máy tính và bạn có thể chạy nó như cách bạn làm với bất kỳ image nào khác:
docker run --rm hello
Bây giờ, bạn có thể public image của mình để những người khác chạy các container dựa trên nó. Chúng ta sẽ xem cách thực hiện điều đó sau một thời gian ngắn nhưng hiện tại, hãy tập trung vào việc tạo image.
Cho đến hiện tại đây là những gì chúng ta đã được thực hiện:
- Đã tạo một image
- Đã tạo một file có tên Dockerfile
- Chạy lệnh docker build
- Chạy một container từ image đã tạo
Vậy điều này có ý nghĩa là gì; chạy một container tương đương với việc khởi động một máy hoàn toàn mới và sau đó chuyển nó vào thùng rác. Để in thông báo “Hello world”, về cơ bản, chúng ta có một máy tính mới, yêu cầu nó thực hiện lệnh echo, sau đó chuyển nó vào thùng rác. Docker làm cho máy tính ghi-và-quên trở nên rẻ tiền. Tất nhiên, điều này là quá mức cần thiết cho một mục đích đơn giản như vậy, nhưng nó vẫn đúng ngay cả khi chúng ta cài đặt các framework hoặc di chuyển các file xung quanh bên trong các container của chúng ta; đó là một tính năng tuyệt vời. Hầu hết sức mạnh Docker của bạn sẽ đến khi bạn hiểu bạn có thể tạo và dọn rác các máy tính ảo bị cô lập dễ dàng như thế nào.
Publish Docker Image
Một Docker Registry về cơ bản là một nơi lưu trữ image để cung cấp các tính năng sau:
- Khả dụng để lưu trữ nhiều image khác nhau.
- Khả dụng để lưu trữ các tag khác nhau cho cùng một image.
- Một
HTTP API
cho phép push image từ một máy để tạo nó, hoặc pull image đến một máy để chạy container từ các image này. - Kết nối
TLS-secured
đến API theo trật tự đến tránh tấn công MITM(Man in the middle).
Có rất nhiều registry có sẵn. Bạn có thể sử dụng Docker Hub công khai hoặc sử dụng registry riêng của bạn. Trong mọi trường hợp, quy trình gắn tag và public image của bạn vẫn giống nhau đối với mọi regitry.
Cho dù bạn chọn registry nào, việc public image là một quá trình gồm ba bước:
- Build image của bạn (docker build) với tên tiền tố thích hợp hoặc tag (docker tag) hiện có một cách thích hợp.
- Đăng nhập vào Registry (docker login).
- Push image vào Registry (docker push).
Bắt đầu với Kubernetes
Pods
Một pod là đơn vị nhỏ nhất của một ứng dụng trong Kubernetes. Trước khi bắt đầu, ta cần làm rõ một thứ là một pod không bằng với một container trong Docker. Một pod có thể là nhiều container, nếu bạn đến từ thế giới Docker thuần, điều này có thể hơi khó hiểu. Nếu một pod có thể có nhiều hơn một container, thì nó hoạt động như thế nào? Có một số giới hạn mà chúng ta cần phải biết. Một pod có những điều sau đây:
- Một địa chỉ IP duy nhất
- Localhost dùng chung
- Không gian IPC dùng chung
- Phạm vi cổng mạng dùng chung
- Dung lượng dùng chung
Các container trong một pod có thể nói chuyện thông qua localhost, trong đó giao tiếp pod-to-pod có thể thực hiện thông qua các services.
ReplicaSets
Trong phần này, ta sẽ xem xét trường hợp các pod không khả dụng, tức là nếu chúng chết nó sẽ là chấm hết cho chúng ta. Nếu ta muốn 3 phiên bản cùng pod đang chạy khả dụng.
Đây là lúc chúng ta cần đến các trình điều khiển dự phòng.
Trách nhiện chính của trình điều khiển dự phòng là ngăn chặn việc failure xảy ra, nó bao gồm việc đặt các kiểu tài nguyên pod và điều khiển chúng. Ta lấy ví dụ, như muốn triển khai 4 pod x, trong thời gian này ta tạo một tập dự phòng. Một tập dự phòng có số định nghĩa pod cần cho chạy, trong trường hợp này là 4. Nếu một trong các pod này fail, trình điều khiển dự phòng sẽ tạo một pod mới và một lần nữa ta sẽ có 4 pod đang chạy.
Services
Nếu bạn muốn kết nối đến các pod của chúng ta, ta sẽ cần tạo một service. Trong kubernetes, một service là một mạng trừu tượng trên một tập hợp các pod. Điều này cho phép lưu lượng truy cập đến bộ cân bằng tải. MỘt service cho phép Kubernetes thiết lập một bảng ghi DNS cho các pod. Như đã đề cập trước đó, mỗi pod có một địa chỉ IP riêng biệt
Triển khai
Kiểu tài nguyên triển khai đặt trong toàn bộ tập dự phòng và có thể quản lý chúng. Vậy tại sao ta lại muốn quản lý một tập dự phòng? Nếu bạn cần cập nhận hoặc cần thay thế một tập dự phòng. Hành động này sẽ rút gọn thời gian cho ứng dụng của bạn.
Một tiện ích nữa của Kubernetes là tính khả dụng cao. Việc triển khai cho phép ta