多集羣k8s dashboard ldap統一登陸與受權工具

logo.png

工具由來

爲何要寫這樣的一個工具呢?這是由於我司有多個 kubernetes 集羣(8+),且都是雲託管服務沒法接觸到Apiserver配置,這就給咱們帶來一個痛點,開發、sre須要登陸k8s dashbaord且不一樣部門和角色間須要不一樣的受權,原先都是經過 sa token 進行登陸dashboard,但隨着k8s集羣的增加,每增長一個集羣,就須要告知使用方對應dashboard訪問地址以及對應的token,這無論是提供方仍是使用方都讓人感受很是的痛苦。那是否有一款工具能提供統一地址統一登陸多集羣dashboard的方案呢?通過一番搜索後,發現並無,市面上大多數是單集羣集成 LDAP 的方案,主要是以 DEX 爲主,但光單集羣的統一登陸受權方案就讓人感受很是的困難。難道就沒有簡單方便的工具供咱們使用嗎?好吧,那我就來打造這樣一款工具吧。html

Dashboard LDAP集成方案:node

以上兩篇文檔是成LDAP的方案,我的感受還不錯,供有須要的人蔘考!git

如何打造

好吧既然沒有,那就自動動手打造一個!github

目標: 簡單使用!!!經過訪問同一地址,使用LDAP登陸且可切換不一樣集羣的dashboard,同時對應不一樣的集羣權限可單獨配置!

有了上面的目標,那如何來實現呢?golang

實現方式其實很簡單,首先寫一個登陸界面與公司的AD進行打通獲取用戶與組,而後將用戶或者組與k8s集羣中的 service account 進行關聯就實現了對應的rbac與登陸token,最後在登陸後實現一個反向代理服務便可完成。web

是否是很是的簡單!!!api

實現技術棧:golang(gin、client-go、viper、ldap) + Kubernetes Dashboardbash

如何部署

前提條件

在使用此工具前,須要有如下一些條件約束:ide

  1. 已在各k8s集羣部署 dashboard 且能被此工具訪問到
  2. 已有 ldap 且有管理權限能進行訪問操做
  3. 各集羣中有對應的 service account 可進行映射,如需對不一樣用戶和組須要有不一樣的操做權限,則對sa進行rbac受權便可,下面會詳細說明。
  4. 此工具須要操做各集羣的api,故須要獲取每一個集羣的 apiserver地址ca.crt 以及 token 進行配置,至於每一個集羣的 ca.crttoken 若是獲取,後面會進行說明

如何獲取 ca.crt 及 token

此工具須要操做每一個集羣的api來獲取對應的 sa 以及 token,故須要有對各集羣操做的權限。那如何在各集羣生成對應的 ca證書 及 token 呢?答案就是建立一個 sa 並給予必定的權限。工具

在每一個k8s集羣中執行以下yaml文件:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: mutiboard-ldap
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: mutiboard-ldap-crb
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: mutiboard-ldap-view
subjects:
- kind: ServiceAccount
  name: mutiboard-ldap
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: mutiboard-ldap-view
rules:
- apiGroups:
  - ""
  resources:
  - serviceaccounts
  - secrets
  verbs:
  - get
  - list
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - get
  - list
  - watch

此yaml文件的含義:建立一個名爲mutiboard-ldap的 sa,而且給予serviceaccountssecrets的get和list的權限。

獲取 mutiboard-ldap 的 ca.crt:

(⎈|aws-local:default)❯ echo $(kubectl get secret $(kubectl get secret | grep mutiboard-ldap | awk '{print $1}') -o go-template='{{index .data "ca.crt"}}') | base64 -d

-----BEGIN CERTIFICATE-----
MIICyDCCAbCgAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl
cm5ldGVzMB4XDTE5MDEyNTEwMTgzNFoXDTI5MDEyMjEwMTgzNFowFTETMBEGA1UE
AxMKa3ViZXJuZXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMmc
TW0stLLP+M6Pc9wpRgZufg6eQ7puBfbYgik20QlO4LFtocgNUDa0y+aSXjxheA2C
A+o9wW0IC3GHQHKgeFY8KXIJu6wM0TO+JNQy5XZAWfbsLeXU/sLhKuWET/KJzVWT
0uBE+GCADAAQIec1oQXMbQ551hU5gBFcr67NXHpa2qwEGA1mGtZ7ztmW4+IFUD74
G166z4AOgmR4YWxBs/+8NhfWudFD32xevBfSKuHRxRGG5dtffY8QnRbnrmy70HE5
yzLtBvAGfCwtHLTP2ngCAnn2Fb6IeMdIYGpI1544ZjRbzT1YIWsG1v3dlu6tvK1q
X5Pj+UTDmJuf2SW52A0CAwEAAaMjMCEwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB
/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAKE2hV0DIG8fSf4/eOi5R2sPRfBW
qTwgZDDT9dxZNhbxEInALdruwRUbKRpwaUBOGVpIlaK3/rZkAfjUwoDJ+J4fmmCX
w3ySrYFjx6tqVFqCPjDkBHh4xpMwUlvsvryRuCEQUQgjqBvj6sWm9GERF2n3VYBF
S8bjsQQAZJoE4W+OKchlEoSFlKhxAoeZx9CD3Rxnhj2og6doVoGCUqAMh4WZWX+w
pENnui6M96SysH3SkrA02RXWTGeKzK4E6Av3IG+2a2hauHorbqVfaM6HeL3hkU/B
JCWpOgN3T4Fw7E359CBQxnSHPasmZ5VBoyIk/HUU6ZlMK6Xo6JlbS7ZvVl4=
-----END CERTIFICATE-----

獲取 mutiboard-ldap 的 token:

(⎈|aws-local:default)❯ echo $(kubectl get secret $(kubectl get secret | grep mutiboard-ldap | awk '{print $1}') -o go-template='{{.data.token}}') | base64 -d

eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Im11dGlib2FyZC1sZGFwLXRva2VuLWJ3NWdmIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Im11dGlib2FyZC1sZGFwIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiMjVmZjI4MGQtYWJhMi0xMWVhLWFlOGEtMDIzOTBjMzcyNzhlIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6bXV0aWJvYXJkLWxkYXAifQ.q14hqEu2p70_YczDviR6c8McDM5vfnKPzjO9usCsC-uQUxciBbuJU_PK9j3uawppUNlrs3rAPrZIGUS7Jv14rifEXpGxIIfGR6n8-le0b-9YvMZCgs9-jhf-1r01EAnZFh6gcXfxESFguFQI0vYOsX4P2LQvZ9XTMzsqXbW3KGYao5elAjCE4e8Rg4--9e_zU8NGTEycsvUMxP-9p0SaAzn9Iak3saZtAnzJq5hkSf1t7l2_CgEsYN-3b7uGpHupK_zdgAeOflj9ze4Cz2YScv5eixwVXJ-RcI4lgSFCgt5yzSbnIuHgxRZyN3NcYLrSBYKftezZysWm3jELgLPogQ

至此,各集羣的 ca.crttoken 都已獲取,下面會告知如何進行配置使用這些 ca.crttoken

SA RBAC列子

apiVersion: v1
kind: ServiceAccount
metadata:
  name: ops-admin
  namespace: default
  labels:
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: ops-role
rules:
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "list", "watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: ops-listnamespace
roleRef: #引用的角色
  kind: ClusterRole
  name: ops-role
  apiGroup: rbac.authorization.k8s.io
subjects: #主體
- kind: ServiceAccount
  name: ops-admin
  namespace: default
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: ops-ci-admin
  namespace: ops-ci
roleRef: #引用的角色
  kind: ClusterRole
  name: admin
  apiGroup: rbac.authorization.k8s.io
subjects: #主體
- kind: ServiceAccount
  name: ops-admin
  namespace: default
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: ops-qa-admin
  namespace: ops-qa
roleRef: #引用的角色
  kind: ClusterRole
  name: admin
  apiGroup: rbac.authorization.k8s.io
subjects: #主體
- kind: ServiceAccount
  name: ops-admin
  namespace: default

這段YAML的意思爲:建立了一個ops-admin的sa,併爲這個sa賦予了兩個命名空間(ops-ci、ops-qa) admin 的權限。

具體想了解更多rbac相關的說明,可參考:https://www.cnblogs.com/wlbl/p/10694364.html

ldap說明

我司ldap目錄規則以下:

|--域
|--|---公司
|--|----|----分公司
|--|----|-----|----部門
|--|----|-----|-----|-----用戶

對應的Distinguished Name顯示以下:

CN=Peng Xu,OU=部門,OU=分公司,OU=公司,DC=corp,DC=xxx,DC=com

這裏我會獲取第一個OU做爲group,若是你的需求和我不同,能夠給我提 issue 進行適配

ldap 詳細說明請參考:https://blog.poychang.net/ldap-introduction

configmap.yaml 配置說明

ldap:
  addr: ldap://192.168.3.81:389
  adminUser: xxxxx
  adminPwd: xxxxxx
  baseDN: dc=corp,dc=patsnap,dc=com
  filter: (&(objectClass=person)(sAMAccountName=%s))
  attributes: user_dn
  orgUnitName: OU=
#全局用戶/用戶組與SA的映射
rbac:
  DevOps team:
    sa: ops-admin
    ns: kube-system
  xupeng:
    sa: inno-admin
    ns: default
clusters:
  #集羣別名,在登陸下拉框中顯示的key,這個別名須要和secret.sh中的ca.crt和token的鍵名一一對應
  local:
    #apiserver地址,可以被當前工具訪問到
    apiServer: apiserver-dev.jiunile.com
    port: 6443
    #kubernetes dashboard地址,可以被當前工具訪問到
    dashboard: dashboard-dev.jiunile.com
    #集羣說明,在登陸下拉框中顯示的名稱
    desc: Dev Cluster
    #針對單獨集羣細分
    #rbac:
    #  DevOps team:
    #    sa: admin
    #    ns: kube-system
    #  xupeng:
    #    sa: ops-admin
    #    ns: default
  cnrelease:
    apiServer: apiserver-cn-release.jiunile.com
    port: 443
    dashboard: dashboard-cn-release.jiunile.com
    desc: CN Release Cluster
  usrelease:
    apiServer: apiserver-us-release.jiunile.com
    port: 443
    dashboard: dashboard-us-release.jiunile.com
    desc: US Release Cluster
  euprod:
    apiServer: apiserver-eu-prod.jiunile.com
    port: 443
    dashboard: dashboard-eu-prod.jiunile.com
    desc: EU Prod Cluster

部署

  1. 修改並部署deploy/configmap.yaml
  2. 將各集羣獲取的 ca.crttoken 寫入到對應的deploy/token下
  3. 執行 deploy 下的 secret.sh 腳本 sh deploy/secret.sh

    注意: secret.sh 中的 xx_token/xxx_ca.crt中的 xx 對應於 configmap.yaml 中的 集羣別名,必需要一一對應
  4. 部署deploy/deployment.yaml

訪問

http://{nodeip}:31000

mutiboard-ldap

視頻下載地址: https://github.com/icyxp/kubernetes-dashboard-ldap/raw/master/assets/video/intro.webm

git地址:https://github.com/icyxp/kube...

相關文章
相關標籤/搜索