理解OpenShift(1):网络之 Router 和 Routehtml
理解OpenShift(2):网络之 DNS(域名服务)node
理解OpenShift(4):用户及权限管理github
理解OpenShift(5):从 Docker Volume 到 OpenShift Persistent Volume微信
** 本文基于 OpenShift 3.11,Kubernetes 1.11 进行测试 ***网络
OpenShift 支持 RBAC(Role Based Access Controll),基于角色的访问控制。它涉及诸多概念,本文尝试着作一些概念上的梳理,不少细节还须要进一步研究。app
我试着把一个OpenShift 环境中的全部用户分为三大类:ide
认证是确认用户身份是否合法的过程。这能够有多种实现方式,好比用户名/密码、令牌(token)、证书等。不一样类型的用户有不一样的身份管理方式:post
受权是对被认证了的用户访问受控制的资源的权限进行控制。按照资源类型,OpenShift 将受权管理方式分为两大类:测试
就像人的身份证同样,identity 是一个 user 的身份信息,该信息用于用户认证。OpenShift 本身并无实现用户身份信息库,而是经过灵活支持多种 identity provider,来实现各类不一样的身份管理方案。每种实现都以不一样的方式保存着用户的身份信息,好比保存在LDAP 中,保存在 htpasswd 文件中,保存在 OpenStack Keystone 中。
所以,OpenShift 对 user 身份的校验是经过这些配置了的 identity provider 进行的。所以,还须要 OpenShift user 和这些 provider 里面的 identity 的映射关系。OpenShfit 支持四种映射管理,claim,lookup,generate,add。具体请参考官网 https://docs.openshift.com/container-platform/3.11/install_config/configuring_authentication.html#identity-providers_parameters。
上图中以 htpasswd 这种 identity provider 为例,说明了从零建立一个 openshift user,在 htpasswd 中建立 user 及其密码,而后建立 openshift identity 对象以及 useridentitymapping 对象的过程。
用户获取用于身份认证的token的过程:
<master>/oauth/token
。每一个申请 OAuth token 的请求中都必须带有 OAuth client 标识,这是一个 OAuthClient 对象。具体请参阅官方文档。前文说了,角色用于控制对 OpenShift 资源的访问权限,它分为项目角色和集群角色。
OpenShift 系统默认会建立不少的集群角色。经常使用的角色的简单描述以下:
admin |
|
basic-user |
|
cluster-admin |
|
cluster-status |
|
edit |
|
self-provisioner |
|
view |
|
能够查看全部角色,好比 system:router 角色:
可使用 oc adm policy 命令向用户或用户授予角色:
user、group、role、rolebinding 之间的关系:
更多对 role 的说明,可参见官方文档。
OpenShift 的 service account 比较复杂,和不少概念都有关联。官方文档在 https://docs.openshift.com/container-platform/3.11/dev_guide/service_accounts.html。该文档对为何须要这个概念的说明是:当一个天然人用户访问 OpenShfit API 时,OpenShift 对它进行用户认证和权限控制。可是,有时候作操做的并非天然人用户,好比:
为了这种访问,OpenShift 创造了 Service Account (简称sa)概念。每一个项目(project)默认都会自动建立3个sa user:
Service Account | Usage |
---|---|
builder |
用于 build pod。它被授予了 system:image-builder 角色,所以被容许向内部镜像仓库中的任意 image stream 上push 镜像。 |
deployer |
用于 deployment pod。被授予了 system:deployer 角色,所以被容许查看和修改集群中的 RC 及其 pod。 |
default |
当一个 pod 没有显式指定 service account 默认都会使用该 sa user。 |
sa 利用 secret(token)来保存其身份信息。默认状况下,每一个 sa 用户都有两种token,即访问 OpenShift API 的token和访问内部镜像仓库的token。以系统默认的 『builder』 sa user 为例,它包含一个用于拉取镜像的token secret,两个访问API 的token secret,三个secret 中只有两个能被以卷的形式挂接给pod:
能够按需求修改一个 sa 帐户的这些token。可参考 https://docs.openshift.com/enterprise/3.0/dev_guide/image_pull_secrets.html 为service account 建立和添加新的用于拉取镜像的token secret。具体请参考官方文档。
其中,sa 的 API token 会被挂接到 pod 的 目录的 token 文件,从而使得 pod 中的应用能够读取该 token 去访问 OpenShift API:
image pull secret 是如何挂载到 pod 的,我尚未找到。并且在 pod spec 中,只看到 API token secret 的 mountpoint,而并无 imagePullSecret 的 mountpoint:
和天然人 user 相似,对 sa 用户访问OpenShift 集群资源的权限控制是经过 role 进行的。前面的表格代表,项目的两个默认 sa builder 和 deployer 都被授予了相应的 role,从而能访问指定的资源。而默认的 sa 用户,只被授予了 /system:image-puller 角色。这意味着默认的 sa 用户只能拉取镜像,而不能访问集群其它资源。
下图是项目 stage 中的 rolebinding:
用户组 system:serviceaccounts:stage 中包括该项目中的全部 sa 用户。利用 default sa user 来作下实验。先获取其 API token,而后登陆进 OpenShift 集群:
调用 API 获取 pod,结果失败:
向 default sa user 授予 cluster-reader 角色:
而后就能够作集群资源查询操做了。
pod 中的应用除了有访问 OpenShift API 和内部镜像仓库以外,还有一些系统资源访问要求。好比:
对于这些操做系统资源的访问权限,OpenShift 利用 scc 来进行控制。这就要求:
前面说过,SCC 用于控制访问系统资源的权限,那说明只有 service account 才须要使用 scc。没在文档中看到天然人用户 user 使用 scc 的例子。
Linux 中的权限控制非常复杂,这里就不说明了,我本身也没怎么弄清楚。OpenShift scc 将系统权限分为几大类,具体见上图中的『权限』部分,而后能够建立 scc 对象来精细地控制对每种权限的控制。
由于这很是繁琐,所以 OpenShift 默认建立了几个典型的 scc,列表以下。上图中的『系统预约义scc』部分有简要说明,这里再也不重复。
其中,若是 pod 所使用的 scc 的 runAsUser
策略被设置为了 MustRunAsRange,那么 pod 所使用的 uid 和 supplemental-group id 必须在某区间以内。
集群管理员能够在 scc 中设置区间,好比:
可是,OpenShift 默认提供的 scc 都没有设置该区间,而是使用 pod 所在的 project 中定义的区间以内。好比:
[root@master2 cloud-user]# oc describe project dev Name: dev Created: 3 weeks ago Labels: <none> Annotations: openshift.io/description= openshift.io/display-name= openshift.io/requester=demo openshift.io/sa.scc.mcs=s0:c16,c0 openshift.io/sa.scc.supplemental-groups=1000000000/10000 openshift.io/sa.scc.uid-range=1000000000/10000
每一个 project 会被分配不一样的 ID 区间。当未指定 uid 和 supplemental gid 时,会默认使用区间的最小值。
每一个 pod 中,运行主进程的用户都有三个属性:
fsGroup
定义 pod 的 文件系统 group ID,用于块存储,好比 Ceph RDB 和 iSCSI。supplementalGroups
ID 用于共享存储,也是组/group ID 的一种,用于共享存储,好比 NFS 和 GlusterFS。上面例子中的 supplementalGroup ID 为 10000000,取的也是默认值。这两种 group ID 支持 MustRunAs 和 RunAsAny 两种策略。会在下一篇存储部分详细介绍。备注:Supplemental group(附加组)也是Linux 组的一种。当一个进程运行在 Linux 中时,它会拥有一个 UID,一个 GID,以及一个或多个附加组ID。具体请查阅Linux 相关文档。
若是某 scc 设置的 RunAsUser 策略为 MustRunAsRange,它会要求配置合法的 uid 区间(要么在 project 中配置,要么在 scc 中指定)。若是你要指定特定的 uid ,你能够在 pod 定义 yaml 中使用 securityContext: runAsUser <uid> 来指定特定的 user id,可是该 id 必须在区间以内。不然会报错:
Error from server (Forbidden): error when creating "testcontainervolume-restricted.yaml": pods "test-pod-volume-restricted2" is forbidden: unable to validate against any security context constraint: [spec.containers[0].securityContext.securityContext.runAsUser: Invalid value: 65534: must be in the ranges: [1000000000, 1000009999]]
根据建立 pod 的用户不一样,pod 使用不一样的默认 scc:
SCC 优先级:一个 sa user 能够被加到多的 scc 当中。当一个 service account user 有多个 SCC 可用时,其 scc 按照下面的规则排序
每一个 scc 有其用户/用户组列表。以 restricted 为例,全部经过身份验证的用户都在列表中;而 anyuid,只有 cluster-admins 用户组中的用户在里面。
要受权 pod 有除了 restricted 定义的权限以外的权限,主要有两种作法:
官方建议采用第一种。一个很经常使用的例子是运行要使用 root 用户的容器。不少的Docker 镜像都使用的是 root 用户。可是,openshift restricted scc 不容许使用 root 用户,而要使用一个用户区间内的用户:
修复步骤:
$ oc create serviceaccount useroot $ oc adm policy add-scc-to-user anyuid -z useroot $ oc patch dc/myAppNeedsRoot --patch '{"spec":{"template":{"spec":{"serviceAccountName": "useroot"}}}}'
备注:
说明:
感谢您的阅读,欢迎关注个人微信公众号: