یکی از زیرساختهای اصلی GitOps، استفاده از Git به عنوان source در کل سیستم است. بسیاری از برنامهنویسها، با نحوه ذخیرهسازی پروژه و source code در گیت آشنایی دارند؛ اما GitOps حکم میکند که شما باید تمامی بخشهای اپلیکیشن خود مانند تنظیمات kubernetes manifests, db scripts, cluster definitions و… را نیز ذخیره کنید.
اما درباره secret چطور؟ چگونه میتوانیم با کمک GitOps از secretها استفاده کنیم؟ این سوال یکی از سوالات معروف تیمهایی است که از GitOps استفاده میکنند. در این مقاله قصد داریم به این سوال جواب دهیم. با ما همراه باشید.
مدیریت Secretها در GitOps
حقیقت این است که هیچ روش خاص یا واحدی برای مدیریت secretها در GitOps وجود ندارد. اگر شما یک روش خوب و محکم مانند HashiCrop vault دارید، پس منطقی است که از آن استفاده کنید؛ حتی اگر از نظر فنی مخالف GitOps باشد.
وقتی شما پروژه جدیدی را شروع میکنید، راههایی وجود دارد که میتوانید secretها را در Git ذخیره و در عین حال آنها را با استفاده از GitOps principles مدیریت کنید. ناگفته نماند که هرگز نباید raw secretsها در گیت ثبت (commit) شود.
تمامی راه حلهایی که برای مدیریت Secretها وجود دارند، در اصل آنها را در Git به صورت encrypt ذخیره میکنند. secretها میتوانند با GitOps مدیریت شوند و میتوانید آنها را به صورت ایمن در داخل هر Git repository، حتی در repositoryهای عمومی یا Public، قرار دهید.
روش کار Kubernetes secrets
در این مقاله ما در مورد دو نوع secret صحبت خواهیم کرد؛ یکی built-in Kubernetes secrets (که در تمامی خوشههای Kubernetes وجود دارد) و دیگری اسرار مهر و موم شده یا Sealed Secrets، که توسط Bitnami Sealed secrets controller معرفی شد.
قبل از این که بخواهیم درمورد Sealed secrets صحبت کنیم اجازه دهید ابتدا در مورد plain secrets صحبت کنیم. در درون Kubernetes، یک منبع بومی secrets وجود دارد که شما میتوانید از آن در اپلیکیشن خود استفاده کنید. به طور پیشفرض این secretsها به هیچ وجه رمزگذاری (encrypted) نمیشوند و رمزگذاریهایی که بر مبنای base64 استفاده شده است، هرگز نباید به عنوان ویژگی امنیتی در نظر گرفته شوند.
با این که راههایی وجود دارند که بتوانید Kubernetes secretها را در خوشه رمزگذاری کنید، اما توصیه میکنیم که آنها را بیرون از خوشه (cluster) ذخیره کنید؛ زیرا شما میتوانید به طور خارجی (External) آنها را در Git ذخیره کنید، که این مطابق با یکی از اصول GitOps است (همه چیز در Git ذخیره میشود).
استفاده از Kubernetes secrets بسیار راحت و آسان است. شما میتوانید از مکانیزمهای مشابهی مانند configmap استفاده و آنها را به عنوان فایل در اپلیکیشن خود نصب، یا به عنوان متغیر در محیط خود ارسال کنید.
Sealed secretsها فقط به عنوان یک extension در بالای Kubernetes قرار دارند. به این معنی که بعد از encryption/decryption، تمامی secrets functionها به عنوان یک Kubernetes secrets ساده عمل میکنند و بدین ترتیب اپلیکیشن شما به آنها دسترسی میدهد. اگر علاقهای به نحوه کارکردن Kubernetes secretsها ندارید، باید به دنبال راه امنیتی جایگزین باشید.
مثالی از یک اپلیکیشن به همراه secretها
برای یک مثال در حال اجرا، ما از یک برنامه ساده و کاربردی با عنوان kostis-codefresh استفاده خواهیم کرد. این برنامه یک وب اپلیکیشن است که لیستی از dummy secrets را صرفا میخواند و نمایش میدهد (در حقیقت از آنها استفاده نمیکند).
ما انتخاب کردیم که اپلیکیشن به جای استفاده از secretها به عنوان variable، آنها را به عنوان فایل از آدرس /secrets/ بخواند. مسیرهایی که ما استفاده کردیم، به شرح زیر است:
[security] # Path to key pair private_key = /secrets/sign/key.private public_key= /secrets/sign/key.pub [paypal] paypal_url = https://development.paypal.example.com paypal_cert=/secrets/ssl/paypal.crt [mysql] db_con= /secrets/mysql/connection db_user = /secrets/mysql/username db_password = /secrets/mysql/password
این نکته مهم را در نظر بگیرید که این، یک اپلیکیشن ساده است و فقط secrets را از مسیرهای مشخص شده میخواند و در اصل هیچ چیزی درباره Kubernetes, secret resources, volume mounts و … نمیداند.
شما باید آن را داخل Docker container (خارج از Kubernetes) اجرا کنید و اگر مسیرهای صحیح (correct paths) در درون خود secret files داشت، به درستی کار میکند. به منظور نمایش بیشتر، اپلیکیشن secretهای مختلفی مانند username/password, public/private key, certificate را میخواند و بارگذاری (Load) میکند. ما تمامی آنها را به یک روش مدیریت میکنیم.
The Bitnami sealed secret controller
شما Controller Kubernetesها را در خوشه (Cluster) نصب میکنید و آنها یک کار را برای شما انجام میدهند؛ Sealed secrets که میتوانند در Git ثبت شوند را، به plain secret که میتوانند در اپلیکیشن شما استفاده شوند، تبدیل میکنند.
نصب controller به سادگی امکان پذیر است:
helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets helm repo update helm install sealed-secrets-controller sealed-secrets/sealed-secrets
پس از نصب، controller دو کلید ایجاد میکند:
- کلید خصوصی (private key) که برای رمزگشایی مخفی (secret decryption) استفاده میشود. این کلید باید در cluster بماند و هرگز نباید آن را به کسی بدهید.
- کلید عمومی که برای secret encryption استفاده میشود. این کلید میتواند در خارج از cluster بماند و استفاده شود؛ هیچ مشکلی ندارد که این کلید را به کسی بدهید.
زمانی که controller نصب شد، میتوانید برنامه خود را به روش استاندارد نصب و استفاده کنید. نیازی نیست که کدهای برنامه خود را تغییر دهید یا Kubernetes manifestهای خود را دستکاری کنید. اگر برنامه شما قابلیت این را دارد که از vanilla Kubernetes secretها استفاده کند، قابلیت این را دارد که با sealed secretها نیز کار کند.
واضح است که controller به طور مستقیم با برنامه شما در تماس نیست. Sealed secretها را به Kubernetes secrets تبدیل میکند و بعد از آن به برنامه شما بستگی دارد که چگونه از آنها استفاده کند. اپلیکیشن شما حتی نمیداند که secretها در ابتدا در Git رمزگذاری شدهاند.
چگونه Secretهای خود را رمزگذاری کنیم؟
دیدیم که چگونه controllerها، secretها را رمزگذاری میکنند. اما در ابتدا چگونه secretها را رمزگذاری کنیم؟ controller همراه با فایل اجرایی Kubernetes همراه است، که برای همین منظور ایجاد شده است.
شما میتوانید با کپی کردن یک single binary در directory دلخواه خود (به احتمال زیاد در PATH variable)، آن را نصب کنید.
wget https://github.com/bitnami-labs/sealed secrets/releases/download/v0.16.0/kubeseal-linux-amd64 -O kubeseal sudo install -m 755 kubeseal /usr/local/bin/kubeseal
Kubernetes برعکس controllerها عمل میکند؛ به این شکل که Secretهای موجود را میگیرد و آنها را رمزگذاری میکند. Kubeseal کلید عمومی که در فرایند نصب ساخته شده است را از cluster درخواست میکند؛ سپس تمامی secretها به همراه کلید آن را رمزگذاری میکند.
به این معنی که:
- Kubeseal برای رمزگذاری secretها نیاز به دسترسی به cluster دارد (انتظار میرود یک kubeconfig مانند kubectl باشد).
- Secretهای رمزگذاری شده فقط در داخل خوشهای که برای پروسه encryption ساخته شدهاند، قابل استفاده است.
آخرین نکته بسیار مهم است، زیرا نشان میدهد که تمامی secretهای یک خوشه منحصر به فرد هستند. namespace برنامه ما به صورت پیشفرض استفاده میشود، بنابراین secretها خوشه هستند و namespaceها خاص و ویژه.
اگر میخواهید یک secret را برای خوشههای مختلف استفاده کنید، باید آن را به ازای هر cluster به صورت جداگانه رمزگذاری کنید.
برای استفاده از Kubeseal، فقط هر secret با فرمت yaml یا json را بگیرید و آن را رمزگذاری کنید.
kubeseal -n my-namespace < .db-creds.yml > db-creds.json
این کد یک SealedSecret ایجاد میکند، که یک منبع سفارشی kubernetes برای controller است. این فایل برای commit در گیت، یا ذخیره کردن در سیستمهای خارجی دیگر بسیار امن است.
شما میتوانید secret را در داخل خوشه اجرا کنید.
kubectl apply -f db-creds.json -n my-namespace
Secret جزئی از خوشه شما است و با استفاده از controller هر زمان که برنامه به آن نیاز داشت decrypted میشود.
نمودار کامل encryption/decryption
فرایند کامل به شرح زیر است:
- شما plain Kubernetes secret را به صورت local ایجاد میکنید. دقت کنید که نباید آن را در هیچ جا commit کنید.
- از Kubeseal برای رمزگذاری secretها در Sealed Secret استفاده کنید.
- Secret اصلی (original secret) را از workstation خود پاک و sealed secret را روی خوشه اعمال کنید.
- میتوانید Sealed secret را در Git خود commit کنید.
- برنامه خود را همانطور که انتظار میرود normal Kubernetes secrets کار کند، اجرا کنید.
- Controller تمامی Sealed secretها را رمزگشایی کرده، سپس آنها را به عنوان plain secrets به برنامه شما منتقل میکند.
- برنامه طبق معمول کار میکند.
استفاده از sealed secrets با Codefresh GitOps
با استفاده از Sealed Secrets controller، در نهایت میتوانیم تمامی secretها را در داخل Git (به صورت رمزگذاری شده) در هنگام configuration ذخیره کنیم.
در این repository میتوانید تمامی manifestهای برنامه به همراه secretها را مشاهده کنید. شما میتوانید به سادگی codefresh GitOps UI را به این پوشه نشان دهید و برنامه را در یک مرحله اجرا کنید. بعد از اتمام deployment، شما میتوانید تمامی componentهای برنامه را در داشبورد GitOps مشاهده کنید.
اگر شما برنامه را اجرا کنید، میتوانید مشاهده کنید که تمامی secretها را به درستی خوانده است:
از اینجا به بعد، برنامه از اصول GitOps پیروی میکند. اگر هر تغییری در ساختار Git ایجاد کنید که شامل تغییر در ساختار secretsها هم میشود، خوشه شما بهروزرسانی میشود و اگر چیزی را در درون خوشه تغییر دهید (حتی secretها)، Codefresh GitPos تغییرات را شناسایی میکنند.
جمعبندی
Secret rotation یک پروسه پیچیده است که نباید آن را ساده در نظر گرفت. در این مقاله ما موارد ابتدایی Sealed Secretها را در GitOps شرح دادیم؛ اما اگر قصد دارید controllerها را در production استفاده کنید، باید مستندات مورد نیاز را بخوانید و جنبههای دیگری مانند secret rotation و key handling را نیز در نظر بگیرید.
منبع: www.medium.com
دیدگاهتان را بنویسید