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

کنترل دسترسی به API کوبرنتیز
کنترل دسترسی به API کوبرنتیز از اهمیت ویژهای برخوردار است، چرا که تضمین میکند تنها کاربران و برنامههای مجاز به منابع حساس دسترسی پیدا کنند. این فرآیند شامل مراحل احراز هویت، مجوزدهی، کنترل پذیرش و ممیزی است. در ادامه، هر مرحله با جزئیات بیشتر و به زبان ساده توضیح داده شده است.

همانطور که در تصویر بالا میبینید کاربر برای دسترسی گرفتن به api کوبرنتیز از سه مرحله احراز هویت، مجوزدهی و کنترل پذیرش عبور میکند که در ادامه هر مورد را توضیح میدهیم.
احراز هویت (Authentication)
احراز هویت اولین مرحله از فرآیند کنترل دسترسی است که هدف آن شناسایی کاربر یا برنامهای است که درخواست ارسال کرده است. پس از برقراری ارتباط امن TLS، درخواست HTTP به این مرحله وارد میشود.

ماژولهای احراز هویت شامل موارد زیر هستند:
– گواهینامههای کلاینت (Client Certificates): این گواهیها برای شناسایی امن کلاینتها استفاده میشوند.
– رمز عبور و توکنهای ساده: برای دسترسی سریع به منابع کاربرد دارند.
– توکنهای بوتاسترپ: برای ارتباطات اولیه در کلاستر استفاده میشوند.
– توکنهای وب (JWT): این توکنها معمولاً برای حسابهای کاربری سرویسها به کار میروند.
در صورت پیکربندی چند ماژول احراز هویت، هر ماژول به ترتیب بررسی میشود تا یکی از آنها موفق به احراز هویت شود. اگر هیچ ماژولی نتواند درخواست را تایید کند، درخواست با کد وضعیت HTTP 401 رد میشود. به زبان ساده، اگر سیستم نتواند کاربر را شناسایی کند، به او اجازه ادامه کار نمیدهد. همانطور که بالاتر گفتم میتونیم چندین ماژول برای احراز هویت کاربر به صورت همزمان داشته باشیم. هم میتونیم وصلش کنیم به SSO خودمون هم با کلاینت سرتیفیکیت و توکن به افرادی دسترسی بدیم. کوبرنتیز یا بهتر بگیم api-server همزمان همهی آنها رو بررسی میکنه و اگر با یکی تونست تایید کنه به کاربر اجازه میده که لاگین کنه.
مجوزدهی (Authorization)
بعد از احراز هویت، نوبت به مجوزدهی میرسد. در این مرحله، بررسی میشود که آیا کاربر مجاز به انجام عملی است که درخواست داده است یا خیر. درخواست باید شامل اطلاعات زیر باشد:
– نام کاربری: کاربری که درخواست را ارسال کرده است.
– عملیات: کاری که کاربر قصد انجام آن را دارد (مثلاً ایجاد یا حذف یک پاد).
– منبع: آبجکت یا منبعی که قرار است عملیات روی آن انجام شود.

مجوزدهی در کوبرنتیز از طریق چندین ماژول انجام میشود که شامل موارد زیر هستند:
– (مجوزدهی نود) Node Authorization: این روش برای مجوزدهی درخواستهای ارسال شده توسط kubeletها طراحی شده و به کاربران معمولی مربوط نمیشود.

– (کنترل دسترسی مبتنی بر ویژگی) ABAC : در این روش، سیاستها بر اساس ویژگیهای کاربر یا درخواست تعریف میشوند. این روش قدیمی شده و به جای آن از RBAC استفاده میشه که در ادامه توضیح میدیم.
– (کنترل دسترسی مبتنی بر نقش) RBAC : دسترسیها بر اساس نقشهایی که به کاربران اختصاص داده شده است مدیریت میشوند. روش خیلی مرسوم و متداولی که سرویسهای دیگه هم ازش استفاده میکنند. ما دسترسیها رو به roleها میدیم و role ها رو به کاربرها و آدمها متصل میکنیم. نقش اصلی کنترل دسترسی تو کوبرنتیز بر عهدهی RBAC هست و معمولا همه از آن استفاده میکنند.
– (همیشه رد)AlwaysDeny: تمامی درخواستها را بدون بررسی رد میکند (برای محیطهای بسیار امن مناسب است). اینم بگم که کاربردی نیست اونقدر بالاخره نیاز داریم که یکی یا چیزی با سیستم و سرویس کار کنه. برای همین نه به اون بی نمکی قبلی و نه به این شوری این.
کی تصمیم میگیره؟
مدیر کلاستر مشخص میکند که کدام یک از این ماژولها فعال باشند. اگر چند ماژول مجوزدهی فعال باشد، کوبرنتیز درخواست را به ترتیب به هر ماژول ارسال میکند. اگر یکی از ماژولها درخواست را تایید کند، عملیات مجاز خواهد بود. در غیر این صورت، درخواست با کد وضعیت HTTP 403 رد میشود. دقت کنید یکی از اون چند تا اگر اوکی باشه اکسپت میکنه و درخواست رو اعمال میکنه. ممکنه موقعیتی پیش بیاد که یه درخواست با یکی از این ابزارها و سیستمها اوکی باشه و با یکی دیگه نه ولی چون اجتماع آنها هست با هر کدوم که اوکی بشه روال میکنه و کوبرنتیز درخواست رو اوکی میکنه. این موضوع هم تو احراض هویت و هم تو اعمال دسترسی برقرار هست.
پیکربندی حالتهای مجوزدهی
برای پیکربندی حالتهای مجوزدهی در کوبرنتیز، فایل تنظیمات kube-apiserver.yaml را ویرایش کنید که معمولاً در مسیر /etc/kubernetes/manifests/ قرار دارد. در این فایل، حالتهای مجوزدهی مورد نظر خود را به پرچم --authorization-mode اضافه کنید و حالتها را با کاما جدا کنید.
مثال:
--authorization-mode=RBAC,Webhook
پس از اعمال تغییرات، سرور API را ریاستارت کنید تا تغییرات اعمال شوند.
استفاده از چندین حالت مجوزدهی
کوبرنتیز این امکان را فراهم میکند که چندین حالت مجوزدهی به صورت همزمان فعال شوند. در این حالت، هر درخواست به ترتیب توسط تمامی حالتها بررسی میشود تا یکی از آنها درخواست را تایید یا رد کند. اگر تمامی حالتها درخواست را رد کنند، دسترسی داده نمیشود.
کنترل پذیرش (Admission Control)
کنترل پذیرش مرحلهای است که پس از مجوزدهی اجرا میشود. در این مرحله، درخواستها ممکن است تغییر داده شوند یا رد شوند. ماژولهای کنترل پذیرش به درخواستهایی که برای ایجاد، تغییر، حذف، یا اتصال به یک آبجکت هستند، پاسخ میدهند. اما به درخواستهایی که صرفاً برای خواندن اطلاعات هستند، توجهی نمیکنند.
کنترلکنندههای پذیرش به دو دسته تقسیم میشوند:
– کنترلکنندههای تغییردهنده (Mutating Admission Controllers): این کنترلکنندهها درخواستها را قبل از پردازش تغییر میدهند. به عنوان مثال، کنترلکننده ServiceAccount به صورت خودکار یک حساب کاربری سرویس پیشفرض به پاد اضافه میکند. با mutations ما میتونیم درخواست رو تغییر بدیم. مثلا اینکه دیفالت سرویس اکانت رو به پادها اضافه کنیم.
– کنترلکنندههای اعتبارسنجی (Validating Admission Controllers): این کنترلکنندهها درخواستها را بررسی میکنند تا اطمینان حاصل شود که با قوانین تعیین شده مطابقت دارند.
ممیزی (Auditing)
ممیزی در کوبرنتیز ابزاری است که یک مجموعه زمانی از رویدادهای امنیتی را ثبت میکند. این رویدادها شامل فعالیتهای کاربران، برنامهها، و خود سیستم کنترل مرکزی میشوند. رکوردهای ممیزی اطلاعات مهمی مانند زمان، مکان، و نوع عملیات را مستند میکنند. به عبارت دیگه تمام عملکردی که داخل کوبرنتیز در جریان است رو میتونیم با استفاده از Audit لاگ کنیم و به زبان ساده Audit log کوبرنتیز رو داشته باشیم و درست کانفیگ کرده باشیم میتونیم تمام اتفاقاتی که تو کلاستر افتاده رو با جزئیات کامل بدونیم. برای همین خیلی نقش کلیدی و مهمی برای بررسی رخدادهای داخل کلاستر کوبرنتیز داره.
به طور کلی، ممیزی به سوالات زیر پاسخ میدهد:
- چه اتفاقی افتاد؟
- چه زمانی اتفاق افتاد؟
- چه کسی آن را آغاز کرد؟
- بر روی چه چیزی انجام شد؟
- از کجا مشاهده شد؟
- از کجا آغاز شد؟
- به کجا رفت؟
سطوح ممیزی
کوبرنتیز چندین سطح برای ثبت رویدادها ارائه میدهد:
- سطح None: هیچ رویدادی ثبت نمیشود.
- سطح Metadata: فقط متادیتای درخواست (مانند کاربر درخواستکننده، زمان، منبع، و فعل) ثبت میشود.
- سطح Request: متادیتای رویداد به همراه بدنه درخواست ثبت میشود.
- سطح RequestResponse: متادیتای رویداد، بدنه درخواست، و بدنه پاسخ ثبت میشوند.
هر کدوم از این سطوح رو میتونیم بر اساس فعلی (Create,Delete,Get,…) که انجام میشه و کسی که انجام میده داخل آدیت لاگ داشته باشیم. به این نکته توجه کنید که تو کلاسترهای بزرگ حجم این لاگ خیلی میتونه زیاد بشه و اگر درست کانفیگ نشه حتی میتونه که api-serverها رو با مشکل مواجه کنه. برای همین باید دقیق بدونیم که برای کجا میخواهیم اون رو فعال کنیم و سطح آن رو هم کامل مشخص کنیم. مثلا افعال get,watch,list عموما زیاد مهم نیست که بدونیم کی انجام داده. در اکثر اوقات میتونی این افعال رو none بزاریم تا بتونیم حجم لاگ و میزان اون رو منطقی کاهش بدیم.
کنترل دسترسی به API کوبرنتیز یک فرآیند چندمرحلهای است که امنیت و مدیریت دسترسی را تضمین میکند. با استفاده از احراز هویت، مجوزدهی، کنترل پذیرش، و ممیزی، میتوان دسترسی به منابع کلاستر را به طور دقیق مدیریت کرد. این مراحل به مدیران امکان میدهند تا با اطمینان بیشتری منابع حساس را محافظت کنند و دسترسیها را بر اساس نیازهای خاص تنظیم کنند.
کنترل دسترسی مبتنی بر نقش (RBAC) در کوبرنتیز
کنترل دسترسی مبتنی بر نقش یا RBAC (Role-Based Access Control) یکی از کلیدیترین ابزارهای امنیتی در کوبرنتیز است که اطمینان میدهد کاربران و ورکلودها فقط به منابعی دسترسی داشته باشند که برای اجرای وظایفشان نیاز دارند. این مکانیزم به مدیریت دقیق سطوح دسترسی کمک میکند و از دادن مجوزهای غیرضروری به کاربران جلوگیری مینماید.
معرفی آبجکتهای RBAC
در RBAC چهار نوع آبجکت اصلی تعریف میشود:
- Role
- ClusterRole
- RoleBinding
- ClusterRoleBinding
این آبجکتها را میتوان مانند سایر منابع کوبرنتیز با ابزارهایی مانند kubectl مشاهده و ویرایش کرد.
آبجکتهای Role و ClusterRole به عنوان مجموعهای از قوانین دسترسی تعریف میشوند که اجازهی دسترسی به منابع خاص را مشخص میکنند. توجه داشته باشید که مجوزهای RBAC فقط افزایشی هستند؛ یعنی امکان تعریف قانون «رد کردن دسترسی» وجود ندارد. این نکتهی خیلی مهمی است که باید بهش دقت کنیم. به زبان ساده با role و clusterrole ما داریم میگیم چه ریسورسی (مثلا پاد یا سرویس یا هرچی ) چه فعلی (مثلا ساختن یا پاک کردن یا ادیت کردن یا هر چی) رو داشته باشیم. اینجا فقط این دو تا رو داریم مشخص میکنیم.
Role:
یک Role همیشه مجوزهای دسترسی را فقط در فضای نام (Namespace) مشخصشده تنظیم میکند. به همین دلیل هنگام ایجاد Role باید حتماً فضای نام مربوط به آن را مشخص کنید.
مثال ایجاد یک Role در نیماسپیس dev:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
در مثال فوق، Role مجوز مشاهده و لیستکردن Podها را در فضای نام dev فراهم میکند.
Cluster Role:
آبجکت ClusterRole برخلاف Role، به صورت غیرمربوط به فضای نام (Cluster-wide) تعریف میشود و میتواند دسترسی به منابع در کل کلاستر را کنترل کند.
مثال تعریف یک ClusterRole:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-reader
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
در اینجا، ClusterRole مجوز مشاهده و لیست کردن Nodeها را در سطح کل خوشه فراهم میکند.
RoleBinding:
آبجکت RoleBinding یک Role را به یک یا چند موضوع (Subjects) مانند کاربرها، گروهها یا حسابهای کاربری سرویس (ServiceAccounts) متصل میکند. ما تو رول تعریف کردیم چه ریسورسی رو چی کار بتونیم بکنیم و با رول بایندینگ اون رو به یه کاربر یا گروه یا سرویس اکانت متصل میکنیم.
آبجکت RoleBinding مجوزهای مربوط به Role را در فضای نام مشخصی به موضوعات (subject) میدهد. همچنین میتواند به ClusterRole اشاره کند و مجوزهای مربوط به ClusterRole را به یک فضای نام خاص محدود کند.
نمونه RoleBinding:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-binding
namespace: dev
subjects:
- kind: User
name: mamad
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
در مثال فوق، کاربر mamad میتواند Podها را در فضای نام dev بخواند.
ClusterRoleBinding
آبجکت ClusterRoleBinding دقیقاً مانند RoleBinding عمل میکند، اما مجوزهای ClusterRole را در کل کلاستر (Cluster-wide) به موضوعات مشخصشده اعطا میکند.
مثال:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: node-reader-binding
subjects:
- kind: User
name: admin
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: node-reader
apiGroup: rbac.authorization.k8s.io
در این مثال، کاربر admin مجوز مشاهده Nodeها در کل کلاستر را دریافت میکند.
پس عملا اینجا ما با دو تا موضوع مواجه هستیم یکی در سطح یک namespace و یکی در سطح کل کلاستر که هر دو عملکرد یکسان هست ولی حوزهی فعالیتشون باهم متفاوت است.
ServiceAccount
یک سرویس اکانت هویتی برای فرآیندهایی که در Podها اجرا میشوند فراهم میکند.
زمانی که به API Server کوبرنتیز احراز هویت میکنید، خود را به عنوان یک کاربر مشخص معرفی میکنید. با این حال، کوبرنتیز خودش دارای یک User API نیست و هویت کاربران معمولاً در یک سیستم خارجی مدیریت میشود.
مثال تعریف ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
namespace: dev
سپس میتوانید این ServiceAccount را به یک Pod اختصاص دهید:
apiVersion: v1
kind: Pod
metadata:
name: example-pod
namespace: dev
spec:
serviceAccountName: my-service-account
containers:
- name: my-container
image: my-image
در اینجا، Pod با استفاده از my-service-account احراز هویت خواهد شد.
کنترل دسترسی مبتنی بر نقش (RBAC) در کوبرنتیز یکی از مهمترین ابزارهای مدیریت امنیتی است که به شما اجازه میدهد دسترسیهای دقیقی برای کاربران و فرآیندهای مختلف تعریف کنید. با استفاده از Role، ClusterRole، RoleBinding و ClusterRoleBinding میتوان سطوح دسترسی مناسب در نیماسپیس یا در کل کلاستر ایجاد کرد.
با طراحی مناسب RBAC میتوانید به امنیت و کارایی بیشتر در مدیریت منابع کوبرنتیز دست پیدا کنید.
در بلاگ پستهای بعدی مسیرمون رو ادامه میدیم و بیشتر و بیشتر در مورد کوبرنتیز یاد میگیریم.
مراقب خودتون باشید. 🌹🐳🌹
نصب کلاستر با kubeadm (قسمت هفدهم) توی این قسمت قدم به قدم نحوه نصب یک کلاستر کوبرنتیز رو با استفاده از ابزار kubeadm توضیح دادیم.
نصب کلاستر با kubespray (قسمت هجدهم) توی این قسمت نحوه نصب کلاستر با یه پروژه خیلی خوب به نام کیوب اسپری که یه انسیبل خفن برای ستاپ کلاستر رائه میده رو توضیح دادیم.
نصب کلاستر با rancher (قسمت نوزدهم) توی این قسمت توضیح دادیم که چطور با استفاده از ابزار RKE یک کلاستر کوبرنتیز راهاندازی کنیم.


