رفع حفره ها در خوشه Kubernetes. گزارش و رونوشت از DevOpsConf

پاول سلیوانوف، معمار راه حل های Southbridge و معلم Slurm، در DevOpsConf 2019 ارائه کرد. این سخنرانی بخشی از یکی از موضوعات دوره عمیق Kubernetes "Slurm Mega" است.

Slurm Basic: مقدمه ای بر Kubernetes 18 تا 20 نوامبر در مسکو برگزار می شود.
Slurm Mega: نگاه کردن به زیر کاپوت Kubernetes - مسکو، 22-24 نوامبر.
Slurm Online: هر دو دوره Kubernetes همیشه در دسترس.

در زیر برش متن گزارش آمده است.

ظهر بخیر همکاران و کسانی که با آنها همدردی می کنند. امروز در مورد ایمنی صحبت خواهم کرد.

من می بینم که امروز نگهبانان زیادی در سالن حضور دارند. پیشاپیش از شما عذرخواهی می کنم اگر از اصطلاحات دنیای امنیت استفاده می کنم که دقیقاً برای شما مرسوم نیست.

این اتفاق افتاد که حدود شش ماه پیش با یک خوشه عمومی Kubernetes روبرو شدم. Public به این معنی است که یک n ام فضای نام وجود دارد؛ در این فضاهای نام، کاربرانی وجود دارند که در فضای نام خود جدا شده اند. همه این کاربران متعلق به شرکت های مختلف هستند. خب، فرض بر این بود که این خوشه باید به عنوان CDN استفاده شود. یعنی یک خوشه به شما می دهند، یک کاربر در آنجا به شما می دهند، شما به آنجا به فضای نام خود می روید، جبهه های خود را مستقر می کنید.

شرکت قبلی من سعی کرد چنین خدماتی را بفروشد. و از من خواسته شد که خوشه را بکوبم تا ببینم آیا این راه حل مناسب است یا نه.

من به این خوشه رسیدم. به من حقوق محدودی داده شد، فضای نام محدود. بچه های آنجا فهمیدند ایمنی چیست. آنها در مورد کنترل دسترسی مبتنی بر نقش (RBAC) در Kubernetes مطالعه کردند - و آن را پیچاندند تا من نتوانم پادها را جدا از استقرارها راه اندازی کنم. مشکلی را که می‌خواستم با راه‌اندازی یک پاد بدون استقرار حل کنم، به خاطر ندارم، اما واقعاً می‌خواستم فقط یک پاد را راه‌اندازی کنم. برای خوش شانسی، تصمیم گرفتم ببینم چه حقوقی در این کلاستر دارم، چه کاری می توانم انجام دهم، چه کاری نمی توانم انجام دهم، و آنها در آنجا چه چیزهایی را خراب کرده اند. در همان زمان، من به شما خواهم گفت که آنها چه چیزی را به درستی در RBAC پیکربندی کرده اند.

این اتفاق افتاد که در عرض دو دقیقه یک ادمین برای خوشه آنها دریافت کردم، به تمام فضاهای نام مجاور نگاه کردم، جبهه های تولید در حال اجرا شرکت هایی را دیدم که قبلاً این سرویس را خریداری کرده و مستقر کرده بودند. به سختی می‌توانستم جلوی خودم را بگیرم که به جلوی کسی بروم و در صفحه اصلی فحش بدهم.

من با مثال هایی به شما خواهم گفت که چگونه این کار را انجام دادم و چگونه از خود در برابر آن محافظت کنید.

اما ابتدا اجازه دهید خودم را معرفی کنم. نام من پاول سلیوانوف است. من یک معمار در Southbridge هستم. من Kubernetes، DevOps و انواع چیزهای فانتزی را درک می کنم. من و مهندسان Southbridge در حال ساختن همه اینها هستیم و در حال مشاوره هستم.

علاوه بر فعالیت های اصلی خود، اخیرا پروژه هایی به نام Slurms را راه اندازی کرده ایم. ما در تلاش هستیم تا توانایی خود را برای کار با Kubernetes کمی به توده‌ها برسانیم تا به افراد دیگر نیز آموزش دهیم که با K8s کار کنند.

امروز در مورد چه چیزی صحبت خواهم کرد؟ موضوع گزارش واضح است - در مورد امنیت خوشه Kubernetes. اما می خواهم فوراً بگویم که این موضوع بسیار بزرگ است - و بنابراین می خواهم فوراً آنچه را که قطعاً در مورد آن صحبت نمی کنم روشن کنم. من در مورد اصطلاحات هک شده ای که قبلاً صدها بار در اینترنت استفاده شده است صحبت نمی کنم. انواع RBAC و گواهینامه ها.

