一 Kubetcl namespace
1.1 namespace描述
Kubernetes namespace提供了将一组相关资源组合在一起的机制。在Red Hat OpenShift容器平台中,project是一个带有附加注释的Kubernetes namespace。
namespace提供以下特性:
- 命名资源,以避免基本的命名冲突;
- 将管理权限授予受信任的用户;
- 限制用户资源消耗的能力;
- 用户和用户组隔离。
1.2 project
project提供了一种机制,通过这种机制可以管理普通用户对资源的访问。project允许一组用户独立于其他组组织和管理其内容,必须允许用户访问项目。如果允许创建项目,用户将自动访问自己的项目。
项目可以有单独的name、display name和description。
name是项目的唯一标识符,在使用CLI工具或API时都是基于name,name的最大长度为63个字符。
display name是项目在web控制台中显示的方式(默认为name)。
description是项目的更详细描述,并且在web控制台中也可见。
以下组件适用于项目:
- Object:pod、service、rc等;
- Policies:决定用户可以或不能对对象执行哪些操作的规则;
- Constraints:可以限制的每种对象的配额。
1.3 cluster管理
集群管理员可以创建项目并将项目的管理权限委托给任何用户。在OpenShift容器平台中,项目用于对相关对象进行分组和隔离。
管理员可以让用户访问某些项目,允许他们创建自己的项目,并在单个项目中赋予他们管理权限。
管理员可以将角色应用于允许或限制其创建项目能力的用户和组,同时可以在用户初始登录之前分配角色。
限制项目创建:从通过身份验证的用户和组中删除self-provisioning集群角色,将拒绝任何新项目的权限。
[root@master ~]$ oc adm policy remove-cluster-role-from-group \
self-provisioner \
system:authenticated \
system:authenticated:oauth
授予项目创建:项目创建授予具有self-供应者角色和self-provisione集群角色绑定的用户。默认情况下,所有经过身份验证的用户都可以使用这些角色。
[root@master ~]$ oc adm policy add-cluster-role-to-group \
self-provisioner \
system:authenticated \
system:authenticated:oauth
1.4 创建project
如果项目创建权限被授予用户,则可以使用oc命令创建project。
[root@master ~]$ oc new-project demoproject \
--description="Demonstrate project creation" \
--display-name="demo_project"
二 OpenShift角色
2.1 角色概述
role具有不同级别的访问和策略,包括集群和本地策略。user和group可以同时与多个role关联。运行oc description命令查看角色及其绑定的详细信息。
在集群策略中具有cluster-admin缺省角色的用户可以查看集群策略和所有本地策略。在给定的本地策略中具有admin缺省角色的用户可以基于per-project查看策略。
可通过以下命令查看当前的集群绑定集,其中显示绑定到不同角色的用户和组。
[root@demo ~]# oc describe clusterPolicyBindings :default
2.2 查看本地policy
尽管本地角色列表及其关联的规则集在本地策略中是不可查看的,但是所有缺省角色仍然适用,并且可以添加到用户或组中,cluster-admin缺省角色除外。但是,本地绑定是可见的。
可通过以下命令查看当前的本地绑定,其中显示绑定到不同角色的用户和组。
[root@demo ~]# oc describe policyBindings :default
提示:默认情况下,在本地策略中,只会列出admin角色的绑定。但是,如果将其他默认角色添加到本地策略中的用户和组,也会列出它们。
2.3 管理role绑定
向用户或组添加或绑定角色,从而实现向用户或组提供角色授予的相关访问权限。可以使用oc adm policy命令在用户和组之间添加和删除角色。
当使用以下操作管理本地策略的用户和组角色时,可以使用-n选项指定项目。如果没有指定,则使用当前项目。
常见管理本地策略操作:
命令 |
描述 |
oc adm policy who-can verb resource |
设置哪些用户可以对资源执行操作 |
oc adm policy add-role-to-user role username |
将指定角色绑定到指定用户 |
oc adm policy remove-role-from-user role username |
从指定用户中移除给定角色 |
oc adm policy remove-user username |
删除指定的用户及其所有角色 |
oc adm policy add-role-to-group role groupname |
将指定的角色绑定到指定的组 |
oc adm policy remove-role-fromgroup role groupname |
从指定组中移除给定角色 |
oc adm policy remove-group groupname |
删除指定的组及其所有角色 |
还可以使用如下所示的的操作管理cluster policy的role binding,这类命令不需要-n选项,因为cluster policy不在namespace级别上操作。
常见管理cluster policy操作:
命令 |
描述 |
oc adm policy add-cluster-role-to-user role username |
将集群中所有项目的指定角色绑定到指定用户 |
oc adm policy remove-cluster-role-from-user role username |
为集群中的所有项目从指定用户中删除指定角色 |
oc adm policy add-cluster-role-togroup role groupname |
为集群中的所有项目将指定的角色绑定到指定的组 |
oc adm policy remove-cluster-role-from-group role groupname |
从集群中所有项目的指定组中移除给定角色 |
提示:oc policy命令应用于当前项目,而oc adm policy命令应用于集群范围的操作。
示例:在example项目中为developer用户提供admin角色。
[root@demo ~]# oc adm policy add-role-to-user admin developer -n example
[root@demo ~]# oc describe policybindings :default -n example #检查绑定
三 安全上下文约束(SCCS)
3.1 SCCS概述
OpenShift提供安全上下文约束(SCCS),它控制pod可以执行的操作和它可以访问的资源。默认情况下,任何容器的执行都只授予受限制的SCC定义的功能。
SCCS相关命令:
1 [user@demo ~]$ oc get scc #列出可用的SCC
2 [user@demo ~]$ oc describe scc scc_name #现实特定SCC详细信息
3 [user@demo ~]$ oc adm policy add-scc-to-user scc_name user_name
4 [user@demo ~]$ oc adm policy add-scc-to-group scc_name group_name #要授予用户或组特定的SCC
5 [user@demo ~]$ oc adm policy remove-scc-from-user scc_name user_name
6 [user@demo ~]$ oc adm policy remove-scc-from-group scc_name group_name #从特定的SCC中删除用户或组
四 服务账户
4.1 服务账户
service account提供了一种灵活的方法来控制API访问,而无需共享常规用户的凭据。如果应用程序需要访问受限制的SCC未授予的功能,可创建一个新的、特定的service account并将其添加到适当的SCC中。
例如,在缺省情况下,OpenShift不支持部署需要提升特权的应用程序。若有此需求,可创建一个service account,修改dc,然后添加service account至SCC。
示例:将anyuid配置为在容器中作为root用户运行。
[user@demo ~]$ oc create serviceaccount useroot #创建一个名为useroot的新服务帐户
[user@demo ~]$ oc patch dc/demo-app \
--patch '{"spec":{"template":{"spec":{"serviceAccountName": "useroot"}}}}' #修改应用程序的DC
[user@demo ~]$ oc adm policy add-scc-to-user anyuid -z useroot #将useroot服务帐户添加到anyuid SCC中,作为容器中的根用户运行
4.2 Web管理user成员
OCP平台的默认配置是,在用户首次登录成功时,自动创建该用户对象。
要管理允许访问项目的用户,请以项目管理员或集群管理员的身份登录到web控制台,并选择要管理的项目。在左侧窗格中,单击Resources——>membership进入项目member页面。
在Users列中,在突出显示的文本框中输入用户名。在“添加另一个角色”列中,从用户所在行的列表中选择一个角色,然后单击“添加”。
4.3 Cli管理user成员
CLI中如果自动创建对象功能被关闭,集群管理员可通过如下方式创建新用户:
[root@master ~]$ oc create user demo-user
同时还需要在身份认证软件中创建用户,如为HTPasswdIdentityProvider才用户命令如下:
[root@master ~]$ htpasswd /etc/origin/openshift-passwd demo-user
要向用户添加项目角色,首先使用oc project命令输入项目,然后使用oc policy add-role-to-user命令:
[root@master ~]$ oc policy add-role-to-user edit demo-user
要从用户中删除项目角色,使用oc policy remove-role-from-user命令:
[root@master ~]$ oc policy remove-role-from-user edit demo-user
并不是所有OpenShift角色都由项目限定范围。要分配这些规则,请使用oc adm policy command命令。
[root@master ~]$ oc adm policy add-cluster-role-to-user cluster-admin admin
4.4 身份验证和授权
身份验证层标识与对OpenShift容器平台API的请求相关联的用户,然后授权层使用关于请求用户的身份信息来确定是否应该允许该请求。
OCP容器平台中的用户是一个可以向OpenShift API发出请求的实体。通常,这表示与OpenShift交互的develop或administrator的帐户。
可以将用户分配给一个或多个组,每个组表示一组特定的角色(或权限)。当需要通过管理授权策略给多个客户授权时候,group会比较合适。例如允许访问项目中的对象,而不是单独授予用户。
API调用必须使用访问令牌或X.509证书进行身份验证,会话token表示用户,并且是短期的,默认情况下在24小时内到期。
可以通过运行oc whoami命令来验证经过身份验证的用户。
[root@master ~]$ oc login -u demo-user
[root@master ~]$ oc whoami
demo-user
4.5 身份验证类型
本环境中,身份验证由HTPasswdIdentityProvider模块提供,该模块根据使用htpasswd命令生成的文件验证用户名和密码。
OpenShift容器平台支持的其他认证类型包括:
- Basic Authentication (Remote)
一种通用的后端集成机制,允许用户使用针对远程标识提供者验证的凭据登录到OpenShift容器平台。用户将他们的用户名和密码发送到OpenShift容器平台,OpenShift平台通过到服务器的请求验证这些凭据,并将凭据作为基本的Auth头传递。这要求用户在登录过程中向OpenShift容器平台输入他们的凭据。
- Request Header Authentication
用户使用请求头值(如X-RemoteUser)登录到OpenShift容器平台。它通常与身份验证代理结合使用,身份验证代理对用户进行身份验证,然后通过请求头值为OpenShift容器平台提供用户标识。
Keystone是一个OpenStack项目,提供标识、令牌、目录和策略服务。OpenShift容器平台与Keystone集成,通过配置OpenStack Keystone v3服务器将用户存储在内部数据库中,从而支持共享身份验证。这种配置允许用户使用Keystone凭证登录OpenShift容器平台。
用户使用他们的LDAP凭证登录到OpenShift容器平台。在身份验证期间,LDAP目录将搜索与提供的用户名匹配的条目。如果找到匹配项,则尝试使用条目的专有名称(DN)和提供的密码进行简单绑定。
GitHub使用OAuth,它允许与OpenShift容器平台集成使用OAuth身份验证来促进令牌交换流。这允许用户使用他们的GitHub凭证登录到OpenShift容器平台。为了防止使用GitHub用户id的未授权用户登录到OpenShift容器平台集群,可以将访问权限限制在特定的GitHub组织中。
五 管理项目及账户
5.1 前置准备
准备完整的OpenShift集群,参考《003.OpenShift网络》2.1。
5.2 本练习准备
[student@workstation ~]$ lab secure-resources setup
5.3 创建htpasswd账户
1 [kiosk@foundation0 ~]$ ssh root@master
2 [root@master ~]# htpasswd -b /etc/origin/master/htpasswd user1 redhat
3 [root@master ~]# htpasswd -b /etc/origin/master/htpasswd user2 redhat
4 #添加基于htpasswd形式的user1和user2,密码都为redhat。
5.4 设置策略
1 [student@workstation ~]$ oc login -u admin -p redhat https://master.lab.example.com #使用管理员登录
2 [student@workstation ~]$ oc adm policy remove-cluster-role-from-group \
3 self-provisioner system:authenticated:oauth
4 #删除所有赋予普通创建项目的功能,该命令可参考本环境如下目录中的命令。
5 [student@workstation ~]$ cat /home/student/DO280/labs/secure-resources/configure-policy.sh
6 #!/bin/bash
7 oc adm policy remove-cluster-role-from-group \
8 self-provisioner system:authenticated system:authenticated:oauth
5.5 验证策略
1 [student@workstation ~]$ oc login -u user1 -p redhat https://master.lab.example.com #使用普通用户user1登录
2 [student@workstation ~]$ oc new-project test #测试创建project
3 Error from server (Forbidden): You may not request a new project via this API.
5.6 创建项目
1 [student@workstation ~]$ oc login -u admin -p redhat https://master.lab.example.com #使用集群管理员登录
2 [student@workstation ~]$ oc new-project project-user1 #创建两个项目
3 [student@workstation ~]$ oc new-project project-user2
5.7 将项目与user关联
1 #选择项目1
2 Now using project "project-user1" on server "https://master.lab.example.com:443".
3 [student@workstation ~]$ oc policy add-role-to-user admin user1 #将user1添加为项目1的管理员
4 role "admin" added: "user1"
5 [student@workstation ~]$ oc policy add-role-to-user edit user2 #将user2添加为项目1的开发员
6 role "edit" added: "user2"
7
8 [student@workstation ~]$ oc project project-user2 #选择项目2
9 Now using project "project-user2" on server "https://master.lab.example.com:443".
10 [student@workstation ~]$ oc policy add-role-to-user edit user2 #将user2添加为项目2的开发员
11 role "edit" added: "user2"
5.8 验证访问
1 [student@workstation ~]$ oc login -u user1 -p redhat https://master.lab.example.com #使用user1登录
2 [student@workstation ~]$ oc project project-user1 #验证项目1的访问
3 Already on project "project-user1" on server "https://master.lab.example.com:443".
4 [student@workstation ~]$ oc project project-user2 #验证项目2的访问
5 error: You are not a member of project "project-user2".
6 You have one project on this server: project-user1
7
8 [student@workstation ~]$ oc login -u user2 -p redhat https://master.lab.example.com #使用user2登录
9 [student@workstation ~]$ oc project project-user1
10 Already on project "project-user1" on server "https://master.lab.example.com:443". #验证项目1的访问
11 [student@workstation ~]$ oc project project-user2
12 Now using project "project-user2" on server "https://master.lab.example.com:443". #验证项目2的访问
5.9 部署特权应用
1 [student@workstation ~]$ oc login -u user2 -p redhat https://master.lab.example.com
2 [student@workstation ~]$ oc project project-user1
3 Now using project "project-user1" on server "https://master.lab.example.com:443".
4 [student@workstation ~]$ oc new-app --name=nginx --docker-image=registry.lab.example.com/nginx:latest
5 #使用在项目1上不具备admin权限的用户user2登录,并部署应用,会出现如下提示:
5.10 验证部署
1 [student@workstation ~]$ oc get pods
结论:由上可知,部署失败是因为容器映像需要root用户,pod以CrashLoopBackOff或错误状态结束。
5.11 故障排除
若要解决此故障需要减少特定项目的安全限制。
要使用特权访问运行容器,可创建一个允许pod使用操作系统普通用户运行的service account。
如下部分需要具有项目管理员特权的用户执行,而另一些操作需要具有集群管理员特权的用户执行。
本环境中,相关操作命令可以从/home/student/DO280/labs/secure-resources文件夹中的configure-sc.sh脚本运行或复制。
1 [student@workstation ~]$ oc login -u user1 -p redhat https://master.lab.example.com #使用项目1的admin账户登录
2 [student@workstation ~]$ oc create serviceaccount useroot #创建服务账户
3 serviceaccount "useroot" created
4 [student@workstation ~]$ oc login -u admin -p redhat https://master.lab.example.com #使用集群管理员登录
5 [student@workstation ~]$ oc project project-user1 #选择项目1
6 Already on project "project-user1" on server "https://master.lab.example.com:443".
7 [student@workstation ~]$ oc adm policy add-scc-to-user anyuid -z useroot #设置SCC策略
8 scc "anyuid" added to: ["system:serviceaccount:project-user1:useroot"] #将服务帐户与anyuid安全上下文关联,此操作需要集群管理员用户。
9 [student@workstation ~]$ oc login -u user2 -p redhat https://master.lab.example.com #切换user2用户
10 [student@workstation ~]$ oc project project-user1
11 Already on project "project-user1" on server "https://master.lab.example.com:443".
12 [student@workstation ~]$ oc patch dc nginx --patch='{"spec":{"template":{"spec":{"serviceAccountName": "useroot"}}}}'
#更新负责管理nginx的dc资源,任何开发人员用户都可以执行此操作。本环境中,相关操作命令可以从/home/student/DO280/labs/secure-resources文件夹中的configure-sc.sh脚本运行或复制。
5.12 验证确认
1 [student@workstation ~]$ oc get pods
2 NAME READY STATUS RESTARTS AGE
3 nginx-2-98k8f 1/1 Running 0 3m
4
5.13 暴露服务
1 [student@workstation ~]$ oc expose svc nginx
2 route "nginx" exposed
3 [student@workstation ~]$ oc get svc
4 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
5 nginx ClusterIP 172.30.118.63 <none> 80/TCP 13m
6 [student@workstation ~]$ oc get route
7 NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
8 nginx nginx-project-user1.apps.lab.example.com nginx 80-tcp None
5.14 测试访问
1 [student@workstation ~]$ curl -s http://nginx-project-user1.apps.lab.example.com
5.15 策略删除演示
1 [student@workstation ~]$ oc login -u admin -p redhat
2 [student@workstation ~]$ oc adm policy add-cluster-role-to-group self-provisioner system:authenticated system:authenticated:oauth
3 cluster role "self-provisioner" added: ["system:authenticated" "system:authenticated:oauth"]
4 [student@workstation ~]$ oc delete project project-user1
5 project "project-user1" deleted
6 [student@workstation ~]$ oc delete project project-user2
7 [root@master ~]# htpasswd -D /etc/origin/master/htpasswd user1
8 [root@master ~]# htpasswd -D /etc/origin/master/htpasswd user2
#为所有常规用户重新启用项目创建,即重置为初始状态。本环境中,相关操作命令可以从/home/student/DO280/labs/secure-resources文件夹中的restore-policy.sh脚本运行或复制。
六 管理加密信息
6.1 secret特性
Secret对象类型提供了一种机制来保存敏感信息,如密码、OCP客户端配置文件、Docker配置文件和私有仓库凭据。Secrets将敏感内容与Pod解耦。可以使用Volume插件将Secrets挂载到容器上,或者系统可以使用Secrets代表pod执行操作。
Secrets的主要特征包括:
- Secrets data可以独立于其定义引用。
- Secrets data Volume由临时文件存储支持。
- 可以在名称空间中共享Secrets data。
6.2 创建Secrets
在依赖于该Secrets的pod之前创建一个Secrets。
1 [user@demo ~]$ oc create secret generic secret_name \
2 --