在Kubernetes 1.8版本中,RBAC已经毕业成为生产可用的特性,在很多组件诸如Dashboard、Helm (Helm 2)、Prometheus等在1.8版本之后使用的时候不可避免的碰到RBAC,这篇文章通过在Kubernetes中使用Prometheus所需要准备的事项来介绍一下RBAC如何使用。
事前准备
准备Kubernetes环境,本文使用Kubernetes 1.17版本
[root@host131 ansible]# kubectl version
Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-07T21:20:10Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-07T21:12:17Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}
[root@host131 ansible]# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
192.168.163.131 Ready <none> 18m v1.17.0 192.168.163.131 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 docker://18.9.7
[root@host131 ansible]#
可参看下文进行快速环境搭建:
步骤1: 创建角色
角色是一系列权限的集合,Kubernetes中可以创建Role和ClusterRole,两者的区别在于Role是基于命名空间的角色,而如果希望在整个集群中有效的角色则需要使用ClusterRole。比如如下创建一个名为prometheus的ClusterRole:
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups: [""]
resources:
- nodes
- nodes/proxy
- services
- endpoints
- pods
verbs: ["get", "list", "watch"]
- apiGroups:
- extensions
resources:
- ingresses
verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
...
内容说明:
- apiGroups:访问控制实际上是通过对于API的访问控制来实现的,而由于不同的资源相应的api隶属于不同的apiGroups,比如Pod属于core apiGroup,而Deployment属于apps apiGroup,所以在设定的时候需要指定。本例中设定为"",代表指定core apiGroups。
- resources:指定资源的类型,比如node、pod、service
- verbs:对于资源可以进行的操作的类型,比如get、create、list、delete、update、edit、watch、exec等操作。
- rules:对于不同的apiGroups上的资源(resources)可以执行什么样的操作(verbs)的设定被称为规则,在一个角色中可设定多条规则
创建命令:kubectl create -f yaml文件名称
步骤2: 创建用户(Subject)
Kubernetes中的用户(Subject)分为三类:Service Account、User Account和Group。用户指定的是操作对象的类型,这里创建Service Account,yaml文件比较简单,创建一个名为prometheus的Service Account,内容如下所示:
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus
namespace: default
...
内容说明:
- namespace: Service Account需要存在于特定的命令空间之中,本例的账户存在于default的命名空间中
创建命令:kubectl create -f yaml文件名称
步骤3: 绑定角色与用户
将包含一组权限的角色与特定用户进行关联在Kubernetes中被成为绑定,而绑定的过程就是授权的过程。Kubernetes的角色分为Role和ClusterRole,而绑定也相应的分为RoleBinding和ClusterRoleBinding。
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: default
...
内容说明:
- roleRef: 指定要绑定的角色信息
- subjects:指定要绑定的用户信息
创建命令:kubectl create -f yaml文件名称
执行示例:这里将上述三个yaml设定的内容合并到一个文件中一起执行,结果如下所示:
[root@host131 kubernetes]# kubectl get sa |grep prometheus
[root@host131 kubernetes]# kubectl get clusterrole |grep prometheus
[root@host131 kubernetes]# kubectl get clusterrolebindings |grep prometheus
[root@host131 kubernetes]#
[root@host131 kubernetes]# kubectl create -f rabc-prometheus.yml
clusterrole.rbac.authorization.k8s.io/prometheus created
serviceaccount/prometheus created
clusterrolebinding.rbac.authorization.k8s.io/prometheus created
[root@host131 kubernetes]#
[root@host131 kubernetes]# kubectl get sa |grep prometheus
prometheus 1 4s
[root@host131 kubernetes]# kubectl get clusterrole |grep prometheus
prometheus 8s
[root@host131 kubernetes]# kubectl get clusterrolebindings |grep prometheus
prometheus 12s
[root@host131 kubernetes]#
步骤4: 使用Service Account创建Pod
使用上述设定权限之后的Service Account创建Pod,此用户所需要使用的token或者证书的信息均可在Pod中进行查看,设定方式也很简单,只需要设定如下信息即可:
serviceAccountName: prometheus
serviceAccount: prometheus
示例yaml文件如下所示
[root@host131 kubernetes]# cat prometheus-deployment.yml
---
apiVersion: v1
kind: "Service"
metadata:
name: prometheus
labels:
name: prometheus
spec:
ports:
- name: prometheus
protocol: TCP
port: 9090
targetPort: 9090
nodePort: 36613
selector:
app: prometheus
type: NodePort
...
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
name: prometheus
name: prometheus
spec:
replicas: 1
selector:
matchLabels:
app: prometheus
template:
metadata:
labels:
app: prometheus
spec:
serviceAccountName: prometheus
serviceAccount: prometheus
containers:
- name: prometheus
image: prom/prometheus:v2.15.1
command:
- "/bin/prometheus"
args:
- "--config.file=/etc/prometheus/prometheus.yml"
ports:
- containerPort: 9090
protocol: TCP
volumeMounts:
- mountPath: "/etc/prometheus"
name: prometheus-configmap
volumes:
- name: prometheus-configmap
configMap:
name: prometheus-configmap
...
[root@host131 kubernetes]#
由于此示例中使用的Prometheus使用了ConfigMap,所以可以先行设定ConfigMap
[root@host131 kubernetes]# cat prometheus.yml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-configmap
namespace: default
data:
prometheus.yml: |
global:
scrape_interval: 10s
evaluation_interval: 10s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
...
[root@host131 kubernetes]#
[root@host131 kubernetes]# kubectl create -f prometheus.yml
configmap/prometheus-configmap created
[root@host131 kubernetes]# kubectl get cm |grep prometheus
prometheus-configmap 1 9s
[root@host131 kubernetes]#
然后使用此Service Account创建对应的Pod
[root@host131 kubernetes]# kubectl create -f prometheus-deployment.yml
service/prometheus created
deployment.apps/prometheus created
[root@host131 kubernetes]#
确认Pod信息
[root@host131 kubernetes]# kubectl get pods
NAME READY STATUS RESTARTS AGE
prometheus-7b548d854-bhq8k 1/1 Running 0 15s
[root@host131 kubernetes]#
相应的信息会保存在/var/run/secrets/kubernetes.io/serviceaccount/目录下,使用kubectl exec 进入到此Pod中进行结果的确认:
[root@host131 kubernetes]# kubectl exec -it prometheus-7b548d854-bhq8k sh
/prometheus $ cd /var/run/secrets/kubernetes.io/serviceaccount/
/var/run/secrets/kubernetes.io/serviceaccount $ ls
ca.crt namespace token
/var/run/secrets/kubernetes.io/serviceaccount $ cat namespace
/var/run/secrets/kubernetes.io/serviceaccount $ cat token
eyJhbGciOiJSUzI1NiIsImtpZCI6InN5V2d1RWs4dXI3WDF2VGJwOGJlSzQ4V2Y3Z3AyMGY5YjVYMWJLc0dGNjAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InByb21ldGhldXMtdG9rZW4temNzY2giLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicHJvbWV0aGV1cyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImY5MmQ4YzU0LTQ5NzktNGQyNy05NGNjLTlhODYyNTdmMTI5YiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OnByb21ldGhldXMifQ.A6d7kKjJuEfJEuxYX_LyxpPcrHa8tNnxYs0C6fXK7czcdflbgoKJkMpEcHm-jJ2DwOGYMMyxuCruSSh8D9a9PupANiGvhN9Zq_YkMyU0PquHJReL8GMHjA2QFWwgKyHpQlulvbfkTmRdVF6--anKOTrqnAGwHo61RcBUWsZJnA_uv43lKgUI9vtpcDE6emxJVOkGhysMYLn-uKXN5D0KmKKsQxmFeyHqTmNYUIkEnAZTN4AVhr7DgEgVeHZUPTeH2OcPQQunYC1PbZxvLp-QK0RGjxITtdF4uUam-iPyvVrEw4bjNBvta9D2ITtz43X5fkJozMye9PLHAUHCpYkvaw/var/run/secrets/kubernetes.io/serviceaccount $
总结
创建角色和用户,然后进行关联,在创建Pod的时候指定此用户,即可使用,大部分组件均可使用此种方式在Kubernetes中使用。