من در مورد آنچه که من و همکارانم را در مورد امنیت در یک خوشه Kubernetes آزار می دهد صحبت خواهم کرد. ما این مشکلات را هم در میان ارائه دهندگانی که خوشه های Kubernetes را ارائه می دهند و هم در بین مشتریانی که به ما مراجعه می کنند مشاهده می کنیم. و حتی از مشتریانی که از سایر شرکت های مدیریت مشاور به ما مراجعه می کنند. یعنی مقیاس فاجعه در واقع بسیار بزرگ است.

به معنای واقعی کلمه سه نکته وجود دارد که امروز در مورد آنها صحبت خواهم کرد:

  1. حقوق کاربر در مقابل حقوق پاد. حقوق کاربر و حقوق پاد یکسان نیستند.
  2. جمع آوری اطلاعات در مورد خوشه من نشان خواهم داد که می توانید تمام اطلاعات مورد نیاز خود را از یک خوشه بدون داشتن حقوق خاصی در این خوشه جمع آوری کنید.
  3. حمله DoS به خوشه اگر نتوانیم اطلاعات را جمع آوری کنیم، در هر صورت می توانیم یک خوشه قرار دهیم. من در مورد حملات DoS به عناصر کنترل خوشه صحبت خواهم کرد.

یکی دیگر از موارد کلی که من به آن اشاره خواهم کرد این است که همه اینها را روی چه چیزی تست کردم که قطعاً می توانم بگویم که همه اینها کار می کند.

ما نصب یک خوشه Kubernetes را با استفاده از Kubespray به عنوان مبنایی در نظر می گیریم. اگر کسی نمی داند، این در واقع مجموعه ای از نقش ها برای Ansible است. ما دائماً از آن در کار خود استفاده می کنیم. خوبی آن این است که می توانید آن را در هر جایی بغلتانید - می توانید آن را روی قطعات آهن یا در جایی در ابر بغلتانید. یک روش نصب در اصل برای همه چیز کار می کند.

در این خوشه من Kubernetes v1.14.5 را خواهم داشت. کل خوشه Cube که در نظر خواهیم گرفت به فضای نامی تقسیم شده است، هر فضای نام متعلق به یک تیم جداگانه است و اعضای این تیم به هر فضای نام دسترسی دارند. آنها نمی توانند به فضای نام های مختلف بروند، فقط به فضای نام خود. اما یک حساب ادمین خاص وجود دارد که حقوق کل کلاستر را دارد.

رفع حفره ها در خوشه Kubernetes. گزارش و رونوشت از DevOpsConf

من قول دادم که اولین کاری که انجام خواهیم داد این است که حقوق مدیریت برای خوشه را بدست آوریم. ما به یک غلاف آماده مخصوص نیاز داریم که خوشه Kubernetes را بشکند. تنها کاری که باید انجام دهیم این است که آن را در خوشه Kubernetes اعمال کنیم.

kubectl apply -f pod.yaml

این غلاف به یکی از استادان خوشه Kubernetes می رسد. و پس از این خوشه با خوشحالی فایلی به نام admin.conf را به ما باز می گرداند. در Cube، این فایل تمام گواهی‌های مدیر را ذخیره می‌کند و در عین حال Cluster API را پیکربندی می‌کند. به نظر من دسترسی ادمین به 98 درصد از خوشه های Kubernetes به همین راحتی است.

تکرار می‌کنم، این پاد توسط یک توسعه‌دهنده در خوشه شما ساخته شده است که به استقرار پیشنهادات خود در یک فضای نام کوچک دسترسی دارد، همه آن توسط RBAC گیره شده است. او هیچ حقی نداشت. اما با این وجود گواهی برگردانده شد.

و اکنون در مورد یک غلاف مخصوص آماده شده است. ما آن را روی هر تصویری اجرا می کنیم. بیایید debian:jessie را به عنوان مثال در نظر بگیریم.

ما این مورد را داریم:

tolerations:
-   effect: NoSchedule 
    operator: Exists 
nodeSelector: 
    node-role.kubernetes.io/master: "" 

تحمل چیست؟ مسترها در یک خوشه Kubernetes معمولا با چیزی به نام لکه مشخص می شوند. و ماهیت این "عفونت" این است که می گوید که غلاف ها را نمی توان به گره های اصلی اختصاص داد. اما هیچ کس به خود زحمت نمی دهد که در هر غلاف نشان دهد که نسبت به "عفونت" تحمل دارد. بخش Toleration فقط می گوید که اگر برخی از گره ها NoSchedule داشته باشند، گره ما در برابر چنین عفونتی مقاوم است - و هیچ مشکلی وجود ندارد.

علاوه بر این، ما می گوییم که زیر ما نه تنها قابل تحمل است، بلکه می خواهد به طور خاص استاد را هدف قرار دهد. زیرا استادان لذیذترین چیزی را دارند که ما نیاز داریم - همه گواهی ها. بنابراین، ما می‌گوییم nodeSelector - و یک برچسب استاندارد روی masterها داریم که به شما امکان می‌دهد از بین تمام گره‌های خوشه دقیقاً همان گره‌هایی را انتخاب کنید که Master هستند.

با این دو بخش او قطعا به استاد خواهد آمد. و اجازه زندگی در آنجا را خواهد داشت.

اما فقط آمدن نزد استاد برای ما کافی نیست. این چیزی به ما نمی دهد بنابراین در ادامه این دو مورد را داریم:

hostNetwork: true 
hostPID: true 

ما مشخص می کنیم که pod ما که راه اندازی می کنیم، در فضای نام هسته، در فضای نام شبکه و در فضای نام PID زندگی کند. هنگامی که پاد روی Master راه اندازی می شود، می تواند تمام رابط های واقعی و زنده این گره را ببیند، به تمام ترافیک گوش دهد و PID همه فرآیندها را ببیند.

آن وقت بحث چیزهای کوچک است. etcd را بردارید و آنچه را که می خواهید بخوانید.

جالب ترین چیز این ویژگی Kubernetes است که به طور پیش فرض در آنجا وجود دارد.

volumeMounts:
- mountPath: /host 
  name: host 
volumes:
- hostPath: 
    path: / 
    type: Directory 
  name: host 

و ماهیت آن این است که می‌توانیم در پاد بگوییم که راه‌اندازی می‌کنیم، حتی بدون حقوق این کلاستر، که می‌خواهیم حجمی از نوع hostPath ایجاد کنیم. این به این معنی است که مسیر را از میزبانی که در آن راه اندازی خواهیم کرد - و آن را به عنوان حجم در نظر بگیرید. و سپس نام آن را می گذاریم: میزبان. ما کل این hostPath را در داخل پاد قرار می دهیم. در این مثال، به دایرکتوری میزبان /.

دوباره تکرارش میکنم ما به pod گفتیم که به master بیاید، hostNetwork و hostPID را در آنجا دریافت کنید - و کل root master را در داخل این pod قرار دهید.

می‌دانید که در دبیان ما bash run داریم و این bash در زیر ریشه اجرا می‌شود. یعنی ما فقط root را روی master دریافت کردیم، بدون اینکه هیچ حقی در خوشه Kubernetes داشته باشیم.

سپس کل کار این است که به زیر شاخه /host /etc/kubernetes/pki بروید، اگر اشتباه نکنم، تمام گواهینامه های اصلی خوشه را در آنجا انتخاب کنید و بر این اساس، مدیر خوشه شوید.

اگر به این شکل به آن نگاه کنید، اینها برخی از خطرناک ترین حقوق در پادها هستند - صرف نظر از اینکه کاربر چه حقوقی دارد:
رفع حفره ها در خوشه Kubernetes. گزارش و رونوشت از DevOpsConf

اگر من حق اجرای یک pod را در برخی از فضای نام خوشه داشته باشم، پس این پاد به طور پیش فرض دارای این حقوق است. من می‌توانم پادهای ممتاز را اجرا کنم، و اینها عموماً همه حقوق هستند، عملاً روی گره ریشه دارند.

مورد علاقه من کاربر روت است. و Kubernetes این گزینه Run As Non-Root را دارد. این یک نوع محافظت در برابر هکر است. آیا می دانید "ویروس مولداوی" چیست؟ اگر ناگهان هکر شدید و به خوشه Kubernetes من آمدید، ما، مدیران ضعیف، می‌پرسیم: «لطفاً در پادهای خود مشخص کنید که با آن کلاستر من را هک می‌کنید، اجرا به‌عنوان غیر ریشه. در غیر این صورت این اتفاق می افتد که شما فرآیند را در پاد خود به صورت روت اجرا کنید و هک من برای شما بسیار آسان خواهد بود. لطفا از خودت محافظت کن."

حجم مسیر میزبان، به نظر من، سریع ترین راه برای به دست آوردن نتیجه دلخواه از یک خوشه Kubernetes است.

