PX-Security:針對Kubernetes持久卷的多租戶受權、身份驗證和RBAChtml
PX-Security演示視頻連接
https://v.qq.com/x/page/s30609pfmuq.html
安全對於企業來講相當重要,對於運行在Kubernetes上的基於微服務的應用來講更是如此。
Kubernetes提供RBAC受權,根據不一樣角色設定,管理Kubernetes內部特定資源的訪問權限。這些機制對於管理Kubernetes的特定對象(如服務、命名空間、配額等)的訪問權限很是有用。但命名空間和pod的安全策略自己,不足以限制誰有權限能夠請求更改底層數據管理系統。node
許多企業經過CNI或CSI等API,調用其餘的平臺能力來提供網絡和存儲基礎。Kubernetes所缺少的是將RBAC擴展到這些系統的能力,須要外部系統來確保受權和認證功能的實現。mysql
這就是爲何Portworx與Kubernetes攜手,經過對支撐Kubernetes中PVCs的持久卷,進行訪問角色控制,來提供RBAC、加密和控制權限,這將建立一個無縫的保護層,爲您的PVCs提供如下保護:golang
同一命名空間中的用戶能夠受到其角色的限制,好比他們能夠具備讀、寫、管理員或其餘定義的訪問權限。sql
用戶能夠經過Token自動進行身份驗證,這樣審計請求的受權就能夠針對特定命名空間來進行。json
能夠將用戶置於基於租戶的命名空間中,從而爲訪問PVCs提供安全的多租戶。api
即便用戶看到存儲類,也不意味着他們被受權建立PVC。安全
將Portworx RBAC與加密一塊兒使用,意味着數據在host上是安全的,命名空間內的非受權用戶不能訪問數據。bash
要深刻了解Portworx能爲您的Kubernetes平臺提供什麼,能夠查看Portworx網站上的安全參考體系架構。咱們將重點討論一些主題,好比如何設置PX-Security,以及如何使用Token對具備相應持久卷訪問權限的角色用戶進行身份驗證。
首先,Portworx經過使用Token支持RBAC。在本文中,PX-Security將使用存儲在Kubernetes Secrets中的Token,這些Token提供了最靈活的操做,且不犧牲任何安全性。網絡
開始吧!
在咱們討論什麼是Token以及如何使用它以前,有一點須要注意,對Portworx的每一個請求都是使用存儲在Token中的信息進行身份驗證和受權的。其中包含關於用戶及其角色所需全部相關的驗證和簽名的信息。所以,咱們配置了PX-Security後,咱們會建立Token。
讓咱們來配置PX-Security來達到安全性。請訪問 https://central.portworx.com,
點擊安裝並運行。填寫安裝程序要求的信息,完成後下載你的YAML文件,將文件保存以便後續作編輯。
接下來,咱們將建立用於PX-Security的安全共享的Secrets。咱們必須首先建立這些共享的Secrets,由於存儲管理員將使用它們來生成和驗證Token。出於安全緣由,這些數據被存儲在Kube-system命名空間中的Kubernetes Secrets中,只有少許的管理員和應用程序能夠訪問該命名空間。
PORTWORX_AUTH_SYSTEM_KEY=$(cat /dev/urandom | base64 | fold -w 65 | head -n 1) PORTWORX_AUTH_STORK_KEY=$(cat /dev/urandom | base64 | fold -w 64 | head -n 1) PORTWORX_AUTH_SHARED_SECRET=$(cat /dev/urandom | base64 | fold -w 64 | head -n 1)
運行如下命令將這些值放入Kubernetes Secret中:
kubectl -n kube-system create secret generic pxkeys \ --from-literal=system-secret=$PORTWORX_AUTH_SYSTEM_KEY \ --from-literal=stork-secret=$PORTWORX_AUTH_STORK_KEY \ --from-literal=shared-secret=$PORTWORX_AUTH_SHARED_SECRET
您可使用如下命令測試Kubernetes中的共享-secret。
kubectl -n kube-system get secret pxkeys -o json | jq -r '.data."shared-secret"' | base64 -d
打開您的YAML文件,找到PortworxDaemonset,能夠看args, 在image:portworx/oci-monitor下。這裏咱們將添加安全參數(粗體)和PX-Security須要的Secrets:
- name: portworx image: portworx/oci-monitor:2.1.5 imagePullPolicy: Always args: ["-c", "px-cluster", "-s", "/dev/xvdf", "-secret_type", "k8s", "-b", "-x", "kubernetes", "-jwt_issuer", "example-domain.com"] env: - name: "AUTO_NODE_RECOVERY_TIMEOUT_IN_SECS" value: "1500" - name: "PX_TEMPLATE_VERSION" value: "v4" - name: "PORTWORX_AUTH_JWT_SHAREDSECRET" valueFrom: secretKeyRef: name: pxkeys key: shared-secret - name: "PORTWORX_AUTH_SYSTEM_KEY" valueFrom: secretKeyRef: name: pxkeys key: system-secret - name: "PORTWORX_AUTH_STORK_KEY" valueFrom: secretKeyRef: name: pxkeys key: stork-secret
咱們還須要找到Stork部署和編輯環境以包含咱們的共享secret。見下文。
containers: - command: - /stork - --driver=pxd - --verbose - --leader-elect=true - --health-monitor-interval=120 imagePullPolicy: Always image: openstorage/stork:2.2.5 env: - name: "PX_SERVICE_NAME" value: "portworx-api" - name: "PX_SHARED_SECRET" valueFrom: secretKeyRef: name: pxkeys key: stork-secret
完成這兩個步驟後,保存YAML文件。如今,咱們須要建立咱們在Portworx安裝YAML中引用的共享Secret。
接下來,使用下載和編輯過的YAML文件建立Portworx集羣。
$ kubectl apply-f px-sec-cluster-spec.yaml
$ kubectl get po -n kube-system -l name=portworx NAME READY STATUS RESTARTS AGE portworx-4vmcx 1/1 Running 0 3m54s portworx-hwrxh 1/1 Running 0 3m54s portworx-rbqzk 1/1 Running 0 3m54s
用戶和Token
咱們須要定義幾個用戶併爲他們生成Token。一般,這些用戶有分配給他們的屬性,這些屬性定義了他們的用戶類型。
首先,咱們將建立一個存儲管理員,該管理員具備所有權限。這樣的管理員應該只有一兩個。
使用如下內容建立一個名爲admin.yaml的文件:
name: Storage Administrator email: storageadmin@example.com sub: storageadmin@example.com/storageadmin roles: ["system.admin"] groups: ["*"]
接下來,咱們將建立一個Kubernetes用戶,該用戶做爲一個驗證客戶,Kubernetes容許該用戶與Portworx交互,而且這些請求來自Kubernetes。您的存儲管理員須要設置此用戶。
使用如下內容建立一個名爲kubernetes.yaml的文件:
name: Kubernetes email: kubernetes@local.net sub: kubernetes@local.net/kubernetes roles: ["system.user"] groups: ["kubernetes"]
最後,咱們將建立一個僅能看 (view-only) 權限的用戶,用於演示Portworx如何限制對底層數據管理API的訪問。
使用如下內容建立一個名爲viewer.yaml的文件:
name: Viewer email: viewer@example.com sub: viewer@example.com/viewer roles: ["system.view"] groups: ["viewers"]
注意:Sub標記是該用戶的惟一標識符,根據JWT標準,不能與其餘Token共享。這個值被Portworx用來跟蹤資源的全部權。若是電子郵件也用做惟一Sub標識符,請確保它不被任何其餘Token使用。
請注意:有一個用戶的角色是system.admin,另外一個用戶的角色是system.user,最後一個用戶的角色是system.view。這些角色在PX-Security中是默認的,但也能夠根據須要建立其餘角色。咱們來演示用戶如何使用Portworx資源,如建立或刪除卷。這跟該用戶在Kubernetes RBAC的配置無關。
也就是說,具備system.view的用戶也許可以在Kubernetes中內列出和建立PVC對象,但若是他們試圖直接使用Portworx建立卷,將會失敗。咱們還將演示,爲何可以建立PVC對象的用戶在此安全模式中實際上沒法得到PV,除非該用戶擁有由存儲管理員配置的有效Token,來驗證其角色和權限。
配置好了這些具有相關權限的用戶,咱們就可使用咱們的共享Secret和Portworx客戶端工具pxctl,爲這些用戶生成自簽名證書。
注意:您能夠建立本身的應用來生成Token,也能夠基於咱們的開源golang示例程序openstorage-sdk-auth
在這個場景中,咱們將使用共享Secret和pxctl auth token generate命令。讓咱們爲上述兩個用戶建立Token。
首先,獲取共享Secret。
PORTWORX_AUTH_SHARED_SECRET=$(kubectl -n kube-system get secret pxkeys -o json \ | jq -r '.data."shared-secret"' \ | base64 -d)
接下來,配置Admin Token。首先是SSH,到Portworx節點,這樣就可使用pxctl命令。
$ PX_POD=$(kubectl get pods -l name=portworx -n kube-system -o jsonpath='{.items[0].metadata.name}')
$ kubectl exec -it -n kube-system $PX_POD bash
而後,使用admin.yaml和共享Secret建立admin Token。
注意:確保將auth_config文件和PORTWORX_AUTH_SHARED_SECRET 複製到正在使用pxctl的Portworx容器中。
ADMIN_TOKEN=$(/opt/pwx/bin/pxctl auth token generate \ --auth-config=admin.yaml \ --issuer=example-domain.com \ --shared-secret=$PORTWORX_AUTH_SHARED_SECRET \ --token-duration=1y) $ pxctl context create admin --token $ADMIN_TOKEN
接下來,配置Kubernetes Token。
KUBE_TOKEN=$(/opt/pwx/bin/pxctl auth token generate \ --auth-config=kubernetes.yaml \ --issuer=example-domain.com \ --shared-secret=$PORTWORX_AUTH_SHARED_SECRET \ --token-duration=1y)
接下來,配置Viewer token。
VIEWER_TOKEN=$(/opt/pwx/bin/pxctl auth token generate \ --auth-config=viewer.yaml \ --issuer=example-domain.com \ --shared-secret=$PORTWORX_AUTH_SHARED_SECRET \ --token-duration=1y) $ pxctl context create viewer --token $VIEWER_TOKEN
如今咱們已經建立了用戶環境(Context),好比Portworx的Kubectl環境,來供兩個用戶使用,咱們能夠做爲其中一個用戶與Portworx系統進行交互。
注意,您可使用$pxctl contextlist列出全部環境:
$ pxctl context set viewer
$ pxctl volume create --size 5 myvol VolumeCreate: Access denied to roles: [system.view]
發生了什麼?請記住,咱們爲具備system.view角色的Viewer設置了用戶環境。這是Portworx的默認角色,只能運行只讀命令,不具有寫操做的權限,所以訪問被拒絕。
如何與Kubernetes一塊兒使用?
爲了讓Kubernetes的用戶使用PX-Security,用戶必須在向集羣發出請求時使用本身的Token。一種方法是讓管理員在Kubernetes存儲類中配置Token。管理員能夠在Portworx命名空間中名爲px-k8-user的Secret中設置保存Secret Token。
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: px-storage-repl-1 provisioner: kubernetes.io/portworx-volume parameters: repl: "1" openstorage.io/auth-secret-name: px-k8s-user openstorage.io/auth-secret-namespace: portworx allowVolumeExpansion: true
若是您正在使用CSI,請確保設置其餘的參數。
注意:這目前只在經過Portworx使用CSI時有效。
parameters: repl: "1" csi.storage.k8s.io/provisioner-secret-name: px-k8s-user csi.storage.k8s.io/provisioner-secret-namespace: portworx csi.storage.k8s.io/node-publish-secret-name: px-k8s-user csi.storage.k8s.io/node-publish-secret-namespace: portworx csi.storage.k8s.io/controller-expand-secret-name: px-k8s-user csi.storage.k8s.io/controller-expand-secret-namespace: portworx
完成此操做後,具有訪問存儲類權限的用戶能夠建立卷。
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: mysql-data spec: storageClass: px-storage-repl-1 accessModes: - ReadWriteOnce resources: requests: storage: 12Gi
多租戶架構
當您建立上述PVC時,它將使用KubernetesToken做爲用戶進行身份驗證,從而確保該Kubernetes用戶是發出請求的用戶。這很好,可是多租戶環境下,他們均可以使用存儲類,所以咱們須要一種方法來在不一樣的命名空間中使用多租戶的Token。這是由於Kubernetes提供了使用命名空間隔離賬戶資源的好方法,但您須要更安全的多租戶解決方案。Portworx能夠經過爲應用存儲卷添加訪問控制來達到多租戶安全管理。使用PX-Security進行多租戶管理,能夠執行如下操做。
首先,爲租戶建立一個命名空間。
$ kubectl create namespace tenant-a-ns
使用如下建立一個名爲tenant-a.yaml 的文件:
name: tenant-a email: tenant@tenant-a.com sub: tenant@tenant-a.com/tenant roles: ["system.user"] groups: ["developers"]
使用tenant-name.yaml爲Kubernetes建立一個token:
TENANT_A_TOKEN=$(/opt/pwx/bin/pxctl auth token generate \ --auth-config=tenant-a.yaml \ --issuer=example-domain.com \ --shared-secret=$PORTWORX_AUTH_SHARED_SECRET \ --token-duration=1y)
將該租戶的Kubernetes Token保存在一個名爲<tenant namespace>/px-k8 -user的Secret中:
$ kubectl -n tenant-a-ns create secret \ generic px-k8s-user \ --from-literal=auth-token=$TENANT_A_TOKEN
如今能夠設置Kubernetes存儲類,經過使用這個Secret,來得到Token權限,並與Portworx開始通信。
下面的CSI存儲類一旦建立,將使您的多租戶可以使用存儲在其命名空間中的Secret中的Token,來建立卷,方法是在命名空間中查找Secret。在使用CSI時,存儲類將引用三種受支持操做的secret:provision, node-publish(mount/unmount), and controller-expand。
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: px-storage provisioner: pxd.portworx.com parameters: repl: "1" csi.storage.k8s.io/provisioner-secret-name: px-k8s-user csi.storage.k8s.io/provisioner-secret-namespace: ${pvc.namespace} csi.storage.k8s.io/node-publish-secret-name: px-k8s-user csi.storage.k8s.io/node-publish-secret-namespace: ${pvc.namespace} csi.storage.k8s.io/controller-expand-secret-name: px-k8s-user csi.storage.k8s.io/controller-expand-secret-namespace: ${pvc.namespace} allowVolumeExpansion: true
請注意 ${pvc.namespace}。這將確保CSI控制器得到正確的Token,該Token與PVC的命名空間相關聯。您如今就有了一個基於Token身份驗證的多租戶解決方案。
咱們在本Blog中有一部分沒有介紹的PX-Security功能就是Portworx卷的加密。您能夠在這裏(how to work with Encrypted PVCs)查看更多的關於PVC加密的文檔 。您能夠將Portworx RBAC與卷加密結合使用,來使Kubernetes中的數據更加安全。