kubernetes API 訪問控制在阿里雲容器服務(ACK)上的實踐

提起K8s API的訪問控制,很多同學應該都會想到RBAC,這是K8s用來做權限控制的方法,但是K8s對API的訪問控制卻不止於此,今天我們就來簡單介紹下K8s的訪問控制以及ACK如何利用這套方法提供便捷的訪問控制管理

訪問控制簡要說明
kubernetes API 訪問控制在阿里雲容器服務(ACK)上的實踐
控制流程如上圖所示,我們今天關注點在前兩步,也就是圖中的Authentication和Authorization

Authentication做的是身份校驗,Authentication支持的方法包括X509 Client Certs、Password、Plain Tokens、Bootstrap Tokens 和 JWT Tokens,今天我們要實踐的就是X509 Client Certs校驗方式

API server啓動時傳入--client-ca-file=SOMEFILE即可啓用證書校驗,參數指定的文件中必須包含至少一個CA證書用於校驗傳入的客戶端證書。
驗證通過後,證書中的common name(CN)字段會作爲請求的username,organization(O)字段作爲請求的group

Authorization做的是授權鑑定,一個請求通過Authentication後,會帶着一個user和group,Authorization做的就是判斷請求的方法(verb)和對象(object)是否在user和group的權限範圍內;從1.8版本之後,RBAC模式進入stable狀態,也是ACK默認啓用的鑑權方式,RBAC模塊會通過role/clusterrole和rolebinding/clusterrolebinding來鑑定請求所關聯的user和group是否有操作的權限

下面我們通過操作來看下ACK上是如何做這些事的

環境準備
kubernetes
可以通過容器服務管理控制檯非常方便地快速創建 Kubernetes 集羣。具體過程可以參考這裏

一個授予集羣權限的子賬號
子賬號綁定的操作請參考這裏

驗證
我們按照上面的步驟操作,給子賬號綁定default空間下的開發人員角色
kubernetes API 訪問控制在阿里雲容器服務(ACK)上的實踐
登錄子賬號,在集羣的詳情頁找到kubeconfig的信息,複製其中的user.client-certificate-data字段,執行下面的命令

echo $CERTIFICATE | base64 -D > test.crt
openssl x509 -in test.crt -noout -text
會看到類似下面的輸出

Certificate:
Data:
Version: 3 (0x2)
Serial Number: 980377 (0xef599)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O=cb4541f68933d4927b445b1eec47ce8b6, OU=default, CN=cb4541f68933d4927b445b1eec47ce8b6
Validity
Not Before: Apr 24 08:19:00 2019 GMT
Not After : Apr 23 08:24:49 2022 GMT
Subject: O=system:users, OU=, CN=232157355171679750
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
...
看證書的subject字段,O=system:users CN=232157355171679750,表示使用這個證書作爲身份校驗的請求,在服務端看來,user是232157355171679750,group是system:users

接下來我們繼續看這個user和group在集羣中被賦予的權限

~ kubectl get rolebinding
NAME AGE
232157355171679750-default-rolebinding 10s

~ kubectl get rolebinding 232157355171679750-default-rolebinding -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
...
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cs:ns:dev
subjects:

  • apiGroup: rbac.authorization.k8s.io
    kind: User
    name: "232157355171679750"
    可以看到user 232157355171679750被綁定了cs:ns:dev這個集羣角色,可以操作許多資源,但是都被限制在default這個namespace下(不能查看node,因爲node是跨namespace的資源),因爲給這個user綁定是通過rolebinding來做的,是受namespace的約束的(kubectl describe clusterrole cs:ns:dev即可看到這個子賬號被授予的所有權限)

我們再給賬號擴大一些權限,這次給他綁定整個集羣的管理員角色
kubernetes API 訪問控制在阿里雲容器服務(ACK)上的實踐

然後我們就會發現剛纔的rolebinding已經被刪除了

~ kubectl get rolebinding
No resources found.
因爲這次綁定是整個集羣範圍內的,所以產生的是clusterrolebinding

~ kubectl get clusterrolebinding
NAME AGE
232157355171679750-clusterrolebinding 3s
可以用上面的方法繼續查看集羣管理員角色下的所有權限

但是集羣管理員並不是權限最高的角色,權限最高的角色是自定義列表中的cluster-admin,這是kubernetes集羣啓動後內置的角色,也是主賬號創建集羣后生成的config文件中綁定的角色

角色和權限的選擇
既然kubernetes中內置了許多的role和clusterrole,那我們該如何選擇呢?又如何判斷當前的角色是否滿足了需求呢?

還好kubectl已經提供了對應的命令來幫助我們快速判斷權限是否充分

kubectl auth can-i <verb> <resource> [<resourceName>]
我們還是以一個被綁定了集羣管理員的角色爲例,下面的kubectl命令均是使用了對應的config文件

~ kubectl auth can-i delete no
yes

~ kubectl auth can-i drain no
no - no RBAC policy matched

~ kubectl auth can-i taint no
no - no RBAC policy matched

~ kubectl auth can-i cordon no
no - no RBAC policy matched

~ kubectl auth can-i label no
no - no RBAC policy matched

~ kubectl auth can-i delete pv
yes

~ kubectl auth can-i delete pvc
yes
我們看到這個角色的可以刪除node、pv和pvc,但是不能對node做drain,taint,cordon,label,可以利用這個工具快速定位操作失敗是否和權限有關

總結
ACK將阿里雲上的子賬號系統和kubernetes本身的訪問控制非常平滑的連接在一起,對用戶非常友好,不需要花太多的精力在RBAC的細節上,極大的降低了使用門檻

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章