اما با همه اینها چه باید کرد؟

فکری که باید به ذهن هر مدیر عادی که با Kubernetes برخورد می کند این است: "بله، به شما گفتم، Kubernetes کار نمی کند. سوراخ هایی در آن وجود دارد. و کل مکعب مزخرف است." در واقع چیزی به نام مستندات وجود دارد و اگر آنجا را نگاه کنید، یک بخش وجود دارد سیاست امنیتی پاد.

این یک شی yaml است - ما می توانیم آن را در خوشه Kubernetes ایجاد کنیم - که جنبه های امنیتی را به طور خاص در توضیحات pods کنترل می کند. یعنی در واقع، حقوق استفاده از شبکه میزبان، hostPID، انواع حجم خاصی را که در پادها در هنگام راه اندازی هستند، کنترل می کند. با کمک Pod Security Policy می توان همه اینها را شرح داد.

جالب ترین چیز در مورد سیاست امنیتی Pod این است که در خوشه Kubernetes، همه نصب کننده های PSP نه تنها به هیچ وجه توضیح داده نمی شوند، بلکه به طور پیش فرض غیرفعال می شوند. سیاست امنیتی پاد با استفاده از افزونه پذیرش فعال می شود.

خوب، بیایید Pod Security Policy را در خوشه مستقر کنیم، بیایید بگوییم که ما در فضای نام چند غلاف سرویس داریم که فقط مدیران به آنها دسترسی دارند. فرض کنید، در همه موارد دیگر، غلاف ها دارای حقوق محدودی هستند. زیرا به احتمال زیاد توسعه دهندگان نیازی به اجرای پادهای ممتاز در کلاستر شما ندارند.

و به نظر می رسد همه چیز با ما خوب است. و خوشه Kubernetes ما را نمی توان در دو دقیقه هک کرد.

مشکلی وجود دارد. به احتمال زیاد، اگر یک خوشه Kubernetes دارید، نظارت بر روی خوشه شما نصب شده است. حتی پیش‌بینی می‌کنم که اگر خوشه شما نظارت داشته باشد، پرومتئوس نامیده می‌شود.

آنچه می خواهم به شما بگویم هم برای اپراتور Prometheus و هم برای Prometheus که به شکل خالص آن ارائه می شود معتبر است. سوال این است که اگر من نتوانم به این سرعت یک ادمین را وارد کلاستر کنم، به این معنی است که باید بیشتر جستجو کنم. و من می توانم با کمک نظارت شما جستجو کنم.

احتمالاً همه مقالات مشابهی را در Habré می‌خوانند و نظارت در فضای نام مانیتورینگ قرار دارد. نمودار هلم تقریباً برای همه یکسان خوانده می شود. من حدس می‌زنم که اگر Helel install stable/prometheus را انجام دهید، تقریباً نام‌های مشابهی خواهید داشت. و به احتمال زیاد من حتی نیازی به حدس زدن نام DNS در خوشه شما ندارم. چون استاندارده

رفع حفره ها در خوشه Kubernetes. گزارش و رونوشت از DevOpsConf

در مرحله بعد، یک توسعه دهنده خاص داریم که در آن می توانید یک پاد خاص را اجرا کنید. و سپس از این غلاف انجام چنین کاری بسیار آسان است:

$ curl http://prometheus-kube-state-metrics.monitoring 

prometheus-kube-state-metrics یکی از صادرکنندگان Prometheus است که معیارها را از خود API Kubernetes جمع آوری می کند. داده های زیادی در آنجا وجود دارد، آنچه در خوشه شما در حال اجرا است، چیست، چه مشکلاتی با آن دارید.

به عنوان یک مثال ساده:

