Tuyển dụng
Viettel IDC

OOMKiIled là gì? Cách chuẩn đoán và khắc phục Lỗi Exit Code 137

27/07/2026

Một container đang hoạt động êm ả trên hệ thống Kubernetes bỗng dưng bị khai tử không báo trước, không trải qua quá trình đóng ứng dụng an toàn graceful shutdown, mà chỉ để lại dòng trạng thái OOMKiIled cùng mã lỗi exit code 137. 

Bài viết dưới đây, Viettel IDC giải thích chi tiết bản chất OOMKiIled là gì, phân tích các nguyên nhân kỹ thuật cốt lõi và hướng dẫn cách chẩn đoán, khắc phục triệt để cho từng trường hợp cụ thể.

OOMKilled là gì? Cách chuẩn đoán và khắc phục Lỗi Exit Code 137

OOMKiIled là gì?

OOMKiIled (viết tắt của Out Of Memory KiIled) là một trạng thái hệ thống cho biết nhân hệ điều hành Linux đã phải cưỡng chế chấm dứt một container vì nó đang tiêu thụ lượng bộ nhớ RAM vượt quá mức giới hạn được cấp phép.

Khi sự cố này xảy ra, container luôn kết thúc vòng đời với mã lỗi exit code 137. Con số này mang ý nghĩa kỹ thuật rất rõ ràng: 128 là mã cơ sở báo lỗi hệ thống cộng với 9 là mã tín hiệu của lệnh SIGKILL. Điều này phản ánh chính xác việc tiến trình bị nhân Linux buộc dừng ngay lập tức, không cho phép ứng dụng có thêm bất kỳ giây phút nào để dọn dẹp bộ nhớ hay lưu lại các trạng thái đang xử lý dở dang.

Trong kiến trúc Kubernetes, mỗi container được quản lý thông qua hai thông số cấu hình bộ nhớ:

- Memory Request: Mức bộ nhớ tối thiểu mà hệ thống cam kết dành riêng cho container khởi động.

- Memory Limit: Ngưỡng bộ nhớ tối đa mà container tuyệt đối không được phép vượt qua.

Cơ chế giám sát này được thực thi bởi cgroups, một tính năng cốt lõi của nhân Linux giúp kiểm soát chặt chẽ lượng tài nguyên phần cứng. Khi một container chạm ngưỡng memory limit, thành phần OOM KiIler bên trong nhân Linux sẽ lập tức can thiệp, đánh dấu tiến trình đang vi phạm và gửi tín hiệu SIGKILL để kết liễu nó nhằm bảo vệ sự ổn định của toàn bộ máy chủ Node.

4 Nguyên nhân phổ biến gây ra trạng thái OOMKiIled

Khai báo Memory Limit quá thấp so với thực tế

Đây là nguyên nhân kinh điển nhất. Giá trị giới hạn bộ nhớ được khai báo trong tệp tin cấu hình thấp hơn lượng RAM mà ứng dụng thực sự cần để duy trì hoạt động. Sự cố này thường bắt nguồn từ việc đội ngũ phát triển đo lường mức tiêu thụ bộ nhớ trong môi trường thử nghiệm với tải lượng rất nhỏ, dẫn đến việc thiết lập thông số quá khắt khe khi ứng dụng bước ra môi trường sản xuất thực tế production.

Hiện tượng rò rỉ bộ nhớ Memory Leak

Nếu mã nguồn ứng dụng tồn tại lỗi rò rỉ bộ nhớ, lượng RAM bị chiếm dụng sẽ tăng dần đều theo thời gian mà không bao giờ được hệ thống thu hồi hoàn toàn. Ứng dụng có thể chạy rất ổn định trong nhiều ngày, nhưng cuối cùng vẫn sẽ chạm đến ngưỡng giới hạn và bị khai tử. Với nguyên nhân này, việc chỉ tăng thông số memory limit sẽ không giải quyết được vấn đề gốc rễ mà chỉ làm chậm lại thời điểm xảy ra sự cố.

