经过了API对象和自定义控制器两节的内容,可以自己实现一个编排对象,并为这个对象实现自己的控制器模式。
k8s项目,可以基于插件来完成这些工作而完全不需要修改任何代码。但是外部插件在k8s中新增和操作API对象,就需要先了解一下RBAC。
因为对k8s中任何API对象的操作都是通过访问kube-apiserver来完成的。需要APIServer来完成授权工作,k8s中授权工作的机制就是RBAC。
RBAC最基本的三个概念:
- Role:角色。一组规则,定义了一组对k8s API对象的操作权限。
- Subject:被作用者。可以是“人”,“机器”,也可以是k8s中定义的“用户”。
- RoleBinding:定义了“被作用者”和用户之间的绑定关系。
k8s中Role就是一个API对象:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: mynamespace
name: example-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]这个Role对象指定了能够作用的Namespace,Namespace 是 Kubernetes 项目里的一个逻辑管理单位。不同 Namespace 的 API 对象,在通过 kubectl 命令进行操作的时候,是互相隔离开的。默认的kubectl命令默认的Namespace是default。
这个角色就是允许“被作用者”,对 mynamespace 下面的 Pod 对象,进行 GET、WATCH 和 LIST 操作。
通过RoleBinding将角色与被作用者进行绑定,RoleBinding也是一个API对象:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: example-rolebinding
namespace: mynamespace
subjects:
- kind: User
name: example-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: example-role
apiGroup: rbac.authorization.k8s.io而User只是一个逻辑概念,需要通过外部认证服务,例如keyStore来提供,或者直接给APIServer指定一个用户名,密码文件。
RoleBinding通过roleRef字段进行关系绑定。Role 和 RoleBinding 对象都是 Namespaced 对象(Namespaced Object),它们对权限的限制规则仅在它们自己的 Namespace 内有效,roleRef 也只能引用当前 Namespace 里的 Role 对象。
对于非 Namespaced(Non-namespaced)对象(比如:Node),或者,某一个 Role 想要作用于所有的 Namespace 的时候,我们又该如何去做授权呢?
使用 ClusterRole 和 ClusterRoleBinding 这两个组合了
用法与Role 和 RoleBinding 完全一样。只不过,它们的定义里,没有了 Namespace 字段,
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: example-clusterrole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: example-clusterrolebinding
subjects:
- kind: User
name: example-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: example-clusterrole
apiGroup: rbac.authorization.k8s.io通过这两者组合授权的用户具有操作所有Namespace里对应对象的权限。
Role对象的rule字段也可以进一步细化,只对某一具体的对象进行权限设置。
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["my-config"]
verbs: ["get"]在大多数时候,我们其实都不太使用“用户”这个功能,而是直接使用 Kubernetes 里的“内置用户”。通过一个具体的实例来为你讲解一下为 ServiceAccount 分配权限的过程.
首先定义一个 ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: mynamespace
name: example-sa然后,我们通过编写 RoleBinding 的 YAML 文件,来为这个 ServiceAccount 分配权限:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: example-rolebinding
namespace: mynamespace
subjects:
- kind: ServiceAccount
name: example-sa
namespace: mynamespace
roleRef:
kind: Role
name: example-role
apiGroup: rbac.authorization.k8s.io接着,我们用 kubectl 命令创建这三个对象:
$ kubectl create -f svc-account.yaml
$ kubectl create -f role-binding.yaml
$ kubectl create -f role.yaml查看创建的serverAccount可以发现,k8s自动为一个ServiceAccount创建并分配一个Secret对象,用来跟APIServer交互。
创建的Pod可以指定创建的ServiceAccount
apiVersion: v1
kind: Pod
metadata:
namespace: mynamespace
name: sa-token-test
spec:
containers:
- name: nginx
image: nginx:1.7.9
serviceAccountName: example-sa这个ServiecAccount会自动挂载到容器的/var/run/secrets/kubernetes.io/serviceaccount 目录下,这样容器里的应用就可以通过目录中的授权文件来访问APIServer了。