kube_pod_container_info{namespace=“kube-system”,pod=”kube-apiserver-k8s- 1″,container=”kube-apiserver”,image=

"gcr.io/google-containers/kube-apiserver:v1.14.5"

,image_id=»docker-pullable://gcr.io/google-containers/kube- apiserver@sha256:e29561119a52adad9edc72bfe0e7fcab308501313b09bf99df4a96 38ee634989″,container_id=»docker://7cbe7b1fea33f811fdd8f7e0e079191110268f2 853397d7daf08e72c22d3cf8b»} 1

با ایجاد یک درخواست حلقه ساده از یک غلاف غیرمجاز، می توانید اطلاعات زیر را دریافت کنید. اگر نمی دانید چه نسخه ای از Kubernetes را اجرا می کنید، به راحتی به شما می گوید.

و جالب ترین چیز این است که علاوه بر دسترسی به kube-state-metrics، به همین راحتی می توانید مستقیماً به خود Prometheus دسترسی پیدا کنید. می توانید معیارها را از آنجا جمع آوری کنید. حتی می توانید معیارهایی را از آنجا بسازید. حتی از نظر تئوری، می توانید چنین پرس و جوی را از یک خوشه در Prometheus بسازید که به سادگی آن را خاموش می کند. و نظارت شما به‌کلی از روی خوشه کار نخواهد کرد.

و در اینجا این سوال مطرح می شود که آیا هیچ نظارت خارجی بر نظارت شما نظارت می کند؟ من به تازگی این فرصت را پیدا کردم که در یک خوشه Kubernetes بدون هیچ عواقبی برای خودم فعالیت کنم. شما حتی نمی دانید که من در آنجا کار می کنم، زیرا دیگر هیچ نظارتی وجود ندارد.

درست مانند PSP، به نظر می رسد مشکل این است که همه این فناوری های فانتزی - Kubernetes، Prometheus - کار نمی کنند و پر از سوراخ هستند. نه واقعا.

چنین چیزی وجود دارد - خط مشی شبکه.

اگر یک ادمین معمولی هستید، به احتمال زیاد در مورد سیاست شبکه می دانید که این فقط یک یامل دیگر است که در حال حاضر تعداد زیادی از آنها در این کلاستر وجود دارد. و برخی از سیاست های شبکه قطعا مورد نیاز نیستند. و حتی اگر خط مشی شبکه را خوانده باشید، که یک فایروال yaml از Kubernetes است، به شما اجازه می دهد حقوق دسترسی را بین فضاهای نام، بین پادها محدود کنید، مطمئناً تصمیم گرفتید که فایروال در قالب yaml در Kubernetes بر اساس انتزاعات بعدی باشد. ... نه نه این قطعا ضروری نیست.

حتی اگر به متخصصان امنیتی خود نگفته باشید که با استفاده از Kubernetes خود می توانید یک فایروال بسیار آسان و ساده و در عین حال یک فایروال بسیار دقیق بسازید. اگر آن‌ها هنوز این را نمی‌دانند و شما را آزار نمی‌دهند: «خب، به من بده، به من بده...» در هر صورت، برای مسدود کردن دسترسی به برخی مکان‌های خدماتی که می‌توانند از خوشه شما خارج شوند، به Network Policy نیاز دارید. بدون هیچ مجوزی

همانطور که در مثالی که آوردم، می‌توانید معیارهای حالت kube را از هر فضای نامی در خوشه Kubernetes بدون داشتن هیچ حقی برای انجام این کار، استخراج کنید. خط‌مشی‌های شبکه دسترسی از همه فضاهای نام دیگر به فضای نام نظارتی بسته هستند و بس: بدون دسترسی، بدون مشکل. در تمام نمودارهایی که وجود دارد، چه پرومتئوس استاندارد و چه پرومتئوس که در اپراتور است، به سادگی گزینه ای در مقادیر فرمان وجود دارد که به سادگی سیاست های شبکه را برای آنها فعال می کند. شما فقط باید آن را روشن کنید و آنها کار خواهند کرد.

اینجا واقعا یک مشکل وجود دارد. به عنوان یک مدیر ریشو معمولی، به احتمال زیاد تصمیم گرفتید که سیاست های شبکه مورد نیاز نیست. و پس از خواندن انواع مقالات در مورد منابعی مانند Habr، به این نتیجه رسیدید که فلانل، به خصوص با حالت میزبان دروازه، بهترین چیزی است که می توانید انتخاب کنید.

چه کاری انجام دهید؟

می‌توانید راه‌حل شبکه‌ای را که در خوشه Kubernetes خود دارید مجدداً مستقر کنید، سعی کنید آن را با چیزی کاربردی‌تر جایگزین کنید. برای همین کالیکو مثلا. اما می خواهم فوراً بگویم که وظیفه تغییر راه حل شبکه در یک خوشه کاری Kubernetes کاملاً بی اهمیت است. من آن را دو بار حل کردم (هر دو بار، اما از نظر تئوری)، اما ما حتی نحوه انجام آن را در Slurms نشان دادیم. برای دانش‌آموزانمان، نحوه تغییر راه‌حل شبکه را در یک خوشه Kubernetes نشان دادیم. در اصل، شما می توانید سعی کنید مطمئن شوید که در خوشه تولید هیچ خرابی وجود ندارد. اما احتمالاً موفق نخواهید شد.

و مشکل در واقع بسیار ساده حل شده است. گواهینامه هایی در این خوشه وجود دارد و می دانید که گواهینامه های شما یک سال دیگر منقضی می شوند. خوب، و معمولاً یک راه حل معمولی با گواهینامه ها در خوشه - چرا نگران هستیم، یک خوشه جدید در این نزدیکی ایجاد می کنیم، اجازه می دهیم خوشه قدیمی فاسد شود و همه چیز را مجدداً مستقر کنیم. درست است، وقتی پوسیده شود، باید یک روز بنشینیم، اما اینجا یک خوشه جدید است.

هنگامی که یک خوشه جدید را بالا می آورید، در همان زمان به جای فلانل، Calico را وارد کنید.

اگر گواهینامه های شما برای صد سال صادر شود و قصد ندارید کلاستر را مجدداً مستقر کنید، چه باید کرد؟ چیزی به نام Kube-RBAC-Proxy وجود دارد. این یک توسعه بسیار جالب است، به شما امکان می دهد خود را به عنوان یک محفظه کناری در هر غلاف در خوشه Kubernetes قرار دهید. و در واقع مجوز را از طریق RBAC خود Kubernetes به این pod اضافه می کند.

یک مشکل وجود دارد. پیش از این، این راه حل Kube-RBAC-Proxy در Prometheus اپراتور ساخته شده بود. اما بعد او رفته بود. اکنون نسخه های مدرن بر این واقعیت تکیه می کنند که شما یک خط مشی شبکه دارید و آن را با استفاده از آنها می بندید. و بنابراین باید نمودار را کمی بازنویسی کنیم. در واقع، اگر شما به این مخزن، نمونه هایی از نحوه استفاده از این به عنوان کارگاه های جانبی وجود دارد و نمودارها باید حداقل بازنویسی شوند.

یک مشکل کوچک دیگر وجود دارد. Prometheus تنها کسی نیست که معیارهای خود را در اختیار هر کسی قرار می دهد. همه اجزای خوشه Kubernetes ما همچنین می توانند معیارهای خود را برگردانند.

اما همانطور که قبلاً گفتم، اگر نمی توانید به خوشه دسترسی داشته باشید و اطلاعات را جمع آوری کنید، حداقل می توانید آسیبی وارد کنید.

بنابراین من به سرعت دو راه را نشان خواهم داد که چگونه یک خوشه Kubernetes می تواند خراب شود.

وقتی این را به شما می گویم می خندید، این دو مورد واقعی هستند.

روش یک. کاهش منابع

بیایید یک غلاف ویژه دیگر راه اندازی کنیم. یک بخش مانند این خواهد داشت.

resources: 
    requests: 
        cpu: 4 
        memory: 4Gi 

همانطور که می دانید درخواست ها مقدار CPU و حافظه ای است که در هاست برای پادهای خاص با درخواست رزرو شده است. اگر یک هاست چهار هسته ای در یک خوشه Kubernetes داشته باشیم و چهار پاد CPU با درخواست وارد آنجا شوند، به این معنی است که دیگر پادهایی با درخواست نمی توانند به این میزبان بیایند.

اگر من چنین pod را اجرا کنم، دستور زیر را اجرا می کنم:

$ kubectl scale special-pod --replicas=...

سپس هیچ کس دیگری نمی تواند در خوشه Kubernetes مستقر شود. زیرا درخواست تمام گره ها تمام می شود. و بنابراین من خوشه Kubernetes شما را متوقف خواهم کرد. اگر این کار را در عصر انجام دهم، می توانم استقرار را برای مدت طولانی متوقف کنم.

اگر دوباره به مستندات Kubernetes نگاه کنیم، این چیزی را خواهیم دید که محدوده محدوده نامیده می شود. منابع را برای اشیاء خوشه ای تنظیم می کند. شما می توانید یک شی Limit Range در yaml بنویسید، آن را روی فضاهای نامی خاص اعمال کنید - و سپس در این فضای نام می توانید بگویید که منابع پیش فرض، حداکثر و حداقل را برای pods دارید.

با کمک چنین چیزی، می‌توانیم کاربران را در فضای نام محصولات خاص تیم‌ها در توانایی نشان دادن انواع چیزهای ناخوشایند روی پادهای خود محدود کنیم. اما متأسفانه، حتی اگر به کاربر بگویید که نمی‌تواند پادهایی را با درخواست بیش از یک CPU راه‌اندازی کند، چنین دستور مقیاس فوق‌العاده وجود دارد، یا می‌تواند مقیاس را از طریق داشبورد انجام دهد.

و روش شماره دو از اینجا می آید. ما 11،111،111،111،111 غلاف را راه اندازی می کنیم. این یازده میلیارد است. این به این دلیل نیست که چنین عددی به دست آوردم، بلکه به این دلیل است که خودم آن را دیدم.

داستان واقعی. اواخر غروب می خواستم دفتر را ترک کنم. گروهی از توسعه دهندگان را می بینم که در گوشه ای نشسته اند و دیوانه وار با لپ تاپ خود کاری انجام می دهند. من به سمت بچه ها می روم و می پرسم: "چه اتفاقی برای شما افتاده است؟"

کمی زودتر، حوالی نه شب، یکی از توسعه دهندگان آماده رفتن به خانه بود. و من تصمیم گرفتم: "من اکنون درخواست خود را به یک کاهش می دهم." یکی رو فشار دادم ولی سرعت اینترنت کمی کم شد. دوباره یکی را فشار داد، یکی را فشار داد و Enter را زد. به هرچی که میتونستم زدم سپس اینترنت زنده شد - و همه چیز شروع به کاهش به این تعداد کرد.

درست است، این داستان در Kubernetes اتفاق نیفتاد؛ در آن زمان Nomad بود. ماجرا با این واقعیت به پایان رسید که بعد از یک ساعت تلاش ما برای جلوگیری از تلاش های مداوم Nomad برای مقیاس پذیری، Nomad پاسخ داد که از مقیاس گذاری دست برنمی دارد و هیچ کار دیگری انجام نخواهد داد. "خسته ام، دارم می روم." و خم شد.

طبیعتاً من سعی کردم همین کار را در Kubernetes انجام دهم. کوبرنتیس از یازده میلیارد غلاف راضی نبود، او گفت: «نمی‌توانم. بیش از محافظ های داخلی دهان است." اما 1 غلاف می تواند.

در پاسخ به یک میلیارد، مکعب به درون خود عقب نشینی نکرد. او واقعاً شروع به جرم گیری کرد. هرچه این روند جلوتر می رفت، زمان بیشتری برای ایجاد غلاف های جدید از او می گذشت. اما همچنان این روند ادامه داشت. تنها مشکل این است که اگر بتوانم پادها را به صورت نامحدود در فضای نام خود راه‌اندازی کنم، حتی بدون درخواست و محدودیت می‌توانم آنقدر پادها را با برخی وظایف راه‌اندازی کنم که با کمک این وظایف، گره‌ها شروع به جمع شدن در حافظه، در CPU کنند. وقتی من این همه پاد را راه اندازی می کنم، اطلاعات آنها باید به ذخیره سازی، یعنی etcd برود. و هنگامی که اطلاعات بیش از حد به آنجا می رسد، ذخیره سازی به آرامی شروع به بازگشت می کند - و Kubernetes شروع به کسل کننده شدن می کند.

و یک مشکل دیگر... همانطور که می دانید، عناصر کنترل Kubernetes یک چیز مرکزی نیستند، بلکه چندین جزء هستند. به طور خاص، یک مدیر کنترلر، زمانبندی، و غیره وجود دارد. همه این افراد به طور همزمان شروع به انجام کارهای غیر ضروری و احمقانه می کنند که با گذشت زمان زمان بیشتری را به خود اختصاص می دهد. مدیر کنترلر پادهای جدیدی ایجاد خواهد کرد. Scheduler سعی خواهد کرد یک گره جدید برای آنها پیدا کند. به احتمال زیاد به زودی گره های جدید در خوشه خود تمام می شوند. خوشه Kubernetes کندتر و کندتر شروع به کار می کند.

اما تصمیم گرفتم از این هم فراتر بروم. همانطور که می دانید، در Kubernetes چنین چیزی به نام سرویس وجود دارد. خوب، به طور پیش فرض در خوشه های شما، به احتمال زیاد، این سرویس با استفاده از جداول IP کار می کند.

برای مثال، اگر یک میلیارد پاد را اجرا کنید و سپس از یک اسکریپت برای وادار کردن Kubernetis برای ایجاد سرویس‌های جدید استفاده کنید:

for i in {1..1111111}; do
    kubectl expose deployment test --port 80  
        --overrides="{"apiVersion": "v1", 
           "metadata": {"name": "nginx$i"}}"; 
