Sau khi đã làm quen với Docker, biết cách đóng gói ứng dụng thành image, khởi chạy container và kết nối nhiều dịch vụ bằng Docker Compose, phần lớn người học đều gặp một câu hỏi tự nhiên: nếu Docker đã giải quyết được việc chạy ứng dụng trong container, thì Kubernetes sinh ra để làm gì?
Câu trả lời có thể tóm gọn trong một mệnh đề: Docker giải quyết bài toán khởi chạy một container, còn Kubernetes giải quyết bài toán quản lý hàng nghìn container. Với một dự án nhỏ, Docker và Docker Compose thường là đủ. Nhưng khi ứng dụng phải phục vụ hàng triệu người dùng, chạy đồng thời trên nhiều máy chủ và phải sẵn sàng 24/7, sẽ xuất hiện những nhu cầu mà bản thân Docker không đáp ứng được. Chính khoảng trống này đã đưa Kubernetes trở thành chuẩn mực của ngành trong lĩnh vực điều phối container.
Khi nào Docker không còn đủ?
Hãy hình dung một cửa hàng trực tuyến. Ở giai đoạn đầu, kiến trúc của nó khá đơn giản: một máy chủ duy nhất chạy các container Web, API, PostgreSQL và Redis. Với lượng người dùng khiêm tốn, mô hình này hoạt động tốt.
Vấn đề nảy sinh khi hệ thống lớn dần. Số người dùng tăng lên, doanh nghiệp phát hành thêm ứng dụng di động, mở rộng sang nhiều khu vực địa lý, tải hệ thống tăng cao. Một máy chủ không còn kham nổi, buộc phải bổ sung máy chủ thứ hai, thứ ba, rồi sau vài tháng ứng dụng đã trải trên mười máy chủ. Kèm theo đó là hàng loạt bài toán vận hành mới.
Máy chủ hỏng thì sao? Giả sử năm container đang chạy trên một máy chủ và máy chủ đó ngừng phản hồi. Ai sẽ tự động khởi chạy lại các container đó trên một máy chủ khác?
Mở rộng ứng dụng bằng cách nào? Trong đợt khuyến mãi, lượng truy cập tăng gấp mười lần và cần thêm nhiều bản chạy của ứng dụng web. Với Docker, việc này phải làm thủ công. Với Kubernetes, chỉ cần thay đổi số lượng bản sao (replica).
Cập nhật không gián đoạn ra sao? Nếu chỉ đơn giản dừng container cũ rồi khởi chạy container mới, người dùng sẽ gặp lỗi trong khoảng thời gian chuyển giao. Quá trình cập nhật cần diễn ra tuần tự: khởi chạy phiên bản mới, xác nhận nó hoạt động, chuyển hướng lưu lượng sang phiên bản mới, rồi mới gỡ bỏ phiên bản cũ. Cơ chế này gọi là cập nhật cuốn chiếu (Rolling Update), và Kubernetes thực hiện nó một cách tự động.
Phân phối tải như thế nào? Khi mười container giống hệt nhau cùng chạy, cần một thành phần quyết định yêu cầu tiếp theo sẽ được xử lý bởi container nào. Đó là vai trò của bộ cân bằng tải, và Kubernetes đảm nhận nhiệm vụ này tự động.
Phục hồi sau sự cố bằng cơ chế nào? Khi một container bất ngờ dừng, Kubernetes phát hiện và tự động tạo lại container mới thay thế. Khả năng này được gọi là tự phục hồi (Self-healing).
Điểm chung của tất cả các tình huống trên là: chúng đòi hỏi một lớp quản lý đứng phía trên các container riêng lẻ, có khả năng quan sát toàn hệ thống và tự đưa ra quyết định. Đó chính là chỗ đứng của Kubernetes.
Kubernetes là gì?
Kubernetes, thường viết tắt là K8s, là một nền tảng quản lý container tự động. Cách viết tắt K8s xuất phát từ việc giữa chữ "K" đầu và chữ "s" cuối của từ Kubernetes có đúng tám ký tự.
Kubernetes chịu trách nhiệm cho các nhiệm vụ sau: khởi chạy container; mở rộng quy mô ứng dụng; phân phối tải; cập nhật ứng dụng không gián đoạn; tự động phục hồi sau sự cố; quản lý mạng và lưu trữ; và điều phối ứng dụng chạy đồng thời trên nhiều máy chủ. Nói cách khác, Kubernetes không thay thế container mà quản lý vòng đời của chúng ở quy mô lớn.
Điều phối container nghĩa là gì?
Thuật ngữ "điều phối" (orchestration) có nguồn gốc từ lĩnh vực âm nhạc, chỉ hoạt động của người nhạc trưởng điều khiển một dàn nhạc: bảo đảm các nhạc công cùng bắt đầu, giữ đúng nhịp và kết thúc đúng lúc. Áp dụng vào hạ tầng, mỗi container biết cách thực hiện phần việc của riêng nó, còn Kubernetes đóng vai trò điều phối: khởi chạy, dừng, thay thế, mở rộng và kết nối các container với nhau. Vì lý do này, Kubernetes được xếp vào nhóm hệ thống điều phối container (container orchestration).
Docker và Kubernetes có phải là đối thủ?
Một trong những hiểu lầm phổ biến nhất là cho rằng Kubernetes thay thế Docker. Thực tế không phải vậy. Docker tạo ra container, còn Kubernetes quản lý các container đó. Hai công cụ bổ trợ cho nhau chứ không cạnh tranh.
Về mặt lịch sử, Kubernetes từng làm việc trực tiếp với Docker Engine. Ngày nay, nó sử dụng chuẩn giao tiếp Container Runtime Interface (CRI) và có thể phối hợp với nhiều môi trường thực thi container khác nhau, chẳng hạn containerd hoặc CRI-O. Với người mới, điều quan trọng cần nắm là ranh giới trách nhiệm: Docker lo việc tạo ra container, Kubernetes lo vòng đời của container đó bên trong cụm.
Khi nào không cần đến Kubernetes?
Người mới thường mặc định rằng Kubernetes là bắt buộc cho mọi dự án. Điều này không đúng. Với các dự án cá nhân, website nhỏ, dịch vụ nội bộ hay ứng dụng học tập, Docker Compose thường đã đủ. Sử dụng Kubernetes trong những trường hợp này chỉ làm hạ tầng phức tạp thêm mà không mang lại lợi ích tương xứng. Một kỹ sư DevOps giỏi chọn công cụ phù hợp với bài toán, chứ không dùng công nghệ phức tạp nhất chỉ vì các doanh nghiệp lớn đang dùng nó. Đây là nguyên tắc thiết kế cần ghi nhớ ngay từ đầu.
Kiến trúc bên trong một cụm Kubernetes
Nhìn qua, kiến trúc Kubernetes có vẻ phức tạp vì đưa ra hàng loạt thuật ngữ mới: Cluster, Node, Pod, Deployment, ReplicaSet, Control Plane. Tuy nhiên, khi hiểu rõ nhiệm vụ của từng thành phần, bức tranh tổng thể sẽ trở nên mạch lạc.
Cluster: đơn vị làm việc cơ bản
Cluster (cụm) là một nhóm máy chủ được gộp thành một hệ thống thống nhất và do Kubernetes quản lý. Thay vì thao tác với từng máy chủ riêng lẻ, kỹ sư làm việc với cả cụm như với một đối tượng logic duy nhất. Chẳng hạn, thay vì quản lý năm máy chủ độc lập, Kubernetes nhìn nhận chúng như năm nút (Node) thuộc cùng một cụm. Bản thân cụm sẽ tự phân phối tải, giám sát trạng thái ứng dụng và tự động phục hồi khi có sự cố. Cluster do đó là đơn vị làm việc cơ bản trong Kubernetes.
Mỗi cụm Kubernetes gồm hai phần lớn: Control Plane và các Worker Node. Mỗi phần đảm nhận một vai trò riêng.
Control Plane: trung tâm điều khiển
Control Plane là tập hợp các thành phần đưa ra quyết định và quản lý toàn bộ cụm. Nó chịu trách nhiệm lập lịch bố trí ứng dụng, kiểm soát trạng thái cụm, mở rộng quy mô, xử lý yêu cầu của người dùng và lưu trữ cấu hình. Trong hầu hết trường hợp, kỹ sư DevOps tương tác với cụm thông qua Control Plane, ngay cả khi không ý thức rõ điều đó.
Worker Node: nơi ứng dụng thực sự chạy
Worker Node là máy chủ nơi các ứng dụng thực sự được khởi chạy. Mỗi Worker Node chứa ba thành phần chính: môi trường thực thi container (ví dụ containerd); tiến trình kubelet nhận lệnh từ Control Plane; và thành phần mạng kube-proxy bảo đảm cho các dịch vụ hoạt động.
Các đối tượng cốt lõi
Pod: đơn vị triển khai nhỏ nhất
Nhiều người lầm tưởng Kubernetes trực tiếp quản lý container. Thực chất, đối tượng cơ bản của Kubernetes là Pod. Pod là đơn vị triển khai nhỏ nhất trong Kubernetes; trong đa số trường hợp, một Pod chứa một container.
Đôi khi, một Pod có thể chứa nhiều container gắn kết chặt chẽ với nhau, ví dụ một container ứng dụng và một container thu thập log đi kèm. Mọi container trong cùng một Pod đều dùng chung một địa chỉ IP, chia sẻ không gian mạng, và có thể cùng sử dụng các volume lưu trữ.
Câu hỏi thường gặp là vì sao không chạy container trực tiếp. Lý do là Kubernetes cần giải quyết những bài toán phức tạp hơn nhiều so với việc chỉ khởi chạy một container: tự động thay thế container hỏng, mở rộng ứng dụng, di chuyển ứng dụng giữa các máy chủ, và nhóm nhiều container liên quan lại với nhau. Để làm được điều đó, Kubernetes bổ sung một lớp trừu tượng là Pod. Container trở thành một phần của Pod, và Pod mới là đối tượng do Kubernetes quản lý.
ReplicaSet: duy trì đúng số lượng Pod
Giả sử một ứng dụng web cần chạy đồng thời ba bản. ReplicaSet là thành phần liên tục so sánh giữa số lượng Pod mong muốn và số lượng Pod đang thực sự chạy. Nếu một Pod bất ngờ dừng, tổng số bản chạy giảm xuống dưới mức yêu cầu; ReplicaSet phát hiện chênh lệch và tự động tạo một Pod mới để khôi phục về đúng ba bản. Đây chính là nền tảng cho cơ chế tự phục hồi (Self-healing) của Kubernetes.
Deployment: lớp quản lý cấp cao
Mặc dù ReplicaSet có khả năng duy trì số lượng Pod, trong thực tế người ta hầu như không dùng nó trực tiếp mà thông qua Deployment. Deployment là đối tượng cấp cao hơn, quản lý chính ReplicaSet. Nó chịu trách nhiệm tạo ReplicaSet, cập nhật ứng dụng, quay lui về phiên bản trước khi cần, và thay đổi số lượng bản sao. Trên thực tế, kỹ sư DevOps làm việc với Deployment nhiều hơn bất kỳ đối tượng nào khác.
Scheduler: chọn máy chủ phù hợp
Khi bạn tạo một Deployment hoặc Pod, Kubernetes không khởi chạy container ngay trên máy chủ đầu tiên gặp được. Trước hết, kube-scheduler (một thành phần của Control Plane) sẽ vào cuộc để chọn Worker Node phù hợp nhất. Bản thân Pod không biết mình nên chạy ở đâu; Deployment chỉ khai báo trạng thái mong muốn, ví dụ cần ba bản của ứng dụng. Sau đó, Scheduler phân tích trạng thái toàn cụm và quyết định nút đích.
Scheduler cân nhắc nhiều tiêu chí khi chọn nút. Thứ nhất là tài nguyên khả dụng: nút phải còn đủ CPU, RAM, và khi cần cả GPU hoặc các tài nguyên chuyên biệt khác; nếu không đủ, Scheduler chuyển sang nút khác. Thứ hai là các ràng buộc và yêu cầu của Pod: nhà phát triển có thể chỉ định ứng dụng chỉ được chạy trên nút có SSD, có GPU, hoặc thuộc một vùng khả dụng nhất định. Thứ ba là phân bố tải: Scheduler cố gắng không dồn tất cả Pod lên cùng một máy chủ mà trải đều ra nhiều nút nhằm tránh quá tải cục bộ và tăng khả năng chịu lỗi.
Các đối tượng liên kết với nhau như thế nào?
Bốn đối tượng vừa trình bày tạo thành một chuỗi phân cấp: Deployment quản lý ReplicaSet, ReplicaSet quản lý các Pod, và mỗi Pod chứa Container.
Mỗi cấp đảm nhận một nhiệm vụ riêng. Deployment mô tả trạng thái mong muốn của ứng dụng. ReplicaSet duy trì đúng số lượng Pod. Pod là đơn vị triển khai nhỏ nhất. Container thực thi chính ứng dụng. Kiến trúc phân tầng này cho phép Kubernetes tự động giữ hạ tầng ở đúng trạng thái đã khai báo.
Điều gì diễn ra khi triển khai ứng dụng?
Giả sử kỹ sư áp dụng một cấu hình bằng lệnh kubectl apply -f deployment.yaml. Kubernetes khi đó thực hiện tuần tự các bước: Control Plane tiếp nhận mô tả ứng dụng; một Deployment được tạo ra; Deployment tạo ReplicaSet; ReplicaSet xác định số lượng Pod cần có; Scheduler chọn Worker Node phù hợp; kubelet nhận lệnh tạo Pod; môi trường thực thi container tải image về; và cuối cùng container khởi chạy. Kết quả là ứng dụng bắt đầu hoạt động.
Điều gì diễn ra khi có sự cố?
Giả sử một Worker Node ngừng hoạt động. Nếu Pod chỉ tồn tại trên máy chủ đó, Kubernetes phát hiện số bản sao không còn được bảo đảm. ReplicaSet báo cáo tình trạng này cho Deployment, Scheduler chọn một Worker Node khả dụng khác, và một Pod mới được tạo tự động trên máy chủ mới. Đối với người dùng cuối, ứng dụng gần như tiếp tục hoạt động không gián đoạn. Chính đặc tính này khiến Kubernetes trở thành công cụ phù hợp cho các hệ thống tải cao.
Từ Pod đến Service: bài toán truy cập ổn định
Đến đây, chúng ta đã biết container chứa ứng dụng nằm bên trong Pod. Tuy nhiên lại xuất hiện một vấn đề mới. Hãy hình dung bạn đã triển khai một ứng dụng web trong Kubernetes; nó khởi chạy thành công, người dùng sẵn sàng sử dụng, nhưng không thể kết nối tới. Nguyên nhân nằm ở cách Pod vận hành.
Vấn đề thứ nhất: Pod có thể biến mất bất cứ lúc nào
Đặc điểm cốt lõi cần hiểu là Pod là đối tượng tạm thời (ephemeral). Khi container kết thúc với lỗi, khi máy chủ hỏng, hoặc khi Deployment thực hiện cập nhật, Kubernetes sẽ xóa Pod cũ và tạo Pod mới. Pod mới mang một địa chỉ IP khác với Pod cũ. Nếu các ứng dụng khác đang trỏ tới IP cũ, kết nối sẽ đứt. Vì vậy, việc truy cập trực tiếp vào Pod theo IP gần như không bao giờ được khuyến nghị.
Vấn đề thứ hai: mở rộng quy mô
Giả sử ứng dụng chạy đồng thời ba bản. Người dùng làm sao biết nên kết nối tới Pod nào? Cần một đối tượng cung cấp một địa chỉ thống nhất và tự động phân phối yêu cầu giữa tất cả các Pod đang hoạt động. Đó chính là nhiệm vụ của Service.
Service là gì và tìm Pod bằng cách nào?
Service là đối tượng Kubernetes cung cấp một điểm truy cập ổn định tới một hoặc nhiều Pod. Có thể hiểu Service như một địa chỉ ảo giữ nguyên không đổi, ngay cả khi các Pod phía sau liên tục được tạo mới và xóa đi.
Vậy khi Pod thường xuyên tái tạo, Service dựa vào đâu để biết chuyển lưu lượng tới đâu? Câu trả lời nằm ở cặp cơ chế Labels và Selectors. Mỗi Pod có thể mang một tập nhãn, ví dụ app: nginx. Service khai báo một selector tương ứng, ví dụ chọn các Pod có nhãn app: nginx. Kubernetes tự động liên kết Service với mọi Pod mang nhãn phù hợp. Khi Deployment tạo một Pod mới với cùng nhãn đó, Pod này lập tức trở thành một phần của Service mà không cần cấu hình thêm. Labels vì thế là một trong những cơ chế quan trọng nhất của Kubernetes.
Cân bằng tải
Giả sử Deployment duy trì ba bản của ứng dụng. Khi có yêu cầu mới đến, Service phân phối lần lượt cho các Pod khả dụng: yêu cầu thứ nhất tới Pod 1, thứ hai tới Pod 2, thứ ba tới Pod 3, thứ tư quay lại Pod 1, và cứ thế tiếp tục. Đây là hình thức cân bằng tải đơn giản nhất. Nếu một Pod dừng, Service tự động loại nó khỏi danh sách khả dụng và tiếp tục chuyển yêu cầu tới các Pod còn lại; quá trình này thường hoàn toàn trong suốt đối với người dùng.
Ba loại Service thường dùng
Kubernetes hỗ trợ nhiều loại Service, nhưng trong thực tế ba loại sau được dùng phổ biến nhất, mỗi loại giải quyết một bài toán riêng.
ClusterIP là loại mặc định. Nó cung cấp một địa chỉ IP cố định chỉ truy cập được từ bên trong cụm Kubernetes; người dùng từ Internet không thể tiếp cận. Mọi ứng dụng bên trong cụm có thể gọi tới nó qua tên dịch vụ hoặc IP nội bộ. ClusterIP lý tưởng cho các dịch vụ nội bộ như PostgreSQL, Redis, RabbitMQ, các API nội bộ và microservice. Chẳng hạn, ứng dụng web có thể gọi cơ sở dữ liệu chỉ bằng tên postgres mà không cần biết IP cụ thể của Pod nào. Nhờ tính tiện dụng này, ClusterIP là loại Service phổ biến nhất.
NodePort được dùng khi ứng dụng cần truy cập từ bên ngoài nhưng chưa cần đến một bộ cân bằng tải đầy đủ. Kubernetes mở một cổng nhất định trên mỗi Worker Node; người dùng truy cập theo địa chỉ dạng http://IP_của_nút:30080, yêu cầu đi qua Service rồi tới các Pod. NodePort thường xuất hiện trong phòng lab tại nhà, khi học Kubernetes, trong Minikube hoặc các môi trường thử nghiệm nhỏ, và ít được dùng cho hệ thống sản xuất.
LoadBalancer được dùng trên các nền tảng đám mây. Khi tạo một Service loại này, Kubernetes yêu cầu nhà cung cấp đám mây (chẳng hạn AWS, Azure hoặc Google Cloud) tự động dựng một bộ cân bằng tải bên ngoài. Người dùng chỉ tương tác với một địa chỉ công khai duy nhất, còn bộ cân bằng tải tự phân phối yêu cầu tới tất cả các bản của ứng dụng. Đây là loại Service thường gặp trong các cụm Kubernetes trên đám mây.
Bảng 1. So sánh ba loại Service phổ biến
| Loại | Trường hợp sử dụng |
|---|---|
| ClusterIP | Giao tiếp nội bộ giữa các dịch vụ bên trong cụm |
| NodePort | Thử nghiệm, học tập, phòng lab quy mô nhỏ |
| LoadBalancer | Công bố ứng dụng ra Internet qua nhà cung cấp đám mây |
Trên thực tế, đa số dịch vụ nội bộ dùng ClusterIP, còn các ứng dụng web đối ngoại thường được công bố qua Ingress (hoạt động phía trên Service). Vì vậy đối tượng LoadBalancer được dùng ít hơn so với hình dung ban đầu của nhiều người.
Ingress: cổng vào thống nhất cho lưu lượng HTTP(S)
Service đã cung cấp cho ứng dụng một địa chỉ ổn định bên trong cụm, phân phối yêu cầu giữa các Pod và che giấu việc IP của Pod thay đổi. Nhưng khi cụm chạy đồng thời nhiều ứng dụng web, chẳng hạn một cửa hàng trực tuyến, một cổng thông tin doanh nghiệp, một blog và một API, cách tiếp cận tạo riêng một Service loại LoadBalancer cho mỗi ứng dụng bộc lộ nhiều nhược điểm: mỗi ứng dụng cần một IP công khai riêng; trên đám mây, mỗi bộ cân bằng tải thường bị tính phí riêng; việc quản lý chứng chỉ HTTPS trở nên phức tạp; và các quy tắc định tuyến bị phân tán trên nhiều bộ cân bằng tải khác nhau.
Với dự án nhỏ, điều này có thể chấp nhận được, nhưng trong các cụm lớn, cách làm đó nhanh chóng trở nên bất tiện. Cần một thành phần duy nhất tiếp nhận toàn bộ lưu lượng HTTP(S) đi vào và tự quyết định chuyển nó tới ứng dụng nào. Đó là lý do Ingress ra đời.
Ingress là gì?
Ingress là đối tượng Kubernetes mô tả các quy tắc định tuyến cho yêu cầu HTTP và HTTPS tới các dịch vụ bên trong cụm. Service trả lời câu hỏi "làm sao tới được Pod?", thì Ingress trả lời câu hỏi "cần chuyển yêu cầu này tới Service nào?".
Chẳng hạn, có thể định tuyến theo tên miền: shop.example.com tới Shop Service, blog.example.com tới Blog Service, api.example.com tới API Service. Hoặc định tuyến theo đường dẫn URL: example.com/shop, example.com/blog, example.com/api tới các Service tương ứng. Người dùng chỉ thấy một tên miền hoặc một IP công khai duy nhất, còn Ingress tự động chuyển tiếp yêu cầu tới đúng dịch vụ.
Ingress và Ingress Controller
Một hiểu lầm phổ biến của người mới cần được làm rõ: bản thân đối tượng Ingress không tiếp nhận kết nối mạng và không tự chuyển tiếp lưu lượng. Ingress chỉ là một tập quy tắc. Việc thực thi các quy tắc đó thuộc về một ứng dụng riêng gọi là Ingress Controller. Chính Ingress Controller mới tiếp nhận yêu cầu HTTP và HTTPS đi vào, phân tích quy tắc trong Ingress, xác định Service đích và chuyển tiếp yêu cầu tới ứng dụng. Nếu cụm chưa cài đặt Ingress Controller, đối tượng Ingress sẽ không hoạt động.
Các triển khai phổ biến gồm: NGINX Ingress Controller (thông dụng nhất); Traefik (dễ cấu hình, phổ biến trong dự án nhỏ); HAProxy Ingress; và Kong Ingress Controller (thường dùng như một API Gateway).
Ví dụ định tuyến theo tên miền
Giả sử cụm chạy hai ứng dụng: cửa hàng trực tuyến và blog. Khi người dùng mở trình duyệt và truy cập https://shop.example.com, Ingress Controller nhận yêu cầu HTTP, đối chiếu với quy tắc Ingress rồi chuyển yêu cầu tới Shop Service, sau đó Shop Service phân phối yêu cầu giữa các Pod của cửa hàng. Khi người dùng truy cập https://blog.example.com, cũng chính Ingress Controller đó chuyển yêu cầu sang Blog Service. Đáng chú ý, cả hai ứng dụng có thể dùng chung một IP công khai và một Ingress Controller.
Dưới đây là một quy tắc Ingress đơn giản:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
spec:
rules:
- host: shop.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: shop-service
port:
number: 80
- host: blog.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: blog-service
port:
number: 80Trong thực tế, các cấu hình như vậy có thể chứa hàng chục hoặc hàng trăm quy tắc định tuyến. Ngoài ra, Ingress còn cho phép gắn chứng chỉ HTTPS, chuyển hướng từ HTTP sang HTTPS, giới hạn truy cập theo địa chỉ IP và tùy chỉnh nhiều tham số khác.
Lỗi thường gặp của người mới
Lỗi thứ nhất là quên Ingress Controller. Chỉ tạo đối tượng Ingress là chưa đủ; nếu cụm chưa cài Ingress Controller, việc định tuyến sẽ không diễn ra.
Lỗi thứ hai là tạo một LoadBalancer riêng cho từng ứng dụng. Cách làm này nhanh chóng làm tăng chi phí hạ tầng và gây khó khăn cho việc vận hành. Trong nhiều trường hợp, chỉ cần một Ingress Controller và một bộ cân bằng tải bên ngoài là đủ.
Lỗi thứ ba là không dùng HTTPS. Ngay cả với dự án thử nghiệm, việc tập thói quen công bố ứng dụng qua HTTPS là hữu ích. Trong nhiều cụm Kubernetes, chứng chỉ được cấp và gia hạn tự động nhờ cert-manager kết hợp với Let's Encrypt, nên việc hỗ trợ HTTPS gần như không đòi hỏi can thiệp thủ công.
Kết luận
Service đã giải quyết bài toán quan trọng đầu tiên: cung cấp cho ứng dụng một điểm truy cập ổn định bên trong cụm và biết cách phân phối tải giữa các Pod. Ingress tiến thêm một bước, cho phép công bố đồng thời nhiều ứng dụng web qua một địa chỉ bên ngoài duy nhất, quản lý định tuyến yêu cầu và xử lý HTTPS một cách tập trung.



