این فرآیندی که من در هاست خود می بینم از کدام پاد (و فضای نام!) Kubernetes است؟
بنابراین متوجه شدید که پیدهای ظروف Kubernetes (یا Docker) شما در هاست شما ظاهر می شوند:
$ ps auxw | fgrep python
root 11282 0.0 0.0 94628 24372 ? Ss 04:53 0:00 python app.py
root 11439 0.0 0.0 41968 13072 ? Ss 04:53 0:00 python event-simulator.py
root 12527 0.0 0.0 6796 2292 pts/0 S+ 04:57 0:00 grep -F --color=auto python
اما کدام غلاف Kubernetes مالک این فرآیندها است؟
تا آنجا که دانش من گسترش می یابد، راه بی اهمیتی برای استفاده از دستور بومی برای کشف آن وجود ندارد. شما باید تکه های پازل را خودتان بچینید.
“هک” معمولی که من می بینم اکثر مردم انجام می دهند این است:
$ nsenter -t 11282 -u hostname
webapp-color
$ nsenter -t 11439 -u hostname
e-com-1123
اما این فضای نام Kubernetes را به من نمی دهد.
من به طور تصادفی گوگل انجام دادم و نتوانستم شخص دیگری را پیدا کنم که به اندازه خودم از این موضوع ناراحت است، بنابراین تصمیم گرفتم این پست وبلاگ را بنویسم.
نسخه TL:DR:
$ for i in 11282 11439; do crictl inspect --output go-template --template '{{index .status.labels "io.kubernetes.pod.namespace" }}:{{index .status.labels "io.kubernetes.pod.name" }}' $( head -n1 /proc/$i/cgroup | cut -f5 -d':' ) ; done
default:webapp-color
e-commerce:e-com-1123
اگر می خواهید بدانید که چگونه و چرا کار می کند، به خواندن ادامه دهید.
احتمالاً در جایی خوانده اید که آنچه کانتینرها را واقعی می کند دو منبع لینوکس هستند: cgroups و فضاهای نام.
بیایید به “هک” برگردیم:
$ nsenter -t 11439 -u hostname
e-com-1123
دستور لینوکس nsenter به شما اجازه می دهد تا یک دستور را اجرا کنید داخل فضای نام یک فرآیند دیگر:
$ nsenter -h
Run a program with namespaces of other processes.
...
-u, --uts[=<file>] enter UTS namespace (hostname etc)
...
بنابراین، هک استفاده می کند nsenter -u، که به نوبه خود دستوری را در داخل لینوکس اجرا می کند فضای نام UTS، که به ما امکان می دهد تنظیم کنیم نام میزبان و نام های دامنه بدون اینکه بر بقیه سیستم تاثیر بگذارد.
فضای نام UTS قطعاً قابل تشخیص ترین نیست. وقتی مردم به فضای نام فکر می کنند، معمولاً آن را به خاطر می آورند فضای نام PID، مسئول ارائه یک فضای شناسایی فرآیند ایزوله برای کانتینر یا فضای نام شبکه، که به نوبه خود یک پشته شبکه ایزوله را فراهم می کند. اما بله، تعداد زیادی مورد دیگر وجود دارد، همانطور که می توانید پیوندهای موجود در این پاراگراف را بررسی کنید. یا اگر تنبل هستید، در اینجا یک خروجی توسعه یافته از آن وجود دارد nsenter -h خروجی:
$ nsenter -h
Usage:
nsenter [options] [<program> [<argument>...]]
Run a program with namespaces of other processes.
...
-a, --all enter all namespaces
-t, --target <pid> target process to get namespaces from
-m, --mount[=<file>] enter mount namespace
-u, --uts[=<file>] enter UTS namespace (hostname etc)
-i, --ipc[=<file>] enter System V IPC namespace
-n, --net[=<file>] enter network namespace
-p, --pid[=<file>] enter pid namespace
-C, --cgroup[=<file>] enter cgroup namespace
-U, --user[=<file>] enter user namespace
-T, --time[=<file>] enter time namespace
این یک سرگرم کننده بود! اما چه در مورد cgroups?
خوب، cgroup ها به ما اجازه می دهند استفاده از منابع سیستم مانند CPU، حافظه و پهنای باند شبکه را محدود کنیم.
شما می توانید cgroup های یک فرآیند را با یک آسان ببینید ps*:
$ ps -wwo cgroup= 11439
12:hugetlb:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a,11:cpu,cpuacct:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a,10:memory:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a,9:perf_event:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a,8:net_cls,net_prio:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a,7:cpuset:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a,6:pids:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a,5:blkio:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a,4:devices:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a,3:rdma:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a,2:freezer:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a,1:name=systemd:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
اوه زشت بود بیایید خروجی را زیبا کنیم:
ps -wwo cgroup= 11439 | tr , '\n'
12:hugetlb:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
11:cpu
cpuacct:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
10:memory:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
9:perf_event:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
8:net_cls
net_prio:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
7:cpuset:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
6:pids:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
5:blkio:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
4:devices:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
3:rdma:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
2:freezer:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
1:name=systemd:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
خیلی بهتره
اما حقیقت را بگوییم، اساساً همان خروجی این دستور ساده گربه است:
$ cat /proc/11439/cgroup
12:hugetlb:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
11:cpu,cpuacct:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
10:memory:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
9:perf_event:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
8:net_cls,net_prio:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
7:cpuset:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
6:pids:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
5:blkio:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
4:devices:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
3:rdma:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
2:freezer:/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
1:name=systemd:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
0::/
هر کدام از آنها چه می کنند؟ خوب، شما می توانید این را از هسته لینوکس بخوانید، و این موضوع تمرکز پست امروز نیست.
ما باید بفهمیم که کدام پاد Kubernetes (و فضای نام آن!) صاحب آن فرآیند است!
اگر دقت کنید، متوجه الگوی جالبی در نامگذاری cgroup ها خواهید شد:
$ cat /proc/11439/cgroup | cut -f3- -d':' | sort | uniq -c
1 /
6 /kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
6 /system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
بیایید بخشی از سلسله مراتب را که چندان به آن اهمیت نمی دهیم کنار بگذاریم:
$ cat /proc/11439/cgroup | cut -f4- -d':' | sort | uniq -c
1
12 cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
دنباله شخصیت بعد از “:” به شدت آشنا به نظر می رسد:
$ crictl ps --id da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD
da1bdd84c8b25 ee4be8f9dfd10 7 minutes ago Running simple-webapp 0 48ee11c897fa8 e-com-1123
اینجاست! نام غلاف!
اما فضای نام آن چیست؟
من مطمئن نیستم که آیا راه آسانی برای بازگرداندن crictl به شما وجود دارد یا خیر. من مزاحم را می شناسم: فرمت کردن خروجی آن با استفاده از go-template!
بیایید ببینیم چه چیزی داریم:
$ crictl inspect da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | jq '. | keys'
[
"info",
"status"
]
بیایید عمیق تر برویم:
$ crictl inspect da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | jq '.info | keys'
[
"config",
"pid",
"removing",
"runtimeOptions",
"runtimeSpec",
"runtimeType",
"sandboxID",
"snapshotKey",
"snapshotter"
]
$ crictl inspect da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | jq '.status | keys'
[
"annotations",
"createdAt",
"exitCode",
"finishedAt",
"id",
"image",
"imageId",
"imageRef",
"labels",
"logPath",
"message",
"metadata",
"mounts",
"reason",
"resources",
"startedAt",
"state"
]
من فکر می کنم که می خواهیم ببینیم چه چیزی در .status.labels ذخیره می شود:
$ crictl inspect da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | jq '.status.labels'
{
"io.kubernetes.container.name": "simple-webapp",
"io.kubernetes.pod.name": "e-com-1123",
"io.kubernetes.pod.namespace": "e-commerce",
"io.kubernetes.pod.uid": "86811ae3-b633-4eb8-a508-e3eae190f6ce"
}
اوه بله! این همان چیزی است که ما می خواهیم! یک داریم غلاف تماس گرفت e-com-1123 اجرای فرآیند در Kubernetes است فضای نام تجارت الکترونیک!
بیایید از آن یک Go-template ایجاد کنیم. نحوه دسترسی به اعضای یک نقشه به این صورت است:
$ crictl inspect --output go-template --template '{{.status.labels}}' da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
map[io.kubernetes.container.name:simple-webapp io.kubernetes.pod.name:e-com-1123 io.kubernetes.pod.namespace:e-commerce io.kubernetes.pod.uid:86811ae3-b633-4eb8-a508-e3eae190f6ce]
همانطور که می توانید تصور کنید، اگر یکی از اعضای یک نقشه یک “.” داشته باشد. در نام آن، با مشکلاتی مواجه خواهید شد:
$ crictl inspect --output go-template --template '{{.status.labels.io.kubernetes.pod.name}}' da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
FATA[0000] getting the status of the container "da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a": failed to template data: template: tmplExecuteRawJSON:1:9: executing "tmplExecuteRawJSON" at <.status.labels.io.kubernetes.pod.name>: map has no entry for key "io"
نگران نباشید، فقط از یکی از معدود عملکردهای go-template داخلی استفاده کنید:
$ crictl inspect --output go-template --template '{{index .status.labels "io.kubernetes.pod.name" }}' da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
e-com-1123
ما در نیمه راه هستیم:
$ crictl inspect --output go-template --template '{{index .status.labels "io.kubernetes.pod.namespace" }}:{{index .status.labels "io.kubernetes.pod.name" }}' da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a
e-commerce:e-com-1123
و اکنون، تبدیل به یک خطی:
$ for i in $( pgrep python -d ' ' ); do crictl inspect --output go-template --template '{{index .status.labels "io.kubernetes.pod.namespace" }}:{{index .status.labels "io.kubernetes.pod.name" }}' $( head -n1 /proc/$i/cgroup | cut -f5 -d':' ) ; done
default:webapp-color
e-commerce:e-com-1123
این پاسخی است که من به دنبال آن بودهام: چگونه بفهمم که یک فرآیند روی میزبان من از کدام فضای نام و پاد در حال اجرا است.
اعتراف می کنم که ساختن آن به صورت تک خطی کمک چندانی به خوانا بودن آن نکرد، بنابراین به امید اینکه درک آن آسان تر باشد، فیلمنامه ای خواهم نوشت:
$ cat which-pod-am-i.sh
#!/bin/bash
# This is NOT a production script!
# This was made just to make the techniques legible!
# Pieces of go templates.
# We need to retrieve two fields from .status.labels:
# .status.labels."io.kubernetes.pod.namespace"
NAMESPACE_TMPL='{{index .status.labels "io.kubernetes.pod.namespace" }}'
# .status.labels."io.kubernetes.pod.name"
POD_TMPL='{{index .status.labels "io.kubernetes.pod.name" }}'
# I'm passing the process name from command line:
for i in $( pgrep ${1?Parameter not passed} -d ' ' ); do
# Get the container ID from the cgroups:
CONTAINER_ID=$( head -n1 /proc/$i/cgroup | cut -f5 -d':' )
# Inspect with go templates:
crictl inspect --output go-template \
--template "$NAMESPACE_TMPL:$POD_TMPL" \
${CONTAINER_ID:?Container not found}
done
$ ./which-pod-am-i.sh python
default:webapp-color
e-commerce:e-com-1123
به هر حال، تمام این دستورات در سندباکس KodeKloud ارائه شده با دوره Udemy CKAD اجرا شدند. فریاد زدن به آنها برای ارائه فوق العاده
منبع عملی مقرون به صرفه و غیر قابل انقضا برای مطالعه برای گواهینامه های CNCF CKA/CKAD.