Debug máy chủ Linux của khách qua bastion: một dòng ssh -J và ba lệnh đầu tiên cần gõ
Ở site khách, máy chủ đang lỗi thường không có dashboard và không cho cài thêm công cụ. Thứ bạn chắc chắn có chỉ là một bastion, một shell và vài phút trước khi có người hỏi bạn đã tìm ra nguyên nhân chưa.
- 1ssh -J qua bastionMột dòng lệnh, kết nối xuất phát từ laptop; nhiều bastion thì cách nhau bằng dấu phẩy
- 2Kiểm tra hostnameChắc chắn bạn đang ở máy đích chứ không phải trên bastion
- 3Chạy lệnh có sẵnuptime, dmesg | tail, vmstat 1: ba lệnh trong danh sách 60 giây của Gregg
- 4Lưu kết quả về laptopChạy script qua ssh 'bash -s' rồi ghi output ra file làm bằng chứng
- 5Đối chiếu với mốcSo với output bạn đã lưu trên máy mình lúc rảnh và lúc tải nặng
Vào máy đích bằng một lệnh qua bastion, kiểm tra đúng host, rồi lưu output của các lệnh có sẵn để so với mốc trước khi đoán.
Đồ hoạ: FDE Times
Tóm tắt nhanh
- ssh -J là lối tắt cho ProxyJump: chỉ một dòng lệnh, đi qua bao nhiêu bastion cũng được, mỗi chặng cách nhau bằng dấu phẩy.
- Danh sách mười lệnh nên chạy đầu tiên khi điều tra, do Brendan Gregg và đội performance của Netflix viết năm 2015, có uptime, dmesg | tail và vmstat 1.
- Script chẩn đoán phải dễ đọc trước hết, vì script đơn giản thường dần lớn thành script phức tạp.
Ở site khách, lệnh đầu tiên bạn gõ thường chưa phải code. Thường đó là một dòng ssh có cờ -J, rồi đến uptime. Trong vài phút đó, khách sẽ đánh giá xem bạn có làm chủ được hệ thống của họ hay không.
Máy chủ của doanh nghiệp hiếm khi mở thẳng ra Internet. Bạn phải đi qua một bastion, và trên máy đích thường không được cài thêm gì. Muốn làm FDE thì bạn cần thạo hai việc: vào được máy đích cho gọn, và ghi lại tình trạng máy trước khi bắt đầu đoán.
Bài này hướng dẫn bạn dựng một tình huống giống thật ngay trên laptop: vào máy đích qua bastion, chạy vài lệnh có sẵn, rồi gói chúng vào một script ngắn để mang kết quả về. Bạn cần một máy có OpenSSH client và hai máy Linux SSH vào được, máy ảo hay máy cloud đều được.
Máy thứ nhất đóng vai bastion, máy thứ hai là “máy chủ của khách”.
Bước 1: một dòng ssh -J thay cho hai lần đăng nhập
Người mới thường SSH vào bastion, rồi từ đó SSH tiếp vào máy đích. Cách này chạy được, nhưng dễ khiến bạn để private key nằm lại trên bastion, mà bastion lại là máy của khách. Theo manual ssh(1) của OpenSSH, cờ -J là lối tắt cho directive ProxyJump, và đây là cách chuẩn để đi qua jump host.
ssh -J user@bastion.example user@app-01.internal
Bạn chỉ chạy một lệnh, và kết nối tới máy đích được tạo từ laptop của bạn, đi xuyên qua bastion. Sau bước này, hãy chạy hostname để chắc mình đang đứng trên app-01 chứ không phải trên bastion. Lỗi này nghe thì ngớ ngẩn, nhưng chạy nhầm lệnh trên bastion của khách thì hậu quả không nhỏ.
Có khách đặt hai lớp bastion, chẳng hạn một lớp cho mạng văn phòng và một lớp cho vùng production. Manual cho phép khai báo nhiều chặng, cách nhau bằng dấu phẩy:
ssh -J user@bastion-ngoai,user@bastion-trong user@app-01.internal
Bước 2: đưa đường đi vào ~/.ssh/config
Gõ lại cả chuỗi trên mỗi lần vừa mệt vừa dễ sai. Vì -J chỉ là lối tắt cho ProxyJump, bạn có thể ghi đường đi vào file config một lần rồi dùng mãi. Ví dụ dưới đây đã được đơn giản hóa, chỉ giữ những dòng tối thiểu:
Host khach-bastion
HostName bastion.example
User user
Host khach-app01
HostName app-01.internal
User user
ProxyJump khach-bastion
Từ giờ, ssh khach-app01 là đủ. Hãy chạy lại hostname để kiểm tra. Nên đặt tên host có tiền tố theo từng khách, vì khi làm cùng lúc hai dự án, tên kiểu app01 rất dễ đưa bạn vào nhầm môi trường.
Ở một số khách, bạn sẽ thấy config cũ dùng ProxyCommand thay vì ProxyJump. Cách này dựa trên cờ -W, cờ mà manual mô tả là chuyển stdin và stdout của client tới một host và port qua kênh mã hóa. Bạn không cần tự viết kiểu này, nhưng cần đọc hiểu được nó. Ví dụ dưới đây đã đơn giản hóa:
Host khach-app01-cu
HostName app-01.internal
ProxyCommand ssh -W app-01.internal:22 khach-bastion
Bước 3: ba lệnh đầu tiên, và so với cái gì?
Vào được máy rồi, bạn dễ muốn mở ngay log ứng dụng. Nên kìm lại một chút. Trang Linux performance của Brendan Gregg dẫn tới bài “Linux Performance Analysis in 60,000 Milliseconds”, do ông viết cùng đội performance engineering của Netflix năm 2015, giới thiệu mười lệnh nên dùng đầu tiên trong một cuộc điều tra.
Wiki của Thomas-Krenn chép lại danh sách này. Trong đó có ba lệnh đều có sẵn trên hầu hết máy Linux:
uptime
dmesg | tail
vmstat 1
Output thô chưa nói lên gì nếu bạn không có thứ để so. Vì vậy, trước khi đến site khách, hãy chạy ba lệnh này trên máy của chính bạn, một lần lúc máy rảnh và một lần lúc đang chạy nặng, rồi lưu cả hai bản làm mốc.
Khi đứng trên máy khách, việc cụ thể cần làm là đặt output cạnh hai bản mốc và đánh dấu chỗ khác biệt. Các con số uptime in ra gần bản lúc rảnh hay bản lúc tải nặng hơn? dmesg | tail có dòng nào mà bản mốc không có? Cột nào trong vmstat lệch xa nhất? Ba câu hỏi đó đủ để bạn biết nên đào tiếp hướng nào.
Giải nghĩa từng cột là bài học tiếp theo. Muốn đọc vmstat cho đúng, bạn nên xem bài viết riêng về vmstat mà wiki Thomas-Krenn dẫn link, và đọc toàn bộ danh sách mười lệnh trong bài gốc của Gregg.
Bước 4: script chẩn đoán phải đọc được trong 10 giây
Sau vài lần làm, bạn sẽ muốn gói các lệnh vào một file. Shell Scripting Tutorial coi bố cục rõ ràng, dễ đọc là tiêu chí quan trọng nhất. Script viết vội ở site khách hay bị người khác mở ra đọc, có khi chính là kỹ sư vận hành của khách đang đứng cạnh bạn.
#!/bin/bash
# chan-doan.sh: ghi lại tình trạng máy, chỉ dùng lệnh có sẵn
echo "== Máy: $(hostname)"
echo "== uptime"
uptime
echo "== dmesg | tail"
dmesg | tail
echo "== vmstat (5 mẫu, mỗi giây một mẫu)"
vmstat 1 5
Dòng cuối dùng vmstat 1 5 để script tự dừng sau năm lần lấy mẫu thay vì chạy mãi. Đây là bản đơn giản hóa, bạn nên đối chiếu với man vmstat trên đúng máy đang dùng. Một số hệ thống có thể không cho user thường đọc dmesg; gặp trường hợp đó, hãy ghi lại thông báo lỗi chứ đừng tự ý xin quyền root.
Chạy script mà không cần chép file lên máy khách (cách viết đã đơn giản hóa):
cat chan-doan.sh | ssh khach-app01 'bash -s' > ket-qua-app01.txt
Kết quả nằm trên laptop của bạn, có thể gửi cho đồng đội hoặc dán vào ticket. Nhớ kiểm tra dòng == Máy: trong file để chắc kết quả đến từ đúng host.
Lỗi hay gặp: để script lớn quá
Shell Scripting Tutorial cảnh báo rằng script đơn giản thường dần trở thành script phức tạp. Ở site khách, chuyện này diễn ra rất nhanh. Hôm nay bạn thêm một vòng lặp qua mười host, mai thêm phần parse output, tuần sau đã có 300 dòng Bash mà không ai dám sửa.
Đến lúc script bắt đầu có logic rẽ nhánh, nên dừng lại tự hỏi: đây là công cụ chẩn đoán dùng một lần, hay là sản phẩm khách sẽ phải bảo trì? Nếu là sản phẩm, hãy bàn với khách trước khi để nó lại trên máy của họ.
Hai lỗi khác cũng phổ biến. Một là copy private key lên bastion cho tiện; với -J, bạn không cần làm vậy. Hai là quên kiểm tra hostname, rồi mất nửa giờ chẩn đoán nhầm máy.
Ở site khách, kỹ năng này thể hiện ra sao?
Thử hình dung khách báo API chậm từ sáng. Bạn chưa có quyền xem hệ thống monitoring, chỉ có tài khoản SSH qua bastion. Chừng một phút sau khi vào máy, bạn đã có trong tay một file output ghi rõ tên host, sẵn sàng đối chiếu với mốc bình thường và chia cho đồng đội.
Như vậy dễ được tin hơn nhiều so với câu “để em xem code”.
Để luyện có hệ thống, có hai nguồn đáng dùng. Linux Journey do Cindy Quach tạo năm 2015, nay do LabEx vận hành, miễn phí và không cần đăng ký. Các phần intermediate và networking có nội dung về logging và troubleshooting.
Khóa Linux for Noobs của LabEx có 37 lab trên terminal Linux thật, gồm 19 lab có hướng dẫn và 18 challenge tự làm, bao quát SSH, log, process và Bash scripting.
Khi đọc JD vị trí FDE, nếu thấy nhắc tới việc làm trong môi trường của khách hay với quyền truy cập hạn chế, điều đó thường gợi ý bạn sẽ phải đi qua bastion như trong bài; đáng hỏi lại cho rõ ở vòng phỏng vấn.
Trong CV, thay vì ghi chung chung “thành thạo Linux”, hãy mô tả một sự cố cụ thể: bạn đã vào máy bằng cách nào, chạy lệnh gì đầu tiên, và tìm ra nguyên nhân sau bao lâu.
Khách nhớ một FDE nhờ những phút đầu tiên trên máy của họ, khi bạn biết mình đang đứng trên host nào và mang về được bằng chứng, hơn là nhờ những dòng code viết sau đó.