هر ماشین مجازی روی Proxmox VE، VMware vSphere، KVM، Hyper-V، oVirt / OLVM، Nutanix AHV و OpenStack، وصلشده به شبکهٔ فیزیکی: پورت سوئیچی که هر ماشین مجازی از آن بیرون میرود، اینکه آن پورت VLAN آن را عبور میدهد یا نه، به کجا میتواند بیخطر جابهجا شود، خرابی یک سوئیچ چه چیزی را از کار میاندازد، و ذخیرهسازی کی پر میشود. فقط خواندنی.
## در یک دقیقه
Zaryn هایپروایزرها و سوئیچهای شما را با همان جمعآوریکننده میخواند و این دو را در یک تصویر کنار هم میگذارد: هر ماشین مجازی، پورت فیزیکی سوئیچی که ترافیکش از آن بیرون میرود، و معنای اینها وقتی چیزی جابهجا میشود، پر میشود یا از کار میافتد. این صفحه از مبانی شروع میکند و تا جزئیات تصمیمگیری هر بررسی پیش میرود؛ هر جا کافی بود دست نگه دارید.
- **هایپروایزر را بهعنوان یک دستگاه اضافه کنید**، با کاربری که فقط میتواند نگاه کند: یک کلاستر Proxmox VE، یک VMware vCenter، یک میزبان KVM یا Hyper-V، یک engine در oVirt / OLVM، یک Nutanix Prism Central یا یک ابر OpenStack. چند پلتفرم میتوانند در یک سایت کنار هم باشند.
- **هر ماشین مجازی را همانجا که واقعاً هست ببینید**: میزبانش، آدرسهایش، VLANهایش و راه خروجش: `VM → bridge, VLAN 20 → bond0 → eno1 → sw1 Gi1/0/5`.
- **پیش از آنکه آسیب بزند باخبر شوید**: ماشین مجازیای که پورت سوئیچش VLAN آن را عبور نمیدهد، میزبانهایی که یک ماشین مجازی نمیتواند به آنها برود، میزبانی که فقط به یک سوئیچ وصل است، ماشینهای مجازیای که با ریاستارت یک سوئیچ قطع میشوند، دیتااستوری که ۹ روز دیگر پر میشود.
- **هیچ چیزی تغییر نمیکند**. جمعآوریکننده فقط میخواند، گذرواژهها روی جمعآوریکننده میمانند، و هر درخواستی که میفرستد پایینتر فهرست شده است.
```diagram
type: graph
title: Zaryn چه چیزی را میخواند، و به کجا میرود
alt: هایپروایزرها و سوئیچها را جمعآوریکننده با ورودهای فقطخواندنی میخواند؛ جمعآوریکننده آنچه خوانده را با HTTPS به Zaryn میفرستد
legend: path=HTTPS خروجی; ghost=فقطخواندنی
caption: روی هر چیزی بروید تا ببینید چیست. یک جمعآوریکننده همهٔ پلتفرمها و همهٔ سوئیچها را میخواند و در یک تصویر به هم وصل میکند.
---
box سایت شما | 2 3 66 56 good
node pve | Proxmox VE | 12 12 | host | | یک توکن API با نقش PVEAuditor: فقط میتواند نگاه کند
node vc | VMware vCenter | 12 28 | host | | یک حساب فقطخواندنی vCenter، با ورود و خروج در هر خواندن
node kvm | KVM، Hyper-V، … | 12 44 | host | | یک اسکریپت ثابت فقطخواندنی با SSH یا PowerShell
node sw | سوئیچها | 34 28 | switch | | کانفیگها و LLDP یا CDP آنها: هر میزبان به کدام پورت وصل است، و VLANهایش
node col | جمعآوریکننده | 54 28 | collector | accent | گذرواژهها را نگه میدارد، ماشینها را به پورت سوئیچ وصل میکند، فقط آنچه خوانده را میفرستد
node zaryn | Zaryn | 88 18 | cloud | accent | رسیدن VLAN، live migration، افزونگی و ذخیرهسازی را میسنجد
node you | شما | 88 44 | user | | زبانهٔ ماشینهای مجازی: هر ماشین، کجاست، چه چیزی رسیدگی میخواهد
link pve col | | ghost
link vc col | | ghost
link kvm col | | ghost
link sw col | SSH، فقطخواندنی | ghost
link col zaryn | HTTPS، خروجی | path
link zaryn you | ماشینها، بررسیها، پیشبینیها
```
## مبانی
تازه با مجازیسازی، یا با بخش شبکهای آن، آشنا شدهاید؟ این واژههایی است که بقیهٔ صفحه به کار میبرد.
### هایپروایزرها، ماشینهای مجازی و کانتینرها
یک **هایپروایزر** (Proxmox VE، VMware ESXi، Hyper-V، KVM، oVirt، Nutanix AHV؛ OpenStack هم روی میزبانهای زیادی KVM اجرا میکند) روی یک سرور فیزیکی چندین ماشین جدا از هم اجرا میکند: هر **ماشین مجازی** (VM) پردازنده، حافظه، دیسک و کارت شبکهٔ مجازی خودش را دارد که از منابع واقعی میزبان جدا شده است. کانتینرها (LXC) همین کار را سبکتر انجام میدهند و هستهٔ سیستمعامل میزبان را مشترک به کار میبرند. یک **کلاستر** از میزبانها اجازه میدهد ماشین مجازی در حال اجرا از یک میزبان به دیگری برود (**live migration**: vMotion یا Live Migration)، و وقتی میزبانش از کار افتاد روی میزبان دیگری دوباره بالا بیاید (**high availability** یا HA).
### یک ماشین مجازی چطور به شبکه میرسد
کارت شبکهٔ یک ماشین مجازی به هیچ چیز فیزیکی وصل نیست. به یک **سوئیچ مجازی** داخل میزبانش وصل است، و کابلهای خود میزبان ترافیکش را به شبکهٔ واقعی میبرند:
```diagram
type: graph
title: راه یک ماشین مجازی تا شبکهٔ واقعی
alt: کارت ماشین مجازی روی یک bridge در میزبان با برچسب VLAN است؛ bridge از یک bond دو لینک بالادست استفاده میکند که هر کدام به پورت یک سوئیچ وصلاند
legend: path=فریمهای ماشین مجازی از کجا میروند; down=کابل جدا شده
start: هر دو لینک برقرار
caption: روی هر بخش بروید تا ببینید چه میکند. فریمهای با برچسب VLAN 20 از bond و روی هر دو کابل بیرون میروند.
---
box میزبان pve1 | 2 4 55 52 accent
box شبکهٔ فیزیکی | 70 4 28 52 good
node web1 | web1 | 10 30 | vm | accent | ماشین مجازی: کارت eth0 آن به یک سوئیچ مجازی وصل است، نه به چیزی فیزیکی
node br | vmbr0 | 29 30 | switch | | bridge: سوئیچی داخل میزبان. فریمهای web1 را با VLAN 20 برچسب میزند
node eno1 | eno1 | 47 16 | dot | | یک پورت فیزیکی میزبان، یکی از دو پورت bond0
node eno2 | eno2 | 47 44 | dot | | پورت دیگر bond0 (LACP): هر کدام میتواند همهچیز را ببرد
node sw1 | sw1 Gi1/0/5 | 84 16 | switch | | یک پورت trunk که VLANهای ۱ و ۲۰ را میگذراند
node sw2 | sw2 Gi1/0/5 | 84 44 | switch | | یک پورت trunk که همهٔ VLANها را میگذراند
link web1 br | VLAN 20 | path
link br eno1 | bond0 | path
link br eno2 | bond0 | path
link eno1 sw1 | trunk 1,20 | path
link eno2 sw2 | trunk all | path
step یک کابل جدا میشود | لینک eno1 قطع میشود. bond همهچیز را به eno2 میبرد و web1 متوجه نمیشود: لینکهای بالادست افزونه برای همیناند.
link br eno1 | down
link eno1 sw1 | dim
node eno1 | bad
```
1. کارت ماشین مجازی روی یک **bridge** یا سوئیچ مجازی است (`vmbr0` در Proxmox، یک port group در vSphere، یک شبکهٔ منطقی در oVirt، یک subnet در Nutanix، یک شبکهٔ Neutron در OpenStack).
2. ترافیک ماشین مجازی معمولاً با یک شمارهٔ **VLAN** **برچسب** میخورد، که شبکهها را روی کابلهای مشترک از هم جدا نگه میدارد.
3. bridge روی پورتهای فیزیکی میزبان (**لینکهای بالادست** یا uplink) قرار دارد، که اغلب دو تا از آنها در یک **bond** (LACP، NIC team) کنار هم هستند تا اگر یکی از کار افتاد، دیگری کار کند.
4. هر لینک بالادست با کابل به یک **پورت سوئیچ** وصل است. پورت **trunk** VLANهای فهرست *allowed* خودش را با برچسب عبور میدهد؛ پورت **access** فقط یک VLAN را بدون برچسب عبور میدهد. اگر پورت VLAN ماشین مجازی را مجاز نکرده باشد، فریمهای ماشین مجازی همانجا از بین میروند.
### واژههایی که میبینید
| واژه | معنایش در اینجا |
|---|---|
| میزبان (Host) | یک سرور فیزیکی که هایپروایزر اجرا میکند |
| مهمان (Guest) | یک ماشین مجازی یا کانتینر روی یک میزبان |
| Bridge، vSwitch، port group | سوئیچ مجازیای که کارت ماشین مجازی به آن وصل است |
| VLAN | شمارهای که شبکهها را روی کابلهای مشترک جدا میکند (۱ تا ۴۰۹۴) |
| پورت trunk / access | پورت سوئیچی که چند VLAN برچسبدار / یک VLAN بیبرچسب را عبور میدهد |
| Allowed VLANs | VLANهایی که یک پورت trunk عبور میدهد (`switchport trunk allowed vlan`) |
| لینک بالادست (Uplink) | یکی از پورتهای فیزیکی میزبان به سمت سوئیچها |
| Bond، LACP، NIC team | چند لینک بالادست که مثل یکی کار میکنند تا یکی بتواند از کار بیفتد |
| LLDP، CDP | راهی که سوئیچ با آن میفهمد به هر پورتش چه چیزی وصل است |
| Overcommit | دادن vCPU یا حافظهٔ بیشتر از آنچه میزبان دارد به مهمانها |
| Datastore، pool، container | جایی که دیسکهای ماشینهای مجازی نگه داشته میشوند |
## چرا امروز سخت است
مجازیسازی ساختن سرور را ارزان و جابهجا کردنش را آسان کرد، اما شبکه پا به پای آن عوض نشد. فاصلهٔ میان این دو، بخش بزرگی از سختتوضیحترین حادثهها را میسازد:
- **دو تیم، دو نگاه.** تیم شبکه آدرس MAC و پورت سوئیچ میبیند؛ تیم مجازیسازی نام ماشین مجازی و میزبان. پاسخ به «`erp-db` از کدام پورت سوئیچ بیرون میرود؟» یک جلسه طول میکشد، و با vMotion بعدی کهنه میشود.
- **ماشینهای مجازی جابهجا میشوند؛ کانفیگ سوئیچها نه.** live migration و HA ماشین مجازی را به میزبانی میبرند که شاید پورت سوئیچش VLAN آن را عبور ندهد. ماشین مجازی روشن است، هایپروایزر سبز نشان میدهد، و هیچ چیز به آن نمیرسد. این یکی از رایجترین دلیلهای «دیروز کار میکرد» است.
- **افزونگیای که افزونگی نیست.** یک bond از دو کابل فقط وقتی افزونه است که به دو سوئیچ برسد. اگر هر دو روی یک سوئیچ باشند، یا یکی ماهها پیش جدا شده باشد، ریاستارت یک سوئیچ همهٔ ماشینهای مجازی آن میزبان را قطع میکند.
- **چند پلتفرم همزمان.** تغییرهای لایسنس از سال ۲۰۲۴ (بهویژه بستههای جدید VMware پس از Broadcom) بسیاری از سازمانها را به افزودن یا رفتن به Proxmox، Nutanix، Hyper-V، OpenStack یا oVirt واداشت. کمتر کسی فقط یک پلتفرم دارد؛ بیشترشان دو یا سه تا دارند، هر کدام با کنسول خودش، و هیچکدام شبکه را نشان نمیدهد.
- **غافلگیریهای ظرفیت.** حافظهای که بیش از آنچه میزبانها دارند واگذار شده، و ذخیرهسازیای که هر روز کمی پرتر میشود تا ماشینهای مجازی متوقف شوند.
- **مهاجرت بدون نقشه.** جابهجا کردن ماشینهای مجازی بدون دانستن اینکه چه کسی با چه کسی حرف میزند، برنامهها را میان پلتفرم قدیم و جدید تکهتکه میکند.
- **ابزارهایی که بیش از حد میخواهند.** بسیاری از ابزارهای دیدپذیری دسترسی نوشتن، عامل داخل هر ماشین مجازی، یا اتصال SaaS به شبکهٔ مدیریت میخواهند، و تیمهای امنیت بهدرستی میگویند نه.
## آنچه Zaryn میدهد
| مشکل | کاری که Zaryn میکند | کجا میبینیدش |
|---|---|---|
| دو تیم، دو نگاه | هر ماشین مجازی را به میزبانش، bridge و VLANش، پورتهای فیزیکی میزبان و پورت سوئیچ آن سر وصل میکند | زبانهٔ Virtual machines، جزئیات هر ماشین مجازی |
| VLAN گمشده پس از جابهجایی | کانفیگ سوئیچها را میخواند و بررسی میکند که هر پورتی که ترافیک ماشین مجازی از آن میگذرد VLAN آن را عبور بدهد | ✓ / ✗ روی هر لینک بالادست، **آنچه رسیدگی میخواهد** |
| live migrationهای ناامن | برای هر ماشین مجازی، میزبانهایی از کلاسترش که میتواند با شبکه و دیسکهای سالم به آنها برود، و دلیل نرفتن به بقیه | **کجا میتواند جابهجا شود**، در جزئیات ماشین مجازی |
| افزونگیای که افزونگی نیست | به لینکهای بالادست هر میزبان نمره میدهد: افزونه، یک سوئیچ، یک پورت، یا نامعلوم | نشان روی هر میزبان |
| «اگر این سوئیچ ریاستارت شود چه چیزی خراب میشود؟» | برای هر سوئیچ، میزبانهایی که قطع میشوند و ماشینهای مجازی در حال اجرایی که خاموش میشوند، و میزبانهایی که فقط افزونگی را از دست میدهند | **اگر یک سوئیچ از کار بیفتد** |
| پر شدن ذخیرهسازی | میزان پری برای همهٔ پلتفرمها، و پیشبینی بر اساس نمونهای در هر ساعت | **ذخیرهسازی**: «حدود ۹ روز دیگر پر میشود» |
| دیسکهای thin بیش از ظرفیت ذخیرهسازی | جمع اندازهٔ دیسکهای ماشینهای مجازی روی هر ذخیرهسازی، کنار ظرفیتش | **ذخیرهسازی**: «دیسکهای ماشینها: 3 TB (۳۰۰٪ اندازهاش)» |
| Overcommit | vCPU به ازای هر CPU فیزیکی و حافظهٔ واگذارشده، برای هر میزبان و در کل | ردیف ظرفیت، هر میزبان |
| چند پلتفرم | یک فهرست برای هفت پلتفرم، کنار هم | همان زبانه، هر پلتفرمی که باشد |
| مهاجرتها | موجهایی که از روی «چه کسی با چه کسی حرف میزند» برنامهریزی میشوند | **Plan a migration** |
| بازبینیهای امنیتی | کاربرهای فقطخواندنی، بدون عامل در ماشینهای مجازی، گذرواژهها روی جمعآوریکنندهٔ خود شما | **آنچه جمعآوریکننده میفرستد** |
## افزودن یک هایپروایزر
همهٔ پلتفرمها به یک شکل اضافه میشوند: کاربری بسازید که فقط بتواند نگاه کند، آن را با `zev site cred add` به [جمعآوریکننده](/docs/fa/network-sites) بدهید، با `zev site test` امتحانش کنید، بعد هایپروایزر را بهعنوان دستگاه به سایت اضافه کنید.
| پلتفرم | بهعنوان یک دستگاه اضافه کنید | کاربری که لازم دارد | پورت | چطور خوانده میشود |
|---|---|---|---|---|
| Proxmox VE | هر نود (کل کلاستر) | توکن API، نقش PVEAuditor | 8006 | REST، فقط GET |
| VMware vSphere | vCenter | نقش Read-only | 443 | REST (فقط GET) و SOAP (فقط خواندن)، هر کدام با یک نشست |
| KVM (libvirt) | هر میزبان | کاربر SSH | 22 | `virsh -r` (اتصال فقطخواندنی) |
| Hyper-V | یک نود (کل failover cluster) | کاربر SSH در Hyper-V Administrators | 22 | یک اسکریپت ثابت از cmdletهای `Get-` |
| oVirt / OLVM | engine | نقش ReadOnlyAdmin | 443 | REST، فقط GET |
| Nutanix AHV | Prism Central | نقش Prism Viewer | 9440 | فراخوانیهای list در v3 |
| OpenStack | Keystone (کل region) | نقش reader | 5000 | یک توکن، فقط GET، باطل کردن توکن |
## افزودن یک کلاستر Proxmox VE
Zaryn فقط میخواند، از راه API پراکسماکس، با توکنی که فقط میتواند نگاه کند (نقش داخلی `PVEAuditor`). روی یکی از نودهای Proxmox:
```bash
pveum user add zev@pve
pveum acl modify / --users zev@pve --roles PVEAuditor
pveum user token add zev@pve zaryn --privsep 0
```
دستور آخر رمز توکن را یک بار نشان میدهد. روی [جمعآوریکننده](/docs/fa/network-sites):
```bash
zev site cred add pve --user 'zev@pve!zaryn' --password-stdin
zev site test 10.0.0.11 --cred pve --vendor proxmox
```
بعد کلاستر را بهعنوان یک دستگاه به سایت اضافه کنید: آدرس هر یک از نودها، سازنده **Proxmox VE**، اعتبارنامهٔ `pve`. پورت ۸۰۰۶ است مگر خلافش را بگویید. یک دستگاه یعنی کل کلاستر: API بهجای همهٔ نودها پاسخ میدهد.
جمعآوریکننده فقط درخواست GET میفرستد. رمز روی جمعآوریکننده میماند، مثل گذرواژهٔ دستگاهها؛ Zaryn فقط نام اعتبارنامه را میداند.
### گواهی TLS
نودهای Proxmox معمولاً گواهی خودامضا دارند. جمعآوریکننده بار اولی که به یکی میرسد کلید عمومی گواهی را نگه میدارد (`tls_pins.json`، مثل `known_hosts` در SSH) و از آن پس هر کلید دیگری را رد میکند: کسی که در میانه است نمیتواند توکن را بخواند. اگر گواهی را عمداً عوض کردهاید:
```bash
zev site forget-key 10.0.0.11 --port 8006
```
## افزودن یک VMware vCenter
Zaryn محیط vSphere را از راه REST API در vCenter میخواند (vCenter 7.0 Update 2 یا جدیدتر)، و آنچه REST نمیگوید را از SOAP API آن، با کاربری که نقش داخلی **Read-only** دارد. در vSphere Client: Administration ← Single Sign On ← Users، کاربر `zev@vsphere.local` را بسازید؛ بعد روی شیء vCenter، Permissions ← Add، همان کاربر با نقش **Read-only** و **Propagate to children**. روی جمعآوریکننده:
```bash
zev site cred add vc --user zev@vsphere.local --password-stdin
zev site test vcenter.lab.local --cred vc --vendor vsphere
```
vCenter را بهعنوان یک دستگاه اضافه کنید: آدرسش، سازنده **VMware vSphere**، اعتبارنامهٔ `vc`، پورت ۴۴۳. یک دستگاه یعنی هر چه آن vCenter مدیریت میکند: کلاسترها، میزبانهای ESXi، ماشینهای مجازی و datastoreها. میزبانهای ESXi از راه vCenterشان خوانده میشوند، نه یکییکی.
جمعآوریکننده وارد میشود (یک درخواست یک نشست باز میکند)، بعد فقط میخواند، بعد خارج میشود. کلید TLS همانطور که برای Proxmox گفته شد سنجاق میشود.
REST API در vCenter شبکهٔ زیر ماشینهای مجازی را نمیگوید، پس جمعآوریکننده در همان سر زدن SOAP API را هم میخواند (`/sdk`، همانی که PowerCLI و govc به کار میبرند)، با همان کاربر و فقط خواندن:
- **vmnic**های هر میزبان ESXi، **vSwitch**های استانداردش و vmnicهایی که هر کدام به کار میبرد (فعال و آمادهبهکار)؛
- **VLAN هر port group**، روی vSwitchهای استاندارد و روی **distributed switch**ها (port group از نوع trunk بازههایش را نشان میدهد)؛
- اینکه هر میزبان کدام vmnicها را به هر distributed switch داده، و آدرسهای **VMkernel** آن (`vmk0`) که آدرس میزبان میشود؛
- اینکه کدام میزبانها **هر datastore را mount کردهاند** و به آن دسترسی دارند.
پس شبکهٔ یک ماشین مجازی port group آن با VLANش است، و راه خروجش port group ← vSwitch یا distributed switch ← vmnic ← پورت سوئیچی است که LLDP یا CDP برای آن vmnic گزارش میکند (LLDP یا CDP را روی vSwitch یا distributed switch روشن کنید تا سوئیچها میزبانها را ببینند). آدرسها از VMware Tools یا جدولهای ARP سوئیچها میآیند. اگر SOAP API خوانده نشود (مثلاً پروکسیای که فقط `/api` را رد میکند)، دستگاه همین را میگوید و بقیه مثل قبل کار میکند.
```diagram
type: sequence
title: یک سر زدن به vCenter
lanes: جمعآوریکننده | vCenter
alt: جمعآوریکننده یک نشست REST باز میکند و با GET میخواند، بعد یک نشست SOAP باز میکند، میزبانها، سوئیچها، port groupها و datastoreها را از راه یک container view صفحه به صفحه میخواند، و از هر دو خارج میشود
---
== REST ==
جمعآوریکننده -> vCenter : POST /api/session، بعد GETها: کلاسترها، میزبانها، ماشینها، datastoreها
جمعآوریکننده -> vCenter : DELETE /api/session
== SOAP، فقط خواندن ==
جمعآوریکننده -> vCenter : Login، CreateContainerView
جمعآوریکننده -> vCenter : RetrievePropertiesEx: کارتهای میزبانها، port groupها، distributed switchها، mountها
vCenter --> جمعآوریکننده : صفحه به صفحه (ContinueRetrievePropertiesEx)
جمعآوریکننده -> vCenter : DestroyView، Logout
note جمعآوریکننده..vCenter : هیچ چیزی ساخته، عوض یا روشن و خاموش نمیشود | good
```
## افزودن یک میزبان KVM (libvirt)
یک سرور لینوکسی معمولی که ماشینهای مجازی KVM را با libvirt اجرا میکند (`virsh`، virt-manager، Cockpit) مثل یک روتر از راه SSH خوانده میشود. جمعآوریکننده یک اسکریپت ثابت اجرا میکند: `virsh` با **`-r`**، یعنی اتصال فقطخواندنی libvirt، برای ماشینهای مجازی، کانفیگها، وضعیت، دیسکها، شبکهها و استخرهای ذخیرهسازی، و `ip -j addr show` برای پلها و bondهای میزبان. هیچ چیز دیگری.
دسترسی root لازم نیست: سوکت فقطخواندنی libvirt برای همهٔ کاربرهای محلی باز است، مگر اینکه توزیع آن را بسته باشد. روی میزبان یک کاربر بسازید و ببینید میتواند ماشینها را فهرست کند:
```bash
sudo useradd -m zev && sudo passwd zev
sudo -u zev virsh -r -c qemu:///system list --all
```
اگر خطای دسترسی داد، توزیع سوکت فقطخواندنی را محدود کرده است (`unix_sock_ro_perms` در `/etc/libvirt/libvirtd.conf`، یا گروه `/run/libvirt/libvirt-sock-ro`): آن را برای این کاربر باز کنید. افزودن کاربر به گروه `libvirt` هم کار میکند، هرچند آن گروه میتواند ماشینها را تغییر هم بدهد؛ جمعآوریکننده باز هم فقط `virsh -r` اجرا میکند. روی جمعآوریکننده:
```bash
zev site cred add kvm --user zev --password-stdin # یا --key ~/.ssh/zev_kvm
zev site test 10.0.0.21 --cred kvm --vendor kvm
```
میزبان را بهعنوان دستگاه اضافه کنید: آدرسش، سازندهٔ **KVM / libvirt**، اعتبارنامهٔ `kvm` (SSH، پورت 22). libvirt نمای کلاستر ندارد، پس هر میزبان دستگاه جداگانهای است. کلید میزبان در اولین تماس نگه داشته میشود، مثل هر دستگاه SSH دیگری.
کارت شبکهٔ یک ماشین مجازی روی یک پل لینوکسی است (`br0`، با برچسب VLAN آن)، یا یک شبکهٔ libvirt (`default` با پل `virbr0`؛ VLAN یک portgroup هم خوانده میشود)، یا یک پل Open vSwitch، یا مستقیم روی یک پورت میزبان (macvtap). دیسکها از روی مسیرشان به استخر ذخیرهسازیشان نسبت داده میشوند. هر ماشین مجازی با UUID خودش شناخته میشود، پس تغییر نامش تاریخچهاش را از بین نمیبرد.
## افزودن یک میزبان Hyper-V
یک Windows Server با Hyper-V از راه **سرور OpenSSH خود ویندوز** خوانده میشود (که در Windows Server 2019 و جدیدتر هست)، پس جمعآوریکننده نه WinRM لازم دارد و نه عاملی روی ویندوز. روی میزبان، در یک PowerShell با دسترسی مدیر:
```powershell
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd; Set-Service sshd -StartupType Automatic
Add-LocalGroupMember -Group "Hyper-V Administrators" -Member "CORP\zev"
```
Hyper-V نقش فقطخواندنی ندارد: خواندن ماشینهای مجازی عضویت در **Hyper-V Administrators** را میخواهد، گروهی که میتواند آنها را تغییر هم بدهد. آنچه کار را فقطخواندنی نگه میدارد خود جمعآوریکننده است: یک اسکریپت ثابت PowerShell از cmdletهای `Get-` میفرستد (`Get-VM`، `Get-VMNetworkAdapter`، `Get-VMNetworkAdapterVlan`، `Get-VMHardDiskDrive`، `Get-VHD`، `Get-VMSwitch`، `Get-NetAdapter`، `Get-NetIPAddress`، `Get-Volume`، `Get-ClusterNode`، `Get-ClusterSharedVolume`) که با `ConvertTo-Json` تمام میشود، و هیچ چیزی که سرور بگوید نمیتواند آن را به فرستادن چیز دیگری وادار کند. اسکریپت در کد منبع zev است (`src/core/netdev/virt_host.zig`). روی جمعآوریکننده:
```bash
zev site cred add hv --user 'CORP\zev' --password-stdin
zev site test hv01.corp.local --cred hv --vendor hyperv
```
میزبان را بهعنوان دستگاه اضافه کنید: سازندهٔ **Microsoft Hyper-V**، اعتبارنامهٔ `hv`. در یک failover cluster یک نود را اضافه کنید: جمعآوریکننده ماشینهای مجازی هر نود را میپرسد (`Get-VM -ComputerName`)، و نودها و volumeهای اشتراکی کلاستر هم فهرست میشوند. اگر این حساب از آنجا به نودهای دیگر نمیرسد، هر نود را دستگاه جداگانهای کنید.
کارت شبکهٔ هر ماشین مجازی سوئیچ مجازی و VLAN خودش را نشان میدهد (حالت access؛ برای حالت trunk، `trunk`)، آدرسهایش را از integration services در Hyper-V، و دیسکهای مجازیاش را همراه با volume یا cluster shared volume که رویش هستند. راه خروج یک سوئیچ مجازی، کارتهای فیزیکی آن است، و اگر NIC team باشد از راه آن. اگر حساب نتواند volumeها را بخواند، فهرست ذخیرهسازی خالی میماند؛ بقیه کار میکند.
## افزودن یک engine در oVirt یا OLVM
oVirt و محصولاتی که روی آن ساخته شدهاند (**Oracle Linux Virtualization Manager** و Red Hat Virtualization) از راه REST API خود engine خوانده میشوند (`/ovirt-engine/api`، oVirt 4.4 یا جدیدتر)، با کاربری که نقش آمادهٔ **ReadOnlyAdmin** را دارد. روی ماشین engine، کاربر را در دامنهٔ internal بسازید:
```bash
ovirt-aaa-jdbc-tool user add zev
ovirt-aaa-jdbc-tool user password-reset zev --password-valid-to="2030-01-01 00:00:00Z"
```
بعد در Administration Portal: Administration ← Configure ← System Permissions ← Add، کاربر `zev`، نقش **ReadOnlyAdmin**. روی engineی که ورود را از راه Keycloak انجام میدهد (پیشفرض oVirt 4.5)، کاربر را بهجای آن در Keycloak بسازید؛ نامش آنوقت `zev@ovirt@internalsso` است. روی جمعآوریکننده:
```bash
zev site cred add olvm --user zev@internal --password-stdin
zev site test engine.lab.local --cred olvm --vendor ovirt
```
engine را بهعنوان دستگاه اضافه کنید: آدرسش، سازندهٔ **oVirt / OLVM**، اعتبارنامهٔ `olvm` (HTTPS روی ۴۴۳). یک دستگاه یعنی همهٔ آنچه آن engine مدیریت میکند: کلاسترها، میزبانها، ماشینهای مجازی، شبکههای منطقی و storage domainها. جمعآوریکننده فقط درخواست GET میفرستد، چند تا در هر بار خواندن (ماشینهای مجازی با کارتهای شبکه، آدرسهای داخل مهمان، دیسکها و برچسبهایشان در یک درخواست میآیند)، با گذرواژه روی هر کدام، پس هیچ نشستی باز نمیماند. کلید TLS همانطور که برای Proxmox گفته شد pin میشود.
کارت شبکهٔ یک ماشین مجازی روی یک **vNIC profile** است که به یک **شبکهٔ منطقی** تعلق دارد، و آن شبکه ممکن است VLAN داشته باشد. روی هر میزبان، یک شبکهٔ منطقی یک bridge همنام است روی پورت، bond یا VLANی که به آن وصل شده (Setup Host Networks)، پس راه خروج مثل Proxmox است: `nic1 → prod VLAN 20 → bond0 → eno1 → sw1 Gi1/0/8`. آدرسها از guest agentی میآیند که engine گزارش میکند (`qemu-guest-agent` داخل ماشین مجازی). دیسکها storage domainی را که رویش هستند نشان میدهند؛ فقط data domainها جزو ذخیرهسازی شمرده میشوند. هر ماشین مجازی با UUID خودش شناخته میشود. میزبانی که در حالت maintenance است یا به engine جواب نمیدهد، خاموش نشان داده میشود.
## افزودن یک Nutanix Prism Central
کلاسترهای Nutanix AHV از راه REST API نسخهٔ v3 در **Prism Central** خوانده میشوند (Prism Central 2022.6 یا جدیدتر؛ کلاستری که فقط با Prism Element مدیریت میشود باید اول در یک Prism Central ثبت شود)، با کاربری که نقش آمادهٔ **Prism Viewer** را دارد. در Prism Central: Admin Center ← IAM ← Local User Management، کاربر `zev` را اضافه کنید؛ بعد Authorization Policies ← Create، نقش **Prism Viewer**، همان کاربر، روی همهٔ کلاسترها. کاربر دایرکتوری هم همینطور کار میکند. روی جمعآوریکننده:
```bash
zev site cred add prism --user zev --password-stdin
zev site test prism.lab.local --cred prism --vendor nutanix
```
Prism Central را بهعنوان دستگاه اضافه کنید: آدرسش، سازندهٔ **Nutanix AHV**، اعتبارنامهٔ `prism` (HTTPS روی ۹۴۴۰). یک دستگاه یعنی همهٔ کلاسترهایی که آن Prism Central مدیریت میکند: میزبانهای AHV، ماشینهای مجازی و subnetهایشان. خود Prism Central و ماشینهای مجازی خودش کنار گذاشته میشوند.
API نسخهٔ v3 در Prism فهرستها را با یک POST میخواهد که بدنهاش میگوید کدام صفحه فرستاده شود (`POST /api/nutanix/v3/vms/list`). اینها تنها درخواستهای جمعآوریکنندهاند: کلاسترها، میزبانها، subnetها و ماشینهای مجازی، صفحه به صفحه. یک Prism Viewer هر چه فرستاده شود نمیتواند چیزی را تغییر دهد، و گذرواژه همراه هر درخواست میرود، پس هیچ نشستی باز نمیماند. کلید TLS همانطور که برای Proxmox گفته شد pin میشود.
کارت شبکهٔ یک ماشین مجازی روی یک **subnet** با VLAN خودش است. آدرسهایش همانهایی است که AHV میداند: آنهایی که مدیریت آدرس IP خود AHV داده، یا از ترافیک ماشین مجازی یاد گرفته شدهاند. دیسکها storage containerی را که رویش هستند نشان میدهند؛ CD-ROM کنار گذاشته میشود. Categoryها (`Environment: Production`) بهشکل برچسب نشان داده میشوند. هر ماشین مجازی با UUID خودش شناخته میشود.
آنچه API نسخهٔ v3 در Prism نمیگوید و بنابراین Zaryn هنوز نشان نمیدهد: سوئیچ مجازی یک میزبان از کدام پورتهای فیزیکی استفاده میکند، و هر storage container چقدر پر است. راه خروج یک میزبان از همسایههای LLDP یا CDP سوئیچها میآید، مثل vSphere.
## افزودن یک ابر OpenStack
یک ابر OpenStack از راه APIهای خودش خوانده میشود: Keystone برای توکن و فهرست سرویسها، Nova برای سرورها و هایپروایزرها، Neutron برای شبکهها، پورتها و floating IPها، و Cinder برای volumeها. Keystone باید روی HTTPS جواب بدهد. کاربری با نقش **reader** روی کل ابر بسازید (نقشی با scope سیستمی):
```bash
openstack user create --domain Default --password-prompt zev
openstack role add --user zev --user-domain Default --system all reader
```
روی جمعآوریکننده:
```bash
zev site cred add cloud --user zev@Default --password-stdin
zev site test keystone.cloud.local --cred cloud --vendor openstack
```
ابر را بهعنوان دستگاه اضافه کنید: آدرس Keystone، سازندهٔ **OpenStack**، اعتبارنامهٔ `cloud` (پورت ۵۰۰۰). یک دستگاه یعنی همهٔ آنچه در آن region هست: سرورهای همهٔ projectها، هایپروایزرها، شبکهها و volumeها.
نام کاربر بهشکل `name@domain` است و توکن scope سیستمی دارد. یک reader سیستمی وقتی ابر از پیشفرضهای جدید policy در OpenStack استفاده میکند (`[oslo_policy] enforce_new_defaults` و `enforce_scope`، که در نسخههای اخیر بهطور پیشفرض روشناند) همهٔ projectها را میبیند. در ابری که هنوز پیشفرضهای قدیمی را دارد، یک reader فقط project خودش را میبیند: نامش را بدهید، `--user 'zev@Default/shop'`، با نقش reader روی همان project (`openstack role add --user zev --project shop reader`). آنوقت فقط سرورهای آن project فهرست میشوند و هایپروایزرها پنهان میمانند. با پیشفرضهای قدیمی، دیدن همهٔ projectها نقش admin را میخواهد، حسابی که میتواند چیزها را تغییر هم بدهد.
آنچه جمعآوریکننده میفرستد: یک POST به Keystone برای توکن (گذرواژه در یک فایل خصوصی میرود، هیچوقت در خط فرمان نیست)، بعد فقط GET، و در آخر یک DELETE که توکن را باطل میکند. endpointها از فهرست داخل توکن میآیند و endpointهای عمومی استفاده میشوند؛ endpointهای HTTPS مثل خود Keystone در اولین تماس pin میشوند، و endpointهای HTTP همانطور که ابر منتشرشان کرده خوانده میشوند.
کارتهای شبکهٔ یک سرور همان پورتهای Neutron آن است: شبکه، VLAN آن اگر شبکه از نوع VLAN provider باشد (شبکههای tenant از نوع VXLAN و Geneve، VLAN ندارند)، آدرسهای ثابت با prefix زیرشبکهشان، و floating IP اگر باشد. دیسکها دیسک ریشهٔ موقت flavor هستند، یا volumeهای Cinder وصلشده، هر کدام با backend خودش (`ceph-ssd`). هر سرور با project خودش برچسب میخورد. هر سرور با UUID خودش شناخته میشود، پس evacuation یا live migration بهشکل جابهجایی نشان داده میشود.
آنچه APIهای OpenStack نمیگویند و بنابراین Zaryn هنوز نشان نمیدهد: یک هایپروایزر از کدام پورتهای فیزیکی استفاده میکند، و هر backend ذخیرهسازی چقدر پر است. راه خروج یک هایپروایزر از همسایههای LLDP یا CDP سوئیچها میآید (روی نودهای compute بستهٔ `lldpd` را نصب کنید).
## آنچه میبینید
سایتی که هایپروایزر دارد یک زبانهٔ **Virtual machines** میگیرد:
- **ظرفیت**: میزبانها، مهمانهای در حال اجرا، vCPU به ازای هر CPU فیزیکی (overcommit)، حافظهٔ واگذارشده به مهمانهای در حال اجرا در برابر آنچه میزبانها دارند، ذخیرهسازی مصرفشده (ذخیرهسازی اشتراکی مثل Ceph یک بار شمرده میشود).
- **آنچه رسیدگی میخواهد**: ریسکهای پایین، بدترین اول. هدف این است که خالی باشد.
- **اگر یک سوئیچ از کار بیفتد**: هر سوئیچی که میزبانها به آن وصلاند، با میزبانهایی که قطع میکند، مهمانهای در حال اجرایی که همراهشان میروند، و میزبانهایی که فقط افزونگی را از دست میدهند.
- **میزبانها**: CPU و حافظهٔ مصرفی، vCPU روی CPUهای فیزیکی، مهمانهای هر کدام، لینکهای بالادست میزبان (هر پورت فیزیکی به کدام پورت سوئیچ میرود، و آیا آن پورت VLANها را عبور میدهد) و نشان افزونگی.
- **مهمانها**: هر ماشین مجازی و کانتینر با میزبان، وضعیت، اندازه، آدرسها و VLANهایش؛ با نام، شناسه، برچسب، آدرس، MAC یا VLAN فیلتر کنید. یکی را باز کنید تا راه خروج هر کارت شبکه (`net0 → vmbr0 VLAN 20 → bond0 → eno1 → sw1 Gi1/0/5 ✓`)، اینکه با چه کسی حرف میزند، دیسکهایش و **کجا میتواند جابهجا شود** را ببینید.
- **ذخیرهسازی**: هر datastore، pool، storage domain یا container، اینکه چقدر پر است، و با سرعت فعلی کی پر میشود.
### آدرسها از کجا میآیند
به ترتیب: **QEMU guest agent** (برای ماشینهای مجازی در حال اجرایی که آن را دارند)، **VMware Tools**، **integration services** در Hyper-V، guest agent آنطور که engine در oVirt گزارش میکند، آنچه AHV و Neutron میدانند، کانفیگ خود کانتینر، وگرنه **جدولهای ARP** روترها و سوئیچهای سایت، که بر اساس MAC جفت میشوند. هر آدرس میگوید از کجا آمده است. در KVM اتصال فقطخواندنی نمیتواند از guest agent بپرسد، پس اول اجارههای DHCP خود libvirt و جدول ARP میزبان میآیند.
### لینکهای بالادست از کجا میآیند
همسایههای LLDP و CDP سوئیچها نام میزبان و پورت میزبان در آن سر را میگویند. روی میزبانهای Proxmox، KVM، oVirt و نودهای compute در OpenStack بستهٔ `lldpd` را نصب کنید (`apt install lldpd`) تا سوئیچها آنها را ببینند؛ در ESXi، LLDP یا CDP را روی vSwitch یا distributed switch روشن کنید؛ در ویندوز، قابلیت Data Center Bridging یک عامل LLDP دارد (`Install-WindowsFeature Data-Center-Bridging`، بعد `Enable-NetLldpAgent`). پورتی که هیچ سوئیچی گزارشش نکند با `→ ?` نشان داده میشود.
## بررسیهای شبکه با جزئیات
این بخش برای کسی است که باید به پاسخها اعتماد کند: هر بررسی دقیقاً به چه چیزی نگاه میکند، و کی بهجای حدس زدن میگوید «نمیدانم». هیچ بررسیای چیزی نامعلوم را به علامت قرمز تبدیل نمیکند.
### رسیدن VLAN
همان ناهمخوانی کلاسیک VLAN (VLAN mismatch): یک vMotion یا live migration ماشین مجازی را روی میزبانی مینشاند که پورت سوئیچش VLAN آن را مجاز نکرده است. این بررسی پیش از آنکه کسی متوجه قطعی شود آن را پیدا میکند، و برای همهٔ ماشینهای مجازی، نه فقط آنهایی که جابهجا شدهاند.
```diagram
type: graph
title: ناهمخوانی VLAN که هیچکس نمیبیند
alt: یک ماشین مجازی از میزبان pve1 به میزبان pve3 میرود که پورت سوئیچش فقط VLANهای ۱ و ۳۰ را میگذراند، پس ماشین روشن است ولی در دسترس نیست
legend: path=ترافیک ماشین از کجا میرود; ghost=کجا بود; down=VLAN رد نمیشود
start: web1 روی pve1
caption: web1 روی pve1 اجرا میشود که پورت سوئیچش VLAN 20 را میگذراند. همهچیز کار میکند.
---
box رک A | 2 4 44 52 dim
box رک B | 54 4 44 52 dim
node pve1 | pve1 | 14 20 | host | | لینک بالادستش به sw1 میرود، یک trunk که VLANهای ۱ و ۲۰ را میگذراند
node sw1 | sw1 trunk 1,20 | 34 20 | switch | good | VLAN 20 را میگذراند: ترافیک web1 رد میشود
node web1 | web1 VLAN 20 | 50 40 | vm | accent | هر جا اجرا شود با VLAN 20 برچسب میخورد
node pve3 | pve3 | 70 20 | host | | همان کلاستر، رکی دیگر: لینک بالادستش به sw3 میرود
node sw3 | sw3 trunk 1,30 | 88 20 | switch | | فقط VLANهای ۱ و ۳۰ را میگذراند
link web1 pve1 | اینجا اجرا میشود | path
link pve1 sw1 | VLAN 20 ✓ | path
link web1 pve3 | | ghost
link pve3 sw3 | | dim
step live migration به pve3 | HA یا یک vMotion، web1 را به pve3 میبرد. هایپروایزر میگوید سبز است: ماشین در حال اجراست.
link web1 pve1 | ghost | اینجا بود
link pve1 sw1 | dim
link web1 pve3 | path | live migration
link pve3 sw3 | path
step VLAN 20 روی sw3 نیست | trunk سوئیچ sw3 اجازهٔ VLAN 20 را نمیدهد، پس هر فریمی که web1 میفرستد در پورت سوئیچ از بین میرود. Zaryn فهرست مجاز sw3 را میخواند و این لینک را پیش از آنکه کسی ماشین را جابهجا کند علامت میزند.
link pve3 sw3 | down | VLAN 20 ✗
node sw3 | bad
node web1 | bad
note 76 52 | روشن، ولی دستنیافتنی | bad
```
برای هر کارت شبکهٔ ماشین مجازی که VLAN دارد، Zaryn لینکهای بالادستش را تا پورتهای سوئیچ در آن سر دنبال میکند (از روی LLDP یا CDP)، بعد VLANهای آن پورتها را از کانفیگ در حال اجرای سوئیچها میخواند، که جمعآوریکننده از قبل برای [تاریخچهٔ کانفیگ](/docs/fa/network-sites) نگه میدارد:
- **Cisco IOS / IOS-XE**: `switchport mode`، `switchport trunk allowed vlan` با شکلهای `add`، `remove`، `except`، `all` و `none`، `switchport trunk native vlan`، `switchport access vlan`. trunkی که فهرست allowed ندارد همهٔ VLANها را عبور میدهد.
- **Huawei VRP**: `port link-type trunk | access | hybrid`، `port trunk allow-pass vlan` (با بازههای `to` و `all`)، `undo port trunk allow-pass vlan`، `port default vlan`، `port hybrid tagged vlan`. یک trunk تا وقتی چیز دیگری گفته نشده فقط VLAN 1 را عبور میدهد.
VLAN برچسبدار در سمت ماشین مجازی یعنی فریم برچسبدار روی لینک بالادست، پس پورت سوئیچ باید trunk (یا hybrid) باشد و فهرست allowed آن، این VLAN را داشته باشد. پورت access در این بررسی رد میشود حتی اگر شمارهٔ VLANش همان باشد، چون فریم برچسبدار را نمیپذیرد. هر لینک بالادست آنوقت ✓ یا ✗ را همراه با دلیل نشان میدهد: `trunk port without VLAN 20 (allowed: 10,30)`.
وقتی پاسخ معلوم نیست هیچ علامتی داده نمیشود: کارت ماشین مجازی بدون VLAN (از VLAN بومی یا access پورت استفاده میکند، یا port groupی در vSphere با VLAN صفر یا 4095)، سوئیچی که کانفیگش هنوز تحلیل نمیشود (MikroTik، FRRouting، VyOS)، یا پورت میزبانی که هیچ سوئیچی گزارشش نمیکند.
### یک ماشین مجازی کجا میتواند برود
برای هر ماشین مجازی که VLAN یا دیسک دارد، هر میزبان روشن دیگرِ همان کلاستر طوری بررسی میشود که انگار ماشین مجازی همین الان به آن رفته است. شبکه و دیسکها هر کدام یک علامت جدا میگیرند:
1. **شبکه**، برای ماشینهایی که VLAN دارند. در پلتفرمهایی که شبکهٔ میزبان را گزارش میکنند (Proxmox، KVM، Hyper-V، oVirt)، میزبان باید همان bridge، سوئیچ مجازی یا شبکهٔ منطقی را داشته باشد: `no vmbr0 on pve3`. هر VLAN ماشین مجازی باید از همهٔ پورتهای سوئیچی که لینکهای بالادست آن میزبان به آنها میرسند عبور کند: `VLAN 20 not on sw1 Gi1/0/6`.
2. **دیسکها.** ذخیرهسازی مشترک (Ceph، NFS، iSCSI، یک cluster shared volume، یک container در Nutanix، یک pool در Cinder) باید از میزبان مقصد دیده شود: `ceph isn't on pve3`. دیسکی که روی ذخیرهسازی محلی است همراه ماشین کپی میشود، پس میزبان مقصد همان ذخیرهسازی را با جای کافی لازم دارد: `local-lvm on pve2 has 5 GiB free, its disks there need 20 GiB`.
پاسخ ✓ (بیخطر)، ✗ همراه با دلیلها، یا `?` است وقتی چیزی معلوم نیست، مثل پورتهای سوئیچ میزبان مقصد. در vSphere دلیلها همانهایی است که vMotion میدهد: port group روی آن میزبان نیست (`no prod-vlan20 on esx3`)، یا دیسک روی datastoreی است که فقط میزبان فعلیاش آن را mount کرده. اگر SOAP API خوانده نشده باشد، یک datastore فقط وقتی از میزبانی دیدهشده حساب میشود که ماشین مجازی دیگری روی آن میزبان دیسکی روی آن داشته باشد. پیش از یک پنجرهٔ نگهداری، پیش از روشن کردن DRS یا HA روی یک کلاستر، یا پیش از خالی کردن یک میزبان از آن استفاده کنید.
### افزونگی لینکهای بالادست
لینکهای بالادست هر میزبان یک نمره میگیرند:
```diagram
type: graph
title: افزونه، یا فقط روی نقشه
alt: میزبان A به هر یک از دو سوئیچ یک کابل دارد؛ میزبان B دو کابل به یک سوئیچ دارد؛ میزبان C یک کابل دارد؛ ریاستارت یک سوئیچ نشان میدهد کدام میزبان خاموش میشود
legend: new=افزونه: دو سوئیچ; warn=یک سوئیچ، دو پورت; down=قطع
start: سه میزبان
caption: سه میزبان، سه جور کابلکشی. Zaryn به لینکهای بالادست هر میزبان یک نمره میدهد.
---
node sw1 | sw1 | 30 10 | switch | | در قدم بعد برای ارتقا ریاستارت میشود
node sw2 | sw2 | 70 10 | switch
node a | میزبان A | 15 42 | host | good | یک کابل به هر سوئیچ: هر کدام میتواند خراب شود
node b | میزبان B | 50 42 | host | warn | دو کابل، هر دو به sw1: یک bond، اما یک سوئیچ
node c | میزبان C | 85 42 | host | warn | یک کابل به sw2
link a sw1 | | new
link a sw2 | | new
link b sw1 | | warn
link b sw1 | | warn
link c sw2 | | warn
step sw1 ریاستارت میشود | میزبان A از راه sw2 ادامه میدهد. میزبان B هر دو کابلش را با هم از دست میدهد: ماشینهایش خاموش میشوند. «اگر یک سوئیچ از کار بیفتد» دقیقاً همین را برای هر سوئیچ فهرست میکند.
node sw1 | bad
link a sw1 | down
link b sw1 | down
node b | bad
note 50 54 | میزبان B: همهٔ ماشینها خاموش | bad
```
| نمره | معنا |
|---|---|
| لینکهای بالادست افزونه | لینکهای بالادستش به دو سوئیچ یا بیشتر میرسند: یک سوئیچ میتواند از کار بیفتد |
| یک سوئیچ | همهٔ لینکهای بالادست دیده میشوند، و همه به یک سوئیچ میروند |
| یک پورت | میزبان فقط یک لینک بالادست دارد |
| لینکهای بالادست نامعلوم | هیچ سوئیچی این میزبان را گزارش نمیکند، یا بعضی پورتهایش دیده نمیشوند: Zaryn حدس نمیزند |
### اگر یک سوئیچ از کار بیفتد
دامنهٔ اثر (blast radius) خرابی یک سوئیچ، یا ریاستارت برنامهریزیشدهٔ آن، پیش از آنکه رخ دهد.
برای هر سوئیچی که لینکهای بالادست میزبانها به آن میرسند، Zaryn آن را کنار میگذارد و به آنچه میماند نگاه میکند:
- میزبانی که همهٔ لینکهای بالادستش به آن سوئیچ میرفت **قطع میشود**، و مهمانهای در حال اجرایش بهعنوان قطعشونده همراه آن فهرست میشوند؛
- میزبانی که لینک بالادست دیگری برایش میماند فقط **افزونگی را از دست میدهد**.
پورت میزبانی که هیچ سوئیچی گزارشش نمیکند یک راه خروج احتمالی شمرده میشود، پس این فهرست بهجای بزرگنمایی، به سمت «افزونگی را از دست میدهد» خطا میکند. با آن در چند ثانیه به پرسش «اثرش چیست؟» در هیئت تغییرات برای ارتقای یک سوئیچ پاسخ دهید، یا میزبانهایی را پیدا کنید که پیش از دفعهٔ بعد یک کابل دوم لازم دارند.
### میزان پری ذخیرهسازی
هر پلتفرم میگوید ذخیرهسازیاش چقدر پر است:
```diagram
type: stats
title: میزان پری، پیشبینیها و دیسکهای thin
caption: میزان پری از هر پلتفرم میآید. پیشبینی از یک نمونهٔ ساعتی میآید و جمع دیسکهای ماشینها با آنچه ذخیرهسازی نگه میدارد مقایسه میشود.
---
87% | ceph-pool | پر شدن در حدود ۹ روز | 87 | warn
300% | local-lvm | دیسکهای ماشینها: ۳ ترابایت، thin، روی ۱ ترابایت | 100 | bad
42% | nfs-iso | پایدار، بدون روند | 42 | good
```
| پلتفرم | آنچه اندازه گرفته میشود |
|---|---|
| Proxmox VE | هر storage (Ceph، ZFS، LVM، NFS، پوشهها) |
| VMware vSphere | هر datastore |
| KVM (libvirt) | هر storage pool |
| Hyper-V | هر volume و cluster shared volume |
| oVirt / OLVM | هر data storage domain |
| Nutanix AHV | هر storage container (از groups API در Prism) |
| OpenStack | هر pool در Cinder، و دیسک محلی هر هایپروایزر برای دیسکهای موقت |
### دیسکهای thin بیش از ظرفیت ذخیرهسازی
دیسکهای thin فقط به اندازهای که پر میشوند جا میگیرند، پس یک datastore یکترابایتی میتواند ۳ ترابایت دیسک ماشین مجازی را حمل کند در حالی که یکسومش پر است. این تا وقتی کار میکند که ماشینها دیسکهایشان را پر کنند؛ آن وقت همهچیز روی آن با هم از نوشتن میماند. هر ذخیرهسازی جمع اندازهٔ دیسکهای ماشینهای مجازی روی خودش را کنار ظرفیتش نشان میدهد. بالای ۱۰۰٪ یعنی بیش از ظرفیت واگذار شده، و فضای آزاد باقیمانده نشان میدهد چقدر به لبه نزدیک است.
هر پلتفرم اندازهٔ هر دیسک را میدهد: Proxmox از کانفیگ ماشین، vSphere از capacity هر دیسک، libvirt از `virsh domblkinfo`، Hyper-V از `Get-VHD`، oVirt از provisioned size دیسک، Nutanix از فهرست دیسکهای ماشین، OpenStack از flavor و volumeهای وصلشده. snapshotها، ISOها و بکاپهای روی همان ذخیرهسازی شمرده نمیشوند.
### پیشبینی ذخیرهسازی
Zaryn برای هر ذخیرهسازی (datastore، pool، volume یا container) تقریباً هر ساعت یک نمونه نگه میدارد، تا ۹۰ روز. سرعت رشد با برازش کمترین مربعات روی ۳۰ روز گذشته به دست میآید، وقتی دستکم سه نمونه در بازهٔ ۱۲ ساعت باشد؛ **حدود N روز دیگر پر میشود** یعنی فضای آزاد تقسیم بر این سرعت. ذخیرهسازیای که رشد نمیکند همین را میگوید. پیشبینی روند را دنبال میکند؛ یک کپی حجیم ناگهانی تا وقتی نمونهبرداری نشود دیده نمیشود.
### کدام ماشینها آن را پر میکنند
پر شدن یک storage یک پرسش است؛ اینکه کدام ماشینها آن را پر میکنند پرسش بعدی است. جایی که پلتفرم میگوید هر دیسک ماشین مجازی واقعاً چقدر روی storage جا میگیرد (یک دیسک thin با نوشتن مهمان به سمت اندازهاش رشد میکند)، Zaryn آن را هم هر ساعت نمونه میگیرد، برای ۳۵ روز، و رشد هر ماشین را به همان روش برآورد میکند. هر storage سپس ماشینهایی را که روی آن سریعتر از همه رشد میکنند فهرست میکند، و **ذخیرهسازی در حال پر شدن** نام اولی را میآورد: `full in about 26 days at its pace over the last weeks (60.0 GiB a day); growing fastest: erp (12.0 GiB a day)`. دیسکهای خود هر ماشین نشان میدهند اکنون چقدر جا گرفتهاند (`120 GiB نوشتهشده`) و با چه سرعتی رشد میکنند.
```diagram
type: stats
title: ds-ssd، در چند هفتهٔ گذشته
caption: این storage روزی ۶۰ گیگابایت رشد میکند. سهم erp دوازده تا از آن است؛ legacy رشد نمیکند، پس فهرست نمیشود.
---
26 روز | تا پر شدن ds-ssd | ۱٫۵ ترابایت آزاد، با روزی ۶۰ گیگابایت | 75 | warn
+12 GiB | erp، در روز | ۱۲۰ گیگابایت از دیسک ۲۰۰ گیگابایتیاش نوشته شده | 60 | accent
0 | legacy، در روز | رشد نمیکند | 0 | good
```
| پلتفرم | آنچه هر دیسک ماشین مجازی جا میگیرد |
|---|---|
| Proxmox VE | فهرست volumeهای storage (`used`)، جایی که نوع storage آن را گزارش میکند (ZFS، Ceph RBD، LVM-thin و دیگران)؛ فایلسیستم ریشهٔ یک کانتینر از منابع کلاستر |
| VMware vSphere | بایتهای committed هر ماشین روی هر datastore (از SOAP)، تقسیمشده میان دیسکهایش در آنجا |
| KVM (libvirt) | `virsh domstats --block`: اندازهٔ فیزیکی فایل، وگرنه بالاترین آفست نوشتهشده |
| Hyper-V | اندازهٔ فایل دیسک مجازی (`Get-VHD`) |
| oVirt / OLVM | اندازهٔ واقعی (actual size) دیسک |
| Nutanix، OpenStack | گزارش نمیشود: روند خود storage همچنان کار میکند |
### آنچه رسیدگی میخواهد
| ریسک | سطح | کی |
|---|---|---|
| VLAN یک ماشین مجازی از پورت سوئیچ عبور داده نمیشود | بالا | کارت یک ماشین مجازی در حال اجرا از پورت سوئیچی بیرون میرود که VLAN آن را عبور نمیدهد |
| ذخیرهسازی در حال پر شدن | بالا زیر ۷ روز، متوسط زیر ۳۰ روز | پیشبینی میگوید ظرف ۳۰ روز پر میشود؛ ماشینی که روی آن سریعتر از همه رشد میکند نام برده میشود |
| ذخیرهسازی تقریباً پر | متوسط | بیش از ۹۰٪ پر، و هنوز پیشبینیای نیست |
| دیسکهای thin بزرگتر از ذخیرهسازیشان | بالا وقتی ۸۰٪ یا بیشتر پر است، وگرنه متوسط | جمع دیسکهای ماشینهای مجازی روی آن از ظرفیتش بیشتر است |
| همهٔ لینکهای بالادست روی یک سوئیچ | متوسط | میزبانی با مهمان در حال اجرا که همهٔ لینکهای بالادستش به یک سوئیچ میرسند |
| فقط یک لینک بالادست | متوسط | میزبانی با مهمان در حال اجرا روی تنها یک لینک بالادست |
| حافظه بیش از ظرفیت واگذار شده | متوسط | به مهمانهای در حال اجرا بیش از حافظهٔ میزبان داده شده است |
### آنچه جمعآوریکننده میفرستد
مدل امنیتی در یک جا. هر پلتفرم با کاربری خوانده میشود که فقط میتواند نگاه کند؛ جایی که پلتفرم چنین نقشی ندارد (Hyper-V، و SSH ساده برای KVM)، خود جمعآوریکننده است که کار را فقطخواندنی نگه میدارد، چون دستورهایی که میفرستد در کد منبعش ثابتاند.
```diagram
type: sequence
title: چه چیزی از سیم میگذرد
lanes: هایپروایزر | جمعآوریکننده | Zaryn
alt: جمعآوریکننده درخواستهای فقطخواندنی به هایپروایزر میفرستد، گذرواژهها را خودش نگه میدارد و فقط آنچه خوانده را با HTTPS خروجی به Zaryn میفرستد
---
جمعآوریکننده -> هایپروایزر : درخواستهای فقطخواندنی، نه چیز دیگر
هایپروایزر --> جمعآوریکننده : فهرست موجودی
note جمعآوریکننده : گذرواژهها و توکنها اینجا میمانند، در فایلی که فقط خودش میخواند | good
جمعآوریکننده -> Zaryn : آنچه خوانده، HTTPS خروجی
Zaryn --> جمعآوریکننده : هیچچیزی که بتواند دستگاهی را عوض کند
```
| پلتفرم | درخواستها، و نه چیز دیگری |
|---|---|
| Proxmox VE | `GET /api2/json/…` با یک توکن API |
| VMware vSphere | `POST /api/session` (ورود)، `GET /api/vcenter/…`، `DELETE /api/session` (خروج)؛ SOAP روی `/sdk`: `RetrieveServiceContent`، `Login`، `CreateContainerView`، `RetrievePropertiesEx` و `ContinueRetrievePropertiesEx`، `DestroyView`، `Logout` |
| KVM (libvirt) | یک اسکریپت SSH: `virsh -r` (اتصال فقطخواندنی) و `ip -j addr show` |
| Hyper-V | یک اسکریپت PowerShell از cmdletهای `Get-` که با `ConvertTo-Json` تمام میشود |
| oVirt / OLVM | `GET /ovirt-engine/api/…`، با گذرواژه روی هر درخواست |
| Nutanix AHV | `POST /api/nutanix/v3/…/list` و `POST /api/nutanix/v3/groups` (فراخوانیهای خواندن در Prism عمداً POST هستند) |
| OpenStack | `POST /v3/auth/tokens` (یک توکن)، `GET` روی Nova، Neutron، Cinder و Keystone، `DELETE /v3/auth/tokens` (باطل کردن) |
جز اینها: کلیدهای HTTPS در اولین تماس pin میشوند (پس از تعویض عمدی گواهی، `zev site forget-key`) و کلیدهای میزبان SSH مثل `known_hosts` نگه داشته میشوند؛ گذرواژهها و توکنها روی جمعآوریکننده میمانند، که فقط آنچه خوانده را به Zaryn میفرستد؛ گذرواژههای داخل کانفیگها (cloud-init، رمزهای سوئیچ) پیش از آنکه چیزی از جمعآوریکننده بیرون برود جایگزین میشوند؛ هیچ چیزی داخل ماشینهای مجازی شما اجرا نمیشود.
## برنامهریزی یک مهاجرت در موجها
ترک یک هایپروایزر (از VMware به Proxmox، یا از یک کلاستر قدیمی به یک کلاستر جدید) موج به موج انجام میشود: هر بار چند ماشین مجازی، و هر موج جابهجا، بررسی و تثبیت میشود و بعد موج بعدی. بخش سخت انتخاب موجهاست. اگر دو ماشینی که تمام روز با هم حرف میزنند میان پلتفرم قدیم و جدید جدا شوند، هر درخواست باید از لینک میان آن دو بگذرد: کند میشود، یا اگر فایروالی در مسیر باشد قطع میشود.
```diagram
type: flow
title: موجها چطور انتخاب میشوند
loop: هر موج را پیش از موج بعدی بررسی کنید
---
جریانها | هفتهٔ گذشته چه کسی با چه کسی حرف زد | accent | 📊
~ گروهبندی
گروهها | مجموعههای کنار هممانده، بعد پرگفتوگوترین جفتها | | 🔗
~ بستهبندی
موجها | حداکثر اندازهٔ موج، آرامترینها اول | warn | 🌊
~ یکییکی
موج آزمایشی | جابهجا کنید، بررسی کنید، نگه دارید | good | ✓
```
**برنامهریزی یک مهاجرت** در پایین زبانهٔ ماشینهای مجازی این کار را از روی آنچه [جریانهای](/docs/fa/network-flows) سایت در هفتهٔ گذشته گفتهاند انجام میدهد:
1. ماشینهایی که باید با هم بمانند (مجموعههای *با هم بمانند*، مثل `web1,db1; erp,erp-db`) از ابتدا یک گروهاند.
2. جفتهایی که بیشترین ترافیک را رد و بدل کردهاند در یک گروه قرار میگیرند، تا جایی که گروه از اندازهٔ موج بزرگتر نشود.
3. گروهها در موجهایی با حداکثر همان تعداد ماشین بستهبندی میشوند.
4. آرامترین موجها اول میآیند: کمترین ترافیکی که میان موجها جدا میماند، بعد کمترین ترافیک داخلی، بعد کمترین و کوچکترین ماشینها. یک موج اول خوب یک آزمایش است.
هر موج اینها را فهرست میکند:
- ماشینهایش، اندازه، آدرسها و هشدارهایشان: در حال اجرا نیست (سرد جابهجا میشود)، آدرسی معلوم نیست یا guest agent/VMware Tools ندارد (نمیشود خودکار بررسی کرد که پس از جابهجایی پاسخ میدهد)، دیسکهای بزرگ، چند کارت شبکه؛
- شبکههایی (بریج یا port group، با VLAN) که مقصد باید پیش از شروع داشته باشد؛
- ترافیکی که هنگام جابهجایی از موجهای دیگر جدا میماند، با سرویسها و حجمش؛
- نیازهایش بیرون از هایپروایزر: ماشینهای مجازی روی هایپروایزرهای دیگر، دستگاهها، آدرسهای داخلی، اینترنت.
**دریافت بهصورت Markdown** برنامه را بهصورت یک سند برای درخواست تغییر میدهد. بدون جریانها موجها فقط بر اساس اندازهاند، و برنامه این را میگوید.
## تاریخچه و تغییرها
کانفیگ هر VM و کانتینر و تنظیمات شبکهٔ هر میزبان بهعنوان کانفیگ دستگاه نگه داشته میشود: نسخهها، تفاوتها و انحراف همانطور کار میکنند که برای یک روتر. گذرواژههای cloud-init پیش از آنکه چیزی از جمعآوریکننده بیرون برود جایگزین میشوند.
فهرست **تغییرها** در سایت میگوید کی مهمانی پیدا یا ناپدید شد، به میزبان دیگری رفت (live migration یا HA)، روشن یا خاموش شد، و کی میزبانی آفلاین شد.
هایپروایزر روی **نقشهٔ** سایت هم هست، کنار سوئیچهایی که به آنها کابلکشی شده است.
## محدودیتها
- Proxmox VE 7 و 8؛ VMware vCenter 7.0 Update 2 و جدیدتر؛ libvirt 6 و جدیدتر؛ Windows Server 2019 و جدیدتر با Hyper-V (نسخههای قدیمیتر هم پس از نصب OpenSSH Server کار میکنند)؛ oVirt و OLVM نسخهٔ 4.4 و جدیدتر؛ Nutanix Prism Central 2022.6 و جدیدتر با کلاسترهای AHV؛ OpenStack با Keystone v3 و Nova API 2.47 یا جدیدتر (Pike و جدیدتر).
- تا ۲۰۰۰ مهمان در هر دستگاه هایپروایزر خوانده میشود.
- بررسیهای VLAN کانفیگ سوئیچهای Cisco IOS / IOS-XE و Huawei VRP را میخوانند؛ برای سوئیچهای دیگر بررسی نامعلوم میماند. پورتهای فیزیکی میزبانها در Nutanix و OpenStack در API این پلتفرمها نیست، پس لینکهای بالادستشان فقط از LLDP یا CDP میآید.
- لینکهای بالادست، افزونگی و خرابی سوئیچها لازم دارند که سوئیچها میزبانها را از راه LLDP یا CDP ببینند.
- پیشبینی ذخیرهسازی حدود یک روز نمونه لازم دارد؛ poolهای Cinder کاربر readerی میخواهند که policy ابر اجازهٔ دیدنشان را بدهد.
- فقط خواندن: Zaryn ماشینهای مجازی را روشن، خاموش یا جابهجا نمیکند، و [اعمال تغییر](/docs/fa/network-rollouts) روی هایپروایزرها کار نمیکند.
Zaryn هایپروایزرها و سوئیچهای شما را با همان جمعآوریکننده میخواند و این دو را در یک تصویر کنار هم میگذارد: هر ماشین مجازی، پورت فیزیکی سوئیچی که ترافیکش از آن بیرون میرود، و معنای اینها وقتی چیزی جابهجا میشود، پر میشود یا از کار میافتد. این صفحه از مبانی شروع میکند و تا جزئیات تصمیمگیری هر بررسی پیش میرود؛ هر جا کافی بود دست نگه دارید.
هایپروایزر را بهعنوان یک دستگاه اضافه کنید، با کاربری که فقط میتواند نگاه کند: یک کلاستر Proxmox VE، یک VMware vCenter، یک میزبان KVM یا Hyper-V، یک engine در oVirt / OLVM، یک Nutanix Prism Central یا یک ابر OpenStack. چند پلتفرم میتوانند در یک سایت کنار هم باشند.
هر ماشین مجازی را همانجا که واقعاً هست ببینید: میزبانش، آدرسهایش، VLANهایش و راه خروجش: VM → bridge, VLAN 20 → bond0 → eno1 → sw1 Gi1/0/5.
پیش از آنکه آسیب بزند باخبر شوید: ماشین مجازیای که پورت سوئیچش VLAN آن را عبور نمیدهد، میزبانهایی که یک ماشین مجازی نمیتواند به آنها برود، میزبانی که فقط به یک سوئیچ وصل است، ماشینهای مجازیای که با ریاستارت یک سوئیچ قطع میشوند، دیتااستوری که ۹ روز دیگر پر میشود.
هیچ چیزی تغییر نمیکند. جمعآوریکننده فقط میخواند، گذرواژهها روی جمعآوریکننده میمانند، و هر درخواستی که میفرستد پایینتر فهرست شده است.
Zaryn چه چیزی را میخواند، و به کجا میرود
فقطخواندنیHTTPS خروجی
روی هر چیزی بروید تا ببینید چیست. یک جمعآوریکننده همهٔ پلتفرمها و همهٔ سوئیچها را میخواند و در یک تصویر به هم وصل میکند.
یک هایپروایزر (Proxmox VE، VMware ESXi، Hyper-V، KVM، oVirt، Nutanix AHV؛ OpenStack هم روی میزبانهای زیادی KVM اجرا میکند) روی یک سرور فیزیکی چندین ماشین جدا از هم اجرا میکند: هر ماشین مجازی (VM) پردازنده، حافظه، دیسک و کارت شبکهٔ مجازی خودش را دارد که از منابع واقعی میزبان جدا شده است. کانتینرها (LXC) همین کار را سبکتر انجام میدهند و هستهٔ سیستمعامل میزبان را مشترک به کار میبرند. یک کلاستر از میزبانها اجازه میدهد ماشین مجازی در حال اجرا از یک میزبان به دیگری برود (live migration: vMotion یا Live Migration)، و وقتی میزبانش از کار افتاد روی میزبان دیگری دوباره بالا بیاید (high availability یا HA).
کارت شبکهٔ یک ماشین مجازی به هیچ چیز فیزیکی وصل نیست. به یک سوئیچ مجازی داخل میزبانش وصل است، و کابلهای خود میزبان ترافیکش را به شبکهٔ واقعی میبرند:
راه یک ماشین مجازی تا شبکهٔ واقعی
روی هر بخش بروید تا ببینید چه میکند. فریمهای با برچسب VLAN 20 از bond و روی هر دو کابل بیرون میروند.
فریمهای ماشین مجازی از کجا میروندکابل جدا شده
کارت ماشین مجازی روی یک bridge یا سوئیچ مجازی است (vmbr0 در Proxmox، یک port group در vSphere، یک شبکهٔ منطقی در oVirt، یک subnet در Nutanix، یک شبکهٔ Neutron در OpenStack).
ترافیک ماشین مجازی معمولاً با یک شمارهٔ VLANبرچسب میخورد، که شبکهها را روی کابلهای مشترک از هم جدا نگه میدارد.
bridge روی پورتهای فیزیکی میزبان (لینکهای بالادست یا uplink) قرار دارد، که اغلب دو تا از آنها در یک bond (LACP، NIC team) کنار هم هستند تا اگر یکی از کار افتاد، دیگری کار کند.
هر لینک بالادست با کابل به یک پورت سوئیچ وصل است. پورت trunk VLANهای فهرست allowed خودش را با برچسب عبور میدهد؛ پورت access فقط یک VLAN را بدون برچسب عبور میدهد. اگر پورت VLAN ماشین مجازی را مجاز نکرده باشد، فریمهای ماشین مجازی همانجا از بین میروند.
مجازیسازی ساختن سرور را ارزان و جابهجا کردنش را آسان کرد، اما شبکه پا به پای آن عوض نشد. فاصلهٔ میان این دو، بخش بزرگی از سختتوضیحترین حادثهها را میسازد:
دو تیم، دو نگاه. تیم شبکه آدرس MAC و پورت سوئیچ میبیند؛ تیم مجازیسازی نام ماشین مجازی و میزبان. پاسخ به «erp-db از کدام پورت سوئیچ بیرون میرود؟» یک جلسه طول میکشد، و با vMotion بعدی کهنه میشود.
ماشینهای مجازی جابهجا میشوند؛ کانفیگ سوئیچها نه. live migration و HA ماشین مجازی را به میزبانی میبرند که شاید پورت سوئیچش VLAN آن را عبور ندهد. ماشین مجازی روشن است، هایپروایزر سبز نشان میدهد، و هیچ چیز به آن نمیرسد. این یکی از رایجترین دلیلهای «دیروز کار میکرد» است.
افزونگیای که افزونگی نیست. یک bond از دو کابل فقط وقتی افزونه است که به دو سوئیچ برسد. اگر هر دو روی یک سوئیچ باشند، یا یکی ماهها پیش جدا شده باشد، ریاستارت یک سوئیچ همهٔ ماشینهای مجازی آن میزبان را قطع میکند.
چند پلتفرم همزمان. تغییرهای لایسنس از سال ۲۰۲۴ (بهویژه بستههای جدید VMware پس از Broadcom) بسیاری از سازمانها را به افزودن یا رفتن به Proxmox، Nutanix، Hyper-V، OpenStack یا oVirt واداشت. کمتر کسی فقط یک پلتفرم دارد؛ بیشترشان دو یا سه تا دارند، هر کدام با کنسول خودش، و هیچکدام شبکه را نشان نمیدهد.
غافلگیریهای ظرفیت. حافظهای که بیش از آنچه میزبانها دارند واگذار شده، و ذخیرهسازیای که هر روز کمی پرتر میشود تا ماشینهای مجازی متوقف شوند.
مهاجرت بدون نقشه. جابهجا کردن ماشینهای مجازی بدون دانستن اینکه چه کسی با چه کسی حرف میزند، برنامهها را میان پلتفرم قدیم و جدید تکهتکه میکند.
ابزارهایی که بیش از حد میخواهند. بسیاری از ابزارهای دیدپذیری دسترسی نوشتن، عامل داخل هر ماشین مجازی، یا اتصال SaaS به شبکهٔ مدیریت میخواهند، و تیمهای امنیت بهدرستی میگویند نه.
همهٔ پلتفرمها به یک شکل اضافه میشوند: کاربری بسازید که فقط بتواند نگاه کند، آن را با zev site cred add به جمعآوریکننده بدهید، با zev site test امتحانش کنید، بعد هایپروایزر را بهعنوان دستگاه به سایت اضافه کنید.
پلتفرم
بهعنوان یک دستگاه اضافه کنید
کاربری که لازم دارد
پورت
چطور خوانده میشود
Proxmox VE
هر نود (کل کلاستر)
توکن API، نقش PVEAuditor
8006
REST، فقط GET
VMware vSphere
vCenter
نقش Read-only
443
REST (فقط GET) و SOAP (فقط خواندن)، هر کدام با یک نشست
Zaryn فقط میخواند، از راه API پراکسماکس، با توکنی که فقط میتواند نگاه کند (نقش داخلی PVEAuditor). روی یکی از نودهای Proxmox:
Terminal
pveum user add zev@pvepveum acl modify / --users zev@pve --roles PVEAuditorpveum user token add zev@pve zaryn --privsep 0
دستور آخر رمز توکن را یک بار نشان میدهد. روی جمعآوریکننده:
Terminal
zev site cred add pve --user 'zev@pve!zaryn' --password-stdinzev site test 10.0.0.11 --cred pve --vendor proxmox
بعد کلاستر را بهعنوان یک دستگاه به سایت اضافه کنید: آدرس هر یک از نودها، سازنده Proxmox VE، اعتبارنامهٔ pve. پورت ۸۰۰۶ است مگر خلافش را بگویید. یک دستگاه یعنی کل کلاستر: API بهجای همهٔ نودها پاسخ میدهد.
جمعآوریکننده فقط درخواست GET میفرستد. رمز روی جمعآوریکننده میماند، مثل گذرواژهٔ دستگاهها؛ Zaryn فقط نام اعتبارنامه را میداند.
نودهای Proxmox معمولاً گواهی خودامضا دارند. جمعآوریکننده بار اولی که به یکی میرسد کلید عمومی گواهی را نگه میدارد (tls_pins.json، مثل known_hosts در SSH) و از آن پس هر کلید دیگری را رد میکند: کسی که در میانه است نمیتواند توکن را بخواند. اگر گواهی را عمداً عوض کردهاید:
Zaryn محیط vSphere را از راه REST API در vCenter میخواند (vCenter 7.0 Update 2 یا جدیدتر)، و آنچه REST نمیگوید را از SOAP API آن، با کاربری که نقش داخلی Read-only دارد. در vSphere Client: Administration ← Single Sign On ← Users، کاربر zev@vsphere.local را بسازید؛ بعد روی شیء vCenter، Permissions ← Add، همان کاربر با نقش Read-only و Propagate to children. روی جمعآوریکننده:
Terminal
zev site cred add vc --user zev@vsphere.local --password-stdinzev site test vcenter.lab.local --cred vc --vendor vsphere
vCenter را بهعنوان یک دستگاه اضافه کنید: آدرسش، سازنده VMware vSphere، اعتبارنامهٔ vc، پورت ۴۴۳. یک دستگاه یعنی هر چه آن vCenter مدیریت میکند: کلاسترها، میزبانهای ESXi، ماشینهای مجازی و datastoreها. میزبانهای ESXi از راه vCenterشان خوانده میشوند، نه یکییکی.
جمعآوریکننده وارد میشود (یک درخواست یک نشست باز میکند)، بعد فقط میخواند، بعد خارج میشود. کلید TLS همانطور که برای Proxmox گفته شد سنجاق میشود.
REST API در vCenter شبکهٔ زیر ماشینهای مجازی را نمیگوید، پس جمعآوریکننده در همان سر زدن SOAP API را هم میخواند (/sdk، همانی که PowerCLI و govc به کار میبرند)، با همان کاربر و فقط خواندن:
vmnicهای هر میزبان ESXi، vSwitchهای استانداردش و vmnicهایی که هر کدام به کار میبرد (فعال و آمادهبهکار)؛
VLAN هر port group، روی vSwitchهای استاندارد و روی distributed switchها (port group از نوع trunk بازههایش را نشان میدهد)؛
اینکه هر میزبان کدام vmnicها را به هر distributed switch داده، و آدرسهای VMkernel آن (vmk0) که آدرس میزبان میشود؛
اینکه کدام میزبانها هر datastore را mount کردهاند و به آن دسترسی دارند.
پس شبکهٔ یک ماشین مجازی port group آن با VLANش است، و راه خروجش port group ← vSwitch یا distributed switch ← vmnic ← پورت سوئیچی است که LLDP یا CDP برای آن vmnic گزارش میکند (LLDP یا CDP را روی vSwitch یا distributed switch روشن کنید تا سوئیچها میزبانها را ببینند). آدرسها از VMware Tools یا جدولهای ARP سوئیچها میآیند. اگر SOAP API خوانده نشود (مثلاً پروکسیای که فقط /api را رد میکند)، دستگاه همین را میگوید و بقیه مثل قبل کار میکند.
یک سر زدن به vCenter
جمعآوریکننده
vCenter
REST
POST /api/session، بعد GETها: کلاسترها، میزبانها، ماشینها، datastoreها
DELETE /api/session
SOAP، فقط خواندن
Login، CreateContainerView
RetrievePropertiesEx: کارتهای میزبانها، port groupها، distributed switchها، mountها
یک سرور لینوکسی معمولی که ماشینهای مجازی KVM را با libvirt اجرا میکند (virsh، virt-manager، Cockpit) مثل یک روتر از راه SSH خوانده میشود. جمعآوریکننده یک اسکریپت ثابت اجرا میکند: virsh با -r، یعنی اتصال فقطخواندنی libvirt، برای ماشینهای مجازی، کانفیگها، وضعیت، دیسکها، شبکهها و استخرهای ذخیرهسازی، و ip -j addr show برای پلها و bondهای میزبان. هیچ چیز دیگری.
دسترسی root لازم نیست: سوکت فقطخواندنی libvirt برای همهٔ کاربرهای محلی باز است، مگر اینکه توزیع آن را بسته باشد. روی میزبان یک کاربر بسازید و ببینید میتواند ماشینها را فهرست کند:
اگر خطای دسترسی داد، توزیع سوکت فقطخواندنی را محدود کرده است (unix_sock_ro_perms در /etc/libvirt/libvirtd.conf، یا گروه /run/libvirt/libvirt-sock-ro): آن را برای این کاربر باز کنید. افزودن کاربر به گروه libvirt هم کار میکند، هرچند آن گروه میتواند ماشینها را تغییر هم بدهد؛ جمعآوریکننده باز هم فقط virsh -r اجرا میکند. روی جمعآوریکننده:
Terminal
zev site cred add kvm --user zev --password-stdin # یا --key ~/.ssh/zev_kvmzev site test 10.0.0.21 --cred kvm --vendor kvm
میزبان را بهعنوان دستگاه اضافه کنید: آدرسش، سازندهٔ KVM / libvirt، اعتبارنامهٔ kvm (SSH، پورت 22). libvirt نمای کلاستر ندارد، پس هر میزبان دستگاه جداگانهای است. کلید میزبان در اولین تماس نگه داشته میشود، مثل هر دستگاه SSH دیگری.
کارت شبکهٔ یک ماشین مجازی روی یک پل لینوکسی است (br0، با برچسب VLAN آن)، یا یک شبکهٔ libvirt (default با پل virbr0؛ VLAN یک portgroup هم خوانده میشود)، یا یک پل Open vSwitch، یا مستقیم روی یک پورت میزبان (macvtap). دیسکها از روی مسیرشان به استخر ذخیرهسازیشان نسبت داده میشوند. هر ماشین مجازی با UUID خودش شناخته میشود، پس تغییر نامش تاریخچهاش را از بین نمیبرد.
یک Windows Server با Hyper-V از راه سرور OpenSSH خود ویندوز خوانده میشود (که در Windows Server 2019 و جدیدتر هست)، پس جمعآوریکننده نه WinRM لازم دارد و نه عاملی روی ویندوز. روی میزبان، در یک PowerShell با دسترسی مدیر:
Hyper-V نقش فقطخواندنی ندارد: خواندن ماشینهای مجازی عضویت در Hyper-V Administrators را میخواهد، گروهی که میتواند آنها را تغییر هم بدهد. آنچه کار را فقطخواندنی نگه میدارد خود جمعآوریکننده است: یک اسکریپت ثابت PowerShell از cmdletهای Get- میفرستد (Get-VM، Get-VMNetworkAdapter، Get-VMNetworkAdapterVlan، Get-VMHardDiskDrive، Get-VHD، Get-VMSwitch، Get-NetAdapter، Get-NetIPAddress، Get-Volume، Get-ClusterNode، Get-ClusterSharedVolume) که با ConvertTo-Json تمام میشود، و هیچ چیزی که سرور بگوید نمیتواند آن را به فرستادن چیز دیگری وادار کند. اسکریپت در کد منبع zev است (src/core/netdev/virt_host.zig). روی جمعآوریکننده:
Terminal
zev site cred add hv --user 'CORP\zev' --password-stdinzev site test hv01.corp.local --cred hv --vendor hyperv
میزبان را بهعنوان دستگاه اضافه کنید: سازندهٔ Microsoft Hyper-V، اعتبارنامهٔ hv. در یک failover cluster یک نود را اضافه کنید: جمعآوریکننده ماشینهای مجازی هر نود را میپرسد (Get-VM -ComputerName)، و نودها و volumeهای اشتراکی کلاستر هم فهرست میشوند. اگر این حساب از آنجا به نودهای دیگر نمیرسد، هر نود را دستگاه جداگانهای کنید.
کارت شبکهٔ هر ماشین مجازی سوئیچ مجازی و VLAN خودش را نشان میدهد (حالت access؛ برای حالت trunk، trunk)، آدرسهایش را از integration services در Hyper-V، و دیسکهای مجازیاش را همراه با volume یا cluster shared volume که رویش هستند. راه خروج یک سوئیچ مجازی، کارتهای فیزیکی آن است، و اگر NIC team باشد از راه آن. اگر حساب نتواند volumeها را بخواند، فهرست ذخیرهسازی خالی میماند؛ بقیه کار میکند.
oVirt و محصولاتی که روی آن ساخته شدهاند (Oracle Linux Virtualization Manager و Red Hat Virtualization) از راه REST API خود engine خوانده میشوند (/ovirt-engine/api، oVirt 4.4 یا جدیدتر)، با کاربری که نقش آمادهٔ ReadOnlyAdmin را دارد. روی ماشین engine، کاربر را در دامنهٔ internal بسازید:
Terminal
ovirt-aaa-jdbc-tool user add zevovirt-aaa-jdbc-tool user password-reset zev --password-valid-to="2030-01-01 00:00:00Z"
بعد در Administration Portal: Administration ← Configure ← System Permissions ← Add، کاربر zev، نقش ReadOnlyAdmin. روی engineی که ورود را از راه Keycloak انجام میدهد (پیشفرض oVirt 4.5)، کاربر را بهجای آن در Keycloak بسازید؛ نامش آنوقت zev@ovirt@internalsso است. روی جمعآوریکننده:
Terminal
zev site cred add olvm --user zev@internal --password-stdinzev site test engine.lab.local --cred olvm --vendor ovirt
engine را بهعنوان دستگاه اضافه کنید: آدرسش، سازندهٔ oVirt / OLVM، اعتبارنامهٔ olvm (HTTPS روی ۴۴۳). یک دستگاه یعنی همهٔ آنچه آن engine مدیریت میکند: کلاسترها، میزبانها، ماشینهای مجازی، شبکههای منطقی و storage domainها. جمعآوریکننده فقط درخواست GET میفرستد، چند تا در هر بار خواندن (ماشینهای مجازی با کارتهای شبکه، آدرسهای داخل مهمان، دیسکها و برچسبهایشان در یک درخواست میآیند)، با گذرواژه روی هر کدام، پس هیچ نشستی باز نمیماند. کلید TLS همانطور که برای Proxmox گفته شد pin میشود.
کارت شبکهٔ یک ماشین مجازی روی یک vNIC profile است که به یک شبکهٔ منطقی تعلق دارد، و آن شبکه ممکن است VLAN داشته باشد. روی هر میزبان، یک شبکهٔ منطقی یک bridge همنام است روی پورت، bond یا VLANی که به آن وصل شده (Setup Host Networks)، پس راه خروج مثل Proxmox است: nic1 → prod VLAN 20 → bond0 → eno1 → sw1 Gi1/0/8. آدرسها از guest agentی میآیند که engine گزارش میکند (qemu-guest-agent داخل ماشین مجازی). دیسکها storage domainی را که رویش هستند نشان میدهند؛ فقط data domainها جزو ذخیرهسازی شمرده میشوند. هر ماشین مجازی با UUID خودش شناخته میشود. میزبانی که در حالت maintenance است یا به engine جواب نمیدهد، خاموش نشان داده میشود.
کلاسترهای Nutanix AHV از راه REST API نسخهٔ v3 در Prism Central خوانده میشوند (Prism Central 2022.6 یا جدیدتر؛ کلاستری که فقط با Prism Element مدیریت میشود باید اول در یک Prism Central ثبت شود)، با کاربری که نقش آمادهٔ Prism Viewer را دارد. در Prism Central: Admin Center ← IAM ← Local User Management، کاربر zev را اضافه کنید؛ بعد Authorization Policies ← Create، نقش Prism Viewer، همان کاربر، روی همهٔ کلاسترها. کاربر دایرکتوری هم همینطور کار میکند. روی جمعآوریکننده:
Terminal
zev site cred add prism --user zev --password-stdinzev site test prism.lab.local --cred prism --vendor nutanix
Prism Central را بهعنوان دستگاه اضافه کنید: آدرسش، سازندهٔ Nutanix AHV، اعتبارنامهٔ prism (HTTPS روی ۹۴۴۰). یک دستگاه یعنی همهٔ کلاسترهایی که آن Prism Central مدیریت میکند: میزبانهای AHV، ماشینهای مجازی و subnetهایشان. خود Prism Central و ماشینهای مجازی خودش کنار گذاشته میشوند.
API نسخهٔ v3 در Prism فهرستها را با یک POST میخواهد که بدنهاش میگوید کدام صفحه فرستاده شود (POST /api/nutanix/v3/vms/list). اینها تنها درخواستهای جمعآوریکنندهاند: کلاسترها، میزبانها، subnetها و ماشینهای مجازی، صفحه به صفحه. یک Prism Viewer هر چه فرستاده شود نمیتواند چیزی را تغییر دهد، و گذرواژه همراه هر درخواست میرود، پس هیچ نشستی باز نمیماند. کلید TLS همانطور که برای Proxmox گفته شد pin میشود.
کارت شبکهٔ یک ماشین مجازی روی یک subnet با VLAN خودش است. آدرسهایش همانهایی است که AHV میداند: آنهایی که مدیریت آدرس IP خود AHV داده، یا از ترافیک ماشین مجازی یاد گرفته شدهاند. دیسکها storage containerی را که رویش هستند نشان میدهند؛ CD-ROM کنار گذاشته میشود. Categoryها (Environment: Production) بهشکل برچسب نشان داده میشوند. هر ماشین مجازی با UUID خودش شناخته میشود.
آنچه API نسخهٔ v3 در Prism نمیگوید و بنابراین Zaryn هنوز نشان نمیدهد: سوئیچ مجازی یک میزبان از کدام پورتهای فیزیکی استفاده میکند، و هر storage container چقدر پر است. راه خروج یک میزبان از همسایههای LLDP یا CDP سوئیچها میآید، مثل vSphere.
یک ابر OpenStack از راه APIهای خودش خوانده میشود: Keystone برای توکن و فهرست سرویسها، Nova برای سرورها و هایپروایزرها، Neutron برای شبکهها، پورتها و floating IPها، و Cinder برای volumeها. Keystone باید روی HTTPS جواب بدهد. کاربری با نقش reader روی کل ابر بسازید (نقشی با scope سیستمی):
Terminal
openstack user create --domain Default --password-prompt zevopenstack role add --user zev --user-domain Default --system all reader
روی جمعآوریکننده:
Terminal
zev site cred add cloud --user zev@Default --password-stdinzev site test keystone.cloud.local --cred cloud --vendor openstack
ابر را بهعنوان دستگاه اضافه کنید: آدرس Keystone، سازندهٔ OpenStack، اعتبارنامهٔ cloud (پورت ۵۰۰۰). یک دستگاه یعنی همهٔ آنچه در آن region هست: سرورهای همهٔ projectها، هایپروایزرها، شبکهها و volumeها.
نام کاربر بهشکل name@domain است و توکن scope سیستمی دارد. یک reader سیستمی وقتی ابر از پیشفرضهای جدید policy در OpenStack استفاده میکند ([oslo_policy] enforce_new_defaults و enforce_scope، که در نسخههای اخیر بهطور پیشفرض روشناند) همهٔ projectها را میبیند. در ابری که هنوز پیشفرضهای قدیمی را دارد، یک reader فقط project خودش را میبیند: نامش را بدهید، --user 'zev@Default/shop'، با نقش reader روی همان project (openstack role add --user zev --project shop reader). آنوقت فقط سرورهای آن project فهرست میشوند و هایپروایزرها پنهان میمانند. با پیشفرضهای قدیمی، دیدن همهٔ projectها نقش admin را میخواهد، حسابی که میتواند چیزها را تغییر هم بدهد.
آنچه جمعآوریکننده میفرستد: یک POST به Keystone برای توکن (گذرواژه در یک فایل خصوصی میرود، هیچوقت در خط فرمان نیست)، بعد فقط GET، و در آخر یک DELETE که توکن را باطل میکند. endpointها از فهرست داخل توکن میآیند و endpointهای عمومی استفاده میشوند؛ endpointهای HTTPS مثل خود Keystone در اولین تماس pin میشوند، و endpointهای HTTP همانطور که ابر منتشرشان کرده خوانده میشوند.
کارتهای شبکهٔ یک سرور همان پورتهای Neutron آن است: شبکه، VLAN آن اگر شبکه از نوع VLAN provider باشد (شبکههای tenant از نوع VXLAN و Geneve، VLAN ندارند)، آدرسهای ثابت با prefix زیرشبکهشان، و floating IP اگر باشد. دیسکها دیسک ریشهٔ موقت flavor هستند، یا volumeهای Cinder وصلشده، هر کدام با backend خودش (ceph-ssd). هر سرور با project خودش برچسب میخورد. هر سرور با UUID خودش شناخته میشود، پس evacuation یا live migration بهشکل جابهجایی نشان داده میشود.
آنچه APIهای OpenStack نمیگویند و بنابراین Zaryn هنوز نشان نمیدهد: یک هایپروایزر از کدام پورتهای فیزیکی استفاده میکند، و هر backend ذخیرهسازی چقدر پر است. راه خروج یک هایپروایزر از همسایههای LLDP یا CDP سوئیچها میآید (روی نودهای compute بستهٔ lldpd را نصب کنید).
سایتی که هایپروایزر دارد یک زبانهٔ Virtual machines میگیرد:
ظرفیت: میزبانها، مهمانهای در حال اجرا، vCPU به ازای هر CPU فیزیکی (overcommit)، حافظهٔ واگذارشده به مهمانهای در حال اجرا در برابر آنچه میزبانها دارند، ذخیرهسازی مصرفشده (ذخیرهسازی اشتراکی مثل Ceph یک بار شمرده میشود).
آنچه رسیدگی میخواهد: ریسکهای پایین، بدترین اول. هدف این است که خالی باشد.
اگر یک سوئیچ از کار بیفتد: هر سوئیچی که میزبانها به آن وصلاند، با میزبانهایی که قطع میکند، مهمانهای در حال اجرایی که همراهشان میروند، و میزبانهایی که فقط افزونگی را از دست میدهند.
میزبانها: CPU و حافظهٔ مصرفی، vCPU روی CPUهای فیزیکی، مهمانهای هر کدام، لینکهای بالادست میزبان (هر پورت فیزیکی به کدام پورت سوئیچ میرود، و آیا آن پورت VLANها را عبور میدهد) و نشان افزونگی.
مهمانها: هر ماشین مجازی و کانتینر با میزبان، وضعیت، اندازه، آدرسها و VLANهایش؛ با نام، شناسه، برچسب، آدرس، MAC یا VLAN فیلتر کنید. یکی را باز کنید تا راه خروج هر کارت شبکه (net0 → vmbr0 VLAN 20 → bond0 → eno1 → sw1 Gi1/0/5 ✓)، اینکه با چه کسی حرف میزند، دیسکهایش و کجا میتواند جابهجا شود را ببینید.
ذخیرهسازی: هر datastore، pool، storage domain یا container، اینکه چقدر پر است، و با سرعت فعلی کی پر میشود.
به ترتیب: QEMU guest agent (برای ماشینهای مجازی در حال اجرایی که آن را دارند)، VMware Tools، integration services در Hyper-V، guest agent آنطور که engine در oVirt گزارش میکند، آنچه AHV و Neutron میدانند، کانفیگ خود کانتینر، وگرنه جدولهای ARP روترها و سوئیچهای سایت، که بر اساس MAC جفت میشوند. هر آدرس میگوید از کجا آمده است. در KVM اتصال فقطخواندنی نمیتواند از guest agent بپرسد، پس اول اجارههای DHCP خود libvirt و جدول ARP میزبان میآیند.
همسایههای LLDP و CDP سوئیچها نام میزبان و پورت میزبان در آن سر را میگویند. روی میزبانهای Proxmox، KVM، oVirt و نودهای compute در OpenStack بستهٔ lldpd را نصب کنید (apt install lldpd) تا سوئیچها آنها را ببینند؛ در ESXi، LLDP یا CDP را روی vSwitch یا distributed switch روشن کنید؛ در ویندوز، قابلیت Data Center Bridging یک عامل LLDP دارد (Install-WindowsFeature Data-Center-Bridging، بعد Enable-NetLldpAgent). پورتی که هیچ سوئیچی گزارشش نکند با → ? نشان داده میشود.
این بخش برای کسی است که باید به پاسخها اعتماد کند: هر بررسی دقیقاً به چه چیزی نگاه میکند، و کی بهجای حدس زدن میگوید «نمیدانم». هیچ بررسیای چیزی نامعلوم را به علامت قرمز تبدیل نمیکند.
همان ناهمخوانی کلاسیک VLAN (VLAN mismatch): یک vMotion یا live migration ماشین مجازی را روی میزبانی مینشاند که پورت سوئیچش VLAN آن را مجاز نکرده است. این بررسی پیش از آنکه کسی متوجه قطعی شود آن را پیدا میکند، و برای همهٔ ماشینهای مجازی، نه فقط آنهایی که جابهجا شدهاند.
ناهمخوانی VLAN که هیچکس نمیبیند
web1 روی pve1 اجرا میشود که پورت سوئیچش VLAN 20 را میگذراند. همهچیز کار میکند.
ترافیک ماشین از کجا میرودکجا بودVLAN رد نمیشود
برای هر کارت شبکهٔ ماشین مجازی که VLAN دارد، Zaryn لینکهای بالادستش را تا پورتهای سوئیچ در آن سر دنبال میکند (از روی LLDP یا CDP)، بعد VLANهای آن پورتها را از کانفیگ در حال اجرای سوئیچها میخواند، که جمعآوریکننده از قبل برای تاریخچهٔ کانفیگ نگه میدارد:
Cisco IOS / IOS-XE: switchport mode، switchport trunk allowed vlan با شکلهای add، remove، except، all و none، switchport trunk native vlan، switchport access vlan. trunkی که فهرست allowed ندارد همهٔ VLANها را عبور میدهد.
Huawei VRP: port link-type trunk | access | hybrid، port trunk allow-pass vlan (با بازههای to و all)، undo port trunk allow-pass vlan، port default vlan، port hybrid tagged vlan. یک trunk تا وقتی چیز دیگری گفته نشده فقط VLAN 1 را عبور میدهد.
VLAN برچسبدار در سمت ماشین مجازی یعنی فریم برچسبدار روی لینک بالادست، پس پورت سوئیچ باید trunk (یا hybrid) باشد و فهرست allowed آن، این VLAN را داشته باشد. پورت access در این بررسی رد میشود حتی اگر شمارهٔ VLANش همان باشد، چون فریم برچسبدار را نمیپذیرد. هر لینک بالادست آنوقت ✓ یا ✗ را همراه با دلیل نشان میدهد: trunk port without VLAN 20 (allowed: 10,30).
وقتی پاسخ معلوم نیست هیچ علامتی داده نمیشود: کارت ماشین مجازی بدون VLAN (از VLAN بومی یا access پورت استفاده میکند، یا port groupی در vSphere با VLAN صفر یا 4095)، سوئیچی که کانفیگش هنوز تحلیل نمیشود (MikroTik، FRRouting، VyOS)، یا پورت میزبانی که هیچ سوئیچی گزارشش نمیکند.
برای هر ماشین مجازی که VLAN یا دیسک دارد، هر میزبان روشن دیگرِ همان کلاستر طوری بررسی میشود که انگار ماشین مجازی همین الان به آن رفته است. شبکه و دیسکها هر کدام یک علامت جدا میگیرند:
شبکه، برای ماشینهایی که VLAN دارند. در پلتفرمهایی که شبکهٔ میزبان را گزارش میکنند (Proxmox، KVM، Hyper-V، oVirt)، میزبان باید همان bridge، سوئیچ مجازی یا شبکهٔ منطقی را داشته باشد: no vmbr0 on pve3. هر VLAN ماشین مجازی باید از همهٔ پورتهای سوئیچی که لینکهای بالادست آن میزبان به آنها میرسند عبور کند: VLAN 20 not on sw1 Gi1/0/6.
دیسکها. ذخیرهسازی مشترک (Ceph، NFS، iSCSI، یک cluster shared volume، یک container در Nutanix، یک pool در Cinder) باید از میزبان مقصد دیده شود: ceph isn't on pve3. دیسکی که روی ذخیرهسازی محلی است همراه ماشین کپی میشود، پس میزبان مقصد همان ذخیرهسازی را با جای کافی لازم دارد: local-lvm on pve2 has 5 GiB free, its disks there need 20 GiB.
پاسخ ✓ (بیخطر)، ✗ همراه با دلیلها، یا ? است وقتی چیزی معلوم نیست، مثل پورتهای سوئیچ میزبان مقصد. در vSphere دلیلها همانهایی است که vMotion میدهد: port group روی آن میزبان نیست (no prod-vlan20 on esx3)، یا دیسک روی datastoreی است که فقط میزبان فعلیاش آن را mount کرده. اگر SOAP API خوانده نشده باشد، یک datastore فقط وقتی از میزبانی دیدهشده حساب میشود که ماشین مجازی دیگری روی آن میزبان دیسکی روی آن داشته باشد. پیش از یک پنجرهٔ نگهداری، پیش از روشن کردن DRS یا HA روی یک کلاستر، یا پیش از خالی کردن یک میزبان از آن استفاده کنید.
دامنهٔ اثر (blast radius) خرابی یک سوئیچ، یا ریاستارت برنامهریزیشدهٔ آن، پیش از آنکه رخ دهد.
برای هر سوئیچی که لینکهای بالادست میزبانها به آن میرسند، Zaryn آن را کنار میگذارد و به آنچه میماند نگاه میکند:
میزبانی که همهٔ لینکهای بالادستش به آن سوئیچ میرفت قطع میشود، و مهمانهای در حال اجرایش بهعنوان قطعشونده همراه آن فهرست میشوند؛
میزبانی که لینک بالادست دیگری برایش میماند فقط افزونگی را از دست میدهد.
پورت میزبانی که هیچ سوئیچی گزارشش نمیکند یک راه خروج احتمالی شمرده میشود، پس این فهرست بهجای بزرگنمایی، به سمت «افزونگی را از دست میدهد» خطا میکند. با آن در چند ثانیه به پرسش «اثرش چیست؟» در هیئت تغییرات برای ارتقای یک سوئیچ پاسخ دهید، یا میزبانهایی را پیدا کنید که پیش از دفعهٔ بعد یک کابل دوم لازم دارند.
دیسکهای thin فقط به اندازهای که پر میشوند جا میگیرند، پس یک datastore یکترابایتی میتواند ۳ ترابایت دیسک ماشین مجازی را حمل کند در حالی که یکسومش پر است. این تا وقتی کار میکند که ماشینها دیسکهایشان را پر کنند؛ آن وقت همهچیز روی آن با هم از نوشتن میماند. هر ذخیرهسازی جمع اندازهٔ دیسکهای ماشینهای مجازی روی خودش را کنار ظرفیتش نشان میدهد. بالای ۱۰۰٪ یعنی بیش از ظرفیت واگذار شده، و فضای آزاد باقیمانده نشان میدهد چقدر به لبه نزدیک است.
هر پلتفرم اندازهٔ هر دیسک را میدهد: Proxmox از کانفیگ ماشین، vSphere از capacity هر دیسک، libvirt از virsh domblkinfo، Hyper-V از Get-VHD، oVirt از provisioned size دیسک، Nutanix از فهرست دیسکهای ماشین، OpenStack از flavor و volumeهای وصلشده. snapshotها، ISOها و بکاپهای روی همان ذخیرهسازی شمرده نمیشوند.
Zaryn برای هر ذخیرهسازی (datastore، pool، volume یا container) تقریباً هر ساعت یک نمونه نگه میدارد، تا ۹۰ روز. سرعت رشد با برازش کمترین مربعات روی ۳۰ روز گذشته به دست میآید، وقتی دستکم سه نمونه در بازهٔ ۱۲ ساعت باشد؛ حدود N روز دیگر پر میشود یعنی فضای آزاد تقسیم بر این سرعت. ذخیرهسازیای که رشد نمیکند همین را میگوید. پیشبینی روند را دنبال میکند؛ یک کپی حجیم ناگهانی تا وقتی نمونهبرداری نشود دیده نمیشود.
پر شدن یک storage یک پرسش است؛ اینکه کدام ماشینها آن را پر میکنند پرسش بعدی است. جایی که پلتفرم میگوید هر دیسک ماشین مجازی واقعاً چقدر روی storage جا میگیرد (یک دیسک thin با نوشتن مهمان به سمت اندازهاش رشد میکند)، Zaryn آن را هم هر ساعت نمونه میگیرد، برای ۳۵ روز، و رشد هر ماشین را به همان روش برآورد میکند. هر storage سپس ماشینهایی را که روی آن سریعتر از همه رشد میکنند فهرست میکند، و ذخیرهسازی در حال پر شدن نام اولی را میآورد: full in about 26 days at its pace over the last weeks (60.0 GiB a day); growing fastest: erp (12.0 GiB a day). دیسکهای خود هر ماشین نشان میدهند اکنون چقدر جا گرفتهاند (120 GiB نوشتهشده) و با چه سرعتی رشد میکنند.
ds-ssd، در چند هفتهٔ گذشته
26 روز
تا پر شدن ds-ssd
۱٫۵ ترابایت آزاد، با روزی ۶۰ گیگابایت
+12 GiB
erp، در روز
۱۲۰ گیگابایت از دیسک ۲۰۰ گیگابایتیاش نوشته شده
0
legacy، در روز
رشد نمیکند
این storage روزی ۶۰ گیگابایت رشد میکند. سهم erp دوازده تا از آن است؛ legacy رشد نمیکند، پس فهرست نمیشود.
پلتفرم
آنچه هر دیسک ماشین مجازی جا میگیرد
Proxmox VE
فهرست volumeهای storage (used)، جایی که نوع storage آن را گزارش میکند (ZFS، Ceph RBD، LVM-thin و دیگران)؛ فایلسیستم ریشهٔ یک کانتینر از منابع کلاستر
VMware vSphere
بایتهای committed هر ماشین روی هر datastore (از SOAP)، تقسیمشده میان دیسکهایش در آنجا
مدل امنیتی در یک جا. هر پلتفرم با کاربری خوانده میشود که فقط میتواند نگاه کند؛ جایی که پلتفرم چنین نقشی ندارد (Hyper-V، و SSH ساده برای KVM)، خود جمعآوریکننده است که کار را فقطخواندنی نگه میدارد، چون دستورهایی که میفرستد در کد منبعش ثابتاند.
چه چیزی از سیم میگذرد
هایپروایزر
جمعآوریکننده
Zaryn
درخواستهای فقطخواندنی، نه چیز دیگر
فهرست موجودی
گذرواژهها و توکنها اینجا میمانند، در فایلی که فقط خودش میخواند
آنچه خوانده، HTTPS خروجی
هیچچیزی که بتواند دستگاهی را عوض کند
پلتفرم
درخواستها، و نه چیز دیگری
Proxmox VE
GET /api2/json/… با یک توکن API
VMware vSphere
POST /api/session (ورود)، GET /api/vcenter/…، DELETE /api/session (خروج)؛ SOAP روی /sdk: RetrieveServiceContent، Login، CreateContainerView، RetrievePropertiesEx و ContinueRetrievePropertiesEx، DestroyView، Logout
KVM (libvirt)
یک اسکریپت SSH: virsh -r (اتصال فقطخواندنی) و ip -j addr show
Hyper-V
یک اسکریپت PowerShell از cmdletهای Get- که با ConvertTo-Json تمام میشود
oVirt / OLVM
GET /ovirt-engine/api/…، با گذرواژه روی هر درخواست
Nutanix AHV
POST /api/nutanix/v3/…/list و POST /api/nutanix/v3/groups (فراخوانیهای خواندن در Prism عمداً POST هستند)
OpenStack
POST /v3/auth/tokens (یک توکن)، GET روی Nova، Neutron، Cinder و Keystone، DELETE /v3/auth/tokens (باطل کردن)
جز اینها: کلیدهای HTTPS در اولین تماس pin میشوند (پس از تعویض عمدی گواهی، zev site forget-key) و کلیدهای میزبان SSH مثل known_hosts نگه داشته میشوند؛ گذرواژهها و توکنها روی جمعآوریکننده میمانند، که فقط آنچه خوانده را به Zaryn میفرستد؛ گذرواژههای داخل کانفیگها (cloud-init، رمزهای سوئیچ) پیش از آنکه چیزی از جمعآوریکننده بیرون برود جایگزین میشوند؛ هیچ چیزی داخل ماشینهای مجازی شما اجرا نمیشود.
ترک یک هایپروایزر (از VMware به Proxmox، یا از یک کلاستر قدیمی به یک کلاستر جدید) موج به موج انجام میشود: هر بار چند ماشین مجازی، و هر موج جابهجا، بررسی و تثبیت میشود و بعد موج بعدی. بخش سخت انتخاب موجهاست. اگر دو ماشینی که تمام روز با هم حرف میزنند میان پلتفرم قدیم و جدید جدا شوند، هر درخواست باید از لینک میان آن دو بگذرد: کند میشود، یا اگر فایروالی در مسیر باشد قطع میشود.
موجها چطور انتخاب میشوند
📊
جریانها
هفتهٔ گذشته چه کسی با چه کسی حرف زد
گروهبندی
🔗
گروهها
مجموعههای کنار هممانده، بعد پرگفتوگوترین جفتها
بستهبندی
🌊
موجها
حداکثر اندازهٔ موج، آرامترینها اول
یکییکی
✓
موج آزمایشی
جابهجا کنید، بررسی کنید، نگه دارید
↺ هر موج را پیش از موج بعدی بررسی کنید
برنامهریزی یک مهاجرت در پایین زبانهٔ ماشینهای مجازی این کار را از روی آنچه جریانهای سایت در هفتهٔ گذشته گفتهاند انجام میدهد:
ماشینهایی که باید با هم بمانند (مجموعههای با هم بمانند، مثل web1,db1; erp,erp-db) از ابتدا یک گروهاند.
جفتهایی که بیشترین ترافیک را رد و بدل کردهاند در یک گروه قرار میگیرند، تا جایی که گروه از اندازهٔ موج بزرگتر نشود.
گروهها در موجهایی با حداکثر همان تعداد ماشین بستهبندی میشوند.
آرامترین موجها اول میآیند: کمترین ترافیکی که میان موجها جدا میماند، بعد کمترین ترافیک داخلی، بعد کمترین و کوچکترین ماشینها. یک موج اول خوب یک آزمایش است.
هر موج اینها را فهرست میکند:
ماشینهایش، اندازه، آدرسها و هشدارهایشان: در حال اجرا نیست (سرد جابهجا میشود)، آدرسی معلوم نیست یا guest agent/VMware Tools ندارد (نمیشود خودکار بررسی کرد که پس از جابهجایی پاسخ میدهد)، دیسکهای بزرگ، چند کارت شبکه؛
شبکههایی (بریج یا port group، با VLAN) که مقصد باید پیش از شروع داشته باشد؛
ترافیکی که هنگام جابهجایی از موجهای دیگر جدا میماند، با سرویسها و حجمش؛
نیازهایش بیرون از هایپروایزر: ماشینهای مجازی روی هایپروایزرهای دیگر، دستگاهها، آدرسهای داخلی، اینترنت.
دریافت بهصورت Markdown برنامه را بهصورت یک سند برای درخواست تغییر میدهد. بدون جریانها موجها فقط بر اساس اندازهاند، و برنامه این را میگوید.
کانفیگ هر VM و کانتینر و تنظیمات شبکهٔ هر میزبان بهعنوان کانفیگ دستگاه نگه داشته میشود: نسخهها، تفاوتها و انحراف همانطور کار میکنند که برای یک روتر. گذرواژههای cloud-init پیش از آنکه چیزی از جمعآوریکننده بیرون برود جایگزین میشوند.
فهرست تغییرها در سایت میگوید کی مهمانی پیدا یا ناپدید شد، به میزبان دیگری رفت (live migration یا HA)، روشن یا خاموش شد، و کی میزبانی آفلاین شد.
هایپروایزر روی نقشهٔ سایت هم هست، کنار سوئیچهایی که به آنها کابلکشی شده است.
Proxmox VE 7 و 8؛ VMware vCenter 7.0 Update 2 و جدیدتر؛ libvirt 6 و جدیدتر؛ Windows Server 2019 و جدیدتر با Hyper-V (نسخههای قدیمیتر هم پس از نصب OpenSSH Server کار میکنند)؛ oVirt و OLVM نسخهٔ 4.4 و جدیدتر؛ Nutanix Prism Central 2022.6 و جدیدتر با کلاسترهای AHV؛ OpenStack با Keystone v3 و Nova API 2.47 یا جدیدتر (Pike و جدیدتر).
تا ۲۰۰۰ مهمان در هر دستگاه هایپروایزر خوانده میشود.
بررسیهای VLAN کانفیگ سوئیچهای Cisco IOS / IOS-XE و Huawei VRP را میخوانند؛ برای سوئیچهای دیگر بررسی نامعلوم میماند. پورتهای فیزیکی میزبانها در Nutanix و OpenStack در API این پلتفرمها نیست، پس لینکهای بالادستشان فقط از LLDP یا CDP میآید.
لینکهای بالادست، افزونگی و خرابی سوئیچها لازم دارند که سوئیچها میزبانها را از راه LLDP یا CDP ببینند.
پیشبینی ذخیرهسازی حدود یک روز نمونه لازم دارد؛ poolهای Cinder کاربر readerی میخواهند که policy ابر اجازهٔ دیدنشان را بدهد.
فقط خواندن: Zaryn ماشینهای مجازی را روشن، خاموش یا جابهجا نمیکند، و اعمال تغییر روی هایپروایزرها کار نمیکند.