
عاجلاً أم آجلاً ، يثير تشغيل أي نظام مسألة الأمان: ضمان المصادقة ، وفصل الحقوق ، ومراجعة الحسابات وغيرها من المهام. تم بالفعل إنشاء
العديد من الحلول لـ Kubernetes التي يمكنها تحقيق الامتثال للمعايير حتى في البيئات التي تتطلب الكثير من المتطلبات ... وتكرس نفس المواد لجوانب الأمان الأساسية المنفذة في إطار الآليات المدمجة في K8. بادئ ذي بدء ، سيكون مفيدًا لأولئك الذين يبدأون في التعرف على Kubernetes ، كنقطة انطلاق لدراسة القضايا الأمنية.
المصادقة
Kubernetes لديه نوعان من المستخدمين:
- حسابات الخدمة - الحسابات التي يديرها Kubernetes API ؛
- المستخدمون - المستخدمون "العاديون" الذين تسيطر عليهم خدمات خارجية مستقلة.
الفرق الرئيسي بين هذه الأنواع هو أنه بالنسبة لحسابات الخدمة ، توجد كائنات خاصة في Kubernetes API (يطلق عليها
ServiceAccounts
) مرتبطة بمساحة اسم ومجموعة من بيانات التخويل المخزنة في كتلة في كائنات من النوع Secrets. الهدف من هؤلاء المستخدمين (حسابات الخدمة) في المقام الأول هو إدارة حقوق الوصول إلى عمليات Kubernetes API التي تعمل في كتلة Kubernetes.
لا يملك المستخدمون العاديون إدخالات في واجهة برمجة تطبيقات Kubernetes: يجب إدارتها بواسطة آليات خارجية. وهي مخصصة للأشخاص أو العمليات التي تعيش خارج الكتلة.
يرتبط كل طلب مقدم إلى واجهة برمجة التطبيقات إما بحساب الخدمة أو بالمستخدم ، أو يعتبر مجهولًا.
تشمل بيانات مصادقة المستخدم:
- اسم المستخدم - اسم المستخدم (حساس لحالة الأحرف!) ؛
- UID عبارة عن سلسلة تعريف للمستخدم يمكن قراءتها بواسطة الآلة وهي "أكثر اتساقًا وفريدة من اسم المستخدم" ؛
- المجموعات - قائمة بالمجموعات التي ينتمي إليها المستخدم ؛
- حقول إضافية - يمكن استخدامها من قبل آلية الترخيص.
يمكن أن يستخدم Kubernetes عددًا كبيرًا من آليات المصادقة: شهادات X509 ورموز Bearer ووكلاء المصادقة و HTTP Basic Auth. باستخدام هذه الآليات ، يمكن تنفيذ عدد كبير من مخططات التفويض: من ملف ثابت بكلمات مرور إلى OpenID OAuth2.
علاوة على ذلك ، يُسمح بمخططات الترخيص المتعددة في نفس الوقت. بشكل افتراضي ، يستخدم الكتلة:
- رموز حساب الخدمة - لحسابات الخدمة ؛
- X509 - للمستخدمين.
إن مسألة إدارة ServiceAccounts تتجاوز نطاق هذه المقالة ، لكنني أوصي بالبدء في معرفة المزيد حول هذه المشكلة من
صفحة الوثائق الرسمية . سننظر بمزيد من التفصيل في مسألة عمل شهادات X509.
شهادات للمستخدمين (X.509)
تتضمن الطريقة الكلاسيكية للعمل مع الشهادات:
- جيل المفتاح:
mkdir -p ~/mynewuser/.certs/ openssl genrsa -out ~/.certs/mynewuser.key 2048
- جيل طلب الشهادة:
openssl req -new -key ~/.certs/mynewuser.key -out ~/.certs/mynewuser.csr -subj "/CN=mynewuser/O=company"
- معالجة طلب الشهادة باستخدام مفاتيح CA لنظام المجموعة Kubernetes ، والحصول على شهادة مستخدم (للحصول على شهادة ، تحتاج إلى استخدام حساب لديه حق الوصول إلى مفتاح مرجع شهادة نظام المجموعة Kubernetes ، الموجود في
/etc/kubernetes/pki/ca.key
بشكل افتراضي):
openssl x509 -req -in ~/.certs/mynewuser.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out ~/.certs/mynewuser.crt -days 500
- إنشاء ملف التكوين:
- وصف نظام المجموعة (حدد عنوان وموقع ملف شهادة المرجع المصدق (CA) لتثبيت نظام المجموعة المحدد):
kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://192.168.100.200:6443
- أو - إذا لم يكن الخيار الموصى به - يمكنك حذف شهادة الجذر (ثم لن يتحقق kubectl من صحة كتلة api-server):
kubectl config set-cluster kubernetes --insecure-skip-tls-verify=true --server=https://192.168.100.200:6443
- إضافة مستخدم إلى ملف التكوين:
kubectl config set-credentials mynewuser --client-certificate=.certs/mynewuser.crt --client-key=.certs/mynewuser.key
- إضافة السياق:
kubectl config set-context mynewuser-context --cluster=kubernetes --namespace=target-namespace --user=mynewuser
- تعيين السياق الافتراضي:
kubectl config use-context mynewuser-context
بعد التلاعب أعلاه ، سيتم إنشاء تكوين النموذج في ملف
.kube/config
:
apiVersion: v1 clusters: - cluster: certificate-authority: /etc/kubernetes/pki/ca.crt server: https://192.168.100.200:6443 name: kubernetes contexts: - context: cluster: kubernetes namespace: target-namespace user: mynewuser name: mynewuser-context current-context: mynewuser-context kind: Config preferences: {} users: - name: mynewuser user: client-certificate: /home/mynewuser/.certs/mynewuser.crt client-key: /home/mynewuser/.certs/mynewuser.key
لتسهيل نقل التكوين بين الحسابات والخوادم ، من المفيد تحرير قيم المفاتيح التالية:
certificate-authority
client-certificate
client-key
للقيام بذلك ، يمكنك تشفير الملفات المشار إليها فيها باستخدام base64 وتسجيلها في التكوين عن طريق إضافة بيانات لاحقة إلى اسم المفاتيح ، أي الحصول على
certificate-authority-data
، الخ
الشهادات مع kubeadm
مع إصدار
Kubernetes 1.15 ، أصبح العمل مع الشهادات أسهل كثيرًا بفضل إصدار alpha الخاص بدعمه في
أداة kubeadm . على سبيل المثال ، إليك ما قد يبدو عليه الآن إنشاء ملف التكوين باستخدام مفاتيح المستخدم:
kubeadm alpha kubeconfig user --client-name=mynewuser --apiserver-advertise-address 192.168.100.200
ملحوظة : يمكن عرض عنوان الإعلان المطلوب في تهيئة خادم api ، والذي يقع في /etc/kubernetes/manifests/kube-apiserver.yaml
افتراضيًا.سيتم إخراج التكوين الناتج إلى stdout. يجب حفظه في
~/.kube/config
لحساب المستخدم أو في الملف المحدد في
KUBECONFIG
البيئة
KUBECONFIG
.
حفر أعمق
بالنسبة لأولئك الذين يرغبون في فهم القضايا الموصوفة بدقة:
ترخيص
ليس لدى الحساب المصادق إذن التصرف في كتلة بشكل افتراضي. Kubernetes لديه آلية ترخيص لمنح الأذونات.
قبل الإصدار 1.6 ، استخدم Kubernetes نوع مصادقة يسمى
ABAC (التحكم في الوصول المستند إلى السمات). يمكن الاطلاع على التفاصيل المتعلقة به في
الوثائق الرسمية . يعتبر هذا النهج حاليًا قديمًا ، لكن لا يزال بإمكانك استخدامه في نفس الوقت الذي تستخدم فيه أنواع الترخيص الأخرى.
تسمى الطريقة الفعلية (والأكثر مرونة) لتقسيم حقوق الوصول إلى نظام المجموعة
RBAC (
التحكم في الوصول المستند إلى الدور ). تم الإعلان عن
ثباته منذ
Kubernetes 1.8 . تطبق RBAC نموذج حقوق يحظر أي شيء غير مسموح به صراحة.
لتمكين RBAC ، تحتاج إلى تشغيل Kubernetes api-server مع
--authorization-mode=RBAC
. يتم تعيين المعلمات في البيان مع تكوين خادم api ، والذي يقع افتراضيًا على المسار
/etc/kubernetes/manifests/kube-apiserver.yaml
، في قسم
command
. ومع ذلك ، يتم تمكين RBAC بالفعل افتراضيًا ، لذلك من المحتمل ألا تقلق بشأن هذا: يمكنك التحقق من ذلك من خلال قيمة
authorization-mode
(في
kube-apiserver.yaml
المذكور
kube-apiserver.yaml
). بالمناسبة ، من بين قيمها قد يكون هناك أنواع أخرى من التخويل (
node
،
webhook
،
always allow
) ، لكننا
webhook
خارج نطاق المادة.
بالمناسبة ، لقد نشرنا بالفعل
مقالًا يحتوي على قصة مفصلة إلى حد ما حول مبادئ وميزات العمل مع RBAC ، لذلك سأقتصر على سرد موجز للأساسيات والأمثلة.
تُستخدم كيانات واجهة برمجة التطبيقات التالية للتحكم في الوصول إلى Kubernetes عبر RBAC:
Role
و ClusterRole
أدوار تصف الامتيازات:- يتيح لك
Role
وصف الحقوق ضمن مساحة الاسم ؛ ClusterRole
- داخل الكتلة ، بما في ذلك الكائنات الخاصة بالكتلة مثل العقد ، عناوين url غير المتعلقة بالموارد (على سبيل المثال ، لا تتعلق بموارد Kubernetes - على سبيل المثال ، /version
، /logs
، /api*
) ؛RoleBinding
and ClusterRoleBinding
- يعمل على ربط Role
and ClusterRole
بمستخدم أو مجموعة مستخدمين أو ServiceAccount.
يقتصر دور الكيانات وتجليد الأدوار على مساحة الاسم ، أي يجب أن يكون داخل نفس مساحة الاسم. ومع ذلك ، يمكن أن يشير RoleBinding إلى ClusterRole ، والذي يسمح لك بإنشاء مجموعة من الأذونات القياسية والتحكم في الوصول إليها.
تصف الأدوار الحقوق باستخدام مجموعات القواعد التي تحتوي على:
- مجموعات واجهة برمجة التطبيقات - راجع الوثائق الرسمية لـ apiGroups وإخراج موارد
kubectl api-resources
. - الموارد ( الموارد :
pod
، namespace
، deployment
، إلخ) ؛ - الأفعال ( الأفعال :
set
، update
، وما إلى ذلك). - أسماء الموارد (أسماء
resourceNames
) - للحالة عندما تحتاج إلى توفير الوصول إلى مورد معين ، وليس لجميع الموارد من هذا النوع.
يمكن الاطلاع على مناقشة أكثر تفصيلاً للترخيص في Kubernetes على صفحة
الوثائق الرسمية . بدلاً من ذلك (أو بالأحرى ، بالإضافة إلى ذلك) سأقدم أمثلة توضح عملها.
أمثلة الكيان RBAC
Role
بسيط يسمح لك بالحصول على قائمة وحافظات البرامج ومراقبتها في
target-namespace
:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: target-namespace name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]
مثال على
ClusterRole
، والذي يتيح لك الحصول على قائمة وحالة القرون ومراقبتها في جميع أنحاء الكتلة:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: # "namespace" , ClusterRole name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]
مثال
RoleBinding
، والذي يسمح للمستخدم
mynewuser
"قراءة" pods في
my-namespace
:
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-pods namespace: target-namespace subjects: - kind: User name: mynewuser # ! apiGroup: rbac.authorization.k8s.io roleRef: kind: Role # “Role” “ClusterRole” name: pod-reader # Role, namespace, # ClusterRole, # apiGroup: rbac.authorization.k8s.io
تدقيق الأحداث
من الناحية التخطيطية ، يمكن تمثيل بنية Kubernetes على النحو التالي:

المكون الرئيسي لـ Kubernetes ، المسؤول عن معالجة الطلبات ، هو
api-server . تمر جميع العمليات على الكتلة من خلالها. اقرأ المزيد عن هذه الآليات الداخلية في المقالة "
ماذا يحدث في Kubernetes عندما يبدأ تشغيل kubectl؟ ".
يعد تدقيق النظام ميزة مهمة في Kubernetes ، حيث يتم إيقاف تشغيله افتراضيًا. يسمح لك بتسجيل جميع المكالمات إلى Kubernetes API. كما يمكنك أن تخمن بسهولة ، من خلال واجهة برمجة التطبيقات هذه ، يتم تنفيذ جميع الإجراءات المتعلقة بمراقبة وتغيير حالة المجموعة. يمكن العثور على وصف جيد لميزاته (كالمعتاد) في
وثائق K8s
الرسمية . بعد ذلك ، سأحاول تقديم الموضوع بلغة أبسط.
لذلك ،
لتمكين التدقيق ، نحتاج إلى تمرير ثلاثة معلمات مطلوبة إلى الحاوية في خادم api ، ويرد المزيد حول الموضح أدناه:
--audit-policy-file=/etc/kubernetes/policies/audit-policy.yaml
--audit-log-path=/var/log/kube-audit/audit.log
--audit-log-format=json
بالإضافة إلى هذه المعلمات الثلاثة الضرورية ، هناك العديد من الإعدادات الإضافية المتعلقة بالتدقيق: من تدوير السجل إلى أوصاف webhook. مثال معلمات دوران السجل:
--audit-log-maxbackup=10
--audit-log-maxsize=100
--audit-log-maxage=7
لكننا لن نتناولها بمزيد من التفاصيل - يمكنك العثور على جميع التفاصيل في
وثائق kube-apiserver .
كما ذكرنا سابقًا ، يتم تعيين جميع المعلمات في البيان مع تكوين خادم api (افتراضيًا
/etc/kubernetes/manifests/kube-apiserver.yaml
) ، في قسم
command
. دعنا نعود إلى المعلمات الثلاثة المطلوبة وتحليلها:
audit-policy-file
- المسار إلى ملف YAML مع وصف سياسة التدقيق. سنعود إلى محتوياته ، لكنني ألاحظ الآن أنه يجب أن يكون الملف متاحًا للقراءة بواسطة عملية خادم api. لذلك ، من الضروري تثبيته داخل الحاوية ، حيث يمكنك إضافة التعليمة البرمجية التالية إلى الأقسام المناسبة من التكوين:
volumeMounts: - mountPath: /etc/kubernetes/policies name: policies readOnly: true volumes: - hostPath: path: /etc/kubernetes/policies type: DirectoryOrCreate name: policies
audit-log-path
- المسار إلى ملف السجل. يجب أن يكون المسار أيضًا متاحًا لعملية خادم api ، وبالتالي ، فإننا نصف طريقة تركيبه بالمثل:
volumeMounts: - mountPath: /var/log/kube-audit name: logs readOnly: false volumes: - hostPath: path: /var/log/kube-audit type: DirectoryOrCreate name: logs
- شكل سجل التدقيق - شكل سجل التدقيق. بشكل افتراضي ، هذا
json
، لكن تنسيق النص القديم متاح أيضًا.
سياسة التدقيق
الآن حول الملف المذكور مع وصف سياسة التسجيل. المفهوم الأول لسياسة التدقيق هو
level
،
ومستوى التسجيل . هم على النحو التالي:
None
- لا تقم بتسجيل الدخول ؛Metadata
- سجل طلب البيانات الوصفية: المستخدم ، وقت الطلب ، المورد المستهدف (pod ، مساحة الاسم ، وما إلى ذلك) ، نوع الإجراء (الفعل) ، وما إلى ذلك ؛Request
- سجل البيانات الوصفية ونص الطلب ؛RequestResponse
- RequestResponse
البيانات الوصفية ، RequestResponse
الطلب وجسم الاستجابة.
لا يقوم المستويان الأخيران (
Request
و
RequestResponse
) بتسجيل الطلبات التي لم تصل إلى الموارد (استدعاءات لما يسمى عناوين url بخلاف الموارد).
أيضًا ، تمر جميع الطلبات
بعدة مراحل :
RequestReceived
- المرحلة التي يتم فيها استلام الطلب من قبل المعالج ولم يتم نقله بعد على طول سلسلة من المناضلين ؛ResponseStarted
- تم إرسال رؤوس الاستجابة ، ولكن قبل إرسال نص الاستجابة. تم إنشاؤه للاستعلامات الطويلة (مثل watch
) ؛ResponseComplete
- تم إرسال نص الاستجابة ، ولن يتم إرسال المزيد من المعلومات ؛Panic
- يتم إنشاء الأحداث عند اكتشاف حالة الطوارئ.
يمكنك استخدام
omitStages
لتخطي أي مراحل.
في ملف السياسة ، يمكننا وصف عدة أقسام بمستويات مختلفة من التسجيل. سيتم تطبيق قاعدة المطابقة الأولى الموجودة في وصف السياسة.
يراقب البرنامج الخفي kubelet التغيير الظاهر من خلال تكوين api-server ، وإذا تم اكتشاف أي شيء ، فإنه يعيد تشغيل الحاوية بخادم api. ولكن هناك تفاصيل مهمة:
سوف يتجاهلون التغييرات في ملف السياسة . بعد إجراء تغييرات على ملف السياسة ، ستحتاج إلى إعادة تشغيل api-server يدويًا. نظرًا لأن api-server يعمل
kubectl delete
ثابتة ، فإن أمر
kubectl delete
يعيد تشغيله. سيتعين عليك
docker stop
يدويًا على kube-masters حيث تم تغيير سياسة التدقيق:
docker stop $(docker ps | grep k8s_kube-apiserver | awk '{print $1}')
عند تمكين التدوين ، من المهم أن تتذكر أن
kube-apiserver له حمل أعلى . على وجه الخصوص ، يزداد استهلاك الذاكرة لتخزين سياق الطلبات. يبدأ التسجيل فقط بعد إرسال رأس الاستجابة. أيضا ، يعتمد الحمل على تكوين سياسة التدقيق.
أمثلة السياسة
دعنا نحلل بنية ملفات السياسة باستخدام الأمثلة.
إليك ملف
policy
بسيط لتسجيل كل شيء على مستوى
Metadata
:
apiVersion: audit.k8s.io/v1 kind: Policy rules: - level: Metadata
يمكنك تحديد قائمة المستخدمين (
Users
و
ServiceAccounts
) ومجموعات المستخدمين في السياسة. على سبيل المثال ، هذه هي الطريقة التي نتجاهل بها مستخدمي النظام ، ولكننا نسجل كل شيء آخر على مستوى
Request
:
apiVersion: audit.k8s.io/v1 kind: Policy rules: - level: None userGroups: - "system:serviceaccounts" - "system:nodes" users: - "system:anonymous" - "system:apiserver" - "system:kube-controller-manager" - "system:kube-scheduler" - level: Request
من الممكن أيضًا وصف الهدف:
- مساحة (
namespaces
)؛ - الأفعال ( الأفعال :
get
، update
، delete
and others)؛ - الموارد ( الموارد ، وهي:
pod
، configmaps
، إلخ) ومجموعات الموارد ( apiGroups
).
انتبه! يمكن الحصول على مجموعات الموارد والموارد (مجموعات API ، أي apiGroups) ، وكذلك إصداراتها المثبتة في الكتلة ، باستخدام الأوامر:
kubectl api-resources kubectl api-versions
يتم توفير سياسة التدقيق التالية كدليل على أفضل الممارسات في
وثائق Alibaba Cloud :
apiVersion: audit.k8s.io/v1beta1 kind: Policy # RequestReceived omitStages: - "RequestReceived" rules: # , : - level: None users: ["system:kube-proxy"] verbs: ["watch"] resources: - group: "" # api group , # Kubernetes, “core” resources: ["endpoints", "services"] - level: None users: ["system:unsecured"] namespaces: ["kube-system"] verbs: ["get"] resources: - group: "" # core resources: ["configmaps"] - level: None users: ["kubelet"] verbs: ["get"] resources: - group: "" # core resources: ["nodes"] - level: None userGroups: ["system:nodes"] verbs: ["get"] resources: - group: "" # core resources: ["nodes"] - level: None users: - system:kube-controller-manager - system:kube-scheduler - system:serviceaccount:kube-system:endpoint-controller verbs: ["get", "update"] namespaces: ["kube-system"] resources: - group: "" # core resources: ["endpoints"] - level: None users: ["system:apiserver"] verbs: ["get"] resources: - group: "" # core resources: ["namespaces"] # read-only URLs: - level: None nonResourceURLs: - /healthz* - /version - /swagger* # , “”: - level: None resources: - group: "" # core resources: ["events"] # Secret, ConfigMap TokenReview , # - level: Metadata resources: - group: "" # core resources: ["secrets", "configmaps"] - group: authentication.k8s.io resources: ["tokenreviews"] # get, list watch ; - level: Request verbs: ["get", "list", "watch"] resources: - group: "" # core - group: "admissionregistration.k8s.io" - group: "apps" - group: "authentication.k8s.io" - group: "authorization.k8s.io" - group: "autoscaling" - group: "batch" - group: "certificates.k8s.io" - group: "extensions" - group: "networking.k8s.io" - group: "policy" - group: "rbac.authorization.k8s.io" - group: "settings.k8s.io" - group: "storage.k8s.io" # API - level: RequestResponse resources: - group: "" # core - group: "admissionregistration.k8s.io" - group: "apps" - group: "authentication.k8s.io" - group: "authorization.k8s.io" - group: "autoscaling" - group: "batch" - group: "certificates.k8s.io" - group: "extensions" - group: "networking.k8s.io" - group: "policy" - group: "rbac.authorization.k8s.io" - group: "settings.k8s.io" - group: "storage.k8s.io" # - level: Metadata
مثال جيد آخر لسياسة التدقيق هو
ملف التعريف المستخدم في الحملة العالمية للتعليم .
للاستجابة السريعة لأحداث التدقيق ، من الممكن
وصف webhook . تم الكشف عن هذه المشكلة في
الوثائق الرسمية ، سأتركها خارج نطاق هذه المقالة.
النتائج
توفر هذه المقالة نظرة عامة حول آليات الأمان الأساسية في مجموعات Kubernetes التي تتيح لك إنشاء حسابات مستخدم مخصصة ومشاركة حقوقها وتسجيل إجراءاتها. آمل أن تكون مفيدة لأولئك الذين يواجهون مثل هذه الأسئلة من الناحية النظرية أو بالفعل في الممارسة. أوصي أيضًا بأن تنظر إلى قائمة المواد الأخرى حول موضوع الأمن في Kubernetes ، المدرجة في "PS" - ربما فيما بينها ستجد التفاصيل اللازمة حول القضايا ذات الصلة بك.
PS
اقرأ أيضًا في مدونتنا: