[TOC]
基于角色(Role)的訪問控制(RBAC)是一種基于組織中用戶的角色來調節控制對 計算機或網絡資源的訪問的方法。
RBAC 鑒權機制使用 `rbac.authorization.k8s.io` API組來驅動鑒權決定,允許你通過 Kubernetes API 動態配置策略。
要啟用 RBAC,在啟動 kube-apiserver 時將 `--authorization-mode` 參數設置為一個逗號分隔的列表并確保其中包含 RBAC。
## Role 和 ClusterRole
RBAC 的 Role 或 ClusterRole 中包含一組代表相關權限的規則。 這些權限是純粹累加的(不存在拒絕某操作的規則)。
Role 總是用來在某個名字空間 內設置訪問權限;在你創建 Role 時,你必須指定該 Role 所屬的名字空間。
與之相對,ClusterRole 則是一個集群作用域的資源。這兩種資源的名字不同(Role 和 ClusterRole)是因為 Kubernetes 對象要么是名字空間作用域的,要么是集群作用域的, 不可兩者兼具。
Role 示例
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jiaxzeng
namespace: default
rules:
# pod資源只有create get list watch的操作
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "get", "list", "watch"]
# 登錄pod容器,查看pod日志
- apiGroups: [""]
resources: ["pods/exec", "pods/log"]
verbs: ["get", "create"]
# deployment資源只有get list watch的操作,其他權限均沒有
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch"]
```
> - Role 與 ClusterRole,除了 `kind` 和 `ClusterRole` 資源清單不需要 `cluster.namespace` 字段外,其他都一致。
> - verbs具體有什么操作,請看下面的 [查看資源操作](#verbs) 的段落
## serviceaccount 和 user
### serviceaccount
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: jiaxzeng
namespace: default
```
### user
查看 kube-apiserver 的配置文件,確定 ca 證書的相關文件路徑。這里演示路徑是在 `/data/k8s/certs/`
創建一個 JSON 配置文件,用來為 kube-apiserver 生成秘鑰和證書,例如:server-csr.json。 確認用你需要的值替換掉尖括號中的值。USER 是為 kube-apiserver綁定的用戶名,MASTER_CLUSTER_IP 是為 kube-apiserver 指定的服務集群IP,就像前面小節描述的那樣。 以下示例假定你的默認 DSN 域名為cluster.local。
```json
{
"CN": "<USER>",
"hosts": [
"127.0.0.1",
"<MASTER_IP>",
"<MASTER_CLUSTER_IP>",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [{
"C": "CN",
"L": "GuangDong",
"O": "ecloud",
"OU": "ecloud"
}]
}
```
為 kube-apiserver 生成秘鑰和證書,默認會分別存儲為server-key.pem 和 server.pem 兩個文件。
```shell
$ cfssl gencert -ca /data/k8s/certs/ca.pem -ca-key /data/k8s/certs/ca-key.pem --config /data/k8s/certs/ca-config.json -profile kubernetes jiaxzeng-csr.json | cfssljson -bare jiaxzeng
2022/01/28 15:51:28 [INFO] generate received request
2022/01/28 15:51:28 [INFO] received CSR
2022/01/28 15:51:28 [INFO] generating key: rsa-2048
2022/01/28 15:51:28 [INFO] encoded CSR
2022/01/28 15:51:28 [INFO] signed certificate with serial number 89734874854127747600656517401688932704615436370
2022/01/28 15:51:28 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
```
> 踩坑:第二行的CN要填寫用戶名,hosts添加主機的IP地址
## RoleBinding 和 ClusterRoleBinding
角色綁定(Role Binding)是將角色中定義的權限賦予一個或者一組用戶。 它包含若干 主體(用戶、組或服務賬戶)的列表和對這些主體所獲得的角色的引用。 RoleBinding 在指定的名字空間中執行授權,而 ClusterRoleBinding 在集群范圍執行授權。
一個 RoleBinding 可以引用同一的名字空間中的任何 Role。 或者,一個 RoleBinding 可以引用某 ClusterRole 并將該 ClusterRole 綁定到 RoleBinding 所在的名字空間。 如果你希望將某 ClusterRole 綁定到集群中所有名字空間,你要使用 ClusterRoleBinding。
創建了綁定之后,你不能再修改綁定對象所引用的 Role 或 ClusterRole。 試圖改變綁定對象的 roleRef 將導致合法性檢查錯誤。 如果你想要改變現有綁定對象中 roleRef 字段的內容,必須刪除重新創建綁定對象。
### RoleBinding ServiceAccount
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: jiaxzeng
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jiaxzeng
subjects:
- apiGroup: ""
kind: ServiceAccount
name: jiaxzeng
```
### RoleBinding User
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: jiaxzeng
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jiaxzeng
subjects:
- apiGroup: "rbac.authorization.k8s.io"
kind: User
name: jiaxzeng
```
## 創建kubectl命令的鑒權文件
### ServiceAccount
```shell
# 獲取sa的token
TOKEN=$(kubectl describe secrets "$(kubectl describe serviceaccount jiaxzeng | grep -i Tokens | awk '{print $2}')" | grep token: | awk '{print $2}')
# 設置集群信息。如果有集群信息,則無需再設置
kubectl config set-cluster jiaxzeng-k8s --server=https://192.168.31.103:6443 --insecure-skip-tls-verify
# 設置token
kubectl config set-credentials jiaxzeng --token=$TOKEN
# 設置上下文
kubectl config set-context jiaxzeng --cluster=jiaxzeng-k8s --user=jiaxzeng
# 切換上下文
kubectl config use-context jiaxzeng
```
### User
```shell
# 設置集群信息。如果有集群信息,則無需再設置
KUBE_APISERVER="https://192.168.31.103:6443"
kubectl config set-cluster kubernetes \
--certificate-authority=/data/k8s/certs/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER}
# 設置證書
kubectl config set-credentials jiaxzeng \
--client-certificate=jiaxzeng.pem \
--client-key=jiaxzeng-key.pem \
--embed-certs=true
# 設置上下文
kubectl config set-context jiaxzeng \
--cluster=kubernetes \
--user=jiaxzeng
# 切換上下文
kubectl config use-context jiaxzeng
```
## <a name="verbs"> 查看資源操作 </a>
### 暴露apiserver接口
```shell
kubectl proxy --address='192.168.31.103' --port=8001 --accept-hosts='^*$'
```
> 啟動 `kubectl proxy` 使用網卡IP,從其他機器訪問, `--accept-hosts='^*$'` 表示接受所有源IP,否則會顯示不被授權
訪問 `http://192.168.31.103:8001/` ,顯示所有可用的api接口。根據 `apiVersion` 來找出對應的api接口。進入對應的api接口,查看 `resources` 類型,`resources` 類型可以還有子資源。可根據 `kind` 的關鍵字來確認。
### 查看資源操作的示例
這里演示的查看deployment的資源情況以及有什么可用的操作
1. 查看deployment的 apiVersion 信息
```shell
kubectl explain deployment | grep 'VERSION'
VERSION: apps/v1
```
2. 查看對應的deployment api接口信息

