一、Openshift的认证
在OCP中,有用户和组的概念。
OpenShift中的用户:
可以向OpenShift API发出请求
通常表示与OpenShift交互的开发人员或管理员的帐户
Openshift的组由多个用户组成,用于管理授权策略以一次向多个用户授予权限。
OCP采用OAuth认证方式。关于OAuth的概念(源自百度百科):
OAuth是由Blaine Cook、Chris Messina、Larry Halff 及David Recordon共同发起的,目的在于为API访问授权提供一个开放的标准。
OAuth:
OpenShift Master节点包含内置OAuth服务器
用户获取OAuth访问令牌以对API进行身份验证
当用户请求OAuth令牌时,OAuth服务器使用配置的身份提供程序来确定请求者的身份
OAuth服务器:
确定用户身份映射的位置
为用户创建访问令牌
返回令牌以供使用
OAuth客户端
OAuth令牌请求必须指定OAuth客户端才能接收和使用令牌
-
启动OpenShift API时自动创建OAuth客户端
几类客户端如下:
三、Openshift的认证的身份提供者
在OCP的master上,可以配置Identity Providers,也就是说,谁提供身份识别的源。
Identity Providers有几种:
AllowAll:允许任何非空的用户名/密码登录
DenyAll:绝任何用户名/密码的访问
LDAP Authentication:使用LDAPv3服务器的用户名和密码进行验证
htpasswd:使用htpasswd生成的平面文件验证用户名和密码。
将Identity映射到user的策略(mappingMethod)有多个:
参数 | 具体描述 |
claim | 默认值。 为用户提供标识的首选用户名。 如果具有该名称的用户已映射到另一个标识,则会失败。 |
lookup | 查找现有标识,用户标识映射和用户,但不自动配置用户或标识。 这允许集群管理员手动或通过外部进程设置身份和用户。 |
generate | 为用户提供标识的首选用户名。 如果具有首选用户名的用户已映射到现有标识,则会生成唯一的用户名。 例如,myuser2。 此方法不应与需要产品用户名和身份提供程序用户名(如LDAP组同步)之间完全匹配的外部进程结合使用。 |
add | 为用户提供标识的首选用户名。 如果具有该用户名的用户已存在,则该身份将映射到现有用户,并添加到该用户的任何现有身份映射。 这种方式适用于配置多个身份提供程序以识别同一组用户并映射到相同的用户名时。 |
查看一下我实验环境的配置:
/etc/origin/master/master-config.yaml
在实验环境中,Identity Providers使用LDAP;mappingMethod是默认的claim:
Openshift中的策略有两类:
集群级别:控制OpenShift平台和项目的访问级别
本地级别:控制对自己项目的访问
我们看一下两者的对比:
我们接下来,看三个概念:Rules、Roles 和Bindings
Rules 管理角色 | 设置角色 |
Roles 角色 | 规则集;用户和组可以同时与多个角色关联或绑定 |
Bindings 绑定 | 将role和用户/组进行绑定 |
我们看几个系统自带的roles:
举个例子,查看basic-user的角色
下图中,Resources指的是规则适用的对象,如projects;Verbs指的是能对这个对象做啥,如list watch
四、安全上下文约束
Openshift的scc有两类:Privileged SCC和 Restricted SCC。
默认情况下,cluster administrators, nodes, and build controller被授权访问Privileged SCC
所有经过身份验证的用户都可以访问 Restricted SCC
两者的区别:
五、实验1:权限分配
在使用中,我们将会把OCP和LDAP对接.
LDAP包含的组有:
用户有:
OCP中的项目:
如果想将OCP和LDAP对接,那么部署OCP之前,需要到ansible inventory中进行如下配置:
也就是配置如下两个参数:
openshift_master_ldap_ca_file
openshift_master_identity_providers
然后执行playbook安装/配置OCP。
配置成功以后,先用LDAP用户登录OCP:
payment1 / r3dh4t1!
登录成功:
接下来,我们将LDAP上的用户同步到OCP上。
首先创建组同步文件:
/etc/origin/master/groupsync.yaml
cat << EOF > /etc/origin/master/groupsync.yaml
kind: LDAPSyncConfig
apiVersion: v1
url: "ldap://ipa.shared.example.opentlc.com"
insecure: false
ca: "/etc/origin/master/ipa-ca.crt"
bindDN: "uid=admin,cn=users,cn=accounts,dc=shared,dc=example,dc=opentlc,dc=com"
bindPassword: "r3dh4t1!"
rfc2307:
groupsQuery:
baseDN: "cn=groups,cn=accounts,dc=shared,dc=example,dc=opentlc,dc=com"
scope: sub
derefAliases: never
filter: (&(!(objectClass=mepManagedEntry))(!(cn=trust admins))(!(cn=groups))(!(cn=admins))(!(cn=ipausers))(!(cn=editors))(!(cn=ocp-users))(!(cn=evmgroup*))(!(cn=ipac*)))
groupUIDAttribute: dn
groupNameAttributes: [ cn ]
groupMembershipAttributes: [ member ]
usersQuery:
baseDN: "cn=users,cn=accounts,dc=shared,dc=example,dc=opentlc,dc=com"
scope: sub
derefAliases: never
userUIDAttribute: dn
userNameAttributes: [ uid ]
EOF
将LDAP组映射到OpenShift中的特定名称:
echo '
groupUIDNameMapping:
"cn=portalapp,cn=groups,cn=accounts,dc=shared,dc=example,dc=opentlc,dc=com": "portalapp"
"cn=paymentapp,cn=groups,cn=accounts,dc=shared,dc=example,dc=opentlc,dc=com": "paymentapp"
"cn=ocp-production,cn=groups,cn=accounts,dc=shared,dc=example,dc=opentlc,dc=com": "ocp-production"
"cn=ocp-platform,cn=groups,cn=accounts,dc=shared,dc=example,dc=opentlc,dc=com": "ocp-platform"
' >>/etc/origin/master/groupsync.yaml
创建/etc/origin/master/whitelist.yaml文件:
cat << EOF > /etc/origin/master/whitelist.yaml
cn=portalapp,cn=groups,cn=accounts,dc=shared,dc=example,dc=opentlc,dc=com
cn=paymentapp,cn=groups,cn=accounts,dc=shared,dc=example,dc=opentlc,dc=com
cn=ocp-platform,cn=groups,cn=accounts,dc=shared,dc=example,dc=opentlc,dc=com
cn=ocp-production,cn=groups,cn=accounts,dc=shared,dc=example,dc=opentlc,dc=com
EOF
接下来,从LDAP上同步用户到OCP上:
oc adm groups sync --sync-config=/etc/origin/master/groupsync.yaml --whitelist=/etc/origin/master/whitelist.yaml
接下来,从LDAP上同步组到OCP上:
oc adm groups sync --sync-config=/etc/origin/master/groupsync.yaml --whitelist=/etc/origin/master/whitelist.yaml --confirm
查看OCP上的组以及组中的用户:
接下来,我们在OCP中创建项目和策略,并把他们指定到不同的组:
创建项目(每个项目名称有三个阶段:dev、test、prod):
export APPNAME=portalapp
export APPTEXT="Portal App"
oc new-project ${APPNAME}-dev --display-name="${APPTEXT} Development"
oc new-project ${APPNAME}-test --display-name="${APPTEXT} Testing"
oc new-project ${APPNAME}-prod --display-name="${APPTEXT} Production"
export APPNAME=paymentapp
export APPTEXT="Payment App"
oc new-project ${APPNAME}-dev --display-name="${APPTEXT} Development"
oc new-project ${APPNAME}-test --display-name="${APPTEXT} Testing"
oc new-project ${APPNAME}-prod --display-name="${APPTEXT} Production"
接下来,为各自的项目分配开发人员组的管理权限 - 在本例中,使用OpenShift附带的默认管理员角色。
oc adm policy add-role-to-group admin portalapp -n portalapp-dev
oc adm policy add-role-to-group admin portalapp -n portalapp-test
oc adm policy add-role-to-group admin paymentapp -n paymentapp-dev
oc adm policy add-role-to-group admin paymentapp -n paymentapp-test
我们查看一个项目的角色绑定:
oc describe rolebinding.rbac -n paymentapp-dev
为pro项目赋予管理组的权限:
oc adm policy add-role-to-group admin ocp-production -n portalapp-prod
oc adm policy add-role-to-group admin ocp-production -n paymentapp-prod
将cluster-admin角色添加到ocp-platform组:
oc adm policy add-cluster-role-to-group cluster-admin ocp-platform
做完以上操作之后,我们已经完成了权限分配的目标:
接下来,我们设置允许一个项目查看、并从另一个项目中pull image的策略。允许来自paymentapp-prod和paymentapp-test的服务帐户提取在paymentapp-dev项目中创建的image。
oc policy add-role-to-group system:image-puller system:serviceaccounts:paymentapp-prod -n paymentapp-dev
oc policy add-role-to-group system:image-puller system:serviceaccounts:paymentapp-test -n paymentapp-dev
将registry-viewer角色分配给ocp-production组,以便生产管理员可以查看imagestream。
oc policy add-role-to-group registry-viewer ocp-production -n paymentapp-dev
oc policy add-role-to-group registry-viewer ocp-production -n paymentapp-test
接下来,通过S2I部署应用:
oc login -u marina --password 'r3dh4t1!'
oc project paymentapp-dev
oc new-app ruby~https://github.com/openshift/sinatra-example --name=sinatra -n paymentapp-dev
现在构建成功的image,位于paymentapp-dev路径中。
我们给镜像打一个test的标签:
oc tag sinatra:latest sinatra:test
接下来,我们到test项目中去部署应用:
oc login -u marina --password 'r3dh4t1!'
oc project paymentapp-test
oc new-app paymentapp-dev/sinatra:test -n paymentapp-test
接下来,我们把镜像打上prod的tag,然后在生产环境部署:
oc tag sinatra:test sinatra:prod -n paymentapp-dev
oc login -u david -p 'r3dh4t1!'
oc project paymentapp-prod
oc new-app paymentapp-dev/sinatra:prod -n paymentapp-prod
oc get pod
六、实验2:允许生产环境的管理员运行不安全的容器
本实现中,我们允许在一个项目中使用root权限创建和部署S2I构建的映像 - 换句话说,运行特权容器。
我们通常不直接创建pod。 而是通过创建dc、rc,触发创建pod的操作。 因此,项目中的serviceaccount需要root权限。
OpenShift带有许多安全上下文约束(SCC)。anyuid SCC可以允许运行特权容器。
在此步骤中,修改SCC允许paymentapp-prod项目中的sa运行与root用户一起运行的映像/容器。
修改SCC以允许在paymentapp-prod项目中为sa授予anyuid权限。
oc login -u system:admin
oc adm policy add-scc-to-group anyuid system:serviceaccounts:paymentapp-prod
以prod1身份登录OCP并切换到paymentapp-prod项目:
oc login -u prod1 -p 'r3dh4t1!'
oc project paymentapp-prod
使用S2I构建root Docker镜像:
oc new-app --strategy=docker https://github.com/thoraxe/centos-root-docker-example
查看构建过程:
pod创建成功以后,登录pod:
登录新部署好的pod:
可以看到,是root用户。