资源请求属性
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 dashboard@kubernetes.admin --cluster=kubernetes --user=dashboard --kubeconfig=/root/k8s-dash-user.conf # 切换使用这个上下文 ]# kubectl config use-context --kubeconfig=/root/k8s-dash-user.conf dashboard@kubernetes.admin ]# 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: dashboard@kubernetes.admin current-context: dashboard@kubernetes.admin 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 推荐使用这种