done 

در تمام گره های خوشه، قوانین iptables جدید بیشتر و بیشتری تقریباً به طور همزمان ایجاد می شود. علاوه بر این، یک میلیارد قانون iptable برای هر سرویس ایجاد خواهد شد.

کل این موضوع را روی چند هزار تا ده تا بررسی کردم. و مشکل این است که در حال حاضر در این آستانه، انجام ssh روی گره کاملاً مشکل است. زیرا بسته هایی که از زنجیره های زیادی عبور می کنند، احساس خوبی ندارند.

و این نیز با کمک Kubernetes حل می شود. چنین شیء سهمیه منابع وجود دارد. تعداد منابع و اشیاء موجود را برای فضای نام در خوشه تنظیم می کند. ما می توانیم در هر فضای نامی از خوشه Kubernetes یک شی yaml ایجاد کنیم. با استفاده از این شی می توان گفت که تعداد مشخصی درخواست و محدودیت برای این فضای نام اختصاص داده شده است و سپس می توان گفت که در این فضای نام امکان ایجاد 10 سرویس و 10 پاد وجود دارد. و یک توسعه دهنده مجرد حداقل می تواند عصرها خود را خفه کند. Kubernetes به او خواهد گفت: "شما نمی توانید غلاف های خود را به این مقدار افزایش دهید، زیرا منبع از حد نصاب بیشتر است." همین، مشکل حل شد مستندات اینجا.

