資源請求屬性
Kubernetes是基於http或https協議工作的(restful風格),因此其對應的操作請求,無非就是增刪改查(get、put、delete),因此在每一個Kubernetes的相關請求當中,通常這個請求會包含類似以下的信息; 理論來源
user: 用戶名稱;
group: 用戶所屬的組;
extra: 額外屬性;
Resource: 指定使用哪個Kind資源;
Subresource: 額外資源的子資源;
API: 也就是我們的Kubernetes標準資源屬於哪一個API羣組下面的那個API;
Namespace: 名稱空間;
Request path: 相對於我們API來講,就是請求的URL路徑;
HTTP request verb:HTTP請求方法,GET、DELETE...;
API request verb:向Kubernetes API的請求方法,比如get、list、create、update、patch、watch、proxy、redirect、delete以及deletecollection;
授權插件
- Node:節點認證,根據Pod對象調度的結果爲Node進行授權,Node會自動授權Pod的相關定義的訪問權限;
- ABAC:基於屬性的訪問控制,RBAC之前的算法,1.6之前的版本使用;
- RBAC:Role-based AC, 基於角色的訪問控制,事先定義好角色,直接將權限賦予給角色,只要用戶屬於這個角色也就有該賦予的權限;
- Webhook:web鉤子,其實也就是一個http的回調函數,一般而言就是某一個http上的資源發生變化時,能夠發起觸發,然後做出相應的操作;
RBAC
在k8s1.8之後的版本強制使用RBAC用戶授權,任何人的操作必須在RBAC中有明確定義,無定義無權限,匿名用戶默認無權限,包括剛認證的用戶也只有極少數權限,使用rbac.authorization.k8s.io API驅動授權決策,並支持動態配置,RBAC的出現是因爲SA只認證不授權,也就是默認權限全開;
查看默認授權插件可通過kubadm部署的集羣中查看: /etc/kubernetes/manifests/kube-apiserver.yaml
RBAC的實現方式
爲了實現RBAC,我們需要定義如下消息
- 用戶,我們稱之爲Subjects主語,而這個用戶賬號有兩種,這就是我們RBAC可以拿來當主語的東西;
- 第一種: UserAccount;
- 第二種: ServiceAccount;
- 資源,我們稱之爲Object賓語,在k8s能夠被操作的資源有三類
- 第一類: Resources,比如Pod,Deployment這都是資源;
- 第二類: SubResouces(子資源),比如Pod的logs或者status或者URL類型的非對象型資源;
- 第三種: Role和RoleBinding,在Role當中我們定義能夠對哪個或哪些資源定義哪些操作,比如允許用戶get、put在集羣上的deployment資源,如果需要某個用戶來扮演這個角色,那我們就需要使用RoleBinding,從而使得讓Subjects擁有Role的權限,Role還分爲Role和ClusterRole,集羣級別和namespace級別,RoleBinding還分爲RoleBinding和ClusterRoleBinding,將Role綁定集羣級別和namespace;
角色(role)說明
- 角色: k8s中授權的機制,一個組織或者任務中的工作位置,其表示爲一種責任或資格, 後續的許可授權都添加在角色上, 隨後在讓用戶扮演這個角色,這個用戶就相當於擁有了這個角色權限
- 權限: 基於所謂的對象,每一個被訪問的組件都是對象,在restful的api當中一切皆對象,k8s上運行的組件可分爲三種:
- 對象: 一種角色扮演
- 對象列表: 在api當中一切皆對象
- 虛擬路徑(非對象資源或非資源url):
- Operations:在restful基礎中所有的操作,都是指在某個對象上施加的某個行爲(action),在一個對象上施加的組合請求叫許可權限, 在Role之上可以授予一個許可權限
- 要想實現使用基於的訪問控制應當具備的條件: user, role, permissions(operations, objects)
- role需要定義的 :
- operations:操作屬性
- objects:對哪些對象執行什麼操作, 寫了就是允許,沒寫就拒絕
- 用戶帳號
- rolebinding: 將 用戶帳號 綁定在 哪個 角色上,
所有的授權都是指派在角色之上,讓用戶添加角色即可獲取相對應的權限。
對象引用的URL格式: 名稱空間級別: /apis/<GROUP>/<VERSION>/namespace/<NAMESPACE_NAME>/<KIND>[/OBJECT_ID]
普通角色
在k8s之上,role, rolebinding分別擁有有兩個級別
- 集羣
- 名稱空間: role, rolebinding主要是在名稱空間級別範圍內的許可權限
集羣角色
集羣級別的用戶角色綁定
- clusterrole: 集羣角色
- clusterrolebinding: 集羣角色綁定
rolebinding綁定role: 在名稱空間A中 (default) 定義了一個角色 Role-A, 與用戶A-user建立綁定關係,從而A-user就擁有了當前 (default) 名稱空間的權限, 而不是集羣上的名稱空間權限
clusterrolebinding綁定clusterrole: 在集羣級別定義一個clusterRole, 該用戶就能獲取所有名稱空間的權限
rolebinding綁定ClusterRole: 意味着 這個用戶能獲取所屬名稱空間的所有權限, 使用範圍:假設如果該節點有N個名稱空間, 那麼就需要定義N個role然後進行綁定, 此時定義clusterRole那麼只需要綁定一個cluserRole就能獲取所有名稱空間權限了
- 說明: 就好比 role是單個名稱空間的權限, 而clusterrole卻可以定義多個或全部名稱空間的權限
RBAC-示例
查看api資源詳細信息:
kubectl api-resources
一、rolebinding綁定role
- 創建role
]# kubectl create role pod-reader --verb=get,list,watch --resource=pods --dry-run -o yaml # 創建,不加 --dry-run -o yaml執行
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: pod-reader
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
-
查看role
]# kubectl describe role pod-reader Name: pod-reader Labels: <none> Annotations: PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list watch]
參數 說明 Resources 資源類別, 一整類下的所有資源 object Non-Resource URLs 非資源URL,某種特殊操作 Resource Names 資源名稱,針對這個資源類別的某個特定資源進行操作 Verbs 允許操作的方式,[get、list、create、update、patch、watch、proxy、redirect、delete以及deletecollection] -
創建rolebinding
角色(權限), 用戶 --> rolebinging ]# kubectl create rolebinding xiong-role --role=pod-reader --user=xiong-k8s --dry-run=client -o yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: creationTimestamp: null name: xiong-role roleRef: # 引用 role apiGroup: rbac.authorization.k8s.io kind: Role # role 資源類型 name: pod-reader # role資源名稱 subjects: # 執行主題 綁定哪個用戶 - apiGroup: rbac.authorization.k8s.io kind: User # User資源類別是不存在的 name: xiong
-
查看綁定關係
]# kubectl get rolebindings
NAME ROLE AGE
xiong-role Role/pod-reader 8s
]# kubectl describe rolebindings xiong-role
Name: xiong-role
Labels: <none>
Annotations: Role:
Kind: Role
Name: pod-reader
Subjects:
Kind Name Namespace
---- ---- ---------
User xiong
- 切換用戶
# 創建一個私鑰
]# openssl genrsa -out lzx.key 4096
# 爲證書生成一個證書籤署請求,並且使用kubernetes的CA來簽署, CN代表用戶名, 0組織表示組
]# openssl req -new -key lzx.key -out lzx.csr -subj "/CN=xiong/O=kubernetes"
]# openssl x509 -req -in lzx.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out lzx.crt -days 3650
]# kubectl config set-credentials xiong --client-certificate=/etc/kubernetes/lzx/lzx.crt --client-key=/etc/kubernetes/lzx/lzx.key --embed-certs=true
]# kubectl config set-context xiong-k8s --cluster=kubernetes --user=xiong
]# kubectl config use-context xiong-k8s
]# kubectl get pods
NAME READY STATUS RESTARTS AGE
t3-xiong 1/1 Running 1 6d2h
# 查看svc就沒有權限了,只能查看 default名稱空間
]# kubectl get svc
Error from server (Forbidden): services is forbidden: User "xiong" cannot list resource "services" in API group "" in the namespace "default"
二、集羣角色綁定
創建一個ClusterRole允許訪問集羣級別的資源,集羣級別權限就是最大的,不侷限於namespace,也就是說權限再不受namespace的控制,比如授予了一個list權限,那就可以查看整個集羣所有的namespace,不侷限於namespace,它和Role的區別也僅僅是namespace
- 創建 clusterrole
]# 創建之前先切換回有權限用戶 kubectl config use-config kubernetes-admin@kubernetes
]# kubectl create clusterrole cluster-pod-read --verb=get,list,patch --resource=pods --dry-run=client -o yaml > cluster-pod-read.yaml
]# cat cluster-pod-read.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-pod-read
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- patch
]# kubectl apply -f cluster-pod-read.yaml
- 查看資源
]# kubectl get clusterrole cluster-pod-read
NAME CREATED AT
cluster-pod-read 2020-05-13T09:10:42Z
]# kubectl describe clusterrole cluster-pod-read
Name: cluster-pod-read
Labels: <none>
Annotations: PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get list patch]
- clusterbinding創建
]# kubectl create clusterrolebinding clusterbind-pod-all --clusterrole=cluster-pod-read --user=xiong --dry-run=client -o yaml > clusterbind-pod-all.yaml
]# cat clusterbind-pod-all.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
creationTimestamp: null
name: clusterbind-pod-all
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-pod-read
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: xiong
]# kubectl apply -f clusterbind-pod-all.yaml
- 查看綁定關係
]# kubectl get clusterrolebindings clusterbind-pod-all
NAME ROLE AGE
clusterbind-pod-all ClusterRole/cluster-pod-read 40s
]# kubectl describe clusterrolebindings clusterbind-pod-all
Name: clusterbind-pod-all
Labels: <none>
Annotations: Role:
Kind: ClusterRole
Name: cluster-pod-read
Subjects:
Kind Name Namespace
---- ---- ---------
User xiong
# 切換用戶前先刪除原先的 role 然後使用集羣角色進行測試
- 效果
# 查看pod下所有的名稱空間,沒問題
~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-0 0/1 ContainerCreating 0 27h
myapp-1 0/1 Error 0 4d8h
myapp-2 0/1 Error 0 4d8h
myapp-3 0/1 Error 0 4d8h
myapp-4 0/1 Error 0 4d8h
pod-sa 1/1 Running 0 27h
s1-secret 1/1 Running 1 6d2h
t3-xiong 1/1 Running 1 6d3h
~]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-67754f4878-fr8cz 1/1 Running 1 2d2h
~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-7ff77c879f-4pbhq 1/1 Running 1 6d5h
# 在verbs中沒有定義delete就不能進行操作啦
~]# kubectl delete pod myapp-1
Error from server (Forbidden): pods "myapp-1" is forbidden: User "xiong" cannot delete resource "pods" in API group "" in the namespace "default"
三、rolebinding綁定ClusterRole
# 刪除上面綁定的clusterrolebind
# 將rolebinding綁定至clusterrole
]# kubectl create rolebinding rolebind-clusterrole-pod-read --clusterrole=cluster-pod-read --user=xiong --dry-run=client -o yaml > rolebind-clusterrole-pod-read.yaml
]# kubectl apply -f rolebind-clusterrole-pod-read.yaml
rolebinding.rbac.authorization.k8s.io/rolebind-clusterrole-pod-read created
]# kubectl get rolebindings rolebind-clusterrole-pod-read
NAME ROLE AGE
rolebind-clusterrole-pod-read ClusterRole/cluster-pod-read 26s
]# kubectl describe rolebindings rolebind-clusterrole-pod-read
Name: rolebind-clusterrole-pod-read
Labels: <none>
Annotations: Role:
Kind: ClusterRole
Name: cluster-pod-read
Subjects:
Kind Name Namespace
---- ---- ---------
User xiong
]# kubectl get pods
NAME READY STATUS RESTARTS AGE
t3-xiong 1/1 Terminating 1 6d21h
# 將 普通角色綁定到集羣角色,其實是一個降級降維的結果, 訪問的最終還是該節點的默認名稱空間
]# kubectl get pods -n ingress-nginx
Error from server (Forbidden): pods is forbidden: User "xiong" cannot list resource "pods" in API group "" in the namespace "ingress-nginx"
Kubernetes內建Cluster
通過: kubectl get clusterRole
可以查看所有的集羣角色
- cluster-admin:超級管理員權限,擁有整個集羣的所有權限;
- admin:假如需要授權一個用戶對某個名稱空間具有管理員權限,那麼就可以使用rolebinding綁定到這個admin的集羣角色,自動成爲該名稱空間的管理員;
- edit:假如需要授權一個用戶對某個名稱空間具有修改權限,那麼就可以使用rolebinding綁定到這個edit的集羣角色,然後就可以修改該名稱空間的資源了;
- view:假如需要授權一個用戶對某個名稱空間具有查看你權限,那麼就可以使用rolebinding綁定到這個view的集羣角色,然後就可以查看該名稱空間的資源了;
總結
通過 clusterrole get綁定clusterrolebind擁有集羣中整個名稱空間pod資源的查看權限,rolebind綁定clusterrole則是一個降維的過程,跟role綁定rolebind是一樣的權限, 通過cluster-admin綁定clusterrolebind則是超級管理員權限, 權限操作過程,需要先定義用戶[注意證書],然後 配置角色(role|clusterrole), 最後在通過 rolebind或clusterrolebind綁定 role|clusterrole跟用戶,最後在切換用戶,在普通客戶機上定義用戶時需要指定service的路徑
dashboard
Dashboard 是基於網頁的 Kubernetes 用戶界面。您可以使用 Dashboard 將容器應用部署到 Kubernetes 集羣中,也可以對容器應用排錯,還能管理集羣資源。您可以使用 Dashboard 獲取運行在集羣中的應用的概覽信息,也可以創建或者修改 Kubernetes 資源(如 Deployment,Job,DaemonSet 等等)。例如,您可以對 Deployment 實現彈性伸縮、發起滾動升級、重啓 Pod 或者使用嚮導創建新的應用。
kubeadm安裝和部署的集羣默認是強制啓動的rbac, 而dashboard接口是管理所有集羣的接口,登陸dashboard只是一個認證代表,所有的帳號應該是k8s的帳號以及授權
部署 Dashboard UI
默認情況下不會部署 Dashboard。可以通過以下命令部署:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml
查看
]# kubectl get svc -n kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dashboard-metrics-scraper ClusterIP 10.105.31.103 <none> 8000/TCP 48s
kubernetes-dashboard ClusterIP 10.108.182.92 <none> 443/TCP 50s
]# kubectl get pods -n kubernetes-dashboard
NAME READY STATUS RESTARTS AGE
dashboard-metrics-scraper-6b4884c9d5-4z4h9 1/1 Running 0 75s
kubernetes-dashboard-7b544877d5-4tmnc 1/1 Running 0 76s
訪問Dashboard
集羣外連接
-
定義一個Nodeport
]# cat k8s-dashboard.yaml apiVersion: v1 kind: Service metadata: name: k8s-dashboard namespace: kubernetes-dashboard labels: # 需要先查看 deployment對應的dashboard的label k8s-app: kubernetes-dashboard spec: selector: k8s-app: kubernetes-dashboard type: NodePort clusterIP: "" ports: - name: k8s-dashboard-http port: 8443 nodePort: 30443
-
直接修改
]# kubectl get svc -n kubernetes-dashboard NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes-dashboard ClusterIP 10.108.182.92 <none> 443/TCP 114m ]# kubectl patch svc -p '{"spec":{"type":"NodePort"}}' -n kubernetes-dashboard kubernetes-dashboard # 通過 這個隨機端口也能直接訪問 kubernetes-dashboard NodePort 10.108.182.92 <none> 443:30993/TCP 117m
通過Token訪問
admin權限
需要使用: ServerAccount而不是直接寫義某個系統用戶
創建一個管理員權限的帳號: service-accout綁定在cluster-admin角色上
# 創建一個sa
]# kubectl create sa k8s-dashboard-sa -n kube-system
# 綁定一個admin的集羣admin權限sa
]# kubectl create clusterrolebinding k8s-cls-dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:k8s-dashboard-sa
# serviceaccount=左名稱空間:sa名稱
]# kubectl describe clusterrolebindings k8s-cluster-dashboard
Name: k8s-cluster-dashboard
Labels: <none>
Annotations: <none>
Role:
Kind: ClusterRole
Name: cluster-admin
Subjects:
Kind Name Namespace
---- ---- ---------
ServiceAccount k8s-dashboard-sa kube-system
# 查看sa的token
]# kubectl describe secrets k8s-dashboard-sa-token-nqz74
Name: k8s-dashboard-sa-token-kxmks
Namespace: kube-system
Type: kubernetes.io/service-account-token
Data
====
namespace: 7 bytes
token: # 這段token用來登陸
ca.crt: 1025 bytes
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-fzrcYfCc-1593652468945)(C:\Users\xiong\AppData\Roaming\Typora\typora-user-images\image-20200514160245370.png)]
普通名稱空間權限
# 1、創建一個sa
]# kubectl create sa def-dashboard-sa
2、創建一個普通角色 權限綁定集羣角色
]# kubectl create rolebinding def-dashboard-sa --clusterrole=admin --serviceaccount=default:def-dashboard-sa
3、查看token
]# kubectl describe secrets def-dashboard-sa-token-2lcmp
Name: def-dashboard-sa-token-2lcmp
Namespace: default
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1025 bytes
namespace: 7 bytes
token: 這裏是token
此時就只剩下一個名稱空間的內容了
通過.conf訪問
-
創建ServiceAccount, 根據其管理目標, 使用rolebinding或clusterrolebinding綁定至合理role或clusterrole
]# kubectl create sa dash-cf-sa ]# kubectl create rolebinding dash-cf-sa --clusterrole=admin --serviceaccount=defalut:dash-cf-sa
-
獲取as的token
# 將base64加密的token解密,用於kubeconfig文件使用 KUBE_DASH_SA=$(kubectl get secrets dash-cf-sa-token-4nln4 -o jsonpath= {".data.token"} | base64 -d)
-
生成kubeconfig文件
kubectl config set-cluster kubectl config set-credentisales NAME --token= kubectl config set-context kubectl config use-context # 設定連接地址 ]# kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://192.168.2.220:6443 --kubeconfig=/root/k8s-dash-user.conf # 指定token ]# kubectl config set-credentials dashboard --token=$KUBE_DASH_SA --kubeconfig=/root/k8s-dash-user.conf # 將連接地址與token進行綁定,定義一個上下文 ]# kubectl config set-context [email protected] --cluster=kubernetes --user=dashboard --kubeconfig=/root/k8s-dash-user.conf # 切換使用這個上下文 ]# kubectl config use-context --kubeconfig=/root/k8s-dash-user.conf [email protected] ]# cat /root/k8s-dash-user.conf apiVersion: v1 clusters: - cluster: certificate-authority: /etc/kubernetes/pki/ca.crt server: https://192.168.2.220:6443 name: kubernetes contexts: - context: cluster: kubernetes user: dashboard name: [email protected] current-context: [email protected] kind: Config preferences: {} users: - name: dashboard user: token: 這個是token內容
-
驗證,下載這個conf文件, 然後登陸
k8s集羣的管理方式:
- 命令式: create , run , expose, delete, edit
- 命令式配置文件: create -f /PATH/TO/resource_container_file, delete -f, replace -f
- 聲明式配置文件: apply -f, patch 推薦使用這種