اشکال زدایی تصاویر Distroless با kubectl و cdebug

ایوان ولیچکو اخیراً مرا آگاه کرد مشکلات مربوط به اشکال زدایی ظروف بدون توزیع در Kubernetes با kubectl debug
. این وبلاگ به مشکل نگاه میکند و نشان میدهد که میتوانید برای اهداف اشکالزدایی به سیستم فایل یک پاد بدون توزیع دسترسی داشته باشید.
مشکلی که ایوان پیدا کرد فقدان مجوز برای دسترسی به سیستم فایل کانتینری بود که اشکال زدایی شده بود. این به بهترین شکل با چند مثال توضیح داده می شود. با یک کانتینر معمولی (بدون توزیع)، میتوانید برای راهاندازی یک کانتینر اشکالزدایی زودگذر که فضاهای نام مختلفی را با کانتینر هدف به اشتراک میگذارد، کارهای زیر را انجام دهید:
$ kubectl run nginx-pod --image nginx
pod/nginx-pod created
$ kubectl debug -it nginx-pod --image alpine --target nginx-pod
Targeting container "nginx-pod". If you don't see processes from this container it may be because the container runtime doesn't support this feature.
Defaulting debug container name to debugger-h4fzv.
If you don't see a command prompt, try pressing enter.
/ # ps
PID USER TIME COMMAND
1 root 0:00 nginx: master process nginx -g daemon off;
32 101 0:00 nginx: worker process
33 101 0:00 nginx: worker process
34 101 0:00 nginx: worker process
35 101 0:00 nginx: worker process
36 101 0:00 nginx: worker process
37 101 0:00 nginx: worker process
38 101 0:00 nginx: worker process
39 101 0:00 nginx: worker process
40 101 0:00 nginx: worker process
41 101 0:00 nginx: worker process
308 root 0:00 /bin/sh
317 root 0:00 ps
(همچنین می توانید استفاده کنید kubectl exec -it nginx-pod -- /bin/sh
، اما البته این در یک ظرف بدون توزیع امکان پذیر نیست)
توجه داشته باشید که فایل سیستم فایل سیستم ظرف اشکال زدایی Alpine است، نه ظرف nginx:
/ # cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.19.1
PRETTY_NAME="Alpine Linux v3.19"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
اما از طریق /proc/1/root
فایل سیستم برای تجزیه این:
-
/proc
یک فایل سیستم مجازی است که توسط هسته ایجاد شده و حاوی متادیتاهای مختلفی است -
1
به شناسه فرآیند اشاره دارد، در این مورد فرآیند اصلی nginx در حال اجرا ما. و -
root
پیوندی به ریشه سیستم فایلی است که فرآیند در آن اجرا می شود.
بنابراین ما می توانیم به فایل index.html در داخل ظرف nginx مانند این دسترسی داشته باشیم:
/ # cat /proc/1/root/usr/share/nginx/html/index.html
<!DOCTYPE html>
…
/ #
حالا بیایید آن را با cgr.dev/chainguard/nginx
تصویر، که یکی از تصاویر بدون توزیع Chainguard است:
$ kubectl run nginx-distroless --image cgr.dev/chainguard/nginx
pod/nginx-distroless created
$ kubectl debug -it nginx-distroless --image alpine --target nginx-distroless
Targeting container "nginx-distroless". If you don't see processes from this container it may be because the container runtime doesn't support this feature.
Defaulting debug container name to debugger-bcr26.
If you don't see a command prompt, try pressing enter.
/ # cat /proc/1/root/usr/share/nginx/html/index.html
cat: can't open '/proc/1/root/usr/share/nginx/html/index.html': Permission denied
/ # whoami
root
ما گرفتیم Permission denied
.
به نظر می رسد که مشکل این است که ظرف nginx به عنوان کاربر در حال اجرا است nonroot
با UID 65532 که علیرغم وجود اجازه دسترسی به آن را نداریم root
(استفاده كردن --profile
تنظیم یک نمایه امنیتی متفاوت نیز کمکی نکرد، اما من گمان میکنم که در آینده ممکن است باشد). برای رفع این مشکل، ما به محفظه اشکال زدایی نیاز داریم تا به عنوان کاربر مشابه ظرف nginx اجرا شود. متاسفانه وجود ندارد --user
پرچم برای kubectl
، بنابراین باید تصویری داشته باشیم که به صورت پیش فرض به عنوان این کاربر اجرا شود. ما می توانیم با یک Dockerfile مانند:
FROM alpine
USER 65532
اما در مورد Chainguard Images راه حل بسیار ساده تری وجود دارد. اکثر تصاویر ما همراه هستند -dev
انواعی که به عنوان یک کاربر اجرا می شوند اما شامل یک پوسته نیز می شوند و می توانند برای اشکال زدایی استفاده شوند، بنابراین ما می توانیم انجام دهیم:
$ kubectl debug -it nginx-distroless --image cgr.dev/chainguard/nginx:latest-dev --target nginx-distroless -- /bin/sh
Targeting container "nginx-distroless". If you don't see processes from this container it may be because the container runtime doesn't support this feature.
Defaulting debug container name to debugger-nbvjt.
If you don't see a command prompt, try pressing enter.
/ $
/ $ cat /proc/1/root/usr/share/nginx/html/index.html
…
و همه چیز همانطور که انتظار می رود کار می کند.
در واقع یک چین و چروک دوم نیز وجود دارد که با تنظیم کاربر حل می شود – اگر غلاف شما با آن کار می کند runAsNonRoot
سیاست، شما نمی توانید یک محفظه اشکال زدایی را که به عنوان root با نمایه پیش فرض اجرا می شود راه اندازی کنید.
این به راه هایی اشاره می کند که در آن kubectl debug
می تواند بهبود یابد:
- a اضافه کنید
--user
گزینه ای برای تنظیم کاربر در ظرف اشکال زدایی - یک راه رسمی برای دسترسی به سیستم فایل کانتینر مورد نظر اضافه کنید. رفتن از طریق
/proc/1/root
کمی هک و غیر شهودی به نظر می رسد - برای توضیح همه اینها چند سند دیگر اضافه کنید (که جایی است که من قصد کمک به آن را دارم).
(من می بینم که برخی از پیشرفت های پیشنهادی مربوط به نمایه ها وجود دارد که ممکن است در اینجا به شما کمک کند)
همچنین باید اشاره کنم که ایوان این مشکلات را مستقیماً با ابزار cdebug خود برطرف می کند. شما می توانید استفاده کنید cdebug
برای اشکال زدایی مستقیم یک پاد:
$ cdebug exec -it --privileged pod/nginx-distroless/nginx-distroless
Debugger container name: cdebug-20ba5985
Starting debugger container...
Waiting for debugger container...
Attaching to debugger container...
If you don't see a command prompt, try pressing enter.
/ # cat /proc/1/root/usr/share/nginx/html/index.html
…
cdebug
از a نیز پشتیبانی می کند --user
پرچم اگر دارید runAsNonRoot
سیاست به عنوان مثال:
cdebug exec -it --user 65532 pod/nginx-distroless/nginx-distroless
…
این در مورد آن است. اجرای بارهای کاری تولید در کانتینرهای بدون توزیع یک پیشرفت بزرگ از نظر امنیت است. با کمی دانش، این ظروف هنوز هم می توانند به راحتی اشکال زدایی کنند.