یک نکته مشکل ساز در این زمینه مطرح می شود. احساس می کنید که ایجاد فضای نام در Kubernetes چقدر دشوار شده است. برای ایجاد آن، باید موارد زیادی را در نظر بگیریم.

سهمیه منابع + محدوده محدود + RBAC
• یک فضای نام ایجاد کنید
• یک محدوده محدود در داخل ایجاد کنید
• سهمیه منابع داخلی ایجاد کنید
• یک حساب سرویس برای CI ایجاد کنید
• Rolebinding برای CI و کاربران ایجاد کنید
• به صورت اختیاری غلاف های خدماتی لازم را راه اندازی کنید

بنابراین، مایلم از این فرصت استفاده کنم و تحولات خود را به اشتراک بگذارم. چنین چیزی به نام اپراتور SDK وجود دارد. این روشی است برای خوشه Kubernetes تا عملگرهایی برای آن بنویسد. می توانید با استفاده از Ansible عبارات بنویسید.

ابتدا در Ansible نوشته شد و بعد دیدم که یک اپراتور SDK وجود دارد و نقش Ansible را دوباره به یک اپراتور بازنویسی کردم. این عبارت به شما این امکان را می دهد که در خوشه Kubernetes یک شی به نام فرمان ایجاد کنید. در داخل یک دستور، به شما این امکان را می دهد که محیط این دستور را در yaml توصیف کنید. و در محیط تیم، به ما اجازه می دهد تا توصیف کنیم که منابع زیادی را تخصیص می دهیم.