Cấu hình sai Heap Size của máy ảo Java JVM

Đây là một cạm bẫy cực kỳ phổ biến đối với các ứng dụng lập trình bằng Java. Nếu bạn không chủ động giới hạn kích thước vùng nhớ heap thông qua các tham số như -Xmx, máy ảo JVM sẽ tự động cấp phát bộ nhớ dựa trên tổng dung lượng RAM vật lý của máy chủ, hoàn toàn phớt lờ các giới hạn cgroups mà Kubernetes áp đặt. Hậu quả là JVM cố gắng nuốt trọn bộ nhớ và bị OOM KiIler trừng phạt ngay lập tức.

Nút mạng Node cạn kiệt tài nguyên tổng thể

OOMKiIled không chỉ xảy ra khi một container vượt quá giới hạn của chính nó. Nếu tổng lượng bộ nhớ mà tất cả các Pod đang sử dụng cộng dồn lại vượt quá dung lượng RAM vật lý của toàn bộ máy chủ Node, hệ điều hành sẽ rơi vào trạng thái hoảng loạn. Để cứu lấy tính mạng của Node, thành phần OOM Killer buộc phải hy sinh một vài Pod để giải phóng RAM, bất chấp việc các Pod đó có thể vẫn chưa chạm đến ngưỡng giới hạn cá nhân của chúng.

Hướng dẫn chẩn đoán lỗi OOMKiIled 

Có thể kiểm tra nhanh như sau: 

Hướng dẫn chẩn đoán lỗi OOMKilled

Thay vì đoán mò, hãy thực hiện tuần tự các bước sau dựa trên luồng tư duy xử lý sự cố chuẩn mực.

Bước 1: Xác nhận nguồn phát tín hiệu kết liễu

Khi một container dừng hoạt động với mã lỗi 137, điều đầu tiên cần làm là chạy lệnh kiểm tra trạng thái OOMKiIled. Nếu kết quả trả về là true, nhân hệ điều hành Linux chính là thủ phạm đã can thiệp. Ngược lại, nếu kết quả là false nhưng mã lỗi vẫn là 137, tín hiệu ngắt SIGKILL chắc chắn đến từ một nguồn bên ngoài. Bạn cần rà soát lại nhật ký của nền tảng điều phối, các operator hoặc các tiến trình giám sát watchdog.

Bước 2: Kiểm tra cấu hình giới hạn phần cứng

Hãy xác minh xem container có được thiết lập mức giới hạn bộ nhớ riêng hay không. Nếu hệ thống trả về giá trị 0, container của bạn đã bị tiêu diệt vì toàn bộ máy chủ vật lý đã cạn kiệt RAM. Trong tình huống này, bạn phải chuyển hướng điều tra sang mức độ máy chủ để xem những tiến trình nào đang cạnh tranh tài nguyên khốc liệt nhất.

Bước 3: Phân tích xu hướng tiêu thụ bộ nhớ

Biểu đồ giám sát tài nguyên trong những phút trước khi xảy ra sự cố chứa đựng những manh mối cực kỳ quan trọng:

- Tiêu thụ tăng đều đặn qua nhiều giờ: Đây là dấu hiệu kinh điển của lỗi rò rỉ bộ nhớ từ mã nguồn.

- Tiêu thụ tăng vọt đột ngột: Ứng dụng vừa hứng chịu một đợt bùng nổ lưu lượng truy cập hoặc đang xử lý một lượng dữ liệu đầu vào bất thường.

- Tiêu thụ đi ngang sát đường giới hạn: Cấu hình bộ nhớ hiện tại quá thấp so với nhu cầu nền tảng cơ bản của ứng dụng.

Bước 4: Xử lý đặc thù cho máy ảo JVM

Đối với các ứng dụng Java, vùng nhớ Heap không phải là toàn bộ bức tranh. Nếu bạn giới hạn container ở mức 2GB và đặt cấu hình Heap là 1800MB, ứng dụng chắc chắn sẽ bị sập. Máy ảo JVM luôn cần thêm tối thiểu 20 đến 30 phần trăm tài nguyên bổ sung cho metaspace, mã lưu trữ đệm và luồng xử lý thread stack.

Nghiêm trọng hơn, nếu bạn không khai báo tường minh các cờ cấu hình bên trong container, nhiều phiên bản JVM không tương thích với cgroups sẽ tự động nhận diện dung lượng RAM của toàn bộ máy chủ để cấp phát. Điều này chắc chắn sẽ phá vỡ giới hạn của container.

Bước 5: Truy vết tiến trình con bị tiêu diệt

Trong nhiều trường hợp, tiến trình mang mã định danh PID 1 của container là một trình quản lý tác vụ dạng shell. Trình xử lý OOM KiIler có thể chỉ tiêu diệt một tiến trình con đang làm việc quá sức thay vì tiêu diệt PID 1. Khi đó, container vẫn hiển thị trạng thái đang chạy nhưng thực tế luồng xử lý bên trong đã bị suy thoái. Hãy dùng lệnh đọc log để tìm kiếm các thông báo lỗi sập tiến trình con.

Bước 6: Đối chiếu với nhật ký dmesg

Nhật ký của nhân hệ điều hành là nguồn thông tin có thẩm quyền cao nhất. Khi can thiệp, hệ thống luôn ghi lại chính xác tên tiến trình vi phạm, mã định danh PID và các thông số bộ nhớ liên quan. Việc đối chiếu với các dòng sự kiện trong dmesg sẽ giúp bạn đưa ra kết luận cuối cùng và chính xác nhất về nguyên nhân gây ra sự cố.

Sơ đồ minh họa OOMKilled

Cách khắc phục OOMKiIled theo từng nguyên nhân cụ thể 

1. Nguyên nhân cấu hình giới hạn quá thấp so với tải thực tế

Khi ứng dụng hoạt động, nếu mức tiêu thụ bộ nhớ luôn loanh quanh ở ngưỡng 95% giới hạn, hệ thống của bạn hoàn toàn không có khoảng trống an toàn để xử lý các tác vụ dọn rác bộ nhớ Garbage Collection, các đợt bùng nổ lưu lượng truy cập đột ngột hoặc các sai số cấp phát thông thường.

Giải pháp tối ưu: Nới rộng giới hạn bộ nhớ kết hợp với một không gian đệm an toàn. Các kỹ sư DevOps khuyến nghị mức thiết lập lý tưởng nhất là 150% so với mức tiêu thụ đỉnh điểm được ghi nhận trong điều kiện vận hành bình thường.

Thao tác kỹ thuật: Cập nhật giới hạn cho một container đang chạy ngay lập tức bằng lệnh sau: docker update --memory 2g --memory-swap 2g <container_id>

Lưu ý vận hành: Việc thiết lập tham số bộ nhớ ảo swap bằng với RAM vật lý sẽ vô hiệu hóa hoàn toàn cơ chế swap cho container đó. Nếu hạ tầng của doanh nghiệp được quản lý qua hệ thống Compose, hãy cập nhật tham số cấu hình mem_limit và tiến hành triển khai lại toàn bộ.

2. Nguyên nhân xung đột cấu hình bộ nhớ máy ảo java jvm

Các ứng dụng Java thường tự cấp phát bộ nhớ dựa trên dung lượng RAM của máy chủ vật lý thay vì tuân thủ giới hạn của container, dẫn đến rủi ro sập hệ thống không báo trước.

Giải pháp cấu hình: Khai báo giới hạn vùng nhớ Heap một cách tường minh và đảm bảo máy ảo JVM nhận thức được các quy tắc kiểm soát của cgroups.

- Sử dụng cờ -Xmx và -Xms để đóng khung vùng nhớ Heap. Bắt buộc phải để lại tối thiểu 25 đến 30 phần trăm hạn mức của container cho các vùng nhớ ngoài Heap.

- Kích hoạt cờ -XX:+UseContainerSupport để ép JVM đọc giới hạn tài nguyên của cgroups. Tùy chọn này được bật mặc định từ JDK 10 trở lên và bản vá JDK 8u191, nhưng với các phiên bản cũ hơn, bạn bắt buộc phải cấu hình thủ công.

- Thiết lập cờ -XX:MaxMetaspaceSize để khống chế sự phình to của vùng nhớ siêu dữ liệu metaspace.

Ví dụ: Với một container giới hạn 2GB RAM, bộ thông số an toàn sẽ là -Xmx1200m -Xms1200m -XX:MaxMetaspaceSize=256m. Cách chia này dự trữ khoảng 550MB cho bộ nhớ đệm mã lệnh, ngăn xếp luồng và các chi phí vận hành lõi.

3. Nguyên nhân sự cố rò rỉ bộ nhớ memory leak từ mã nguồn

Trong trường hợp này, việc tăng mức giới hạn RAM chỉ mang tính chất mua thêm thời gian chứ không giải quyết được gốc rễ. Container chắc chắn sẽ tiếp tục sập, chỉ là vấn đề sớm hay muộn.

Quy trình xử lý triệt để:

1. Trích xuất kết xuất bộ nhớ Heap Dump ngay trước khi sự cố sập tiếp theo xảy ra. Đối với nền tảng JVM, hãy tự động hóa quá trình này bằng cụm cờ -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heap.hprof.

2. Chuyển giao tệp kết xuất cho đội ngũ phát triển phần mềm phân tích để định vị chính xác hàm nào đang gây rò rỉ.

3. Trực tiếp vá cấu trúc mã nguồn gây ra tình trạng cấp phát bộ nhớ vô hạn.

Giải pháp tình thế: Trong thời gian chờ đợi bản vá lỗi, quản trị viên có thể tăng tạm giới hạn RAM và bổ sung chính sách tự động khởi động lại để kéo dài thời gian sống của ứng dụng.

4. Nguyên nhân quá tải cạn kiệt bộ nhớ toàn hệ thống

Nếu doanh nghiệp bỏ ngỏ việc áp đặt giới hạn bộ nhớ cho từng container, khi máy chủ cạn kiệt RAM, hệ thống nhân Linux sẽ tự động lựa chọn nạn nhân để tiêu diệt dựa trên thuật toán phỏng đoán riêng của nó. Điều này tạo ra rủi ro hệ thống sập dây chuyền cực kỳ nguy hiểm.

Quy hoạch lại hạ tầng: Khắc phục triệt để bằng cách áp đặt thông số giới hạn bộ nhớ cho toàn bộ container. Đồng thời, phải tính toán cẩn thận để tổng giới hạn của tất cả các container không bao giờ vượt qua dung lượng RAM vật lý của máy chủ.

Lệnh rà soát lỗ hổng: Sử dụng đoạn mã bash script không chứa ký tự đặc biệt dưới đây để quét và tìm ra các container đang chạy thả rông không có giới hạn:

# Find containers with no memory limit set

for c in $(docker ps -q); do

 limit=$(docker inspect --format '{{.HostConfig.Memory}}' "$c")

 name=$(docker inspect --format '{{.Name}}' "$c")

 [ "$limit" = "0" ] && echo "No limit: $name"

done

5. Lỗi ngầm tiến trình con bị tiêu diệt

Đây là trạng thái lỗi suy thoái kiến trúc. Tiến trình gốc PID 1 vẫn sống và container hiển thị trạng thái đang hoạt động, nhưng thực chất một tiến trình con đảm nhiệm logic cốt lõi đã bị tiêu diệt do thiếu RAM, khiến ứng dụng tê liệt trong im lặng.