3. 過濾deployment類型, 確認資源以及可用操作

> 說明:
> - 訪問的url,根據上面查出來的接口查詢
> - 過濾kind的類型,顯示如果有多少條記錄,則有多個資源。資源名稱是name對應的值
> - 資源對應的操作是verbs中的值
## 驗證
```shell
# 確認使用的上下文
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
default kubernetes system:admin
* jiaxzeng kubernetes jiaxzeng
# 切換上下文
$ kubectl config use-context jiaxzeng
Switched to context "jiaxzeng".
# 檢驗權限
$ kubectl auth can-i get deployment
yes
$ kubectl auth can-i create deployment
no
$ kubectl auth can-i create pod
yes
$ kubectl auth can-i watch pod
yes
$ kubectl auth can-i get pod -n kube-system
no
```
## 參考文章
- 創建證書:https://kubernetes.io/zh/docs/tasks/administer-cluster/certificates/
- rbdc文檔:https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/
- api文檔:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/
- 前言
- 架構
- 部署
- kubeadm部署
- kubeadm擴容節點
- 二進制安裝基礎組件
- 添加master節點
- 添加工作節點
- 選裝插件安裝
- Kubernetes使用
- k8s與dockerfile啟動參數
- hostPort與hostNetwork異同
- 應用上下線最佳實踐
- 進入容器命名空間
- 主機與pod之間拷貝
- events排序問題
- k8s會話保持
- 容器root特權
- CNI插件
- calico
- calicoctl安裝
- calico網絡通信
- calico更改pod地址范圍
- 新增節點網卡名不一致
- 修改calico模式
- calico數據存儲遷移
- 啟用 kubectl 來管理 Calico
- calico卸載
- cilium
- cilium架構
- cilium/hubble安裝
- cilium網絡路由
- IP地址管理(IPAM)
- Cilium替換KubeProxy
- NodePort運行DSR模式
- IP地址偽裝
- ingress使用
- nginx-ingress
- ingress安裝
- ingress高可用
- helm方式安裝
- 基本使用
- Rewrite配置
- tls安全路由
- ingress發布管理
- 代理k8s集群外的web應用
- ingress自定義日志
- ingress記錄真實IP地址
- 自定義參數
- traefik-ingress
- traefik名詞概念
- traefik安裝
- traefik初次使用
- traefik路由(IngressRoute)
- traefik中間件(middlewares)
- traefik記錄真實IP地址
- cert-manager
- 安裝教程
- 頒布者CA
- 創建證書
- 外部存儲
- 對接NFS
- 對接ceph-rbd
- 對接cephfs
- 監控平臺
- Prometheus
- Prometheus安裝
- grafana安裝
- Prometheus配置文件
- node_exporter安裝
- kube-state-metrics安裝
- Prometheus黑盒監控
- Prometheus告警
- grafana儀表盤設置
- 常用監控配置文件
- thanos
- Prometheus
- Sidecar組件
- Store Gateway組件
- Querier組件
- Compactor組件
- Prometheus監控項
- grafana
- Querier對接grafana
- alertmanager
- Prometheus對接alertmanager
- 日志中心
- filebeat安裝
- kafka安裝
- logstash安裝
- elasticsearch安裝
- elasticsearch索引生命周期管理
- kibana安裝
- event事件收集
- 資源預留
- 節點資源預留
- imagefs與nodefs驗證
- 資源預留 vs 驅逐 vs OOM
- scheduler調度原理
- Helm
- Helm安裝
- Helm基本使用
- 安全
- apiserver審計日志
- RBAC鑒權
- namespace資源限制
- 加密Secret數據
- 服務網格
- 備份恢復
- Velero安裝
- 備份與恢復
- 常用維護操作
- container runtime
- 拉取私有倉庫鏡像配置
- 拉取公網鏡像加速配置
- runtime網絡代理
- overlay2目錄占用過大
- 更改Docker的數據目錄
- Harbor
- 重置Harbor密碼
- 問題處理
- 關閉或開啟Harbor的認證
- 固定harbor的IP地址范圍
- ETCD
- ETCD擴縮容
- ETCD常用命令
- ETCD數據空間壓縮清理
- ingress
- ingress-nginx header配置
- kubernetes
- 驗證yaml合法性
- 切換KubeProxy模式
- 容器解析域名
- 刪除節點
- 修改鏡像倉庫
- 修改node名稱
- 升級k8s集群
- 切換容器運行時
- apiserver接口
- 其他
- 升級內核
- k8s組件性能分析
- ETCD
- calico
- calico健康檢查失敗
- Harbor
- harbor同步失敗
- Kubernetes
- 資源Terminating狀態
- 啟動容器報錯