#175 - Kubernetes: Tại sao bạn nên giữ cho container image nhỏ nhất có thể?
Những bài viết hay
Kubernetes best practices: Why you should keep your container images as small as possible
Docker giúp việc xây dựng các containers trở nên dễ dàng. Chỉ cần đặt một Dockerfile chuẩn vào thư mục của bạn, chạy lệnh docker build và thế là docker image của bạn đã được tạo ra.
Nhược điểm của sự đơn giản này là dễ dàng tạo ra các docker image khổng lồ chứa đầy những thứ bạn không cần, bao gồm cả các lỗ hổng bảo mật tiềm ẩn.
Quá trình build docker image khác nhau tùy thuộc vào việc bạn đang sử dụng ngôn ngữ thông dịch (interpreted language) hay ngôn ngữ biên dịch compiled language.
Các ngôn ngữ được thông dịch, chẳng hạn như Ruby, Python, Node.js, PHP, ... gửi mã nguồn thông qua trình thông dịch chạy code. Điều này mang lại cho bạn lợi ích của việc bỏ qua bước biên dịch, nhưng có nhược điểm là yêu cầu bạn gửi trình thông dịch cùng với code. May mắn thay, hầu hết các ngôn ngữ này đều cung cấp các base image được build sẵn, chứa một môi trường nhẹ, cho phép bạn chạy các container nhỏ hơn nhiều. Bằng cách sử dụng các base image nhỏ, chẳng hạn như Alpine, bạn có thể cắt giảm đáng kể kích thước container của mình.
Các ngôn ngữ biên dịch như Go, C, C ++, Rust, Haskell, ... tạo ra các tệp nhị phân có thể chạy mà không cần nhiều dependencies ngoài. Điều này có nghĩa là bạn có thể tạo tệp nhị phân trước và đưa vào docker image mà không cần phải vận chuyển các công cụ để tạo tệp nhị phân như trình biên dịch.
Để tạo và lưu trữ image, chúng ta có thể kết hợp Google Container Builder và Google Container Registry. Container Builder rất nhanh và tự động push image vào Container Registry. Các nền tảng như Google Kubernetes Engine có thể pull image một cách an toàn từ Google Container Registry mà không cần bất kỳ cấu hình bổ sung nào.
Các image nhỏ không chỉ giúp quá tình build, push và pull nhanh hơn rất nhiều, nó cũng giúp chúng ta giảm thiểu các nguy cơ bảo mật khi image có nhiều dependencies.
Is software development really a dead-end job after age 35-40?
Có lẽ rất nhiều bạn băn khoăn về vấn đề "tuổi đời" của một lập trình viên. Liệu rằng ở tuổi 35-40 chúng ta có thể code tiếp, trao dồi những kỹ thuật công nghệ mới nữa hay không? Hay sẽ bị những thế hệ trẻ hơn đào thải?
Góc Distributed System
Cách dropbox giảm latency thông qua DNS-based load balancing
Tính năng cơ bản nhất của Dropbox là đồng bộ file từ máy cá nhân tới Dropbox's server. Tốc độ upload/download file phụ thuộc vào nhiều yếu tố, trong đó việc quyết định client kết nối tới server nào là quan trọng. Để làm việc đó, Dropbox xử lý ngay ở DNS query giúp client chọn được server "gần nó nhất". Thời kì đầu, Dropbox xử lý bài toán này đơn giản là geolocation-based, tức là DNS response trả về cho client điểm PoP (Point of Presence) gần nhất theo địa lý kết hợp kĩ thuật Anycast, được mô tả ở bài viết phụ (link số 2). Tuy nhiên, có rất nhiều corner case trong thực tế cho thấy cách làm này không tối ưu. Ví dụ được mô tả kĩ trong bài, nôm na là những vị trí địa lý gần đại dương nhưng không có kết nối cáp ngầm (submarine cables) tới điểm PoP ở bờ đại dương phía bên kia, thì traffic lại phải đi 1 vòng trái đất.
Dropbox đã khắc phục bằng việc xác định "điểm gần nhất" dựa vào network latency thay vì geolocation, được hợp tác phát triển cùng với công ty NS1. Cụ thể trong Dropbox client sẽ thường xuyên thực hiện ngầm (background job) những truy vấn DNS ngẫu nhiên tới rất nhiều subdomain khác nhau của Dropbox (*.dropbox.com) và xây dựng bản đồ latency. Việc ngẫu nhiên tới nhiều subdomain giúp loại bỏ những kết quả cached từ DNS servers. Bản đồ latency được thiết lập bắt nguồn từ 3 thông tin:
IP của DNS resolver của client (dropbox không biết được IP của client). Phía server biết được IP này thông qua DNS ECS extension được một số bên hỗ trợ như Facebook Sonar/Doppler hoặc Google, OpenDNS.
DNS resolver trả ra kết quả.
P75 latency từ client tới tất cả các PoP của Dropbox.
Cách xây dựng bản đồ latency không được mô tả chi tiết, nhưng kết quả của nó thì chỉ là 1 file json với hai thông tin cơ bản: network của client và PoP được chọn (có P75 latency thấp nhất). Bài viết cũng đưa ra một số kết quả thực tế để chứng minh. Mời bạn đọc bài viết sau đây
Nếu bạn quan tâm tới thiết kế ban đầu của Dropbox với Geolocation-based, sử dụng BGP Anycast, bạn có thể xem bài viết sau đây
Góc Database
Các bạn nào đã làm việc với Cassandra thì hẳn là sẽ nghe qua các thuật ngữ như memtable, commitlog, SSTable, compaction, ...
Hiểu một cách đơn giản, chúng ta có thể hình dung hoạt động ghi (write) của Cassandra trên một node như sau:
Dữ liệu khi được ghi sẽ được ghi vào commitlog (hoạt động tương tự như Write Ahead Log). Sau đó sẽ được ghi tiếp vào Memtable, một cơ chế tổ chức lưu tạm dữ liệu trên memory.
Sau một khoảng thời gian, dựa theo cơ chế được lựa chọn, dữ liệu sẽ được ghi xuống đĩa thành các SSTable (Sorted String Table). Mỗi SSTable là một tập hợp các file có nhiều chức năng như chứa dữ liệu, chứa index, chứa bloom filter, ...
Sau một khoảng thời gian, các SSTable riêng lẻ sẽ được gộp lại để cho quá trình đọc hiệu quả hơn, tránh tình trạng trùng lắp dữ liệu (do một dòng có thể được cập nhật nhiều lần, mỗi lần sẽ được lưu trên các file SSTable khác nhau.
Để hiểu rõ hơn về cấu trúc của Memtable xem nó bao gồm các thành phần nào, cách tổ chức như thế nào, các bạn có thể đọc thêm bài blog này nhé.
Góc Lập Trình
Đề ra tuần này
Cho một mảng các số nguyên không âm, bạn được khởi đầu ở vị trí đầu tiên trong mảng. Mỗi phần tử trong mảng thể hiện số bước nhảy tối đa tại vị trí đó. Mục tiêu của bạn là nhảy tới vị trí cuối cùng trong mảng với số bước nhảy ít nhất.
Ví dụ:
Input: nums = [2,3,1,1,4]
Output: 2 (Chỉ cần nhảy 2 bước, bước đầu tiên từ index 0 tới index 1, sau đó nhảy tới vị trí cuối cùng)
Lời giải tuần trước
Chúng ta luôn có 2 chiến lược cơ bản để duyệt một cây, đó là Depth First Search (DFS) và Breadth First Search (BFS).
Chiến lược dùng DFS được phân ra các cách duyệt preorder, inorder, và postorder.
Với BFS, chúng ta sẽ duyệt qua cây theo từng level, từ trên xuống dưới. Các node ở level cao hơn sẽ được duyệt thông qua các node ở level thấp hơn.
Để giải quyết bài toán tuần trước, một phương án cơ bản đó là lưu các node vào một cấu trúc dữ liệu queue (FIFO) thông qua chiến lược duyệt BFS. Các node cùng level sẽ được lưu vào queue và sử dụng để duyệt tới các node ở level tiếp theo.
Giải thuật sẽ đơn giản như sau:
Tuy nhiên bài toán sẽ trở nên phức tạp hơn một chút nếu chúng ta muốn duyệt theo kiểu zigzag. Ta sẽ chỉnh sửa lại một chút đoạn code ở trên như sau:
Vậy là chúng ta đã có thể in các node của một cây theo chiều ngang, tuy nhiên trong trường hợp chúng ta muốn in theo chiều dọc thì sao? Hãy coi đây như một bài tập nhỏ để bạn đọc cùng tìm hiểu nhé.
Code & Tools
GRON A tool written in Go that transforms JSON into more easily greppable assignments
dadbob A Vim plugin for interacting with numerous databases
This Week Sponsors
KMS Technology là một trong những công ty dịch vụ phần mềm hàng đầu, với 12 năm hoạt động và phát triển trên thị trường Châu Âu, Mỹ, và khu vực APAC; hiện có 05 văn phòng tại Atlanta (Mỹ), TP.HCM và Đà Nẵng.
Số lượng KMSer hiện tại đã lên đến 1000+ và vẫn đang trên đà phát triển, mở rộng cho nhiều dự án lớn, quy mô toàn cầu với các chiến dịch tuyển dụng hấp dẫn, phúc lợi ấn tượng.
Nếu bạn đang tìm kiếm một cơ hội mới, thì dưới đây là những cơ hội khó bỏ lỡ.
Các vị trí khác tại KMS Technology Careers
Quotes
No man burdens his mind with small matters unless he has some very good reason for doing so.
- Sherlock Holmes in Sir Arthur Conan Doyle’s “A Study in Scarlet” (1887)