Phương án tái thiết kế:

- Cấu hình lại luồng thực thi để khi bất kỳ một tiến trình con nào chết, tiến trình gốc PID 1 cũng bắt buộc phải thoát ra, từ đó kích hoạt cơ chế khởi động lại an toàn của hệ thống.

- Tích hợp cơ chế kiểm tra sức khỏe Health Check thông minh nhằm đánh giá chính xác trạng thái của các tiến trình con, chủ động đánh dấu container là lỗi nếu hệ thống ngầm bị suy thoái.

- Triển khai một trình giám sát độc lập Process Supervisor ngay bên trong container để nó tự động khởi động lại các tiến trình con gặp sự cố mà không cần đánh sập toàn bộ vùng chứa.

Kết luận

OOMKiIled là một trong những sự cố vận hành kinh điển nhất trên môi trường Kubernetes. Tuy nhiên, hệ thống luôn để lại những dấu vết rõ ràng qua mã lỗi 137 và trạng thái Terminated. Bằng cách thiết lập thông số giới hạn RAM dựa trên số liệu thực tế, kiểm soát chặt chẽ cấu hình máy ảo Java và xây dựng hệ thống giám sát chủ động, doanh nghiệp có thể loại bỏ hoàn toàn bóng ma thiếu hụt bộ nhớ ra khỏi chu trình vận hành.

Việc tự tối ưu hóa tài nguyên và trực trực giám sát cụm máy chủ 24/7 đòi hỏi nguồn lực kỹ thuật rất lớn. Để giải phóng gánh nặng này, nhiều tổ chức đang chuyển hướng sang sử dụng dịch vụ chuyên biệt như Viettel Dedicated Kubernetes Service vDKS. Với hạ tầng được quản lý toàn diện bởi các chuyên gia Viettel IDC, hệ thống của bạn sẽ được tích hợp sẵn các cơ chế giám sát tài nguyên thông minh và cảnh báo chủ động, giúp loại trừ triệt để rủi ro gián đoạn dịch vụ do các sự cố hạ tầng như OOMKiIled, tạo điều kiện tối đa để đội ngũ công nghệ tập trung toàn lực vào việc phát triển sản phẩm phần mềm. 

Tham khảo dịch vụ Viettel Dedicated Kubernetes Service (vDKS) của Viettel IDC tại https://viettelidc.com.vn/viettel-kubernetes-service 

Để được hỗ trợ tư vấn và tìm hiểu các dịch vụ của Viettel, bạn có thể liên hệ trực tiếp tới Viettel IDC qua các kênh:

- Hotline: 1800 8088 (miễn phí cước gọi)

- Fanpage: https://www.facebook.com/viettelidc  

Bình luận ()

Đăng nhập | Đăng ký
để gửi bình luận
Ý kiến của bạn sẽ được xét duyệt trước khi đăng.
Ý kiến của bạn sẽ được xét duyệt trước khi đăng.
Ý kiến của bạn sẽ được xét duyệt trước khi đăng.
Xem thêm bình luận

Tin liên quan

29/09/2026

"SOVEREIGN CLOUD" VÀ NGHỊCH LÝ CHUYỂN ĐỔI SỐ: GIẢI MÃ BÀI TOÁN TUÂN THỦ CHO NGÀNH TÀI CHÍNH & CHÍNH PHỦ

Các tổ chức thuộc nhóm ngành trọng yếu như tài chính, ngân hàng (BFSI) và cơ quan nhà nước đang khao khát hiện đại hóa hệ thống IT (chuyển đổi sang kiến trúc Microservices, sử dụng Container/Kubernetes) để tăng tốc độ triển khai dịch vụ và nâng cao trải nghiệm người dùng. Tuy nhiên, họ lại đang vấp phải một "nghịch lý" lớn: Càng muốn áp dụng công nghệ Cloud hiện đại, rào cản về tuân thủ pháp lý và an toàn thông tin càng trở nên khắt khe.

29/09/2026

BÀI TOÁN "NOISY NEIGHBOR" TRÊN CLOUD VÀ CHIẾN LƯỢC TỐI ƯU HIỆU NĂNG CHO HỆ THỐNG CỐT LÕI

Trong kỷ nguyên mà dữ liệu là "dầu mỏ mới", việc vận hành các hệ thống xương sống (Core ERP, Core Banking) hay các workload tính toán chuyên sâu (AI, Machine Learning, Datalake) đòi hỏi năng lực phần cứng vô cùng mạnh mẽ.

27/09/2026

"BÃO GIÁ" HẠ TẦNG CNTT VÀ BÀI TOÁN SỐNG CÒN CỦA DOANH NGHIỆP: VÌ SAO PRIVATE CLOUD DẠNG DỊCH VỤ LÊN NGÔI?

Làn sóng bùng nổ hạ tầng AI toàn cầu đang tạo ra một "cơn địa chấn" về giá phần cứng máy chủ, chip nhớ DRAM, ổ cứng doanh nghiệp và chi phí năng lượng. Đứng trước áp lực phải chuyển đổi số nhưng lại vấp phải bài toán chi phí đầu tư (CapEx) đắt đỏ cùng thời gian giao hàng kéo dài hàng tháng, các nhà quản trị công nghệ (CIO) và tài chính (CFO) đang tìm kiếm một hướng đi mới: Không cần bỏ hàng tỷ đồng mua sắm hạ tầng mà vẫn sở hữu riêng một hệ thống Private Cloud hoàn chỉnh, an toàn và sẵn sàng vận hành ngay lập tức.

29/09/2026

Digital Workplace là gì? Xu hướng môi trường làm việc số cho doanh nghiệp

Digital Workplace là gì? Khám phá mô hình vận hành, thành phần, lợi ích, ứng dụng, thách thức và xu hướng môi trường làm việc số cho doanh nghiệp.

29/09/2026

Lỗ hổng Shellshock là gì? Cơ chế, tác động và cách khắc phục

Lỗ hổng Shellshock (CVE-2014-6271) trong Bash là gì, vì sao nghiêm trọng? Tìm hiểu nguyên nhân, hệ thống bị ảnh hưởng và cách kiểm tra, vá lỗi.

29/09/2026

Scratch là gì? Cách hoạt động, ứng dụng và đối tượng phù hợp

Scratch là gì? Tìm hiểu cách lập trình bằng khối lệnh, các khái niệm có thể học, ứng dụng thực tế và sự khác nhau giữa Scratch với ScratchJr.

29/09/2026

Phân biệt các loại Web Hosting: Đâu là lựa chọn phù hợp cho website?

Phân biệt các loại Web Hosting và tìm hiểu cách mỗi mô hình hoạt động, từ đó lựa chọn giải pháp phù hợp với nhu cầu, quy mô và định hướng phát triển website.

29/09/2026

Website có cần hosting không? Giải đáp chi tiết từ A-Z

Website có cần hosting không? Tìm hiểu vai trò của hosting, domain và các trường hợp cần và không cần mua hosting riêng cho website.

29/09/2026

Top nhà cung cấp dịch vụ Cloud Camera uy tín tại Việt Nam

Top nhà cung cấp dịch vụ Cloud Camera uy tín tại Việt Nam, cùng tiêu chí lựa chọn và những lưu ý quan trọng trước khi đăng ký dịch vụ.

28/09/2026

Trigger là gì trong DBMS? Cách hoạt động, các loại phổ biến và ứng dụng

Trigger là gì trong DBMS? Tìm hiểu cách trigger hoạt động, các loại phổ biến, ví dụ minh họa, ưu nhược điểm và khi nào nên sử dụng.