理解OpenShift(1):網絡之 Router 和 Routehtml
理解OpenShift(2):網絡之 DNS(域名服務)node
理解OpenShift(4):用戶及權限管理github
理解OpenShift(5):從 Docker Volume 到 OpenShift Persistent Volume微信
** 本文基於 OpenShift 3.11,Kubernetes 1.11 進行測試 ***網絡
OpenShift 支持 RBAC(Role Based Access Controll),基於角色的訪問控制。它涉及諸多概念,本文嘗試着作一些概念上的梳理,不少細節還須要進一步研究。app
我試着把一個OpenShift 環境中的全部用戶分爲三大類:ide
認證是確認用戶身份是否合法的過程。這能夠有多種實現方式,好比用戶名/密碼、令牌(token)、證書等。不一樣類型的用戶有不一樣的身份管理方式:post
受權是對被認證了的用戶訪問受控制的資源的權限進行控制。按照資源類型,OpenShift 將受權管理方式分爲兩大類:測試
就像人的身份證同樣,identity 是一個 user 的身份信息,該信息用於用戶認證。OpenShift 本身並無實現用戶身份信息庫,而是經過靈活支持多種 identity provider,來實現各類不一樣的身份管理方案。每種實現都以不一樣的方式保存着用戶的身份信息,好比保存在LDAP 中,保存在 htpasswd 文件中,保存在 OpenStack Keystone 中。
所以,OpenShift 對 user 身份的校驗是經過這些配置了的 identity provider 進行的。所以,還須要 OpenShift user 和這些 provider 裏面的 identity 的映射關係。OpenShfit 支持四種映射管理,claim,lookup,generate,add。具體請參考官網 https://docs.openshift.com/container-platform/3.11/install_config/configuring_authentication.html#identity-providers_parameters。
上圖中以 htpasswd 這種 identity provider 爲例,說明了從零建立一個 openshift user,在 htpasswd 中建立 user 及其密碼,而後建立 openshift identity 對象以及 useridentitymapping 對象的過程。
用戶獲取用於身份認證的token的過程:
<master>/oauth/token
。每一個申請 OAuth token 的請求中都必須帶有 OAuth client 標識,這是一個 OAuthClient 對象。具體請參閱官方文檔。前文說了,角色用於控制對 OpenShift 資源的訪問權限,它分爲項目角色和集羣角色。
OpenShift 系統默認會建立不少的集羣角色。經常使用的角色的簡單描述以下:
admin |
|
basic-user |
|
cluster-admin |
|
cluster-status |
|
edit |
|
self-provisioner |
|
view |
|
能夠查看全部角色,好比 system:router 角色:
可使用 oc adm policy 命令向用戶或用戶授予角色:
user、group、role、rolebinding 之間的關係:
更多對 role 的說明,可參見官方文檔。
OpenShift 的 service account 比較複雜,和不少概念都有關聯。官方文檔在 https://docs.openshift.com/container-platform/3.11/dev_guide/service_accounts.html。該文檔對爲何須要這個概念的說明是:當一個天然人用戶訪問 OpenShfit API 時,OpenShift 對它進行用戶認證和權限控制。可是,有時候作操做的並非天然人用戶,好比:
爲了這種訪問,OpenShift 創造了 Service Account (簡稱sa)概念。每一個項目(project)默認都會自動建立3個sa user:
Service Account | Usage |
---|---|
builder |
用於 build pod。它被授予了 system:image-builder 角色,所以被容許向內部鏡像倉庫中的任意 image stream 上push 鏡像。 |
deployer |
用於 deployment pod。被授予了 system:deployer 角色,所以被容許查看和修改集羣中的 RC 及其 pod。 |
default |
當一個 pod 沒有顯式指定 service account 默認都會使用該 sa user。 |
sa 利用 secret(token)來保存其身份信息。默認狀況下,每一個 sa 用戶都有兩種token,即訪問 OpenShift API 的token和訪問內部鏡像倉庫的token。以系統默認的 『builder』 sa user 爲例,它包含一個用於拉取鏡像的token secret,兩個訪問API 的token secret,三個secret 中只有兩個能被以卷的形式掛接給pod:
能夠按需求修改一個 sa 帳戶的這些token。可參考 https://docs.openshift.com/enterprise/3.0/dev_guide/image_pull_secrets.html 爲service account 建立和添加新的用於拉取鏡像的token secret。具體請參考官方文檔。
其中,sa 的 API token 會被掛接到 pod 的 目錄的 token 文件,從而使得 pod 中的應用能夠讀取該 token 去訪問 OpenShift API:
image pull secret 是如何掛載到 pod 的,我尚未找到。並且在 pod spec 中,只看到 API token secret 的 mountpoint,而並無 imagePullSecret 的 mountpoint:
和天然人 user 相似,對 sa 用戶訪問OpenShift 集羣資源的權限控制是經過 role 進行的。前面的表格代表,項目的兩個默認 sa builder 和 deployer 都被授予了相應的 role,從而能訪問指定的資源。而默認的 sa 用戶,只被授予了 /system:image-puller 角色。這意味着默認的 sa 用戶只能拉取鏡像,而不能訪問集羣其它資源。
下圖是項目 stage 中的 rolebinding:
用戶組 system:serviceaccounts:stage 中包括該項目中的全部 sa 用戶。利用 default sa user 來作下實驗。先獲取其 API token,而後登陸進 OpenShift 集羣:
調用 API 獲取 pod,結果失敗:
向 default sa user 授予 cluster-reader 角色:
而後就能夠作集羣資源查詢操做了。
pod 中的應用除了有訪問 OpenShift API 和內部鏡像倉庫以外,還有一些系統資源訪問要求。好比:
對於這些操做系統資源的訪問權限,OpenShift 利用 scc 來進行控制。這就要求:
前面說過,SCC 用於控制訪問系統資源的權限,那說明只有 service account 才須要使用 scc。沒在文檔中看到天然人用戶 user 使用 scc 的例子。
Linux 中的權限控制非常複雜,這裏就不說明了,我本身也沒怎麼弄清楚。OpenShift scc 將系統權限分爲幾大類,具體見上圖中的『權限』部分,而後能夠建立 scc 對象來精細地控制對每種權限的控制。
由於這很是繁瑣,所以 OpenShift 默認建立了幾個典型的 scc,列表以下。上圖中的『系統預約義scc』部分有簡要說明,這裏再也不重複。
其中,若是 pod 所使用的 scc 的 runAsUser
策略被設置爲了 MustRunAsRange,那麼 pod 所使用的 uid 和 supplemental-group id 必須在某區間以內。
集羣管理員能夠在 scc 中設置區間,好比:
可是,OpenShift 默認提供的 scc 都沒有設置該區間,而是使用 pod 所在的 project 中定義的區間以內。好比:
[root@master2 cloud-user]# oc describe project dev Name: dev Created: 3 weeks ago Labels: <none> Annotations: openshift.io/description= openshift.io/display-name= openshift.io/requester=demo openshift.io/sa.scc.mcs=s0:c16,c0 openshift.io/sa.scc.supplemental-groups=1000000000/10000 openshift.io/sa.scc.uid-range=1000000000/10000
每一個 project 會被分配不一樣的 ID 區間。當未指定 uid 和 supplemental gid 時,會默認使用區間的最小值。
每一個 pod 中,運行主進程的用戶都有三個屬性:
fsGroup
定義 pod 的 文件系統 group ID,用於塊存儲,好比 Ceph RDB 和 iSCSI。supplementalGroups
ID 用於共享存儲,也是組/group ID 的一種,用於共享存儲,好比 NFS 和 GlusterFS。上面例子中的 supplementalGroup ID 爲 10000000,取的也是默認值。這兩種 group ID 支持 MustRunAs 和 RunAsAny 兩種策略。會在下一篇存儲部分詳細介紹。備註:Supplemental group(附加組)也是Linux 組的一種。當一個進程運行在 Linux 中時,它會擁有一個 UID,一個 GID,以及一個或多個附加組ID。具體請查閱Linux 相關文檔。
若是某 scc 設置的 RunAsUser 策略爲 MustRunAsRange,它會要求配置合法的 uid 區間(要麼在 project 中配置,要麼在 scc 中指定)。若是你要指定特定的 uid ,你能夠在 pod 定義 yaml 中使用 securityContext: runAsUser <uid> 來指定特定的 user id,可是該 id 必須在區間以內。不然會報錯:
Error from server (Forbidden): error when creating "testcontainervolume-restricted.yaml": pods "test-pod-volume-restricted2" is forbidden: unable to validate against any security context constraint: [spec.containers[0].securityContext.securityContext.runAsUser: Invalid value: 65534: must be in the ranges: [1000000000, 1000009999]]
根據建立 pod 的用戶不一樣,pod 使用不一樣的默認 scc:
SCC 優先級:一個 sa user 能夠被加到多的 scc 當中。當一個 service account user 有多個 SCC 可用時,其 scc 按照下面的規則排序
每一個 scc 有其用戶/用戶組列表。以 restricted 爲例,全部經過身份驗證的用戶都在列表中;而 anyuid,只有 cluster-admins 用戶組中的用戶在裏面。
要受權 pod 有除了 restricted 定義的權限以外的權限,主要有兩種作法:
官方建議採用第一種。一個很經常使用的例子是運行要使用 root 用戶的容器。不少的Docker 鏡像都使用的是 root 用戶。可是,openshift restricted scc 不容許使用 root 用戶,而要使用一個用戶區間內的用戶:
修復步驟:
$ oc create serviceaccount useroot $ oc adm policy add-scc-to-user anyuid -z useroot $ oc patch dc/myAppNeedsRoot --patch '{"spec":{"template":{"spec":{"serviceAccountName": "useroot"}}}}'
備註:
說明:
感謝您的閱讀,歡迎關注個人微信公衆號: