<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های محمدحسين افشاری کلانی</title>
        <link>https://virgool.io/feed/@mhafshari</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-06-16 13:35:35</pubDate>
        <image>
            <url>https://static.virgool.io/images/default-avatar.jpg</url>
            <title>محمدحسين افشاری کلانی</title>
            <link>https://virgool.io/@mhafshari</link>
        </image>

                    <item>
                <title>تفاوت Deployment و StatefulSet در کوبرنتیس</title>
                <link>https://virgool.io/Abriment/%D8%AA%D9%81%D8%A7%D9%88%D8%AA-deployment-%D9%88-statefulset-%D8%AF%D8%B1-%DA%A9%D9%88%D8%A8%D8%B1%D9%86%D8%AA%DB%8C%D8%B3-wql4aiea1e97</link>
                <description>برای پیاده سازی اپلیکیشن در محیط کوبرنتیس گزینه های مختلفی وجود دارد اما استفاده از Deployment و StatefulSet بسیار پرکاربرد تر از سایر گزینه ها است. گاهی اوقات تصمیم گیری در رابطه با اینکه چه زمانی باید از Deployment یا StatefulSet استفاده کرد، دشوار است. در این مقاله سعی داریم تا با بررسی ویژگی های این دو آبجکت تفاوت آن ها را استخراج کنیم تا برای پیاده سازی اپلیکیشن از بهترین گزینه استفاده کنیم.یک آبجکت سطح بالا برای پیاده سازی و به روز رسانی اپلیکیشن Deployment است. زمانی که Deploymentساخته می شود یک آبجکت دیگر با نام ReplicaSet در پشت صحنه ساخته می شود. این آبجکت مسئول کنترل پادهای تحت مدیریت یک Deployment است. پس توجه به این نکته ضروری است که پادهای یک Deployment مستقیم توسط آن مدیریت و کنترل نمی شوند بلکه از طریق ReplicaSet این کار انجام می شود. در شکل 1 ارتباط بین Deployment و پاد های آن نشان داده شده است که توسط ReplicaSet کنترل می شوند.شکل 1- ارتباط بین Deployment و پادها که توسط یک آبجکت میانی به نام ReplicaSet مدیریت می شوندبنابراین برای اینکه تفاوت Deployment با StatefulSet را متوجه شویم باید نحوه عملکرد ReplicaSet را با StatefulSet مقایسه کرد. ذکر این نکته ضروری است که ما هیچگاه اقدام به ساخت ReplicaSet به صورت مجزا نمی کنیم بلکه با ساخت Deployment یک ReplicaSet ساخته می شود.در زمان تعریف Deployment بخشی با عنوان templateوجود دارد که با استفاده از آن ReplicaSetپادهای یکسان می سازد. به عبارت دیگر در زمان ساخت پاد از این تمپلیت استفاده می شود تا مشخصات آن تعیین شود بنابراین این پادها به جز در اسم و آدرس IP تفاوتی با یکدیگر ندارند. اگر در بخش template یک volume مشخص شده باشد که به یک PersistentVolumeClaim اشاره کند، تمامی پادهای ساخته شده از روی template به این فضای ذخیره سازی دسترسی خواهند داشت در واقع این فضای ذخیره سازی بین چندین پاد تحت مدیریت یک ReplicaSet به اشتراک گذاشته می شود. در شکل2 این موضوع نشان داده شده است.شکل 2- تمام پادهای مرتبط با یک ReplicaSet از یک PersistentVolumeClaim استفاده می کننددر حالتی که از ReplicaSet استفاده شود و لازم باشد که هر پاد به یک فضای ذخیره سازی مجزا متصل باشد راهی جز ساختن ReplicaSet های مجزا با template های مختلف نیست، واضح است که این template ها فقط در بخش volumeمتفاوت هستند. در شکل3 نحوه اتصال هر پاد به فضاهای ذخیره سازی مجزا با استفاده از ReplicaSet نشان داده شده است.شکل 3- نحوه اتصال هر پاد به فضاهای ذخیره سازی مجزا با استفاده از ReplicaSetهمانطور که می دانید برای اتصال به پادهای یک Deployment یا ReplicaSet از مفهومی به نام سرویس استفاده می شود، زمانی که درخواست به یک سرویس وارد می شود، سرویس این درخواست را بین پادهایی توزیع می کند که به عنوان endpoint آن سرویس تعریف شده اند. حال سناریو شکل 3 را در نظر بگیرید که هر پاد فضای ذخیره سازی مجزایی داشته بنابراین پاسخ هایی که از جانب هر پاد داده می شوند، متفاوت خواهد بود. پس برای اینکه بتوان به طور مجزا به هر پاد متصل شد باید به ازای هر پاد یک سرویس مجزا تعریف کرد و تنها یک پاد را endpoint آن سرویس قرار داد. شکل 4 نحوه اتصال به هر پاد یک ReplicaSet که از فضای ذخیره سازی مجزا استفاده می کند را نشان می دهد. در این شکل سرویس A دارای سه endpoint هست اما سرویس های A1، A2 و A3 تنها دارای یک endpoint مجزا هستند.شکل 4- نحوه اتصال به هر پاد یک ReplicaSet که از فضای ذخیره سازی مجزا استفاده می کندواضح است که در شرایط ذکر شده استفاده از ReplicaSet یا همان Deployment کار راحتی نیست و دارای پیچیدگی های زیادی است که امکان بروز اشتباه از سمت کاربر را افزایش می دهد. اکنون که با نحوه عملکرد Deployment یا ReplicaSet آشنا شدیم به مقایسه آن با StatefulSet پرداخته می شود.از تفاوت اصلی ReplicaSet و StatefulSet نام گذاری پادهای ساخته شده از template است. نام گذاری پادها در Replicasetدارای فرمتی به شکل ReplicaSetName-RandomID است در صورتی که در StatefulSet به صورت StatefulSetName-ordinaIndex است. شکل 5 تفاوت نام گذاری پادها را نمایش می دهد.شکل 5- تفاوت نام گذاری پادها در ReplicaSet و StatefulSetدر صورتی که یک پاد از بین برود در هر دو حالت یک پاد جایگزین ساخته خواهد شد با این تفاوت که در ReplicaSet نام پاد جدید با پاد از دست رفته متفاوت خواهد بود اما در StatefulSet نام پاد جدید با پاد از دست رفته دقیقا یکسان است که در شکل 6 این مورد قابل مشاهده است.شکل 6- تفاوت نام گذاری پادها در ReplicaSet و StatefulSetهمانطور که در شکل 7 آمده است StatefulSet در کنار مشخص کردن template برای پادها قابلیت تعریف templateبرای فضای ذخیره سازی هم فراهم می کند که با نام volumeClaimTemplates مشخص می شود. استفاده از volumeClaimTemplates این قابلیت را فراهم می کند تا هر کدام از پادهای مرتبط با یک StatefulSet به یک فضای ذخیره سازی مجزا متصل شود. از طرف دیگر از آنجایی که هر پاد نام مشخص خود را دارد با تعریف یک سرویس خاص با نوع headless می توان به طور مستقیم به هرکدام از پادها متصل شد. این کار از طریق آدرس دهی با فرمت PodName.HeadlessService انجام می شود.شکل 7- نحوه اتصال فضای ذخیره سازی مجزا به هر پاد در StatefulSetدر صورتی که بخواهیم تعداد پاد های یک StaefulSet را افزایش یا کاهش دهیم با سناریو شکل 8 مواجه می شویم. در این سناریو در صورتی که تعداد پاد کاهش پیدا کند، آن پاد از مدار خارج می شود ولی فضای ذخیره سازی حذف نمی شود (مگر اینکه کاربر به صورت دستی این کار را انجام بدهد) و در صورت افزایش تعداد پاد در صورتی که از قبل یک فضای ذخیره سازی برای این پاد وجود داشته باشد، آن را به پاد متصل می کند و در صورتی که وجود نداشته باشد یک فضای ذخیره سازی از روی volumeClaimTemplates مشخص شده می سازد و آن را به پاد متصل می کند.شکل 8- نحوه اتصال فضای ذخیره سازی به هر پاد در زمان کاهش یا افزایش تعداد پادهای تحت کنترل StatefulSetبه طور خلاصه تفاوت بین Deployment و StatefulSet را می توان به این صورت تشریح کرد، پاد تحت کنترل StatefulSet شناسه یکتا خواهد داشت که با استفاده از سرویس headless می توان مستقیما به هر پاد متصل شد، از طرف دیگر قابلیت اختصاص دیسک مجزا به هر پاد نیز در این حالت وجود دارد. پاد تحت کنترل Deployment شناسه تصادفی خواهد داشت و از طریق سرویس داخلی درخواست بین پاد های مختلف آن توزیع می شود، از طرف دیگر امکان اختصاص دیسک مجزا به هر پاد وجود ندارد و یک دیسک بین تمامی پاد ها به اشتراک گذاشته می شود.برای پیاده سازی اپلیکیشن در صورتی که نمی دانید از Deployment یا StatefulSet استفاده کنید، پیشنهاد می شود کار خود را با Deployment شروع کنید و اگر با محدودیت های ذکر شده Deployment مواجه شدید، پیاده سازی اپلیکیشن خود را به StatefulSet تغییر دهید.منبعMarko Luksa - Kubernetes in Action-Manning Publications (2018)</description>
                <category>محمدحسين افشاری کلانی</category>
                <author>محمدحسين افشاری کلانی</author>
                <pubDate>Sun, 14 Aug 2022 12:20:49 +0430</pubDate>
            </item>
                    <item>
                <title>امنیت کوبرنتیس</title>
                <link>https://virgool.io/Abriment/%D8%A7%D9%85%D9%86%DB%8C%D8%AA-%DA%A9%D9%88%D8%A8%D8%B1%D9%86%D8%AA%DB%8C%D8%B3-pxbf7o729te8</link>
                <description>برای برقراری امنیت کوبرنتیس باید در لایه های مختلف و توسط تیم های متفاوت اقداماتی انجام شود، در این مقاله به عنوان مدیر کلاستر کوبرنتیس باید اقداماتی انجام شود تا آسیب پذیری کلاستر و اپلیکیشن های در حال اجرا بر روی کلاستر را به حداقل رساند. به عبارت دیگر با انجام مجموعه ای از اقدامات نباید اجازه راه اندازی اپلیکیشن هایی که می توانند امنیت کلاستر را به خطر بیاندازند را داد. برخی از اقدامات امنیتی باید در زمان ساخت ایمیج های اپلیکیشن انجام شود که باید توسط تیم DevOps و در پایپ لاین CI/CD مورد توجه قرار بگیرند. در این مقاله تمرکز بر روی اقداماتی است که توسط مدیر کلاستر کوبرنتیس در لایه سرور و کلاستر کوبرنتیس انجام می شود. لازم به ذکر است تمام موارد ذکر شده در این مقاله از کتاب هایی که نام آن ها در بخش منابع آمده، جمع آوری شده است. همچنین فرض بر آن است که خواننده این مقاله با مفاهیم کوبرنتیس آشنایی کامل داشته باشد.امن کردن سرورهای کلاستر کوبرنتیسدر مرحله اول برای راه اندازی کلاستر کوبرنتیس باید از سرور هایی به عنوان وورکر یا مستر استفاده کرد. انتخاب سیستم عامل برای این سرور ها اولین اقدام برای برقراری امنیت کلاستر کوبرنتیس است. در صورتی که سازمان تاکیدی بر استفاده از سیستم عامل خاصی ندارد می توان از توزیع های لینوکسی غیرقابل تغییر استفاده کرد. مزیت استفاده از این سیستم عامل ها lock بودن root filesystem آن است که باعث می شود قابلیت تغییر توسط اپلیکیشن ها را نداشته باشد. قابلیت به روز رسانی خودکار این نوع سیستم عامل نیز کمک بزرگی در کاهش ریسک آسیب پذیری های عمومی و شناخته شده می کند. در صورتی که امکان استفاده از قابلیت به روزرسانی خودکار سیستم عامل وجود ندارد باید به صورت دستی سیستم عامل به آخرین نسخه به روز رسانی شود. لیستی از سیستم عامل های غیرقابل تغییر و معروف در زیر آمده است: Flatcar Container Linux Bottlerocket RancherOS Red Hat Atomicسرور هایی که به عنوان وورکر یا مستر در کلاستر از آن ها استفاده می شود نیازی به اجرای فرآیند های خاصی نظیر kubelet یا container engine دارند. سایر فرآیند های نامرتبط با محیط کوبرنتیس به عنوان فرآیند های غیر ضروری شناخته می شوند و باید از روی این سرور ها حذف شوند. در صورتی که از سیستم عامل های غیرقابل تغییر استفاده شود، این سیستم عامل ها برای استفاده در محیط های کانتینری بهینه سازی شده اند و فرآیند های غیرضروری از قبل بر روی این سرور ها وجود نخواهد داشت.با استفاده از دیواره آتش محلی تنها پورت های ضروری بر روی سرور قابل دسترس باشند، این پورت های ضروری برای ترافیک های وروردی خاص با آدرس های IP مشخص باید در دسترس باشند. در جدول زیر پورت هایی که باید بر روی هر سرور (با توجه به نقش آن ها در کلاستر کوبرنتیس) باز باشند، مشخص شده است.جدول 1- تنظیمات دیواره آتش بر روی سرور های کلاستر کوبرنتیس متناسب با نقش آن هایکی از اجزاء مهم سرور هایی که در کلاستر کوبرنتیس استفاده می شوند container engine ها هستند. برخی از container engine ها را می توان به صورت unprivileged راه اندازی کرد به این صورت که از یوزر روت برای اجرای daemon آن استفاده نشود. به این روش از راه اندازی، rootless container engine گفته می شود. با وجود اینکه این رویکرد، سطح خوبی از امنیت را فراهم می کند اما بسیاری از container engine های موجود این ویژگی را به صورت پایدار راهی بازار نکرده اند و این ویژگی در مرحله آزمایشی قرار دارد. اما لازم است تا در صورت راهی شدن یک نسخه پایدار از این ویژگی که با محیط کوبرنتیس سازگار باشد، مدیر کلاستر کوبرنتیس برای ارتقا امنیت از آن استفاده کند.در نهایت باید در سطح سیستم عامل لاگ های تولید شده برای SSH، OS audit و کرنل را جمع آوری کرد و با استفاده از ابزار های مصور سازی و تحلیل لاگ، هشدارهایی برای مخاطرات امنیتی احتمالی در نظر گرفت.امن کردن کلاستر کوبرنتیسکاربران از طریق kubernetes API server با کلاستر کوبرنتیس ارتباط برقرار می کنند. پس از ارسال درخواست به API server اطلاعات موجود در درخواست در یک پایگاه داده توزیع شده کلید-مقدار با نام etcd ذخیره می شود. ملاحظات امنیتی در این بخش از عملکرد کلاستر کوبرنتیس متمرکز می شود که در ادامه به بررسی آن پرداخته می شود.امن کردن kubernetes API Serverاز آنجایی که تمامی ارتباطات بین اجزاء کنترلی کوبرنتیس و API server آن مبتنی بر TLS است، توصیه شده است که در بازه های زمانی کوتاه گواهی نامه های ارتباطی را تغییر دهیم این امر با اصطلاح Rotating credentials شناخته شده است.برای کاربرانی که قرار است با کلاستر کوبرنتیس تعامل داشته باشند، بهتر است حساب کاربری مجزا در نظر گرفت سپس با استفاده از مکانیسم کنترل سطح دسترسی مبتنی بر نقش یا RBAC دسترسی لازم به کاربران داده شود. این دسترسی باید متناسب با تعامل کاربر با کلاستر باشد و دسترسی بیشتری به کاربر اعطا نشود. به طور کلی کوبرنتیس قابلیت احراز هویت محدودی برای کاربران در نظر گرفته است اما این امکان وجود دارد که با یک ابزار مدیریت کاربران مثل LDAP یا Keystone یکپارچه شود. در صورت یکپارچه شدن با یک ابزار مدیریت کاربران امکان تغییر گواهینامه کاربران (برای تعامل با API server کوبرنتیس) به صورت خودکار و دوره ای فراهم می شود، این فرآیند باید به نحوی باشد که کاربر از تغییر گواهینامه با خبر نشود و ارتباط آن با کلاستر دچار اختلال نشود. یکی از مزایای استفاده از حساب کاربری مجزا امکان فعال کردن لاگ audit کوبرنتیس و ذخیره سازی آن ها در یک زیرساخت ذخیره لاگ است. با تحلیل کردن و ایجاد داشبورد و آلارم های مناسب می توان مخاطرات امنیتی را تشخیص داد. لاگ audit در سطوح مختلف و برای منابع مختلف کلاستر کوبرنتیس از طریق تعریف کردن policy امکان پذیر است. در هنگام تعریف policy می توان مشخص کرد که برای رویداد های چه منابعی و با چه سطح از جزئیات لاگ تولید شود. بنابراین فعال کردن لاگ audit در کوبرنتیس کاملا تنظیم پذیر است. علاوه بر لاگ audit باید لاگ های مربوط به CNI و DNS کوبرنتیس نیز جمع آوری و تحلیل شود.هر نسخه کوبرنتیس شامل منابعی با نسخه های آلفا و بتا هست. چون این نسخه ها تحت توسعه هستند امکان وجود باگ و آسیب پذیری امنیتی در آن ها بالا است. بنابراین بهتر است امکان استفاده از نسخه های آلفا و بتا را غیرفعال کرد. نسخه های آلفا معمولا (اما نه همیشه) غیرفعال هستند و توصیه می شود که در کلاستر های عملیاتی از آن ها استفاده نشود، اما استفاده در کلاستر های تستی بلامانع است. نسخه های بتا به طور پیش فرض فعال هستند و تا حد خوبی مکانیسم های امنیتی در آن ها تست شده است اما به علت فراگیر نبودن و استفاده کمتر از آن ها، پتانسیل بروز آسیب پذیری امنیتی در آن ها بالا است. این کار از طریق تنظیم API server کوبرنتیس انجام می شود. API Server کوبرنتیس می تواند بر روی دو پورت سرویس دهی کند، پورت پیش فرض 8080 که با فلگ insecure-bind-address قابل تنظیم است. در صورتی که API server از این پورت استفاده کند مراحل احراز هویت و کنترل سطح دسترسی توسط API server انجام نمی گیرد که از لحاظ امنیتی خطر بزرگی محسوب می شود، در نتیجه لازم است که API server از فلگ secure-port که بر روی پورت پیش فرض 6443 فعالیت می کند، استفاده کند تا از انجام احراز هویت و کنترل سطح دسترسی اطمینان حاصل شود.در تنظیمات API server در صورتی که فلگ anonymous-auth فعال باشد، API server به کاربرانی که احراز هویت نشده باشند این امکان را می دهد که بتوانند به آن متصل شوند. از نسخه 1.6 به بعد کوبرنتیس این فلگ به صورت پیش فرض فعال هست که باید غیرفعال شود.نکته آخر در تنظیمات API server استفاده از پلاگین های از پیش تعریف شده admission-control است که اطلاعات ارسال شده سمت کاربر را اعتبار سنجی می کند. البته امکان استفاده از admission-control های شخصی سازی شده با استفاده از webhook هم وجود دارد تا با استفاده از آن ها بتوان اعتبار سنجی درخواست های وارد شده را انجام داد و در صورت نیاز تغیراتی بر روی درخواست های وارد شده اعمال کرد. به علت گستردگی این مبحث سعی بر بررسی این موضوع در یک مقاله جداگانه داریم. اما در این مرحله بهتر است از پلاگین های از پیش تعریف شده API server برای تامین امنیت بهره برد. همچنین استفاده از ImagePolicyWebhook برای جلوگیری از پیاده سازی کانتینرهایی که ایمیج های آن ها دارای آسیب پذیری هست، نیز توصیه می شود.امن کردن etcdاستفاده از x509 PKI و TLS در ETCD به صورتی که تنها کلاینت ها با گواهی نامه معتبر بتوانند با ETCD ارتباط برقرار کنند و هرگونه ارتباط بین کلاینت و سرور ETCD به صورت رمز شده باشد. رمز کردن اطلاعات ذخیره شده حساس در ETCD مانند اطلاعات سکرت های کوبرنتیس، دو روش برای رمز کردن اطلاعات ETCD وجود دارد. استفاده از تنظیمات محلی کوبرنتیس که مدیریت کلید ها به صورت محلی انجام می شود و روش دوم استفاده از یک سامانه خارجی مدیریت کلید یا KMS مانند HashiCorp’s Vault است.امن کردن kubeletاحراز هویت کاربران ناشناس برای kubelet باید غیرفعال شود تا نتوان به kubelet های موجود بر روی هر سرور بدون احراز هویت متصل شد. این کار در فایل کانفیگ kubelet قابل انجام است. از طرف دیگر نوع سطح دسترسی kubelet یا KubeletAuthorizationMode باید بر روی webhook تنظیم شود و در هیچ یک از kubelet ها از نوع AlwaysAllow استفاده نشود.در نسخه های قدیمی کوبرنتیس از cadvisor در kubelet برای جمع آوری اطلاعات مانیتورینگ استفاده می شد. برای جلوگیری از در دسترس قرار گرفتن بار کاری روی سرور های کوبرنتیس باید با استفاده از فلگ cadvisor-port این دسترسی غیرفعال شود. البته از نسخه 1.11 کوبرنتیس این تنظیمات به صورت پیش فرض وجود دارد.با استفاده از پروفایل های seccomp می توان قابلیت system call های کانتینر ها را محدود کرد. همچنین می توان مشخص کرد که اجرای کدام یک از system call ها توسط کانتینر مجاز هستند، کدام یک غیر مجاز هستند و لاگ کدام یک از آن ها باید ایجاد شود. برای استفاده از یک پروفایل شخصی سازی شده، پروفایل را با فرمت  JSON، در مسیر /var/lib/kubelet/seccomp/ قرار داده می شود.برای هرکدام از پاد ها باید محدودیتی در تعداد شناسه فرآیندها یا PID ها تعریف کرد که با استفاده از آن تعداد فرآیند های در حال اجرا بر روی هر پاد را محدود کرد. این کار از طریق تنظیمات kubelet قابل انجام است.سایر موارد امنیتی جهت امن کردن کلاستر کوبرنتیسبا گذشت زمان میزان آسیب پذیری های شناخته شده برای نسخه های قدیمی کوبرنتیس بیشتر می شود، بنابراین به طور بالقوه کلاستر های قدیمی تر در معرض خطر بیشتری هستند. پس باید برنامه ای برای به روز رسانی دوره ای کلاستر کوبرنتیس وجود داشته باشد و حتی المقدور کلاستر کوبرنتیس باید روی آخرین نسخه باشد.به دلیل ساختار متفاوت شبکه کوبرنتیس استفاده از Network Policies برای محدود کردن ارتباط شبکه ای به/از پادهای در حال اجرای کاربران بسیار با اهمیت است تا از دسترسی های غیر مجاز تحت شبکه جلوگیری کرد. لازم به ذکر است که برای این منظور باید از CNI plugin هایی استفاده کرد که از NetworkPolicy API پشتیبانی کنند.یکی از راه های تشخیص خطرات امنیتی بررسی لاگ در سطوح مختلف است، توصیه می شود در لایه های زیر جمع آوری و تحلیل لاگ صورت بگیرد تا در صورت بروز ناهنجاری بتوان آن ها را کشف کرد.در سطح اپلیکیشندر سطح کلاستر کوبرنتیس از طریق جمع آوری لاگ شبکه، audit و DNSدر سطح کانتینر از طریق جمع آوری لاگ فرآیندها، syscalls، شبکه و filesystemبا ابزارهای مختلفی نظیر falco، ebpf، kprobes، ptrace و tracepoints می توان جمع آوری لاگ در لایه های ذکر شده در بالا را انجام داد.برای اطمینان از امن بودن کلاستر کوبرنتیس می توان از بنچ مارک CIS (Center Internet Security) برای کلاستر کوبرنتیس استفاده کرد. همچنین ابزار های متن باز تست نفوذ مانند kube-hunter نیز وجود دارد. توصیه می شود از این ابزار ها برای سنجش امنیت کلاستر کوبرنتیس استفاده کرد.اما در نهایت راهکاری وجود دارد تا سطح مسئولیت خود را در برابر تامین امنیت کلاستر کوبرنتس به صفر کاهش داد. استفاده از کلاستر های کوبرنتیس مدیریت شده مانند پلتفرم ابریمنت به جای راه اندازی کلاستر کوبرنتیس باعث می شود تا از مزایای انعطاف پذیری و در دسترس پذیری کوبرنتیس بهره برد و در عین حال نگران مخاطرات امنیتی هم نبود.منابعKubernetes Security: Operating Kubernetes Clusters and Applications SafelyKubernetes Security and Observability: A Holistic Approach to Securing and Troubleshooting Cloud Native Applications</description>
                <category>محمدحسين افشاری کلانی</category>
                <author>محمدحسين افشاری کلانی</author>
                <pubDate>Sat, 18 Jun 2022 14:05:12 +0430</pubDate>
            </item>
            </channel>
</rss>