وقتی یادگیری OpenStack را شروع کردم، Keystone در نگاه اول یکی از سادهترین سرویسها به نظر میرسید. تعریفش هم خیلی پیچیده نیست: Keystone سرویس Identity در OpenStack است و Authentication و Authorization را مدیریت میکند.
اما وقتی وارد کار عملی شدم، متوجه شدم دانستن همین تعریف تقریباً هیچ کمکی در زمان Troubleshooting نمیکند.
اولین باری که با مشکل واقعی Keystone مواجه شدم، سرویس ظاهراً بالا بود، Horizon در دسترس بود و بخشهایی از محیط هم کار میکردند، اما OpenStack CLI رفتاری که انتظار داشتم نداشت.
همین تجربه باعث شد Keystone را نه بهعنوان «سرویس مدیریت کاربران»، بلکه بهعنوان یکی از نقاط مرکزی ارتباط سرویسهای OpenStack ببینم.
در این مقاله میخواهم دقیقاً از همین زاویه درباره Keystone صحبت کنم: وقتی Authentication خراب میشود چه اتفاقی میافتد، Token چیست، Endpoint چرا اهمیت دارد، Domain و Project چه تفاوتی دارند و مهمتر از همه، وقتی دستورهای OpenStack خطای Authentication میدهند از کجا باید Troubleshooting را شروع کنیم.
چیزی که ابتدا درباره Keystone اشتباه متوجه شده بودم
در ابتدای کار، Keystone را تقریباً معادل یک سیستم Login میدیدم.
یعنی:
Username + Password → Login
ولی معماری Identity در OpenStack کمی فراتر از این است.
وقتی با OpenStack کار میکنیم فقط مسئله این نیست که «این Username و Password صحیح هستند یا نه».
OpenStack باید بداند:
این User متعلق به کدام Domain است؟
روی کدام Project کار میکند؟
چه Roleهایی دارد؟
به چه Resourceهایی اجازه دسترسی دارد؟
درخواست برای کدام Service است؟
Endpoint آن Service کجاست؟
و درخواست در چه Scopeای معتبر است؟
به همین دلیل ممکن است Username و Password کاملاً درست باشند، اما باز هم یک دستور OpenStack شکست بخورد.
این یکی از اولین درسهای مهم من در کار با Keystone بود:
Authentication موفق فقط یکی از قسمتهای مسیر دسترسی است.
Keystone دقیقاً کجای OpenStack قرار دارد؟
برای درک Keystone، بهتر است یک بار مسیر یک درخواست عادی را دنبال کنیم.
فرض کنیم میخواهم لیست Instanceها را ببینم:
openstack server list
در نگاه اول این دستور مربوط به Nova است.
اما Client نمیتواند همینطور مستقیم به Nova بگوید لیست VMها را بده.
ابتدا باید Identity من مشخص شود.
به شکل سادهشده:
User
↓
OpenStack Client
↓
Keystone
↓
Token
↓
Service Catalog
↓
Nova API
این موضوع فقط برای Nova نیست.
همین مفهوم در ارتباط با Glance، Neutron، Cinder و سرویسهای دیگر هم وجود دارد.
بنابراین وقتی Keystone مشکل داشته باشد، ممکن است از دید کاربر اینطور به نظر برسد که چند سرویس مختلف OpenStack همزمان خراب شدهاند.
در حالی که Root Cause میتواند یک نقطه مشترک باشد:
Identity.
Token؛ چیزی که بعد از Login واقعاً اهمیت دارد
یکی از دستورهایی که در Troubleshooting برای من بسیار مهم شد این بود:
openstack token issue
این دستور سادهتر از چیزی است که اهمیتش نشان میدهد.
اگر Credential و Authentication Configuration صحیح باشند، Keystone باید بتواند Token صادر کند.
خروجی معمولاً اطلاعاتی مثل Token ID، Project و Expiration را نشان میدهد.
وقتی این دستور Fail میشود، برای من یک مرزبندی مهم ایجاد میشود.
هنوز دلیلی ندارد سراغ Nova برویم.
هنوز Neutron متهم نیست.
Glance هم مسئله اصلی ما نیست.
اول باید بفهمیم چرا Identity درست کار نمیکند.
این روش خیلی بهتر از این است که با مشاهده یک خطای CLI شروع کنیم سرویسهای مختلف را Restart کنیم.
تجربهای که با Auth URL داشتم
در یکی از Labهای اولیه، Keystone روی Endpointی قرار گرفته بود که Client به شکل مورد انتظار به آن دسترسی نداشت.
در بخشی از تستها با آدرس و Path مربوط به Identity API درگیر شدم و در نهایت برای دسترسی مناسب به Keystone از Reverse Proxy روی Port دیگری استفاده کردم.
همین مسئله یک نکته مهم را برایم روشن کرد:
ممکن است خود Keystone کار کند، ولی مسیری که Client برای رسیدن به آن استفاده میکند مشکل داشته باشد.
مثلاً متغیری شبیه این را در نظر بگیرید:
OS_AUTH_URL=http://controller:5000/v3
اگر این URL اشتباه باشد، مشکل Password نیست.
اگر DNS نام controller را Resolve نکند، مشکل Keystone User نیست.
اگر Reverse Proxy درخواست را به Backend اشتباه بفرستد، تغییر Role کمکی نمیکند.
اگر TLS فعال باشد و Certificate Verification شکست بخورد، ساختن User جدید راهحل نیست.
در Troubleshooting باید این لایهها را از هم جدا کرد.
اولین بررسی من: واقعاً به Endpoint دسترسی دارم؟
قبل از اینکه Configuration پیچیدهای را بررسی کنم، Connectivity را چک میکنم.
مثلاً:
curl -v http://controller:5000/v3
در محیط TLS:
curl -vk https://controller:5000/v3
البته استفاده از -k راهحل Production نیست؛ اینجا فقط برای تشخیص تفاوت بین مشکل TLS Verification و مشکل Connectivity استفاده میشود.
اگر TCP Connection برقرار نمیشود، بررسی User و Role تقریباً بیمعنی است.
مسیر بررسی من معمولاً از پایین شروع میشود:
DNS
↓
TCP Connectivity
↓
TLS
↓
HTTP/API
↓
Authentication
↓
Authorization
این ترتیب در عمل زمان زیادی ذخیره میکند.
یکی از خطاهای آزاردهنده: Environment Variable اشتباه
یکی دیگر از مشکلاتی که در کار عملی با آن مواجه شدم مربوط به Environment Variableهای OpenStack CLI بود.
وقتی فایل RC را Source میکنیم، متغیرهایی مانند اینها وارد Shell میشوند:
OS_AUTH_URL
OS_USERNAME
OS_PASSWORD
OS_PROJECT_NAME
OS_USER_DOMAIN_NAME
OS_PROJECT_DOMAIN_NAME
OS_REGION_NAME
OS_IDENTITY_API_VERSION
در ظاهر سادهاند.
اما یک مقدار اشتباه میتواند رفتار Client را کاملاً تغییر دهد.
برای دیدن Environment معمولاً بررسی میکنم:
env | grep '^OS_'
این دستور در Troubleshooting بسیار کاربردی است.
چون چیزی که تصور میکنم تنظیم شده الزاماً همان چیزی نیست که Shell واقعاً استفاده میکند.
تجربه من با Scope؛ وقتی unset هم آن چیزی که انتظار داشتم نبود
در یکی از Troubleshootingهای CLI با مسئله Scope مواجه شدم.
متغیری مرتبط با System Scope روی Authentication اثر میگذاشت و حتی بعد از unset کردن، رفتار مورد انتظار را نمیدیدم.
اولین واکنش طبیعی این است که فکر کنیم:
«من که متغیر را unset کردم؛ پس دیگر نباید وجود داشته باشد.»
اما در Linux باید پرسید:
این متغیر از کجا دوباره وارد Environment میشود؟
ممکن است:
RC File
Shell Profile
Script
Environment File
یا یک Source دیگر
آن را دوباره تعریف کند.
برای همین بررسی فایلهای Shell هم بخشی از Troubleshooting شد.
مثلاً:
grep -R "OS_SYSTEM_SCOPE" ~/.bashrc ~/.bash_profile ~/.profile /etc/profile /etc/bash.bashrc /etc/environment 2>/dev/null
در آن سناریو همین تفکیک بین چیزی که در Shell میبینیم و چیزی که فکر میکنیم Config کردهایم مهم بود.
این تجربه یک قانون عمومیتر برای من ایجاد کرد:
در Troubleshooting به Configuration واقعی اعتماد کنید، نه Configurationی که فکر میکنید اعمال شده است.
Domain، Project و Role؛ سه مفهومی که نباید با هم قاطی شوند
یکی از جاهایی که Keystone برای افراد تازهکار کمی گیجکننده میشود همین قسمت است.
Domain
Domain یک مرز منطقی برای مدیریت Identityها و Projectهاست.
در بسیاری از محیطهای ساده با:
Default
مواجه میشویم.
Project
Project محدودهای است که Resourceهای Cloud معمولاً در آن سازماندهی میشوند.
Instance، Network، Volume و Resourceهای دیگر معمولاً در Context یک Project استفاده میشوند.
Role
Role مشخص میکند User در Context موردنظر چه سطحی از دسترسی دارد.
برای مشاهده اطلاعات:
openstack domain list
openstack project list
openstack user list
openstack role list
اما نکته مهم اینجاست:
وجود User بهتنهایی به معنی داشتن دسترسی موردنظر نیست.
باید Assignment را هم بررسی کرد.
مثلاً:
openstack role assignment list --user <USER> --project <PROJECT> --names
اینجاست که Authentication و Authorization از یکدیگر جدا میشوند.
ممکن است Authentication کاملاً موفق باشد، ولی عملیات موردنظر با خطای Permission مواجه شود.
در چنین شرایطی Reset کردن Password مسئله را حل نمیکند.
Service Catalog؛ بخشی که اهمیتش را دیرتر فهمیدم
یکی از دستورهایی که تقریباً همیشه در Troubleshooting Identity استفاده میکنم:
openstack catalog list
و دستور مهم دیگر:
openstack endpoint list
است.
Service Catalog به Client میگوید سرویسهای مختلف Cloud کجا قرار دارند.
برای مثال ممکن است برای Keystone، Nova، Neutron یا Glance Endpointهای مختلفی وجود داشته باشد.
معمولاً با Interfaceهایی مثل:
Public
Internal
Admin
مواجه میشویم.
این موضوع در معماری Production بسیار مهمتر میشود.
ممکن است Public Endpoint برای دسترسی کاربران باشد، ولی سرویسهای داخلی از Internal Endpoint استفاده کنند.
اگر Internal Endpoint اشتباه باشد، ممکن است کاربر از بیرون بخشی از Cloud را سالم ببیند اما ارتباط Service-to-Service مشکل داشته باشد.
این یکی از سناریوهایی است که نشان میدهد چرا صرفاً باز شدن Horizon معیار خوبی برای سلامت OpenStack نیست.
Endpoint خراب چگونه خودش را نشان میدهد؟
فرض کنیم Authentication انجام شده و Token داریم.
اما Nova Endpoint اشتباه است.
در این حالت Keystone وظیفه خودش را انجام داده است.
ولی وقتی Client بخواهد از Service Catalog برای رسیدن به Nova استفاده کند، درخواست شکست میخورد.
برای همین:
openstack token issue
ممکن است موفق باشد،
ولی:
openstack server list
Fail شود.
این تفاوت برای Troubleshooting بسیار ارزشمند است.
اگر Token صادر نمیشود، تمرکز من روی Identity است.
اگر Token صادر میشود ولی فقط یک Service خاص Fail میشود، بررسی را به سمت Endpoint و همان Service میبرم.
به این ترتیب محدوده مشکل خیلی سریع کوچکتر میشود.
چطور Endpointها را بررسی میکنم؟
اول:
openstack endpoint list
اگر خروجی زیاد باشد:
openstack endpoint list --service keystone
یا Service موردنظر را مشخص میکنم.
بعد موارد زیر را بررسی میکنم:
Region
Service Name
Service Type
Interface
URL
Enabled
به URL خیلی دقت میکنم.
اشتباه سادهای مثل:
HTTP به جای HTTPS
Port اشتباه
Hostname اشتباه
Version Path اشتباه
یا DNS Name غیرقابل Resolve
میتواند کل ارتباط را مختل کند.
Horizon کار میکند؛ آیا یعنی Keystone سالم است؟
نه الزاماً.
این یکی از برداشتهایی است که به نظرم باید در محیط OpenStack کنار گذاشت.
فرض کنید Login به Horizon انجام میشود.
این فقط نشان میدهد یک مسیر مشخص از Authentication در آن لحظه کار کرده است.
اما هنوز نمیتوان نتیجه گرفت:
تمام Endpointها درست هستند.
تمام Scopeها صحیح هستند.
تمام Service Userها سالماند.
Internal Endpointها قابل دسترسی هستند.
تمام Service-to-Service Authenticationها کار میکنند.
به همین دلیل در Troubleshooting به UI بهعنوان تنها معیار Health اعتماد نمیکنم.
CLI معمولاً دید دقیقتری میدهد.
Service Userها؛ Keystone فقط برای کاربران انسانی نیست
نکته مهم دیگر این است که Keystone فقط Userهایی مثل Admin یا Operator را Authenticate نمیکند.
خود سرویسهای OpenStack هم برای ارتباط با یکدیگر نیاز به Identity و Credential دارند.
Nova باید بتواند با سرویسهای دیگر ارتباط برقرار کند.
Neutron همینطور.
Glance نیز در سناریوهای مختلف با سایر Componentها در ارتباط است.
بنابراین ممکن است Login کاربر کاملاً درست باشد ولی یک Service Credential اشتباه باشد.
این نوع Failure معمولاً از سمت کاربر عجیب به نظر میرسد.
مثلاً درخواست ساخت Instance ارسال میشود ولی در یکی از مراحل Backend شکست میخورد.
در این شرایط باید Log سرویس مربوطه را دید و دنبال خطاهایی مثل:
401 Unauthorized
403 Forbidden
Authentication failed
Unable to establish connection
Endpoint not found
گشت.
تفاوت 401 و 403 برای من مهم است
در Troubleshooting Keystone این دو HTTP Status را نباید یکی دانست.
401 Unauthorized
معمولاً اولین سؤال من این است:
آیا Authentication صحیح است؟
Credential درست است؟
Token معتبر است؟
Auth URL صحیح است؟
403 Forbidden
اینجا احتمالاً Authentication انجام شده ولی User اجازه عملیات موردنظر را ندارد.
در این حالت بیشتر به:
Role
Policy
Scope
Project Assignment
فکر میکنم.
این تفکیک ساده میتواند مسیر Troubleshooting را کاملاً عوض کند.
Token Expiration؛ خطایی که ممکن است ناگهانی دیده شود
Tokenهای Keystone دائمی نیستند.
Expiration دارند.
این موضوع از نظر Security منطقی است، ولی در Scriptها و Automation باید به آن توجه کرد.
برای بررسی:
openstack token issue
اطلاعات Expiration را میبینیم.
اگر یک Automation برای مدت طولانی از Credential یا Session نامناسب استفاده کند، باید نحوه Refresh Authentication را در طراحی در نظر گرفت.
به همین دلیل نگه داشتن Token ثابت در Script، روشی نیست که بخواهم برای Automation جدی روی آن حساب کنم.
Troubleshooting واقعی Keystone را از کجا شروع میکنم؟
اگر امروز با خطای Authentication در یک OpenStack مواجه شوم، مسیرم تقریباً این است.
مرحله اول: Environment
env | grep '^OS_'
بررسی میکنم:
Auth URL
Username
Project
Domain
Region
Scope
مرحله دوم: Endpoint Connectivity
curl -v <KEYSTONE-ENDPOINT>
اگر TLS داریم، Certificate و TLS Handshake را جداگانه بررسی میکنم.
مرحله سوم: Token
openstack token issue
اگر این مرحله Fail شود، هنوز سراغ Nova و Neutron نمیروم.
مرحله چهارم: Catalog
openstack catalog list
مرحله پنجم: Endpoint
openstack endpoint list
مرحله ششم: Identity Objects
openstack user list
openstack project list
openstack role list
مرحله هفتم: Assignment
openstack role assignment list --user <USER> --names
مرحله هشتم: Log
اگر موارد بالا درست باشند، تازه Logهای Keystone یا Reverse Proxy را بررسی میکنم.
این ترتیب باعث میشود Troubleshooting از حالت:
«شاید این باشد، شاید آن باشد»
خارج شود.
چیزی که از Troubleshooting Keystone یاد گرفتم
مهمترین چیزی که کار با Keystone به من یاد داد این نبود که چطور User بسازم یا Project ایجاد کنم.
مهمترین نکته این بود که در یک سیستم Distributed، خطایی که کاربر میبیند الزاماً در همان سرویسی نیست که ظاهراً Fail شده است.
وقتی:
openstack server list
خطا میدهد، اولین واکنش نباید همیشه بررسی Nova باشد.
وقتی Horizon مشکلی نشان میدهد، الزاماً Horizon خراب نیست.
وقتی یک API پاسخ نمیدهد، الزاماً Process آن API Down نیست.
باید مسیر درخواست را بشناسیم.
در مورد Identity این مسیر معمولاً از Credential شروع میشود و از:
Environment → Endpoint → Keystone → Token → Catalog → Service API
عبور میکند.
اگر این Flow را بفهمیم، Keystone دیگر یک سرویس مبهم در ابتدای دیاگرام OpenStack نیست.
تبدیل میشود به چیزی که میتوان رفتار آن را مرحلهبهمرحله مشاهده و عیبیابی کرد.
و برای من این دقیقاً تفاوت بین «شناختن Keystone» و «توانایی کار کردن با Keystone» است.