
رمز دیتابیس، کلید API و گواهی TLS نباید همراه کد نرمافزار در مخزن Git یا داخل ایمیج کانتینر قرار بگیرند. با افزایش تعداد سرویسها، مدیریت این اطلاعات به مسئلهای فراتر از نگهداری یک فایل تنظیمات تبدیل میشود: چه سرویسی به کدام رمز دسترسی دارد؟ اعتبار آن تا چه زمانی است؟ هنگام تغییر رمز، برنامه چگونه مقدار جدید را دریافت میکند؟
HashiCorp Vault ابزاری برای مدیریت متمرکز اطلاعات محرمانه یا Secret است. در این مقاله، روش اتصال Vault به Kubernetes و الگوهای مصرف Secret در نرمافزار را بررسی میکنیم؛ با تمرکز بر انتخاب معماری و رفتار واقعی برنامه هنگام تغییر اطلاعات دسترسی.
Vault چه مسئلهای را حل میکند؟
Vault دسترسی به اطلاعات محرمانه را بر پایهٔ هویت و Policy کنترل میکند. بهجای دادن یک رمز مشترک به همهٔ سرویسها، میتوان برای هر نرمافزار دسترسی مشخصی تعریف کرد.
یکی از کاربردهای آن، نگهداری اطلاعات ثابت مانند کلید سرویسهای بیرونی است. موتور KV نسخهٔ دوم امکان نسخهبندی مقادیر را فراهم میکند؛ بااینحال، ذخیرهٔ رمز در KV به معنی تغییر خودکار رمز در سامانهٔ مقصد نیست. برای مثال، ویرایش مقدار رمز دیتابیس در Vault بهتنهایی رمز همان کاربر در دیتابیس را عوض نمیکند. مستندات KV v2
کاربرد دیگر Vault، عملیات رمزنگاری با موتور Transit است. نرمافزار داده را برای رمزنگاری یا رمزگشایی ارسال میکند؛ Transit محل نگهداری دادهٔ کسبوکار نیست و برنامه باید خروجی رمزشده را در محل مناسب خود ذخیره کند. مستندات Transit
تفاوت Vault و Kubernetes Secret چیست؟
Kubernetes Secret راهی بومی برای تحویل اطلاعات حساس به Podهاست. اما Base64 رمزنگاری نیست و حفاظت از دادهٔ ذخیرهشده به تنظیم رمزنگاری در حالت سکون، RBAC و کنترل دسترسی به کلاستر وابسته است.
Vault و Kubernetes Secret میتوانند کنار هم استفاده شوند. اگر اطلاعات Vault را در Kubernetes Secret همگام کنید، یک نسخه از آن وارد سازوکار ذخیرهسازی و دسترسی Kubernetes میشود. بنابراین استفاده از Vault، نیاز به حفاظت از Secretهای کلاستر را حذف نمیکند. مستندات Kubernetes Secret
احراز هویت Kubernetes در Vault چگونه انجام میشود؟
در روش Kubernetes Auth، برنامه یا عامل همراه آن، توکن ServiceAccount را به Vault ارائه میکند. Vault برای اعتبارسنجی آن از API مربوط به TokenReview در Kubernetes استفاده میکند. سپس Role مشخص میکند کدام ServiceAccount در کدام Namespace، چه Policyهایی دریافت کند.
سه مفهوم را جدا نگه دارید:
- ServiceAccount: هویت workload در Kubernetes.
- Vault Role: اتصال هویت معتبر به مجوزهای Vault.
- Vault Policy: تعیین عملیات مجاز روی مسیرهای مشخص.
در محیط عملیاتی باید اعتبار گواهی Kubernetes API، مجوز TokenReview و نحوهٔ استفاده از توکنهای کوتاهعمر مشخص باشد. در صورت تنظیم audience در Role، توکن ارائهشده نیز باید audience سازگار داشته باشد. راهنمای Kubernetes Auth
روشهای اتصال Vault به Kubernetes
۱. Vault Agent Injector؛ تحویل Secret بهصورت فایل
Injector بر اساس annotationهای Pod، کانتینرهای Vault Agent را به آن اضافه میکند. Agent احراز هویت میکند و اطلاعات را با قالب موردنظر در فضای مشترک در اختیار کانتینر برنامه قرار میدهد.
این روش برای نرمافزاری مناسب است که تنظیمات را از فایل میخواند و نمیخواهید منطق ارتباط با Vault را وارد کد آن کنید. هزینهٔ منابع Agent و نحوهٔ بارگذاری مجدد فایل در برنامه باید در طراحی در نظر گرفته شود. راهنمای مصرف Secret در Kubernetes
۲. Vault Secrets Operator؛ استفاده از Kubernetes Secret
اپراتور میتواند اطلاعات Vault را به Kubernetes Secret همگام کند. این الگو برای برنامهها یا chartهایی مناسب است که از قبل انتظار دریافت Secret بومی Kubernetes را دارند.
در حالت معمول این همگامسازی، داده در etcd نیز ذخیره میشود. همچنین باید مشخص کنید تغییر Secret چگونه به برنامه منتقل میشود: تغییر متغیر محیطی کانتینرِ در حال اجرا خودکار انجام نمیشود و ممکن است به rollout نیاز باشد. VSO قابلیت CSI جداگانهای نیز دارد که طبق مستندات فعلی، به مجوز مناسب Enterprise نیاز دارد. مقایسهٔ روشهای یکپارچهسازی
۳. Vault CSI Provider؛ ارائهٔ اطلاعات از طریق Volume
در این روش، Secrets Store CSI Driver همراه provider مربوط به Vault، اطلاعات را از طریق Volume در اختیار Pod قرار میدهد. تعریف SecretProviderClass مشخص میکند چه دادهای دریافت شود.
در انتخاب CSI، پشتیبانی نسخهٔ نصبشده از بهروزرسانی مقادیر و رفتار برنامه پس از آن را بررسی کنید. Vault CSI Provider را با CSI driver مربوط به VSO یکسان فرض نکنید؛ اینها مسیرهای یکپارچهسازی متفاوتی هستند. طراحی معتبر HashiCorp
۴. ارتباط مستقیم برنامه با API یا SDK
برنامه میتواند خودش با Vault احراز هویت کند و اطلاعات موردنیاز را دریافت کند. این روش کنترل بیشتری روی زمان دریافت و مصرف داده میدهد، اما مسئولیت تمدید توکن، مدیریت خطا، timeout و رفتار هنگام قطعی را وارد کد برنامه میکند.
پیشنهاد معماری: اگر برنامه فایل تنظیمات را پشتیبانی میکند، ابتدا الگوی Agent را ارزیابی کنید. برای برنامهٔ وابسته به Secret بومی Kubernetes، اپراتور را بررسی کنید. ارتباط مستقیم زمانی مناسبتر است که تیم توسعه مسئولیت چرخهٔ عمر دسترسی را آگاهانه بپذیرد.
نمونهٔ آموزشی: دریافت فایل تنظیمات با Agent Injector
این نمونه برای توضیح اتصال اجزاست و دستورالعمل کامل استقرار production نیست. پیشفرضها عبارتاند از: Vault با TLS معتبر در دسترس است، Injector نصب شده، Kubernetes Auth و TokenReview تنظیم شدهاند و KV v2 در مسیر kv فعال است. مقدار آموزشی در kv/apps/payments/config قرار دارد. هیچ رمز واقعی را در Git ثبت نکنید.
تعریف دسترسی محدود
Policy برنامه فقط اجازهٔ خواندن همین مسیر را میدهد:
path "kv/data/apps/payments/config" {
capabilities = ["read"]
}
وجود بخش data در مسیر Policy و template مربوط به ساختار KV v2 است. نام Policy را برای نمونه payments-read در نظر میگیریم. مدیر Vault پس از ثبت Policy، Role را ایجاد میکند:
vault write auth/kubernetes/role/payments \
bound_service_account_names=payments \
bound_service_account_namespaces=payments \
policies=payments-read \
ttl=1h
این فرمان، احراز هویت Kubernetes را نصب یا تنظیم نمیکند؛ Role را روی auth mount از قبل آمادهشده میسازد. در این مثال audience سفارشی تعیین نشده است؛ اگر سیاست محیط شما آن را الزامی میکند، Role و توکن Pod را هماهنگ تنظیم کنید. مرجع Kubernetes Auth API
تنظیم Pod برای دریافت JSON
annotationها باید زیر spec.template.metadata در Deployment قرار بگیرند، نه فقط روی metadata خود Deployment. ServiceAccount با نام payments نیز باید در Namespace همنام ساخته شده باشد:
# بخشی از مشخصات Deployment؛ فایل کامل قابل اجرا نیست
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "payments"
vault.hashicorp.com/agent-inject-secret-config.json: "kv/data/apps/payments/config"
vault.hashicorp.com/agent-inject-template-config.json: |
{{- with secret "kv/data/apps/payments/config" -}}
{{ .Data.data | toJSON }}
{{- end }}
vault.hashicorp.com/agent-inject-perms-config.json: "0440"
spec:
serviceAccountName: payments
# containers و سایر تنظیمات Deployment در این بخش قرار میگیرند.
خروجی مورد انتظار، فایل /vault/secrets/config.json است. قالب JSON از اتصال دستی رشتهها و مشکلات escape کردن رمز جلوگیری میکند. برای مجوز 0440، کاربر یا گروه اجرای برنامه باید دسترسی خواندن فایل را داشته باشد؛ این موضوع را با securityContext واقعی Pod تطبیق دهید. تنظیم نام Role و مسیر Secret نیز باید با Policy یکسان باشد. مرجع annotationهای Injector
نرمافزار چگونه از Secret استفاده کند؟
خواندن فایل در برنامه
فرض کنید دادهٔ KV شامل کلیدهای username و password است. در یک برنامهٔ Python، بخش بارگذاری تنظیمات میتواند چنین باشد:
import json
from pathlib import Path
def load_database_credentials():
config = json.loads(
Path("/vault/secrets/config.json").read_text(encoding="utf-8")
)
username = config.get("username")
password = config.get("password")
if not username or not password:
raise RuntimeError("Database credentials are unavailable")
return username, password
این تابع فقط اطلاعات را میخواند؛ اتصال دیتابیس یا reload خودکار ایجاد نمیکند. هنگام ثبت خطا، محتوای فایل، رمز و توکن را چاپ نکنید.
دریافت Secret از متغیر محیطی
اگر برنامه فقط environment variable میپذیرد، باید روشی مشخص برای تبدیل داده و راهاندازی فرایند داشته باشید. خواندن فایل در startup و تنظیم محیط، مقدار همان لحظه را به فرایند میدهد؛ با تغییر فایل، environment آن فرایند عوض نمیشود. در این الگو، تغییر رمز باید با راهاندازی مجدد کنترلشده هماهنگ شود.
دریافت مستقیم در زمان اجرا
در ارتباط مستقیم، برنامه نباید برای تکتک درخواستهای کاربر یک خواندن بیقیدوشرط از Vault انجام دهد. پیشنهاد طراحی این است که اطلاعات تا حد مجاز اعتبارشان نگهداری شوند، درخواستها timeout داشته باشند و retry با فاصلهٔ افزایشی انجام شود. برای دادههای دارای lease، تمدید و انقضا باید بخشی از منطق دسترسی باشد.
تغییر رمز و Rotation؛ جایی که طراحی برنامه اهمیت پیدا میکند
سه اتفاق مستقل را از هم جدا کنید: تغییر مقدار در Vault، بهروزرسانی فایل یا Kubernetes Secret و استفادهٔ برنامه از مقدار جدید.
برای مثال، اگر برنامه pool اتصال دیتابیس را فقط هنگام startup میسازد، تغییر فایل رمز الزاماً pool را بازسازی نمیکند. راهکار میتواند reload کنترلشده، بازسازی اتصالها یا rollout باشد؛ انتخاب آن به driver و معماری نرمافزار وابسته است.
رفتار Vault Agent نیز به نوع Secret وابسته است. دادهٔ KV ثابت، توکن قابل تمدید و Secret دارای lease الزاماً چرخهٔ بهروزرسانی یکسان ندارند. فاصلهٔ render مجدد را مطابق نیاز تنظیم و آزمایش کنید. رفتار Vault Agent Template
پیش از استقرار عملیاتی چه چیزهایی را آزمایش کنیم؟
- برنامه با ServiceAccount یک سرویس دیگر نتواند Secret را بخواند.
- تغییر مقدار، در زمان مورد انتظار به برنامه برسد و اتصالها بهدرستی بازسازی شوند.
- رفتار startup هنگام در دسترس نبودن Vault مشخص باشد.
- انقضا یا لغو دسترسی، به خطای قابل مدیریت تبدیل شود و رمز منقضی بینهایت استفاده نشود.
- Secret وارد لاگ، ایمیج، مخزن Git و خروجی pipeline نشود.
- پشتیبانگیری، بازیابی و پایش خود Vault جزئی از عملیات زیرساخت باشد.
این سناریوها را در محیط آزمایشی اجرا کنید. نمونههای بالا در کلاستر واقعی این مقاله اجرا نشدهاند و باید با نسخهها، TLS، مجوزها و روش استقرار شما تطبیق داده شوند.
اجرای Vault در سازمان از کجا شروع شود؟
از یک سرویس مشخص و یک نوع Secret شروع کنید. ابتدا هویت و دسترسی محدود را تعریف کنید، سپس تحویل اطلاعات و رفتار نرمافزار هنگام تغییر یا قطعی را آزمایش کنید. پس از آن، الگو را برای سرویسهای دیگر گسترش دهید.
اگر برای طراحی این مسیر به همراهی نیاز دارید، در صفحهٔ خدمات دواپس میتوانید دربارهٔ بررسی نیازهای زیرساخت و پیادهسازی فرایندهای مرتبط اطلاعات بیشتری ببینید. برای طراحی بستر اجرای سرویسها نیز صفحهٔ خدمات کوبرنتیز مرتبط است.
پرسشهای متداول
آیا با Vault دیگر به Kubernetes Secret نیاز نداریم؟
به روش اتصال بستگی دارد. Agent و برخی الگوهای CSI اطلاعات را از طریق فایل ارائه میکنند؛ همگامسازی معمول اپراتور، Kubernetes Secret ایجاد یا بهروزرسانی میکند.
آیا برای استفاده از Vault باید کد برنامه تغییر کند؟
اگر نرمافزار فایل تنظیمات یا Kubernetes Secret را پشتیبانی کند، ممکن است تغییر اصلی در استقرار باشد. بااینحال، برای دریافت مقدار جدید بدون restart، برنامه باید قابلیت reload مناسب داشته باشد.
آیا Vault همهٔ رمزها را خودکار تغییر میدهد؟
خیر. نگهداری مقدار در KV با تغییر رمز در سرویس مقصد متفاوت است. قابلیت تغییر یا تولید اعتبارنامه به موتور، تنظیمات و سامانهٔ مقصد وابسته است.
آیا باید Root Token را در برنامه قرار دهیم؟
خیر. برنامه باید با هویت اختصاصی و مجوز محدود احراز هویت شود. در الگوی Kubernetes Auth، ServiceAccount و Role مرتبط، مبنای این دسترسی هستند؛ Root Token برای مصرف روزمرهٔ نرمافزار مناسب نیست.
نشانی ایمیل شما منتشر نخواهد شد. بخشهای موردنیاز علامتگذاری شدهاند *
نظر دهید تعداد کاراکتر مانده: 300