کمی این فرآیند پیچیده را آسان تر می کند.

و در خاتمه با این همه چه باید کرد؟
اولین. سیاست امنیتی پاد خوب است. و علیرغم این واقعیت که هیچ یک از نصب کنندگان Kubernetes تا به امروز از آنها استفاده نمی کنند، شما همچنان باید از آنها در کلاسترهای خود استفاده کنید.

سیاست شبکه فقط یکی دیگر از ویژگی های غیر ضروری نیست. این چیزی است که در یک خوشه واقعاً مورد نیاز است.

LimitRange/ResourceQuota - زمان استفاده از آن فرا رسیده است. ما خیلی وقت پیش شروع به استفاده از این کردیم و برای مدت طولانی مطمئن بودم که همه از آن استفاده می کنند. معلوم شد که این نادر است.

علاوه بر آنچه در طول گزارش به آن اشاره کردم، ویژگی‌های غیرمستندی وجود دارد که به شما امکان حمله به خوشه را می‌دهد. اخیرا منتشر شده است تجزیه و تحلیل گسترده آسیب پذیری های Kubernetes.

بعضی چیزها خیلی غم انگیز و دردناک هستند. به عنوان مثال، تحت شرایط خاص، cubelets در یک خوشه Kubernetes می تواند محتویات فهرست warlocks را به یک کاربر غیرمجاز بدهد.

اینجا دستورالعمل هایی در مورد نحوه بازتولید همه چیزهایی که به شما گفتم وجود دارد. فایل هایی با نمونه های تولیدی از ظاهر ResourceQuota و Pod Security Policy وجود دارد. و شما می توانید همه اینها را لمس کنید.

از همه شما متشکرم

منبع: www.habr.com

اضافه کردن نظر