ملاحظة perev. : كتب هذا المقال خافيير سالمرون ، مهندس من مجتمع Kubernetes المعروف في Bitnami ، ونشر على مدونة CNCF في أوائل أغسطس. يتحدث المؤلف عن أساسيات آلية التحكم في الوصول (RBAC) التي ظهرت في Kubernetes قبل عام ونصف. ستكون المواد مفيدة بشكل خاص لأولئك الذين هم على دراية بجهاز المكونات الرئيسية لـ K8s (انظر الروابط إلى مقالات أخرى مماثلة في النهاية).
شريحة من عرض تقديمي قدمه أحد موظفي Google بمناسبة إصدار Kubernetes 1.6قد يتذكر العديد من مستخدمي Kubernetes ذوي الخبرة إصدار Kubernetes 1.6 ، عندما أصبح التفويض المستند إلى التحكم في الوصول المستند إلى الدور (RBAC) إصدارًا تجريبيًا. لذلك ظهرت آلية مصادقة بديلة ، مكملة للآلية القائمة بالفعل ، ولكن من الصعب إدارتها وفهمها ، التحكم في الوصول القائم على السمات (ABAC). رحب الجميع بحماس بالميزة الجديدة ، ولكن في الوقت نفسه خاب أمل عدد لا يحصى من المستخدمين. تكثر StackOverflow و GitHub مع تقارير قيود RBAC لأن معظم الوثائق والأمثلة لم تأخذ RBAC في الاعتبار (ولكن الآن كل شيء على ما يرام). المثال المرجعي كان Helm: مجرد تشغيل
helm init
+
helm install
لم يعد يعمل. فجأة ، احتجنا إلى إضافة عناصر "غريبة" مثل
ServiceAccounts
أو
RoleBindings
قبل أن
RoleBindings
المخطط مع WordPress أو Redis (انظر
التعليمات للمزيد عن هذا).
إذا تركنا هذه المحاولات الأولى غير الناجحة جانبًا ، فلا يمكن للمرء أن ينكر المساهمة الهائلة التي قدمها RBAC لتحويل Kubernetes إلى منصة جاهزة للإنتاج. تمكن الكثير منا من اللعب مع Kubernetes بامتيازات المشرف الكاملة ، ونحن نتفهم تمامًا أنه من الضروري في بيئة حقيقية:
- الحصول على العديد من المستخدمين بخصائص مختلفة توفر آلية المصادقة المطلوبة.
- السيطرة الكاملة على العمليات التي يمكن لكل مستخدم أو مجموعة من المستخدمين القيام بها.
- السيطرة الكاملة على العمليات التي يمكن أن تؤديها كل عملية في القلب.
- تقييد رؤية موارد معينة في مساحات الأسماء.
وفي هذا الصدد ، RBAC هو عنصر رئيسي يوفر القدرات التي تمس الحاجة إليها. في المقالة ،
سنتناول بسرعة الأساسيات
(راجع مقطع الفيديو هذا للحصول على التفاصيل ؛ اتبع رابط البرنامج التعليمي على الويب لمدة ساعة في Bitnami باللغة الإنجليزية - ترجمة تقريبًا ) ونتعمق قليلاً في اللحظات الأكثر إرباكًا.
المفتاح لفهم RBAC في Kubernetes
لتحقيق فكرة RBAC بالكامل ، عليك أن تفهم أن هناك ثلاثة عناصر متضمنة فيها:
- الموضوعات - مجموعة من المستخدمين والعمليات الذين يرغبون في الوصول إلى Kubernetes API ؛
- الموارد - مجموعة من كائنات Kubernetes API المتوفرة في مجموعة. أمثلةهم (من بين أمور أخرى) هي Pods ، Deployments ، Services ، Nodes ، PersistentVolumes ؛
- الأفعال (الأفعال) - مجموعة من العمليات التي يمكن إجراؤها على الموارد. هناك أفعال مختلفة (الحصول عليها ، ومشاهدتها ، وإنشائها ، وحذفها ، وما إلى ذلك) ، ولكن جميعها في النهاية هي عمليات CRUD (إنشاء ، قراءة ، تحديث ، حذف).

مع وضع هذه العناصر الثلاثة في الاعتبار ، فإن الفكرة الرئيسية لـ RBAC هي:
"نريد ربط الموضوعات وموارد وعمليات API." بمعنى آخر ، نريد أن نشير
لمستخدم معين إلى
العمليات التي يمكن إجراؤها على مجموعة متنوعة من
الموارد .
فهم كائنات RBAC في API
من خلال دمج هذه الأنواع الثلاثة من الكيانات ، تصبح كائنات RBAC المتاحة في Kubernetes API واضحة:
Roles
تربط الموارد والأفعال. يمكن إعادة استخدامها لمواضيع مختلفة. مرتبط بمساحة اسم واحدة (لا يمكننا استخدام قوالب تمثل أكثر من [مساحة اسم] واحدة ، ولكن يمكننا نشر كائن الدور نفسه إلى مساحات أسماء مختلفة). إذا كنت تريد تطبيق الدور على الكتلة بأكملها ، فهناك كائن ClusterRoles
مشابه.- يربط
RoleBindings
الكيانات المتبقية. من خلال تحديد دور يربط بالفعل كائنات واجهة برمجة التطبيقات بالأفعال ، نختار الآن الموضوعات التي يمكنها استخدامها. المكافئ لمستوى الكتلة (أي بدون ربط بمساحات الأسماء) هو ClusterRoleBindings
.
في المثال أدناه ، نعطي المستخدم
jsalmeron الحق في القراءة والحصول على قائمة وإنشاء مداخن في مساحة اسم
الاختبار . هذا يعني أن
jsalmeron سيكون قادرًا على تنفيذ هذه الأوامر:
kubectl get pods --namespace test kubectl describe pod --namespace test pod-name kubectl create --namespace test -f pod.yaml
... ولكن ليس هكذا:
kubectl get pods --namespace kube-system

أمثلة على ملفات YAML:
kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: pod-read-create namespace: test rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "create"]
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: salme-pods namespace: test subjects: - kind: User name: jsalmeron apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-read-create apiGroup: rbac.authorization.k8s.io
نقطة أخرى مثيرة للاهتمام هي: الآن بعد أن يمكن للمستخدم إنشاء قرون ، هل يمكننا تحديد مقدارها؟ سيتطلب هذا كائنات أخرى لا تتعلق مباشرة بمواصفات RBAC وتتيح لك تكوين حدود
ResourceQuota
:
ResourceQuota
و
LimitRanges
. من المؤكد أنها تستحق الاستكشاف عند تكوين مثل هذا المكون العنقودي المهم [مثل إنشاء المداخن].
المواضيع: المستخدمون و ... ServiceAccounts؟
إحدى الصعوبات التي يواجهها العديد من مستخدمي Kubernetes في سياق الموضوعات هي التمييز بين المستخدمين العاديين
ServiceAccounts
. من الناحية النظرية ، كل شيء بسيط:
Users
- المستخدمون العالميون ، المصممون للأشخاص أو العمليات التي تعيش خارج المجموعة ؛ServiceAccounts
- محدودة ServiceAccounts
الاسم ومخصصة للعمليات داخل المجموعة التي تعمل على منصات.
يكمن التشابه بين كلا النوعين في الحاجة إلى المصادقة مع واجهة برمجة التطبيقات لإجراء عمليات معينة على العديد من الموارد ، وتبدو مجالات موضوعها محددة للغاية. يمكن أن تنتمي أيضًا إلى مجموعات ، لذلك يسمح
RoleBinding
بربط أكثر من موضوع واحد (على الرغم من أنه يُسمح فقط بمجموعة واحدة لـ
ServiceAccounts
-
system:serviceaccounts
). ومع ذلك ، فإن الفرق الرئيسي هو سبب الصداع: ليس لدى المستخدمين كائنات مقابلة لها في Kubernetes API. اتضح أن مثل هذه العملية موجودة:
kubectl create serviceaccount test-service-account
... ولكن هذا ذهب:
kubectl create user jsalmeron
هذه الحالة لها عواقب خطيرة: إذا لم تقم المجموعة بتخزين معلومات حول المستخدمين ، فسيتعين على المسؤول إدارة الحسابات خارج المجموعة. هناك طرق مختلفة لحل المشكلة: شهادات TLS ، الرموز المميزة ، OAuth2 ، إلخ.
بالإضافة إلى ذلك ، ستحتاج إلى إنشاء سياقات
kubectl
نتمكن من الوصول إلى المجموعة من خلال هذه الحسابات الجديدة. لإنشاء ملفات معهم ، يمكنك استخدام أوامر
kubectl config
(التي لا تتطلب الوصول إلى Kubernetes API ، بحيث يمكن لأي مستخدم تنفيذها). يحتوي الفيديو أعلاه على مثال لإنشاء مستخدم بشهادات TLS.
RBAC في عمليات النشر: مثال
لقد رأينا مثالًا يتم فيه منح المستخدم المحدد حقوقًا للعمليات في المجموعة. ولكن ماذا عن عمليات
النشر التي تتطلب الوصول إلى Kubernetes API؟ فكر في سيناريو محدد للحصول على فهم أفضل.
خذ على سبيل المثال تطبيق البنية التحتية الشعبية - RabbitMQ. سنستخدم
مخطط Helm لـ RabbitMQ من Bitnami (من مستودع الدفة / الرسوم البيانية الرسمي) ، والذي يستخدم
حاوية bitnami / rabbitmq . تم إنشاء مكون إضافي لـ Kubernetes في الحاوية ، وهو المسؤول عن الكشف عن الأعضاء الآخرين في مجموعة RabbitMQ. لهذا السبب ، تتطلب العملية داخل الحاوية الوصول إلى واجهة برمجة تطبيقات Kubernetes ، ونحن بحاجة إلى تكوين
ServiceAccount
بامتيازات RBAC الصحيحة.
عندما يتعلق الأمر
ServiceAccounts
، اتبع هذه الممارسة الجيدة:
- تكوين
ServiceAccounts لكل عملية نشر بحد أدنى من الامتيازات .
بالنسبة للتطبيقات التي تتطلب الوصول إلى واجهة برمجة تطبيقات Kubernetes ، قد تميل إلى إنشاء نوع من "
ServiceAccount
المميز" الذي يمكنه فعل أي شيء تقريبًا في المجموعة. على الرغم من أن هذا يبدو حلًا أبسط ، إلا أنه قد يؤدي في نهاية المطاف إلى ثغرة أمنية قد تسمح بعمليات غير مرغوب فيها. (ينظر الفيديو إلى مثال على Tiller [مكون Helm] وعواقب امتلاك
ServiceAccounts
بامتيازات رائعة.)
بالإضافة إلى ذلك ، سيكون لعمليات
النشر المختلفة احتياجات مختلفة من حيث الوصول إلى واجهة برمجة التطبيقات ، لذا فمن المنطقي أن يكون لكل عملية
نشر ServiceAccounts
مختلفة.
مع أخذ ذلك في الاعتبار ، دعنا نرى أي تكوين RBAC صحيح لحالة
النشر مع RabbitMQ.
في
وثائق البرنامج المساعد ورمز مصدره ، يمكنك أن ترى أنه يطلب قائمة نقاط
النهاية من واجهة برمجة تطبيقات Kubernetes. هذه هي الطريقة التي يتم بها الكشف عن الأعضاء المتبقيين في مجموعة RabbitMQ. لذلك ، ينشئ مخطط Bitnami RabbitMQ ما يلي:
- ServiceAccount للمداخن مع RabbitMQ:
{{- if .Values.rbacEnabled }} apiVersion: v1 kind: ServiceAccount metadata: name: {{ template "rabbitmq.fullname" . }} labels: app: {{ template "rabbitmq.name" . }} chart: {{ template "rabbitmq.chart" . }} release: "{{ .Release.Name }}" heritage: "{{ .Release.Service }}" {{- end }}
- الدور (نفترض أن مجموعة RabbitMQ بأكملها منتشرة في مساحة اسم واحدة) ، مما يسمح للفعل بالحصول على مورد نقطة النهاية :
{{- if .Values.rbacEnabled }} kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ template "rabbitmq.fullname" . }}-endpoint-reader labels: app: {{ template "rabbitmq.name" . }} chart: {{ template "rabbitmq.chart" . }} release: "{{ .Release.Name }}" heritage: "{{ .Release.Service }}" rules: - apiGroups: [""] resources: ["endpoints"] verbs: ["get"] {{- end }}
- ملزم ربط
ServiceAccount
AccountAccount لدور:
{{- if .Values.rbacEnabled }} kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ template "rabbitmq.fullname" . }}-endpoint-reader labels: app: {{ template "rabbitmq.name" . }} chart: {{ template "rabbitmq.chart" . }} release: "{{ .Release.Name }}" heritage: "{{ .Release.Service }}" subjects: - kind: ServiceAccount name: {{ template "rabbitmq.fullname" . }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ template "rabbitmq.fullname" . }}-endpoint-reader {{- end }}

يوضح الرسم التخطيطي أننا سمحنا للعمليات التي يتم تشغيلها في حوامل RabbitMQ بإجراء عمليات
الحصول على كائنات
نقطة النهاية . هذا هو الحد الأدنى من مجموعة العمليات المطلوبة لكل شيء للعمل. في الوقت نفسه ، نعلم أن المخطط المنشور آمن ولن يقوم بإجراءات غير مرغوب فيها داخل مجموعة Kubernetes.
الأفكار النهائية
للعمل مع Kubernetes في الإنتاج ، فإن سياسات RBAC ليست اختيارية. لا يمكن اعتبارها مجموعة من كائنات API التي يجب أن يعرفها المسؤولون فقط. يحتاج المطورون بالفعل إلى نشر التطبيقات الآمنة والاستفادة الكاملة من الإمكانات التي توفرها واجهة برمجة تطبيقات Kubernetes للتطبيقات السحابية الأصلية. يمكن العثور على مزيد من المعلومات حول RBAC على الروابط التالية:
ملاحظة من المترجم
اقرأ أيضا في مدونتنا: