ابرپلاس - زیرساخت امن درخواست مشاوره
OpenStack

تجربه من با Keystone در OpenStack؛ از Authentication تا عیب‌یابی Token و Endpoint

در این مقاله تجربه کار با Keystone را از زاویه عملی بررسی می‌کنم؛ از Token و Service Catalog تا Endpoint، Scope، Role و خطاهایی که هنگام Authentication در OpenStack با آن‌ها مواجه شدم.

نویسنده: بهزاد بازرگان
معماری Keystone و فرآیند Authentication و Token در OpenStack
ARTICLE OVERVIEW

در این مقاله چه می‌خوانید؟

در این مقاله تجربه کار با Keystone را از زاویه عملی بررسی می‌کنم؛ از Token و Service Catalog تا Endpoint، Scope، Role و خطاهایی که هنگام Authentication در OpenStack با آن‌ها مواجه شدم.

وقتی یادگیری 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» است.

INFRASTRUCTURE & CLOUD برای زیرساخت سازمانتان نیاز به مشاوره دارید؟
درخواست مشاوره ←