PX-Security:針對Kubernetes持久卷的多租戶授權、身份驗證和RBAC PX-Security示範視訊連結 https://v.youku.com/v_show/id_XNDUzMjU3NzU1Ng==.html

安全對于企業來說至關重要,對于運作在Kubernetes上的基于微服務的應用來說更是如此。
Kubernetes提供RBAC授權,根據不同角色設定,管理Kubernetes内部特定資源的通路權限。這些機制對于管理Kubernetes的特定對象(如服務、命名空間、配額等)的通路權限非常有用。但命名空間和pod的安全政策本身,不足以限制誰有權限可以請求更改底層資料管理系統。
許多企業通過CNI或CSI等API,調用其他的平台能力來提供網絡和存儲基礎。Kubernetes所缺乏的是将RBAC擴充到這些系統的能力,需要外部系統來確定授權和認證功能的實作。
這就是為什麼Portworx與Kubernetes攜手,通過對支撐Kubernetes中PVCs的持久卷,進行通路角色控制,來提供RBAC、加密和控制權限,這将建立一個無縫的保護層,為您的PVCs提供以下保護:
- 同一命名空間中的使用者可以受到其角色的限制,比如他們可以具有讀、寫、管理者或其他定義的通路權限。
- 使用者可以通過Token自動進行身份驗證,這樣審計請求的授權就可以針對特定命名空間來進行。
- 可以将使用者置于基于租戶的命名空間中,進而為通路PVCs提供安全的多租戶。
- 即使使用者看到存儲類,也不意味着他們被授權建立PVC。
- 将Portworx RBAC與加密一起使用,意味着資料在host上是安全的,命名空間内的非授權使用者不能通路資料。
- 如果一個請求來自Kubernetes外部而沒有Token,它将被阻止。
要深入了解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: [email protected]
sub: [email protected]/storageadmin
roles: ["system.admin"]
groups: ["*"]
接下來,我們将建立一個Kubernetes使用者,該使用者作為一個驗證客戶,Kubernetes允許該使用者與Portworx互動,并且這些請求來自Kubernetes。您的存儲管理者需要設定此使用者。
使用以下内容建立一個名為kubernetes.yaml的檔案:
name: Kubernetes
email: [email protected]
sub: [email protected]/kubernetes
roles: ["system.user"]
groups: ["kubernetes"]
最後,我們将建立一個僅能看 (view-only) 權限的使用者,用于示範Portworx如何限制對底層資料管理API的通路。
使用以下内容建立一個名為viewer.yaml的檔案:
name: Viewer
email: [email protected]
sub: [email protected]/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: [email protected]
sub: [email protected]/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儲存在一個名為/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中的資料更加安全。