作者:李帥
介紹
KubeSphere 多租戶是實際生產使用中非常需要的一個功能,該功能滿足不同使用者登陸 KubeSphere 平臺的需求。比如開發,運維,測試都需要登陸 KubeSphere 平臺,並且需要為不同身份的使用者配置不同的許可權。當公司內需要訪問 KubeSphere 的使用者比較多時,管理員再去手動為使用者建立賬號就不太靈活了。KubeSphere 包含一個內建的 OAuth 服務和帳戶系統,使用者通過獲取 OAuth 訪問令牌以對 API 進行身份驗證,我們可以通過接入 LDAP 或者 OIDC 來提供身份認證資訊。
多租戶方案
認證鑑權鏈路
使用
假設叢集內已經最小化安裝 KubeSphere。我們這裡使用 OIDC 身份提供者進行認證,通過 Dex 接入到 GitLab 中,使用 GitLab 中的使用者完成認證。
安裝 Dex
Dex 是一種身份認證服務,它使用 OpenID Connect 來驅動其他應用程式的身份驗證。Dex 通過 “connectors” 充當其他身份提供商的門戶。 Dex 可以將身份驗證推到 LDAP 伺服器、SAML 提供商或已建立的身份提供商(如 GitHub、Gitlab、Google 和 Active Directory等)。 客戶端編寫身份驗證邏輯以與 Dex 互動認證,然後 Dex 通過 connector 轉發到後端使用者認證方進行認證,並返回給客戶端 Oauth2 Token。與其相似的身份認證服務還有 Keycloak,auth0 等。
首先需要在 gitlab 上建立應用,在範圍裡勾選這幾個 read_user
profile
email
openid
,建立後需要記住頁面上的應用程式 id 和密碼,後面會用得到。
#新增dex的helm倉庫
root@i-tsfhx8p6:~/qke-k8s/dex# helm repo add dex https://charts.dexidp.io
"dex" has been added to your repositories
#下載dex的chart 檔案到本地
root@i-tsfhx8p6:~/qke-k8s/dex# helm pull dex/dex
root@i-tsfhx8p6:~/qke-k8s/dex# ls
dex-0.5.0.tgz
root@i-tsfhx8p6:~/qke-k8s/dex# tar xf dex-0.5.0.tgz
root@i-tsfhx8p6:~/qke-k8s/dex# ls
dex dex-0.5.0.tgz
root@i-tsfhx8p6:~/qke-k8s/dex# ls dex
Chart.yaml LICENSE README.md ci templates values.yaml
修改values.yaml
檔案
replicaCount: 1
image:
repository: dexidp/dex
pullPolicy: IfNotPresent
tag: "v2.29.0"
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
hostAliases: []
https:
# -- Enable the HTTPS endpoint.
enabled: false
grpc:
# -- Enable the gRPC endpoint.
# Read more in the [documentation](https://dexidp.io/docs/api/).
enabled: false
configSecret:
# -- Enable creating a secret from the values passed to `config`.
# If set to false, name must point to an existing secret.
create: true
# -- The name of the secret to mount as configuration in the pod.
# If not set and create is true, a name is generated using the fullname template.
# Must point to secret that contains at least a `config.yaml` key.
name: ""
config:
issuer: https://dex-qke.lishuai.fun #修改為你實際的地址
storage:
type: kubernetes
config:
inCluster: true
web:
http: 0.0.0.0:5556
telemetry:
http: 0.0.0.0:5558
expiry:
signingKeys: "6h"
idTokens: "24h"
logger:
level: debug
format: json
oauth2:
responseTypes: ["code", "token", "id_token"]
skipApprovalScreen: true
connectors:
- type: gitlab
id: gitlab
name: GitLab
config:
baseURL: https://gitlab.lishuai.fun #修改為你實際的gitlab 地址
clientID: ca14d16e376b6f6634*********57378d1267e946e9d3e758e2f0 #修改為你gitlab 應用的clientid
clientSecret: 15dcb3501becd17******1b82b05874e2ef893b7a0888fdaaa37885fd9387 #修改為你gitlab 應用的clientsecert
redirectURI: https://dex-qke.lishuai.fun/callback #修改為你實際的地址,格式為(dex issuer)/callback
groups:
- k8s-auth
- k8s-auth/dashboard
- k8s-auth/dashboard/show ##gitlab專案組,只允許dashboard專案組成員訪問
staticClients:
- id: dex-k8s-authenticator
name: dex-k8s-authenticator
secret: generatedLongRandomPhrase
redirectURIs:
- 'http://kubesphere.lishuai.fun/oauth/redirect/dex' #這個是kubesphere的回撥地址,對於dex認證,格式為kubesphere_url/oauth/redirect/dex
volumes: []
volumeMounts: []
envFrom: []
env: {}
serviceAccount:
# -- Enable service account creation.
create: true
# -- Annotations to be added to the service account.
annotations: {}
# -- The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template.
name: "dex-sa"
rbac:
create: true
podAnnotations: {}
podDisruptionBudget:
enabled: false
minAvailable:
maxUnavailable:
priorityClassName: ""
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
annotations: {}
type: ClusterIP
ports:
http:
port: 5556
nodePort:
https:
port: 5554
nodePort:
grpc:
port: 5557
nodePort:
ingress:
enabled: true
className: ""
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
cert-manager.io/cluster-issuer: tls #叢集內已經安裝了cert-manager,通過cert-manager來進行證書籤發
hosts:
- host: dex-qke.lishuai.fun
paths:
- path: /
pathType: ImplementationSpecific
tls:
- secretName: dex-tls
hosts:
- dex-qke.lishuai.fun
resources: {}
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
這裡有幾點需要注意:
- Gitlab 配置下的 groups 為專案組,需要根據實際情況填寫,此處填寫專案組的成員才會允許通過 Dex 進行身份認證
- 如果叢集內沒有安裝 cert-manager,需要手動建立證書的 secert
執行如下命令進行安裝。
root@i-tsfhx8p6:~/qke-k8s/dex# ls
dex dex-0.5.0.tgz
#在當前目錄執行
kubectl create ns dex
kubectl -n dex install dex dex
root@i-tsfhx8p6:~/qke-k8s/dex# kubectl -n dex get pod
NAME READY STATUS RESTARTS AGE
dex-d8c5cdfc-577gf 1/1 Running 0 21h
配置 KubeSphere
安裝好 Dex 後需要修改 cluster-configuration.yaml
。
apiVersion: installer.kubesphere.io/v1alpha1
kind: ClusterConfiguration
metadata:
name: ks-installer
namespace: kubesphere-system
labels:
version: v3.1.1
spec:
persistence:
storageClass: "longhorn" # If there is no default StorageClass in your cluster, you need to specify an existing StorageClass here.
authentication:
jwtSecret: ""
authenticateRateLimiterMaxTries: 10
authenticateRateLimiterDuration: 10m0s
oauthOptions:
accessTokenMaxAge: 1h
accessTokenInactivityTimeout: 30m
identityProviders:
- name: dex
type: OIDCIdentityProvider
mappingMethod: auto
provider:
clientID: 'dex-k8s-authenticator'
clientSecret: 'gener*******ongRandomPhrase'
issuer: https://dex-qke.lishuai.fun
redirectURL: http://kubesphere.lishuai.fun/oauth/redirect/dex
scopes:
- openid
- email
......
引數釋意:
authenticateRateLimiterMaxTries
:authenticateLimiterDuration
指定的期間內允許的最大連續登入失敗次數。如果使用者連續登入失敗次數達到限制,則該使用者將被封禁。authenticateRateLimiterDuration
: 作用於authenticateRateLimiterMaxTries
。loginHistoryRetentionPeriod
: 使用者登入記錄保留期限,過期條目將被自動刪除。maximumClockSkew
: 控制執行對時間敏感的操作(例如驗證使用者令牌的過期時間)時允許的最大時鐘偏移,預設值為 10 秒。multipleLogin
: 允許多個使用者同時從不同位置登入,預設值為true
。jwtSecret
: 簽發使用者令牌的金鑰,最小長度為 32 個字元。多叢集環境需要注意的事項。
oauthOptions
: OAuth 設定
accessTokenMaxAge
: 訪問令牌有效期。對於多叢集環境中的成員叢集,預設值為0h
,這意味著訪問令牌永不過期。對於其他叢集,預設值為2h
。accessTokenInactivityTimeout
: 令牌空閒超時時間。該值表示令牌過期後,重新整理使用者令牌最大的間隔時間,如果不在此時間視窗內重新整理使用者身份令牌,使用者將需要重新登入以獲得訪問權。identityProviders: 身份提供者設定
name
: 身份提供者的名稱。type
: 身份提供者的型別。mappingMethod
: 帳戶對映方式. 值可以是auto
或者lookup
。- 預設值為
auto
, 通過第三方帳戶登入時會自動建立關聯帳戶。 - 如果值為
lookup
, 你需要手動關聯第三方帳戶與KubeSphere帳戶。 provider
: Identity provider 配置,此部分中的欄位根據身份提供的型別而異
provider:
- clientID: OAuth2 客戶端 ID
- clientSecret: OAuth2 客戶端secert
- issuer: dex的地址
- redirectURL:重定向到 ks-console 的 URL ,注意這個地址要在dex裡也配置
修改完後執行 kubectl apply -f cluster-configuration.yaml
。
也可以通過以下命令修改認證配置:
kubectl -n kubesphere-system edit cc ks-installer
配置示例:
apiVersion: installer.kubesphere.io/v1alpha1
kind: ClusterConfiguration
metadata:
name: ks-installer
spec:
authentication:
jwtSecret: ********************************
authenticateRateLimiterMaxTries: 10
authenticateRateLimiterDuration: 10m
oauthOptions:
accessTokenInactivityTimeout: 30m
accessTokenMaxAge: 1h
identityProviders:
- mappingMethod: auto
name: github
type: GitHubIdentityProvider
provider:
...
當修改上述配置後,需要等待配置生效,可以通過以下命令檢視相關進度及日誌:
kubectl -n kubesphere-system logs -l app=ks-installer -f
重新應用後開啟登入頁面會發現登入頁面多了通過 dex 登陸
的按鈕。
點選後會自動跳轉到 Gitlab 進行認證,第一次登陸需要授權應用可以訪問,這裡要注意允許訪問的 KubeSphere 的 Gitlab使用者為 Dex 服務中定義的 Gitlab 專案組中的使用者,實際中我們可以設定特定特定的專案組,將使用者新增到專案組中來實現使用者登陸的限制。
點選 authorize
允許後,KubeSphere 會讓我們確認賬戶資訊,此時需要合理修改使用者名稱。
設定完成後,就可以進入 KubeSphere 了,此時該使用者是沒有任何訪問許可權的,還需要管理員對該使用者進行授權才能正常進行使用,希望後期 KubeSphere 可以支援在使用者登陸前可以對使用者組進行授權,或者預先通過郵箱對使用者進行收錢,避免使用者登陸後,管理員還需要手動去建立許可權。
本文由部落格一文多發平臺 OpenWrite 釋出!