Π’Π°Π·ΠΈ ΡΡΠ°ΡΠΈΡ Π΅ Π½Π°ΠΏΠΈΡΠ°Π½Π°, Π·Π° Π΄Π° ΡΠ°Π·ΡΠΈΡΠΈ Π²Π΅ΡΠ΅
Π ΡΠ°Π·ΠΈ ΡΡΠ°ΡΠΈΡ ΡΠ΅ Π²ΠΈ ΠΊΠ°ΠΆΠ° ΠΊΠ°ΠΊ Π΄Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΡΠ΅ ΠΈ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°ΡΠ΅:
- ΠΊΠ»ΡΡΠΎΠ΄ΡΡΠΆΠ°ΡΠ΅Π» Π΅ ΠΏΡΠΎΠ΅ΠΊΡ Ρ ΠΎΡΠ²ΠΎΡΠ΅Π½ ΠΊΠΎΠ΄. ΠΠΎΠ΅ΡΠΎ ΠΎΡΠΈΠ³ΡΡΡΠ²Π° Π΅Π΄ΠΈΠ½Π½Π° Π²Ρ ΠΎΠ΄Π½Π° ΡΠΎΡΠΊΠ° Π·Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. Π Π°Π±ΠΎΡΠΈ Ρ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΈ, Π²ΠΊΠ»ΡΡΠΈΡΠ΅Π»Π½ΠΎ LDAP ΠΈ OpenID, ΠΊΠΎΠΈΡΠΎ Π½ΠΈ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΡΠ²Π°Ρ.
- ΠΊΠ»ΡΡΠΎΠ΄ΡΡΠΆΠ°ΡΠ΅Π» Π²ΡΠ°ΡΠ°Ρ - ΠΎΠ±ΡΠ°ΡΠ½ΠΎ ΠΏΡΠΎΠΊΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΠ΅ΡΠΎ Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π΄Π° ΠΈΠ½ΡΠ΅Π³ΡΠΈΡΠ°ΡΠ΅ ΠΎΡΠΎΡΠΈΠ·Π°ΡΠΈΡ ΡΡΠ΅Π· Keycloak.
- ΡΡΠ΅ΠΊ - ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΠ΅ΡΠΎ Π³Π΅Π½Π΅ΡΠΈΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Π·Π° kubectl, Ρ ΠΊΠΎΡΡΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π²Π»Π΅Π·Π΅ΡΠ΅ ΠΈ Π΄Π° ΡΠ΅ ΡΠ²ΡΡΠΆΠ΅ΡΠ΅ Ρ Kubernetes API ΡΡΠ΅Π· OpenID.
ΠΠ°ΠΊ ΡΠ°Π±ΠΎΡΡΡ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΡΡΠ° Π² Kubernetes.
ΠΠΎΠΆΠ΅ΠΌ Π΄Π° ΡΠΏΡΠ°Π²Π»ΡΠ²Π°ΠΌΠ΅ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈ / Π³ΡΡΠΏΠΎΠ²ΠΈ ΠΏΡΠ°Π²Π° Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° RBAC, Π²Π΅ΡΠ΅ ΡΠ° ΡΡΠ·Π΄Π°Π΄Π΅Π½ΠΈ ΠΊΡΠΏ ΡΡΠ°ΡΠΈΠΈ Π·Π° ΡΠΎΠ²Π°, Π½ΡΠΌΠ° Π΄Π° ΡΠ΅ ΡΠΏΠΈΡΠ°ΠΌ Π½Π° ΡΠΎΠ²Π° ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎ. ΠΡΠΎΠ±Π»Π΅ΠΌΡΡ Π΅, ΡΠ΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ RBAC, Π·Π° Π΄Π° ΠΎΠ³ΡΠ°Π½ΠΈΡΠΈΡΠ΅ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈΡΠ΅ ΠΏΡΠ°Π²Π°, Π½ΠΎ Kubernetes Π½Π΅ Π·Π½Π°Π΅ Π½ΠΈΡΠΎ Π·Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈΡΠ΅. ΠΠΊΠ°Π·Π²Π° ΡΠ΅, ΡΠ΅ ΡΠ΅ Π½ΡΠΆΠ΄Π°Π΅ΠΌ ΠΎΡ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΡΠΌ Π·Π° Π΄ΠΎΡΡΠ°Π²ΠΊΠ° Π½Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈΡΠ΅ Π² Kubernetes. ΠΠ° Π΄Π° Π½Π°ΠΏΡΠ°Π²ΠΈΠΌ ΡΠΎΠ²Π°, ΡΠ΅ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π΄ΠΎΡΡΠ°Π²ΡΠΈΠΊ ΠΊΡΠΌ Kuberntes OpenID, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΠΊΠ°ΠΆΠ΅, ΡΠ΅ ΡΠ°ΠΊΡΠ² ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π» Π½Π°ΠΈΡΡΠΈΠ½Π° ΡΡΡΠ΅ΡΡΠ²ΡΠ²Π° ΠΈ ΡΠ°ΠΌΠΈΡΡ Kubernetes ΡΠ΅ ΠΌΡ Π΄Π°Π΄Π΅ ΠΏΡΠ°Π²Π°ΡΠ°.
ΠΠ±ΡΡΠ΅Π½ΠΈΠ΅
- Π©Π΅ Π²ΠΈ ΡΡΡΠ±Π²Π° Kubernetes ΠΊΠ»ΡΡΡΠ΅Ρ ΠΈΠ»ΠΈ minikube
- Active Directory
- ΠΠΎΠΌΠ΅ΠΉΠ½ΠΈ:
keycloak.example.org
kubernetes-dashboard.example.org
ΠΏΡΠΎΡ ΠΎΠ΄.example.org - Π‘Π΅ΡΡΠΈΡΠΈΠΊΠ°Ρ Π·Π° Π΄ΠΎΠΌΠ΅ΠΉΠ½ΠΈ ΠΈΠ»ΠΈ ΡΠ°ΠΌΠΎΠΏΠΎΠ΄ΠΏΠΈΡΠ°Π½ ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°Ρ
ΠΡΠΌΠ° Π΄Π° ΡΠ΅ ΡΠΏΠΈΡΠ°ΠΌ Π½Π° ΡΠΎΠ²Π° ΠΊΠ°ΠΊ Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΡΠ΅ ΡΠ°ΠΌΠΎΠΏΠΎΠ΄ΠΏΠΈΡΠ°Π½ ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°Ρ, ΡΡΡΠ±Π²Π° Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΡΠ΅ 2 ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°ΡΠ°, ΡΠΎΠ²Π° Π΅ ΠΎΡΠ½ΠΎΠ²Π½ΠΈΡΡ (ΡΠ΅ΡΡΠΈΡΠΈΡΠΈΡΠ°Ρ ΠΎΡΠ³Π°Π½) ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ Ρ Π·Π°ΠΌΠ΅ΡΡΠ²Π°ΡΠΈ ΡΠΈΠΌΠ²ΠΎΠ»ΠΈ Π·Π° Π΄ΠΎΠΌΠ΅ΠΉΠ½Π° *.example.org
Π‘Π»Π΅Π΄ ΠΊΠ°ΡΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ / ΠΈΠ·Π΄Π°Π΄Π΅ΡΠ΅ ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°ΡΠΈ, ΠΊΠ»ΠΈΠ΅Π½ΡΡΡ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ Π΄ΠΎΠ±Π°Π²Π΅Π½ ΠΊΡΠΌ Kubernetes, Π·Π° ΡΠΎΠ²Π° Π½ΠΈΠ΅ ΡΡΠ·Π΄Π°Π²Π°ΠΌΠ΅ ΡΠ°ΠΉΠ½Π° Π·Π° Π½Π΅Π³ΠΎ:
kubectl create secret tls tls-keycloak --cert=example.org.crt --key=example.org.pem
Π‘Π»Π΅Π΄ ΡΠΎΠ²Π° ΡΠ΅ Π³ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Π·Π° Π½Π°ΡΠΈΡ Ingress ΠΊΠΎΠ½ΡΡΠΎΠ»Π΅Ρ.
ΠΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅ Π½Π° Keycloak
Π Π΅ΡΠΈΡ , ΡΠ΅ Π½Π°ΠΉ-Π»Π΅ΡΠ½ΠΎ Π΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ Π³ΠΎΡΠΎΠ²ΠΈ ΡΠ΅ΡΠ΅Π½ΠΈΡ Π·Π° ΡΠΎΠ²Π°, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ helm charts.
ΠΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΉΡΠ΅ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ΡΠΎ ΠΈ Π³ΠΎ Π°ΠΊΡΡΠ°Π»ΠΈΠ·ΠΈΡΠ°ΠΉΡΠ΅:
helm repo add codecentric https://codecentric.github.io/helm-charts
helm repo update
Π‘ΡΠ·Π΄Π°ΠΉΡΠ΅ ΡΠ°ΠΉΠ» keycloak.yml ΡΡΡ ΡΠ»Π΅Π΄Π½ΠΎΡΠΎ ΡΡΠ΄ΡΡΠΆΠ°Π½ΠΈΠ΅:
keycloak.yml
keycloak:
# ΠΠΌΡ Π°Π΄ΠΌΠΈΠ½ΠΈΡΡΡΠ°ΡΠΎΡΠ°
username: "test_admin"
# ΠΠ°ΡΠΎΠ»Ρ Π°Π΄ΠΌΠΈΠ½ΠΈΡΡΡΠ°ΡΠΎΡ
password: "admin"
# ΠΡΠΈ ΡΠ»Π°Π³ΠΈ Π½ΡΠΆΠ½Ρ ΡΡΠΎ Π±Ρ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡΡ Π·Π°Π³ΡΡΠΆΠ°ΡΡ Π² Keycloak ΡΠΊΡΠΈΠΏΡΡ ΠΏΡΡΠΌΠΎ ΡΠ΅ΡΠ΅Π· web ΠΌΠΎΡΠ΄Ρ. ΠΡΠΎ Π½Π°ΠΌ
ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡΡ ΡΡΠΎ Π±Ρ ΠΏΠΎΡΠΈΠ½ΠΈΡΡ ΠΎΠ΄ΠΈΠ½ Π±Π°Π³, ΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌ Π½ΠΈΠΆΠ΅.
extraArgs: "-Dkeycloak.profile.feature.script=enabled -Dkeycloak.profile.feature.upload_scripts=enabled"
# ΠΠΊΠ»ΡΡΠ°Π΅ΠΌ ingress, ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ ΠΈΠΌΡ Ρ
ΠΎΡΡΠ° ΠΈ ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°Ρ ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΠΎΡ
ΡΠ°Π½ΠΈΠ»ΠΈ Π² secrets
ingress:
enabled: true
path: /
annotations:
kubernetes.io/ingress.class: nginx
ingress.kubernetes.io/affinity: cookie
hosts:
- keycloak.example.org
tls:
- hosts:
- keycloak.example.org
secretName: tls-keycloak
# Keycloak Π΄Π»Ρ ΡΠ²ΠΎΠ΅ΠΉ ΡΠ°Π±ΠΎΡΡ ΡΡΠ΅Π±ΡΠ΅Ρ Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ
, Π² ΡΠ΅ΡΡΠΎΠ²ΡΡ
ΡΠ΅Π»ΡΡ
Ρ ΡΠ°Π·Π²ΠΎΡΠ°ΡΠΈΠ²Π°Ρ Postgresql ΠΏΡΡΠΌΠΎ Π² Kuberntes, Π² ΠΏΡΠΎΠ΄Π°ΠΊΡΠ΅Π½Π΅ ΡΠ°ΠΊ Π»ΡΡΡΠ΅ Π½Π΅ Π΄Π΅Π»Π°ΡΡ!
persistence:
deployPostgres: true
dbVendor: postgres
postgresql:
postgresUser: keycloak
postgresPassword: ""
postgresDatabase: keycloak
persistence:
enabled: true
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π½Π° ΡΠ΅Π΄Π΅ΡΠ°ΡΠΈΡΡΠ°
Π‘Π»Π΅Π΄ ΡΠΎΠ²Π° ΠΎΡΠΈΠ΄Π΅ΡΠ΅ Π½Π° ΡΠ΅Π± ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°
ΠΠ»ΠΈΠΊΠ½Π΅ΡΠ΅ Π² Π»Π΅Π²ΠΈΡ ΡΠ³ΡΠ» ΠΠΎΠ±Π°Π²Π΅ΡΠ΅ ΠΎΠ±Π»Π°ΡΡ
ΠΊΠ»ΡΡ
Π‘ΡΠΎΠΉΠ½ΠΎΡΡ
ΠΠΌΠ΅
ΠΊΡΠ±Π΅ΡΠ½Π΅ΡΠΈ
ΠΠΌΠ΅ Π·Π° ΠΏΠΎΠΊΠ°Π·Π²Π°Π½Π΅
Kubernetes
ΠΠ΅Π°ΠΊΡΠΈΠ²ΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°ΡΠ° Π½Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈΡ ΠΈΠΌΠ΅ΠΉΠ»:
ΠΠ»ΠΈΠ΅Π½ΡΡΠΊΠΈ ΠΎΠ±Ρ
Π²Π°Ρ β> ΠΠΌΠ΅ΠΉΠ» β> ΠΠ°ΡΡΠΎΠ³ΡΠ°ΡΠΈ β> ΠΡΠΎΠ²Π΅ΡΠ΅Π½ ΠΈΠΌΠ΅ΠΉΠ» (ΠΠ·ΡΡΠΈΠ²Π°Π½Π΅)
ΠΠ°ΡΡΡΠΎΠΈΡ ΠΌΠ΅ ΡΠ΅Π΄Π΅ΡΠ°ΡΠΈΡ Π·Π° ΠΈΠΌΠΏΠΎΡΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈ ΠΎΡ ActiveDirectory, ΡΠ΅ ΠΎΡΡΠ°Π²Ρ Π΅ΠΊΡΠ°Π½Π½ΠΈ ΡΠ½ΠΈΠΌΠΊΠΈ ΠΏΠΎ-Π΄ΠΎΠ»Ρ, ΠΌΠΈΡΠ»Ρ, ΡΠ΅ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΏΠΎ-ΡΡΠ½ΠΎ.
ΠΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠ° ΡΠ΅Π΄Π΅ΡΠ°ΡΠΈΡ β> ΠΠΎΠ±Π°Π²ΡΠ½Π΅ Π½Π° Π΄ΠΎΡΡΠ°Π²ΡΠΈΠΊβ¦ β> ldap
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π½Π° ΡΠ΅Π΄Π΅ΡΠ°ΡΠΈΡΡΠ°
ΠΠΊΠΎ Π²ΡΠΈΡΠΊΠΎ Π΅ Π½Π°ΡΠ΅Π΄, ΡΠ»Π΅Π΄ Π½Π°ΡΠΈΡΠΊΠ°Π½Π΅ Π½Π° Π±ΡΡΠΎΠ½Π° Π‘ΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·ΠΈΡΠ°ΠΉΡΠ΅ Π²ΡΠΈΡΠΊΠΈ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈ ΡΠ΅ Π²ΠΈΠ΄ΠΈΡΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π·Π° ΡΡΠΏΠ΅ΡΠ½ΠΎΡΠΎ ΠΈΠΌΠΏΠΎΡΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈ.
Π‘Π»Π΅Π΄ ΡΠΎΠ²Π° ΡΡΡΠ±Π²Π° Π΄Π° ΠΊΠ°ΡΡΠΎΠ³ΡΠ°ΡΠΈΡΠ°ΠΌΠ΅ Π½Π°ΡΠΈΡΠ΅ Π³ΡΡΠΏΠΈ
ΠΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠ° ΡΠ΅Π΄Π΅ΡΠ°ΡΠΈΡ --> ldap_localhost --> Mappers --> Create
Π‘ΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° ΠΊΠ°ΡΡΠΎΠ³ΡΠ°Ρ
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π½Π° ΠΊΠ»ΠΈΠ΅Π½ΡΠ°
ΠΠ΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΅ Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΡΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ, ΠΏΠΎ ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠ΅ Π½Π° Keycloak, ΡΠΎΠ²Π° Π΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΠ΅ΡΠΎ ΡΠ΅ Π±ΡΠ΄Π΅ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΎ ΠΎΡ Π½Π΅Π³ΠΎ. Π©Π΅ ΠΏΠΎΠ΄ΡΠ΅ΡΡΠ°Ρ Π²Π°ΠΆΠ½ΠΈΡΠ΅ ΡΠΎΡΠΊΠΈ Π² Π΅ΠΊΡΠ°Π½Π½Π°ΡΠ° ΡΠ½ΠΈΠΌΠΊΠ° Π² ΡΠ΅ΡΠ²Π΅Π½ΠΎ.
ΠΠ»ΠΈΠ΅Π½ΡΠΈ β> Π‘ΡΠ·Π΄Π°Π²Π°Π½Π΅
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π½Π° ΠΊΠ»ΠΈΠ΅Π½ΡΠ°
ΠΠ΅ΠΊΠ° ΡΡΠ·Π΄Π°Π΄Π΅ΠΌ ΠΎΠ±Ρ
Π²Π°Ρ Π·Π° Π³ΡΡΠΏΠΈ:
ΠΠ»ΠΈΠ΅Π½ΡΡΠΊΠΈ ΠΎΠ±Ρ Π²Π°ΡΠΈ β> Π‘ΡΠ·Π΄Π°Π²Π°Π½Π΅
Π‘ΡΠ·Π΄Π°ΠΉΡΠ΅ ΠΎΠ±Ρ
Π²Π°Ρ
Π Π½Π°ΡΡΡΠΎΠΉΡΠ΅ ΠΊΠ°ΡΡΠΎΠ³ΡΠ°Ρ Π·Π° ΡΡΡ
:
ΠΠ»ΠΈΠ΅Π½ΡΡΠΊΠΈ ΠΎΠ±Ρ Π²Π°Ρ β> Π³ΡΡΠΏΠΈ β> ΠΠ°ΡΡΠΎΠ³ΡΠ°ΡΠΈ β> Π‘ΡΠ·Π΄Π°Π²Π°Π½Π΅
ΠΠ°ΡΡΠΎΠ³ΡΠ°Ρ
ΠΠΎΠ±Π°Π²Π΅ΡΠ΅ ΠΊΠ°ΡΡΠΎΠ³ΡΠ°ΡΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° Π½Π°ΡΠΈΡΠ΅ Π³ΡΡΠΏΠΈ ΠΊΡΠΌ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΈΡΠ΅ ΠΎΠ±Ρ
Π²Π°ΡΠΈ ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅:
ΠΠ»ΠΈΠ΅Π½ΡΠΈ β> kubernetes β> ΠΠ»ΠΈΠ΅Π½ΡΡΠΊΠΈ ΠΎΠ±Ρ
Π²Π°ΡΠΈ β> ΠΠ»ΠΈΠ΅Π½ΡΡΠΊΠΈ ΠΎΠ±Ρ
Π²Π°ΡΠΈ ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅
ΠΠ·Π±Π΅ΡΠ΅ΡΠ΅ Π³ΡΡΠΏΠΈ Π² ΠΠ°Π»ΠΈΡΠ½ΠΈ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΈ ΠΎΠ±Ρ
Π²Π°ΡΠΈΠ½Π°ΡΠΈΡΠ½Π΅ΡΠ΅ ΠΠΎΠ±Π°Π²ΡΠ½Π΅ Π½Π° ΠΈΠ·Π±ΡΠ°Π½ΠΈ
ΠΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅ ΡΠ°ΠΉΠ½Π°ΡΠ° (ΠΈ Ρ Π·Π°ΠΏΠΈΡΠ²Π°ΠΌΠ΅ Π² Π½ΠΈΡΠΊΠ°ΡΠ°), ΠΊΠΎΡΡΠΎ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Π·Π° ΠΎΡΠΎΡΠΈΠ·Π°ΡΠΈΡ Π² Keycloak:
ΠΠ»ΠΈΠ΅Π½ΡΠΈ β> kubernetes β> ΠΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΎΠ½Π½ΠΈ Π΄Π°Π½Π½ΠΈ β> Π’Π°ΠΉΠ½ΠΎ
Π’ΠΎΠ²Π° Π·Π°Π²ΡΡΡΠ²Π° Π½Π°ΡΡΡΠΎΠΉΠΊΠ°ΡΠ°, Π½ΠΎ ΠΈΠΌΠ°Ρ
Π³ΡΠ΅ΡΠΊΠ°, ΠΊΠΎΠ³Π°ΡΠΎ ΡΠ»Π΅Π΄ ΡΡΠΏΠ΅ΡΠ½ΠΎ ΠΎΡΠΎΡΠΈΠ·ΠΈΡΠ°Π½Π΅ ΠΏΠΎΠ»ΡΡΠΈΡ
Π³ΡΠ΅ΡΠΊΠ° 403.
ΠΠΎΠΏΡΠ°Π²ΠΊΠ°:
ΠΠ»ΠΈΠ΅Π½ΡΡΠΊΠΈ ΠΎΠ±Ρ Π²Π°Ρ β> ΡΠΎΠ»ΠΈ β> ΠΠ°ΡΡΠΎΠ³ΡΠ°ΡΠΈ β> Π‘ΡΠ·Π΄Π°Π²Π°Π½Π΅
ΠΠ°ΡΡΠΎΠ³ΡΠ°Ρ
ΠΠΎΠ΄ Π½Π° ΡΠΊΡΠΈΠΏΡΠ°
// add current client-id to token audience
token.addAudience(token.getIssuedFor());
// return token issuer as dummy result assigned to iss again
token.getIssuer();
ΠΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°Π½Π΅ Π½Π° Kubernetes
Π’ΡΡΠ±Π²Π° Π΄Π° ΠΏΠΎΡΠΎΡΠΈΠΌ ΠΊΡΠ΄Π΅ ΡΠ΅ Π½Π°ΠΌΠΈΡΠ° ΠΎΡΠ½ΠΎΠ²Π½ΠΈΡΡ Π½ΠΈ ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°Ρ ΠΎΡ ΡΠ°ΠΉΡΠ° ΠΈ ΠΊΡΠ΄Π΅ ΡΠ΅ Π½Π°ΠΌΠΈΡΠ° Π΄ΠΎΡΡΠ°Π²ΡΠΈΠΊΡΡ Π½Π° OIDC.
ΠΠ° Π΄Π° Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΡΠΎΠ²Π°, ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠ°ΠΉΡΠ΅ ΡΠ°ΠΉΠ»Π° /etc/kubernetes/manifests/kube-apiserver.yaml
kube-apiserver.yaml
...
spec:
containers:
- command:
- kube-apiserver
...
- --oidc-ca-file=/var/lib/minikube/certs/My_Root.crt
- --oidc-client-id=kubernetes
- --oidc-groups-claim=groups
- --oidc-issuer-url=https://keycloak.example.org/auth/realms/kubernetes
- --oidc-username-claim=email
...
ΠΠΊΡΡΠ°Π»ΠΈΠ·ΠΈΡΠ°ΠΉΡΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΡΠ° Π½Π° kubeadm Π² ΠΊΠ»ΡΡΡΠ΅ΡΠ°:
kubeadmconfig
kubectl edit -n kube-system configmaps kubeadm-config
...
data:
ClusterConfiguration: |
apiServer:
extraArgs:
oidc-ca-file: /var/lib/minikube/certs/My_Root.crt
oidc-client-id: kubernetes
oidc-groups-claim: groups
oidc-issuer-url: https://keycloak.example.org/auth/realms/kubernetes
oidc-username-claim: email
...
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π½Π° ΠΏΡΠΎΠΊΡΠΈ Π·Π° ΡΠ΄ΠΎΡΡΠΎΠ²Π΅ΡΡΠ²Π°Π½Π΅
ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ keycloak gatekeeper, Π·Π° Π΄Π° Π·Π°ΡΠΈΡΠΈΡΠ΅ Π²Π°ΡΠ΅ΡΠΎ ΡΠ΅Π± ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅. Π Π΄ΠΎΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΡΠΌ ΡΠ°ΠΊΡΠ°, ΡΠ΅ ΡΠΎΠ·ΠΈ ΠΎΠ±ΡΠ°ΡΠ΅Π½ ΠΏΡΠΎΠΊΡΠΈ ΡΠ΅ ΡΠΏΡΠ»Π½ΠΎΠΌΠΎΡΠΈ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ, ΠΏΡΠ΅Π΄ΠΈ Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ΅ ΡΡΡΠ°Π½ΠΈΡΠ°ΡΠ°, ΡΠΎΠΉ ΡΡΡΠΎ ΡΠ΅ ΠΏΡΠ΅Π΄Π°Π΄Π΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π·Π° Π²Π°Ρ Π½Π° ΠΊΡΠ°ΠΉΠ½ΠΎΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² Π·Π°Π³Π»Π°Π²ΠΊΠΈΡΠ΅. ΠΠΎ ΡΠΎΠ·ΠΈ Π½Π°ΡΠΈΠ½, Π°ΠΊΠΎ Π²Π°ΡΠ΅ΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ° OpenID, ΡΠΎΠ³Π°Π²Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΡ Π΅ Π½Π΅Π·Π°Π±Π°Π²Π½ΠΎ ΡΠΏΡΠ»Π½ΠΎΠΌΠΎΡΠ΅Π½. ΠΠΎΠΌΠΈΡΠ»Π΅ΡΠ΅ Π·Π° ΠΏΡΠΈΠΌΠ΅ΡΠ° Π½Π° Kubernetes Dashboard
ΠΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅ Π½Π° Kubernetes Dashboard
helm install stable/kubernetes-dashboard --name dashboard -f values_dashboard.yaml
values_dashboard.yaml
enableInsecureLogin: true
service:
externalPort: 80
rbac:
clusterAdminRole: true
create: true
serviceAccount:
create: true
name: 'dashboard-test'
ΠΠ°Π΄Π°Π²Π°Π½Π΅ Π½Π° ΠΏΡΠ°Π²Π° Π·Π° Π΄ΠΎΡΡΡΠΏ:
ΠΠ΅ΠΊΠ° ΡΡΠ·Π΄Π°Π΄Π΅ΠΌ ClusterRoleBinding, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ Π΄Π°Π΄Π΅ Π°Π΄ΠΌΠΈΠ½ΠΈΡΡΡΠ°ΡΠΎΡΡΠΊΠΈ ΠΏΡΠ°Π²Π° Π½Π° ΠΊΠ»ΡΡΡΠ΅Ρ (ΡΡΠ°Π½Π΄Π°ΡΡΠ΅Π½ ClusterRole cluster-admin) Π·Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈΡΠ΅ Π² Π³ΡΡΠΏΠ°ΡΠ° DataOPS.
kubectl apply -f rbac.yaml
rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dataops_group
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: DataOPS
ΠΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΉΡΠ΅ keycloak gatekeeper:
helm repo add gabibbo97 https://gabibbo97.github.io/charts/
helm repo update
helm install gabibbo97/keycloak-gatekeeper --version 2.1.0 --name keycloak-gatekeeper -f values_proxy.yaml
values_proxy.yaml
# ΠΠΊΠ»ΡΡΠ°Π΅ΠΌ ingress
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
path: /
hosts:
- kubernetes-dashboard.example.org
tls:
- secretName: tls-keycloak
hosts:
- kubernetes-dashboard.example.org
# ΠΠΎΠ²ΠΎΡΠΈΠΌ Π³Π΄Π΅ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ Π°Π²ΡΠΎΡΠΈΠ·ΠΎΠ²ΡΠ²Π°ΡΡΡΡ Ρ OIDC ΠΏΡΠΎΠ²Π°ΠΉΠ΄Π΅ΡΠ°
discoveryURL: "https://keycloak.example.org/auth/realms/kubernetes"
# ΠΠΌΡ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΠΌΡ ΡΠΎΠ·Π΄Π°Π»ΠΈ Π² Keycloak
ClientID: "kubernetes"
# Secret ΠΊΠΎΡΠΎΡΡΠΉ Ρ ΠΏΡΠΎΡΠΈΠ» Π·Π°ΠΏΠΈΡΠ°ΡΡ
ClientSecret: "c6ec03b8-d0b8-4cb6-97a0-03becba1d727"
# ΠΡΠ΄Π° ΠΏΠ΅ΡΠ΅Π½Π°ΠΏΡΠ°Π²ΠΈΡΡ Π² ΡΠ»ΡΡΠ°Π΅ ΡΡΠΏΠ΅ΡΠ½ΠΎΠΉ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΈ. Π€ΠΎΡΠΌΠ°Ρ <SCHEMA>://<SERVICE_NAME>.><NAMESAPCE>.<CLUSTER_NAME>
upstreamURL: "http://dashboard-kubernetes-dashboard.default.svc.cluster.local"
# ΠΡΠΎΠΏΡΡΠΊΠ°Π΅ΠΌ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°ΡΠ°, Π΅ΡΠ»ΠΈ Ρ Π½Π°Ρ ΡΠ°ΠΌΠΎΠΏΠΎΠ΄ΠΏΠΈΡΠ°Π½Π½ΡΠΉ
skipOpenidProviderTlsVerify: true
# ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° ΠΏΡΠ°Π² Π΄ΠΎΡΡΡΠΏΠ°, ΠΏΡΡΠΊΠ°Π΅ΠΌ Π½Π° Π²ΡΠ΅ path Π΅ΡΠ»ΠΈ ΠΌΡ Π² Π³ΡΡΠΏΠΏΠ΅ DataOPS
rules:
- "uri=/*|groups=DataOPS"
Π‘Π»Π΅Π΄ ΡΠΎΠ²Π°, ΠΊΠΎΠ³Π°ΡΠΎ ΡΠ΅ ΠΎΠΏΠΈΡΠ°ΡΠ΅ Π΄Π° ΠΎΡΠΈΠ΄Π΅ΡΠ΅ Π½Π°
ΠΌΠΎΠ½ΡΠ°ΠΆ Π½Π° ΠΏΡΡΠ΅ΠΊΠ°
ΠΠ° ΡΠ΄ΠΎΠ±ΡΡΠ²ΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡΠ΅ ΠΏΡΠΎΡ ΠΎΠ΄, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ Π³Π΅Π½Π΅ΡΠΈΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π΅Π½ ΡΠ°ΠΉΠ» Π·Π° kubectl, Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΠΊΠΎΠΉΡΠΎ ΡΠ΅ Π²Π»Π΅Π·Π΅ΠΌ Π² Kubernetes ΠΏΠΎΠ΄ Π½Π°ΡΠΈΡ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π».
helm install --name gangway stable/gangway -f values_gangway.yaml
values_gangway.yaml
gangway:
# ΠΡΠΎΠΈΠ·Π²ΠΎΠ»ΡΠ½ΠΎΠ΅ ΠΈΠΌΡ ΠΊΠ»Π°ΡΡΠ΅ΡΠ°
clusterName: "my-k8s"
# ΠΠ΄Π΅ Ρ Π½Π°Ρ OIDC ΠΏΡΠΎΠ²Π°ΠΉΠ΄Π΅Ρ
authorizeURL: "https://keycloak.example.org/auth/realms/kubernetes/protocol/openid-connect/auth"
tokenURL: "https://keycloak.example.org/auth/realms/kubernetes/protocol/openid-connect/token"
audience: "https://keycloak.example.org/auth/realms/kubernetes/protocol/openid-connect/userinfo"
# Π’Π΅ΠΎΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈ ΡΡΠ΄Π° ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ groups ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ Π·Π°ΠΌΠ°ΠΏΠΈΠ»ΠΈ
scopes: ["openid", "profile", "email", "offline_access"]
redirectURL: "https://gangway.example.org/callback"
# ΠΠΌΡ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°
clientID: "kubernetes"
# Π‘Π΅ΠΊΡΠ΅Ρ
clientSecret: "c6ec03b8-d0b8-4cb6-97a0-03becba1d727"
# ΠΡΠ»ΠΈ ΠΎΡΡΠ°Π²ΠΈΡΡ Π΄Π΅ΡΠΎΠ»ΡΠ½ΠΎΠ΅ Π·Π½Π°ΡΠ½ΠΈΠ΅, ΡΠΎ Π·Π° ΠΈΠΌΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π±ΡΠ΄Π΅Ρ Π±ΡΠ°ΡΡΡ <b>Frist name</b> <b>Second name</b>, Π° ΠΏΡΠΈ "sub" Π΅Π³ΠΎ Π»ΠΎΠ³ΠΈΠ½
usernameClaim: "sub"
# ΠΠΎΠΌΠ΅Π½Π½ΠΎΠ΅ ΠΈΠΌΡ ΠΈΠ»ΠΈ IP Π°Π΄ΡΠ΅ΡΡ API ΡΠ΅ΡΠ²Π΅ΡΠ°
apiServerURL: "https://192.168.99.111:8443"
# ΠΠΊΠ»ΡΡΠ°Π΅ΠΌ Ingress
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-buffer-size: "64k"
path: /
hosts:
- gangway.example.org
tls:
- secretName: tls-keycloak
hosts:
- gangway.example.org
# ΠΡΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΠ°ΠΌΠΎΠΏΠΎΠ΄ΠΏΠΈΡΠ°Π½Π½ΡΠΉ ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°Ρ, ΡΠΎ Π΅Π³ΠΎ(ΠΎΡΠΊΡΡΡΡΠΉ ΠΊΠΎΡΠ½Π΅Π²ΠΎΠΉ ΡΠ΅ΡΡΠΈΡΠΈΠΊΠ°Ρ) Π½Π°Π΄ΠΎ ΡΠΊΠ°Π·Π°ΡΡ.
trustedCACert: |-
-----BEGIN CERTIFICATE-----
MIIDVzCCAj+gAwIBAgIBATANBgkqhkiG9w0BAQsFADA1MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRGF0YU9QUzEUMBIGA1UEAxMLbXkgcm9vdCBrZXkwHhcNMjAwMjE0MDkxODAwWhcNMzAwMjE0MDkxODAwWjA1MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRGF0YU9QUzEUMBIGA1UEAxMLbXkgcm9vdCBrZXkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDyP749PqqIRwNSqaK6qr0Zsi03G4PTCUlgaYTPZuMrwUVPK8xX2dWWs9MPRMOdXpgr8aSTZnVfmelIlVz4D7o2vK5rfmAe9GPcK0WbwKwXyhFU0flS9sU/g46ogHFrk03SZxQAeJhMLfEmAJm8LF5HghtGDs3t4uwGsB95o+lqPLiBvxRB8ZS3jSpYpvPgXAuZWKdZUQ3UUZf0X3hGLp7uIcIwJ7i4MduOGaQEO4cePeEJy9aDAO6qV78YmHbyh9kaW+1DL/Sgq8NmTgHGV6UOnAPKHTnMKXl6KkyUz8uLBGIdVhPxrlzG1EzXresJbJenSZ+FZqm3oLqZbw54Yp5hAgMBAAGjcjBwMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHISTOU/6BQqqnOZj+1xJfxpjiG0MAsGA1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAAcwHgYJYIZIAYb4QgENBBEWD3hjYSBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAQEAj7HC8ObibwOLT4ZYmISJZwub9lcE0AZ5cWkPW39j/syhdbbqjK/6jy2D3WUEbR+s1Vson5Ov7JhN5In2yfZ/ByDvBnoj7CP8Q/ZMjTJgwN7j0rgmEb3CTZvnDPAz8Ijw3FP0cjxfoZ1Z0V2F44Ry7gtLJWr06+MztXVyto3aIz1/XbMQnXYlzc3c3B5yUQIy44Ce5aLRVsAjmXNqVRmDJ2QPNLicvrhnUJsO0zFWI+zZ2hc4Ge1RotCrjfOc9hQY63jZJ17myCZ6QCD7yzMzAob4vrgmkD4q7tpGrhPY/gDcE+lUNhC7DO3l0oPy2wsnT2TEn87eyWmDiTFG9zWDew==
-----END CERTIFICATE-----
ΠΠ·Π³Π»Π΅ΠΆΠ΄Π° ΡΠ°ΠΊΠ°. ΠΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π²ΠΈ Π½Π΅Π·Π°Π±Π°Π²Π½ΠΎ Π΄Π° ΠΈΠ·ΡΠ΅Π³Π»ΠΈΡΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΈΡ ΡΠ°ΠΉΠ» ΠΈ Π΄Π° Π³ΠΎ Π³Π΅Π½Π΅ΡΠΈΡΠ°ΡΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° Π½Π°Π±ΠΎΡ ΠΎΡ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ:
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: www.habr.com