المصادقة في Kubernetes مع GitHub OAuth و Dex

أقدم إليكم البرنامج التعليمي لإنشاء الوصول إلى مجموعة Kubernetes باستخدام Dex و dex-k8s-Authenticator و GitHub.

الصورة

ميم المحلية من اللغة الروسية الدردشة Kubernetes على برقية

مقدمة


نستخدم Kubernetes لإنشاء بيئات ديناميكية لفريق التطوير و QA. وبالتالي ، نريد منحهم إمكانية الوصول إلى الكتلة لكل من لوحات المعلومات و kubectl. بخلاف OpenShift ، لا تملك vanilla Kubernetes مصادقة أصلية ، لذلك نستخدم أدوات الجهات الخارجية لهذا الغرض.

في هذا التكوين ، نستخدم:

  • dex-k8s-Authenticator - تطبيق ويب لإنشاء kubectl config
  • Dex - OpenID Connect Provider
  • جيثب - ببساطة لأننا نستخدم جيثب في شركتنا

لقد حاولنا استخدام Google OIDC ، لكن للأسف لم نتمكن من ضمهم إلى مجموعات ، لذلك كان التكامل مع GitHub جيدًا معنا. بدون تعيين المجموعة ، لا يمكنك إنشاء سياسات RBAC المستندة إلى المجموعة.

لذلك ، كيف تعمل عملية التفويض الخاصة بنا في Kubernetes في تمثيل مرئي:

الصورة
عملية التفويض

مزيد من التفاصيل والنقاط:

  1. يسجل المستخدم الدخول إلى مصادقة dex-k8s ( login.k8s.example.com )
  2. يقوم dex-k8s-Authenticator بإعادة توجيه الطلب إلى Dex ( dex.k8s.example.com )
  3. Dex يعيد التوجيه إلى صفحة تسجيل الدخول إلى جيثب
  4. ينشئ GitHub معلومات الترخيص اللازمة ويعيدها إلى Dex
  5. تقوم Dex بنقل المعلومات المستلمة إلى أداة المصادقة dex-k8s
  6. المستخدم يحصل على رمز OIDC من جيثب
  7. يضيف dex-k8s-Authenticator رمزًا مميزًا إلى kubeconfig
  8. تمرير kubectl الرمز المميز إلى KubeAPIServer
  9. يقوم KubeAPIServer استنادًا إلى الرمز المميز المنقول بإرجاع عمليات الوصول في kubectl
  10. المستخدم يحصل على الوصول من kubectl

الأنشطة التحضيرية


بالطبع ، لدينا بالفعل مجموعة Kubernetes ( k8s.example.com ) مثبتة ، وكذلك HELM. لدينا أيضًا منظمة على GitHub (super-org).
إذا لم يكن لديك HELM ، فمن السهل جدا تثبيت.

أولاً نحتاج إلى تكوين GitHub.

انتقل إلى صفحة إعدادات المؤسسة ( https://github.com/organizations/super-org/settings/applications ) وإنشاء تطبيق جديد (تطبيق OAuth معتمد):
الصورة
إنشاء تطبيق جديد على جيثب

املأ الحقول بعناوين URL الضرورية ، على سبيل المثال:

  • عنوان URL للصفحة الرئيسية: https://dex.k8s.example.com
  • عنوان URL لاستدعاء التخويل: https://dex.k8s.example.com/callback

كن حذرا مع الروابط ، من المهم عدم فقدان خطوط مائلة.

استجابةً للنموذج المكتمل ، ستقوم GitHub بإنشاء Client ID Client secret ، وحفظهما في مكان آمن ، وستكون مفيدة لنا (على سبيل المثال ، نستخدم Vault لتخزين الأسرار):

 Client ID: 1ab2c3d4e5f6g7h8 Client secret: 98z76y54x32w1 

قم بإعداد سجلات DNS login.k8s.example.com الفرعية login.k8s.example.com و dex.k8s.example.com ، بالإضافة إلى شهادات SSL للمجموعات.

إنشاء شهادات SSL:

 cat <<EOF | kubectl create -f - apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: cert-auth-dex namespace: kube-system spec: secretName: cert-auth-dex dnsNames: - dex.k8s.example.com acme: config: - http01: ingressClass: nginx domains: - dex.k8s.example.com issuerRef: name: le-clusterissuer kind: ClusterIssuer --- apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: cert-auth-login namespace: kube-system spec: secretName: cert-auth-login dnsNames: - login.k8s.example.com acme: config: - http01: ingressClass: nginx domains: - login.k8s.example.com issuerRef: name: le-clusterissuer kind: ClusterIssuer EOF kubectl describe certificates cert-auth-dex -n kube-system kubectl describe certificates cert-auth-login -n kube-system 

يجب أن يكون ClusterIssuer يحمل الاسم le-clusterissuer موجودًا بالفعل ، إن لم يكن ، فقم بإنشائه باستخدام HELM:

 helm install --namespace kube-system -n cert-manager stable/cert-manager cat << EOF | kubectl create -f - apiVersion: certmanager.k8s.io/v1alpha1 kind: ClusterIssuer metadata: name: le-clusterissuer namespace: kube-system spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: k8s-admin@example.com privateKeySecretRef: name: le-clusterissuer http01: {} EOF 

تكوين KubeAPIServer


لكي يعمل kubeAPIServer ، يجب عليك تكوين OIDC وتحديث الكتلة:

 kops edit cluster ... kubeAPIServer: anonymousAuth: false authorizationMode: RBAC oidcClientID: dex-k8s-authenticator oidcGroupsClaim: groups oidcIssuerURL: https://dex.k8s.example.com/ oidcUsernameClaim: email kops update cluster --yes kops rolling-update cluster --yes 

نستخدم kops لنشر الكتل ، لكنه يعمل بنفس الطريقة لمديري الكتلة الآخرين .

تكوين Dex و dex-k8s


لكي يعمل Dex ، يجب أن يكون لديك شهادة ومفتاح من Kubernetes الرئيسي ، لسحبها من هناك:

 sudo cat /srv/kubernetes/ca.{crt,key} -----BEGIN CERTIFICATE----- AAAAAAAAAAABBBBBBBBBBCCCCCC -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- DDDDDDDDDDDEEEEEEEEEEFFFFFF -----END RSA PRIVATE KEY----- 

قم بنسخ مستودع مصادقة dex-k8s:

 git clone git@github.com:mintel/dex-k8s-authenticator.git cd dex-k8s-authenticator/ 

باستخدام قيم الملفات ، يمكننا ضبط المتغيرات بمرونة لمخططات HELM الخاصة بنا.

دعنا نصف التكوين ل Dex:

 cat << \EOF > values-dex.yml global: deployEnv: prod tls: certificate: |- -----BEGIN CERTIFICATE----- AAAAAAAAAAABBBBBBBBBBCCCCCC -----END CERTIFICATE----- key: |- -----BEGIN RSA PRIVATE KEY----- DDDDDDDDDDDEEEEEEEEEEFFFFFF -----END RSA PRIVATE KEY----- ingress: enabled: true annotations: kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: "true" path: / hosts: - dex.k8s.example.com tls: - secretName: cert-auth-dex hosts: - dex.k8s.example.com serviceAccount: create: true name: dex-auth-sa config: | issuer: https://dex.k8s.example.com/ storage: # https://github.com/dexidp/dex/issues/798 type: sqlite3 config: file: /var/dex.db web: http: 0.0.0.0:5556 frontend: theme: "coreos" issuer: "Example Co" issuerUrl: "https://example.com" logoUrl: https://example.com/images/logo-250x25.png expiry: signingKeys: "6h" idTokens: "24h" logger: level: debug format: json oauth2: responseTypes: ["code", "token", "id_token"] skipApprovalScreen: true connectors: - type: github id: github name: GitHub config: clientID: $GITHUB_CLIENT_ID clientSecret: $GITHUB_CLIENT_SECRET redirectURI: https://dex.k8s.example.com/callback orgs: - name: super-org teams: - team-red staticClients: - id: dex-k8s-authenticator name: dex-k8s-authenticator secret: generatedLongRandomPhrase redirectURIs: - https://login.k8s.example.com/callback/ envSecrets: GITHUB_CLIENT_ID: "1ab2c3d4e5f6g7h8" GITHUB_CLIENT_SECRET: "98z76y54x32w1" EOF 

وللمصادقة dex-k8s:
 cat << EOF > values-auth.yml global: deployEnv: prod dexK8sAuthenticator: clusters: - name: k8s.example.com short_description: "k8s cluster" description: "Kubernetes cluster" issuer: https://dex.k8s.example.com/ k8s_master_uri: https://api.k8s.example.com client_id: dex-k8s-authenticator client_secret: generatedLongRandomPhrase redirect_uri: https://login.k8s.example.com/callback/ k8s_ca_pem: | -----BEGIN CERTIFICATE----- AAAAAAAAAAABBBBBBBBBBCCCCCC -----END CERTIFICATE----- ingress: enabled: true annotations: kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: "true" path: / hosts: - login.k8s.example.com tls: - secretName: cert-auth-login hosts: - login.k8s.example.com EOF 

تثبيت Dex و dex-k8s-Authenticator:

 helm install -n dex --namespace kube-system --values values-dex.yml charts/dex helm install -n dex-auth --namespace kube-system --values values-auth.yml charts/dex-k8s-authenticator 

دعونا نتحقق من قابلية الصيانة للخدمات (يجب على Dex إرجاع الكود 400 ، و dex-k8s-Authenticator - الكود 200):

 curl -sI https://dex.k8s.example.com/callback | head -1 HTTP/2 400 curl -sI https://login.k8s.example.com/ | head -1 HTTP/2 200 

تكوين RBAC


نقوم بإنشاء ClusterRole للمجموعة ، في حالتنا مع وصول للقراءة فقط:

 cat << EOF | kubectl create -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cluster-read-all rules: - apiGroups: - "" - apps - autoscaling - batch - extensions - policy - rbac.authorization.k8s.io - storage.k8s.io resources: - componentstatuses - configmaps - cronjobs - daemonsets - deployments - events - endpoints - horizontalpodautoscalers - ingress - ingresses - jobs - limitranges - namespaces - nodes - pods - pods/log - pods/exec - persistentvolumes - persistentvolumeclaims - resourcequotas - replicasets - replicationcontrollers - serviceaccounts - services - statefulsets - storageclasses - clusterroles - roles verbs: - get - watch - list - nonResourceURLs: ["*"] verbs: - get - watch - list - apiGroups: [""] resources: ["pods/exec"] verbs: ["create"] EOF 

إنشاء تكوين لـ ClusterRoleBinding:

 cat <<EOF | kubectl create -f - apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: dex-cluster-auth namespace: kube-system roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-read-all subjects: kind: Group name: "super-org:team-red" EOF 

الآن نحن مستعدون للاختبار.

الاختبارات


نذهب إلى صفحة تسجيل الدخول ( https://login.k8s.example.com ) وتسجيل الدخول باستخدام حساب GitHub:

الصورة
صفحة تسجيل الدخول

الصورة
تم إعادة توجيه صفحة تسجيل الدخول إلى جيثب

الصورة
اتبع التعليمات التي تم إنشاؤها للوصول

بعد النسخ واللصق من صفحة الويب ، يمكننا استخدام kubectl لإدارة موارد نظامنا:

 kubectl get po NAME READY STATUS RESTARTS AGE mypod 1/1 Running 0 3d kubectl delete po mypod Error from server (Forbidden): pods "mypod" is forbidden: User "amet@example.com" cannot delete pods in the namespace "default" 

ويعمل هذا الأمر ، حيث يمكن لجميع مستخدمي GitHub في مؤسستنا الاطلاع على الموارد وإدخال البرامج ، لكن ليس لديهم الحق في تغييرها.

Source: https://habr.com/ru/post/ar436238/


All Articles