Tôi đang thử nghiệm các tính năng gỡ lỗi của k8 bao gồm nhóm gỡ lỗi và vùng chứa tạm thời và tôi không thể tìm ra cách ánh xạ chính xác nhóm "mục tiêu" hệ thống tập tin vào vùng chứa gỡ lỗi.
tôi muốn liên kết hai không gian tên gắn kết rời rạc với gắn kết liên kết đệ quy* vì vậy vùng chứa A xem gốc của vùng chứa B là /containerB
hoặc ngược lại. Bao gồm tất cả các tập và các thú cưỡi khác.
Mục tiêu: Truy cập vào cả hệ thống tệp vùng chứa mục tiêu và gỡ lỗi cùng một lúc
Mục tiêu là có nhóm mục tiêu cây hệ thống tập tin đầy đủ, bao gồm các ổ đĩa và các giá treo khác được ánh xạ tới một thư mục con của vùng chứa gỡ lỗi, ví dụ: /chạy/mục tiêu
. Nếu bộ chứa đích gắn các ổ đĩa liên tục, thì các điểm gắn kết đó sẽ được ánh xạ, vì vậy, ví dụ: nếu vùng chứa mục tiêu có /dữ liệu
thì vùng chứa gỡ lỗi phải được gắn /chạy/mục tiêu/dữ liệu
.
Ngoài ra, bạn có thể "đưa" cây hệ thống tệp bộ chứa gỡ lỗi vào bộ chứa đích, vì vậy, ví dụ: một /chạy/gỡ lỗi
hiển thị gốc vùng chứa gỡ lỗi khả dụng khi người nhập viện
vào vùng chứa gỡ lỗi. Kể cả các mount của nó như procfs nên đầy đủ chức năng.
Tôi muốn có thể ví dụ: gdb -p $ target_pid
ở đâu gdb
được cung cấp bởi vùng chứa gỡ lỗi. gdb
phải có khả năng tìm thấy quá trình thực thi từ thùng chứa mục tiêu cho việc này.
Tôi đã khám phá một vài cách tiếp cận giải pháp. Nhưng những gì tôi Thực ra muốn làm là gắn kết --rbind
cây FS vùng chứa mục tiêu lên máy khách hoặc ngược lại. Đưa ra một vùng chứa gỡ lỗi đặc quyền được xây dựng tùy chỉnh như:
phiên bản api: v1
loại: Vỏ
metadata:
tên: debugcontainer
không gian tên: mặc định
thông số kỹ thuật:
tên nút: TARGET_NODE_NAME_HERE
enableServiceLinks: đúng
máy chủIPC: đúng
máy chủ lưu trữ: đúng
máy chủ PID: đúng
restartPolicy: Không bao giờ
hộp đựng:
- hình ảnh: DIAG_CONTAINER_IMAGE_HERE # bạn có thể thử nghiệm bằng thứ gì đó như ubuntu:20.04
tên: trình gỡ lỗi
stdin: đúng
tty: đúng
khối lượngMount:
- mountPath: /mục tiêu
tên: mục tiêu
#- mountPath: /host
# mountPropagation: Không có
# tên: host-root
bối cảnh bảo mật:
đặc quyền: đúng
runAsGroup: 0
runAsUser: 0
khối lượng:
- trốngDir: {}
tên: mục tiêu
#- đường dẫn máy chủ:
# con đường: "/"
# loại: ""
# tên: host-root
nơi bộ chứa gỡ lỗi được khởi chạy vào cùng một nút với tư cách là vùng chứa mục tiêu, tôi có thể:
- Xem các quy trình vùng chứa mục tiêu trong
ps
- gắn vào các quy trình với
bước đi
, gdb
v.v. vì vùng chứa gỡ lỗi đặc quyền có CAP_SYS_PTRACE
nsenter -t $some_target_container_pid --all
để "trở thành" một proc trong vùng chứa mục tiêu, như thể tôi đã hoàn thành giám đốc điều hành kubectl
. Tôi không còn có thể "nhìn thấy" hoặc truy cập các tệp/công cụ chứa gỡ lỗi.
nsenter -t $some_target_container_pid -m --root=/ --wd=/
để nhập không gian tên gắn kết của proc đích, nhưng giữ lại các quyền riêng tư của bộ chứa gỡ lỗi. Tôi không còn có thể "nhìn thấy" hoặc truy cập các tệp/công cụ chứa gỡ lỗi.
Nhưng tôi không thể:
- Xem các tệp trong vùng chứa mục tiêu đồng thời có quyền truy cập vào các công cụ trong vùng chứa gỡ lỗi - ví dụ:
gdb
không thể tìm thấy các tệp thực thi đang được gỡ lỗi
- Xem nội dung của ổ đĩa trong vùng chứa đích và áp dụng các công cụ vùng chứa gỡ lỗi cho chúng
Có cách nào được công nhận để làm điều này?
Nó không hoàn toàn dành riêng cho k8: vấn đề tương tự cũng xảy ra với Docker, containerd, runc
, vân vân.
Bạn có thể mong đợi điều này là có thể bằng cách sử dụng gắn kết --rbind
để "đưa" bộ chứa gỡ lỗi vào bộ chứa đích thông qua không gian tên bộ chứa máy chủ bằng cách sử dụng máy chủ lưu trữ
âm lượng
với mountPropagation: Hai chiều
. Nhưng mà chứa đựng
gắn hình ảnh gốc của vùng chứa, đặt lan truyền gắn kết thành riêng tư sau đó gắn các tập bên trong. Vì vậy, không gian tên mount của máy chủ lưu trữ không nhìn thấy các mount được tạo bên trong ảnh gốc của vùng chứa và các procs trong vùng chứa không thấy các mount mới do máy chủ thêm vào sau khi quá trình đầu tiên của vùng chứa bắt đầu. Nhìn thấy https://man7.org/linux/man-pages/man7/mount_namespaces.7.html để biết chi tiết.
tôi đã thử sử dụng người nhập viện
để "vượt qua" các không gian tên gắn kết, nhưng tôi không thể làm cho một liên kết gắn kết hoạt động. Ví dụ. trong vùng chứa gỡ lỗi tôi có thể
nsenter -t $some_target_container_pid --root=/ -m /bin/bash
mang lại cho tôi một cái vỏ trong đó .
(CWD) là rootf vùng chứa gỡ lỗi và /
là thùng chứa mục tiêu rootfs. Nhưng tôi dường như không thể gắn kết chúng:
$ mkdir /run/gỡ lỗi
$ gắn kết --rbind . /chạy/gỡ lỗi
mount: /run/debug: loại fs sai, tùy chọn không hợp lệ, siêu khối không hợp lệ trên ., thiếu trang mã hoặc chương trình trợ giúp hoặc lỗi khác.
Điều tương tự cũng xảy ra nếu tôi sử dụng nsenter --wd=/
không có --nguồn gốc
, và cố gắng gắn kết --rbind / ./run/debug
.
tôi đã thử sử dụng hủy chia sẻ -m
để tạo một không gian tên gắn kết bên trong mới trước tiên. Và tôi đã thử gắn kết --make-rprivate /
trên cây chứa gỡ lỗi trước khi gắn kết. Thỏa thuận tương tự.
Tôi không thể hiểu tại sao: không có gì trong dmesg và lỗi rất chung chung. Tôi đoán đó là do các gốc rời rạc và/hoặc không gian tên gắn kết rời rạc. Nó dường như không phải là do sự bảo vệ của hạt nhân chống lại vòng tròn gắn kết liên kết. Và tôi đang sử dụng các liên kết đệ quy, vì vậy nó không phải là do sự bảo vệ chống lại sự thoát khỏi cây gắn kết trong không gian tên người dùng linux.
Một thay thế cho --rbind
ing một cây FS sẽ là nếu tôi có một cách để gắn kết --bind
qua id gắn kết như thể hiện trong /proc/$target_pid/mountinfo
. Sau đó, tôi có thể sao chép tất cả các lần gắn kết từ pid đích vào không gian tên gắn kết của bộ chứa gỡ lỗi. Nhưng tôi không thể gắn kết --bind
sử dụng một đường dẫn tuyệt đối bình thường, bởi vì không gian tên mount của vùng chứa gỡ lỗi và vùng chứa đích không liên kết với nhau và cả hai đều có các cây con của mount với lan truyền riêng.
Tôi đã thử sử dụng quy trình đích /proc/$pid/ns/mnt
mount, như tôi đã thấy tài liệu tham khảo để gắn kết liên kết bằng cách sử dụng nó. Nhưng trên kernel 5.16 của tôi, đó là một cây liên kết tượng trưng giả, không phải cây fs:
$ liên kết đọc /proc/self/ns/mnt
mnt:[4026531840]
$ ls /proc/self/ns/mnt/
ls: không thể truy cập '/proc/self/ns/mnt/': Không phải thư mục
Điều gần nhất tôi phải giải quyết vào lúc này là người nhập viện
hack với thư mục làm việc. Điều này cung cấp rất hạn chế việc đưa dụng cụ vào thùng chứa mục tiêu. Trong đó pid 1055 là một pid trong vùng chứa đích:
# nsenter -t 1055 -p -m --wd=/ /bin/bash
shell-init: lỗi truy xuất thư mục hiện tại: getcwd: không thể truy cập thư mục mẹ: Không có tệp hoặc thư mục như vậy
#là /
...mục tiêu nội dung rootfs vùng chứa ở đây...
# là .
...gỡ lỗi vùng chứa rootfs tại đây...
# là ..
...gỡ lỗi vùng chứa rootfs ở đây cũng vì . là gốc...
# pwd
pwd: lỗi truy xuất thư mục hiện tại: getcwd: không thể truy cập thư mục mẹ: Không có tệp hoặc thư mục như vậy
# ls usr/bin/gdb
usr/bin/gdb
# ls /usr/bin/gdb
ls: không thể truy cập '/usr/bin/gdb': Không có tệp hoặc thư mục như vậy
nhưng tôi không thể liên kết gắn kết như tôi muốn, từ trong cùng một phiên nsenter:
# mkdir /run/gỡ lỗi
# núi --rbind . /chạy/gỡ lỗi
mount: /run/debug: loại fs sai, tùy chọn không hợp lệ, siêu khối không hợp lệ trên ., thiếu trang mã hoặc chương trình trợ giúp hoặc lỗi khác.
Gợi ý?
Liên kết tham khảo: