一 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选项指定项目。如果没有指定,则使用当前项目。
常见管理本地策略操作:
还可以使用如下所示的的操作管理cluster policy的role binding,这类命令不需要-n选项,因为cluster policy不在namespace级别上操作。
常见管理cluster policy操作:
提示: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的请求相关联的用户,然后授权层使用关于请求用户的身份信息来确定是否应该允许该请求。
- user和group
OCP容器平台中的用户是一个可以向OpenShift API发出请求的实体。通常,这表示与OpenShift交互的develop或administrator的帐户。
可以将用户分配给一个或多个组,每个组表示一组特定的角色(或权限)。当需要通过管理授权策略给多个客户授权时候,group会比较合适。例如允许访问项目中的对象,而不是单独授予用户。
- Authentication Tokens
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 Authentication
Keystone是一个OpenStack项目,提供标识、令牌、目录和策略服务。OpenShift容器平台与Keystone集成,通过配置OpenStack Keystone v3服务器将用户存储在内部数据库中,从而支持共享身份验证。这种配置允许用户使用Keystone凭证登录OpenShift容器平台。
- LDAP Authentication
用户使用他们的LDAP凭证登录到OpenShift容器平台。在身份验证期间,LDAP目录将搜索与提供的用户名匹配的条目。如果找到匹配项,则尝试使用条目的专有名称(DN)和提供的密码进行简单绑定。
- GitHub Authentication
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
六 管理加密信息
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 --from-literal=key1=secret1 3 --from-literal=key2=secret2 #用secret data创建secret对象 4 [user@demo ~]$ oc secrets add --for=mount serviceaccount/serviceaccount-name 5 secret/secret_name #更新pod的服务帐户,允许引用该secrets。
例如,允许一个运行在指定服务帐户下的pod挂载一个secrets
创建一个pod,该pod使用环境变量或数据卷作为文件的方式使用该secret,通常使用模板完成。
6.3 使用secret暴露Pod
secrets可以作为数据卷挂载,也可以作为环境变量以便供pod中的容器使用。
例如,要向pod公开一个secrets,首先创建一个secrets并将username和password以k/v形式配置,然后将键名分配给pod的YAML文件env定义。
示例:创建名为demo-secret的secrets,它定义用户名和密码为username/demo-user。
[user@demo ~]$ oc create secret generic demo-secret
--from-literal=username=demo-user
要使用前面的secret作为MySQL数据库pod的数据库管理员密码,请定义环境变量,并引用secret名称和密码。
1 env: 2 - name: MYSQL_ROOT_PASSWORD 3 valueFrom: 4 secretKeyRef: 5 key: username 6 name: demo-secret
6.4 web端管理secret
从web控制台管理secret:
1. 以授权用户身份登录到web控制台。
2. 创建或选择一个项目来承载secret。
3. 导航到resource——>secrets。
6.5 Secret使用场景
- password和user names
敏感信息(如password和user name)可以存储在一个secret中,该secret被挂载为容器中的数据卷。数据显示为位于容器的数据卷目录中的文件中的内容。然后,应用程序(如数据库)可以使用这些secret对用户进行身份验证。
- 传输层安全性(TLS)和密钥对
通过让集群将签名证书和密钥对生成到项目名称空间中的secret中,可以实现对服务的通信的保护。证书和密钥对使用PEM格式存储以类似tls.crt和tls.key的格式存储在secret的pod中。
七 ConfigMap对象
7.1 ConfigMap概述
ConfigMaps对象类似于secret,但其设计目的是支持处理不包含敏感信息的字符串。ConfigMap对象持有配置数据的键值对,这些配置数据可以在pods中使用,或者用于存储系统组件(如控制器)的配置数据。
ConfigMap对象提供了将配置数据注入容器的机制。ConfigMap存储精细的粒度信息,比如单个属性,或者详细信息,比如整个配置文件或JSON blob。
7.2 CLI创建ConfigMap
可以使用--from-literal选项从CLI创建ConfigMap对象。
示例:创建一个ConfigMap对象,该对象将IP地址172.20.30.40分配给名为serverAddress的ConfigMap密钥。
1 [user@demo ~]$ oc create configmap special-config 2 --from-literal=serverAddress=172.20.30.40 3 [user@demo ~]$ oc get configmaps special-config -o yaml #查看configMap 4 apiVersion: v1 5 data: 6 key1: serverAddress=172.20.30.40 7 kind: ConfigMap 8 metadata: 9 creationTimestamp: 2017-07-10T17:13:31Z 10 name: special-config 11 …… 12 在配置映射的pod定义中填充环境变量APISERVER。 13 env: 14 - name: APISERVER 15 valueFrom: 16 configMapKeyRef: 17 name: special-config 18 key: serverAddress
7.3 web管理ConfigMap
从web控制台管理ConfigMap对象:
1. 以授权用户身份登录到web控制台。
2. 创建或选择一个项目来承载ConfigMap。
3. 导航到资源→配置映射。
八 加密练习
8.1 前置准备
准备完整的OpenShift集群,参考《003.OpenShift网络》2.1。
8.2 本练习准备
[student@workstation ~]$ lab secure-secrets setup
8.3 创建项目
1 [student@workstation ~]$ oc login -u developer -p redhat 2 [student@workstation ~]$ cd /home/student/DO280/labs/secure-secrets/ 3 [student@workstation secure-secrets]$ less mysql-ephemeral.yml #导入本环境MySQL模板
模板解读:
该mysql-ephemeral.yml模板文件,包含openshift项目中的mysql临时模板,pod所需的其他环境变量由模板参数初始化,并具有默认值。
但没有secret定义,后续操作将手动创建模板所需的secret。
根据模板的要求,创建一个包含MySQL容器image使用的凭证的secret,将这个secret命名为mysql。
- 应用程序访问的数据库用户名由database-user定义。
- 数据库用户的密码由database-password定义。
- 数据库管理员密码由database-root-password定义
8.4 创建新secret
1 [student@workstation secure-secrets]$ oc create secret generic mysql 2 --from-literal='database-user'='mysql' 3 --from-literal='database-password'='redhat' 4 --from-literal='database-root-password'='do280-admin' 5 [student@workstation secure-secrets]$ oc get secret mysql -o yaml #确认secret
8.5 创建应用
1 [student@workstation secure-secrets]$ oc new-app --file=mysql-ephemeral.yml 2 [student@workstation secure-secrets]$ oc get pods #确认应用 3 NAME READY STATUS RESTARTS AGE 4 mysql-1-j4fnz 1/1 Running 0 1m
8.6 端口转发
1 [student@workstation secure-secrets]$ cd 2 [student@workstation ~]$ oc port-forward mysql-1-j4fnz 3306:3306
提示:验证完成之前forward不要关闭。
8.7 确认验证
1 [student@workstation ~]$ mysql -uroot -pdo280-admin -h127.0.0.1 #新开终端测试MySQL
九 管理security policy
9.1 OCP authorization授权
OCP定义了用户可以执行的两组主要操作:
与项目相关的操作(也称为本地策略):project-related
与管理相关的操作(也称为集群策略):administration-related
由于这两种策略都有大量可用的操作,所以将一些操作分组并定义为角色。
为管理本地政策,OCP提供以下角色:
除了能够创建新应用程序之外,admin角色还允许用户访问项目资源,比如配额和限制范围。
edit角色允许用户在项目中充当开发人员,但要在项目管理员配置的约束下工作。
9.2 相关命令
1 向集群用户添加角色 2 $ oc adm policy add-cluster-role-to-user cluster-role username 3 示例:将普通用户更改为集群管理员。 4 $ oc adm policy add-cluster-role-to-user cluster-role username 5 从用户中删除集群角色 6 $ oc adm policy remove-cluster-role-from-user cluster-role username 7 示例:将集群管理员更改为普通用户。 8 $ oc adm policy remove-cluster-role-from-user cluster-admin username 9 将指定的用户绑定到项目中的角色 10 $ oc adm policy add-role-to-user role-name username -n project 11 示例:在WordPress项目中dev用户绑定basic-user角色。 12 $ oc adm policy add-role-to-user basic-user dev -n wordpress
9.3 权限及规则
OpenShift将一组规则集合成一个角色,规则由谓词和资源定义。如create user是OpenShift中的一条规则,它是一个名为cluster-admin的角色的所拥有的权限的一部分。
1 $ oc adm policy who-can delete user
9.4 user类型
与OCP的交互基于用户,OCP的user对象表示可以通过向该用户或用户组添加角色来从而实现相应权限的授予。
Regular users:通常以这种用户类型与OCP交互,常规用户用User对象表。例如,user1,user2。
System users:通常在安装OCP中定义基础设施时自动创建的,主要目的是使基础设施能够安全地与API交互。包括集群管理员(可以访问所有内容)、每个节点的用户、路由器和内部仓库使用的用户,以及各种其他用户。还存在一个匿名系统用户,默认情况下,该用户用于未经身份验证的请求。system user主要包括:system:admin、system:openshift-registry和system:node:node1.example.com。
Service accounts:这些是与项目关联的特殊系统用户。有些是在第一次创建项目时自动创建的,项目管理员可以创建多个,以便定义对每个项目内容的访问。Service accounts由ServiceAccount对象表示。Service accounts主要包括:system:serviceaccount:default:deployer和system:serviceaccount:foo:builder。
每个用户在访问OpenShift容器平台之前必须进行身份验证。没有身份验证或身份验证无效的API请求将使用匿名系统用户身份验证来请求服务。身份验证成功后,策略确定用户被授权做什么。
9.5 安全上下文约束(SCCS)
OpenShift提供了一种名为安全上下文约束的安全机制,它限制对资源的访问,但不限制OpenShift中的操作。
SCC限制从OpenShift中运行的pod到主机环境的访问:
- 运行特权容器
- 请求容器的额外功能
- 使用主机目录作为卷
- 更改容器的SELinux上下文
- 更改用户ID
社区开发的一些容器可能需要放松安全上下文约束,因为它们可能需要访问默认禁止的资源,例如文件系统、套接字或访问SELinux上下文。
OpenShift定义的安全上下文约束(SCCs)可以使用以下命令作为集群管理员列出。
$ oc get scc
SCC通常有以下7中SCCS:
- anyuid
- hostaccess
- hostmount-anyuid
- nonroot
- privileged
- restricted(默认)
$ oc describe scc anyuid #查看某一种SCC详情
OpenShift创建的所有容器都使用restricted类型的SCC,它提供了对OpenShift外部资源的有限访问。
对于anyuid安全上下文,run as user策略被定义为RunAsAny,表示pod可以作为容器中可用的任何用户ID运行。这允许需要特定用户使用特定用户ID运行命令的容器。
要将容器更改为使用不同的SCC运行,需要创建绑定到pod的服务帐户。
$ oc create serviceaccount service-account-name #首先创建服务账户
$ oc adm policy add-scc-to-user SCC -z service-account #将服务帐户与SCC关联
要确定哪个帐户可以创建需要更高安全性要求的pod,可以使用scc-subject-review子命令。
$ oc export pod pod-name > output.yaml
$ oc adm policy scc-subject-review -f output.yaml
9.6 OpenShift与SELinux
OpenShift要求在每个主机上启用SELinux,以便使用强制访问控制提供对资源的安全访问。同样,由OpenShift管理的Docker容器需要管理SELinux上下文,以避免兼容性问题。
为了最小化在不支持SELinux的情况下运行容器的风险,可以创建SELinux上下文策略。
为了更新SELinux上下文,可以使用现有的SCC作为起点生成一个新的SCC。
$ oc export scc restricted > custom_selinux.yml #导出默认的SCC
编辑导出的YAML文件以更改SCC名称和SELinux上下文。
$ oc create -f yaml_file #使用修改后的ymal重新创建一个SCC
9.7 特权容器
有些容器可能需要访问主机的运行时环境。S2I构建器容器需要访问宿主docker守护进程来构建和运行容器。
例如,S2I构建器容器是一类特权容器,它要求访问超出其自身容器的限制。这些容器可能会带来安全风险,因为它们可以使用OpenShift节点上的任何资源。通过创建具有特权访问权的服务帐户,可以使用SCCs启用特权容器的访问。
十 资源访问控制综合实验
10.1 前置准备
准备完整的OpenShift集群,参考《003.OpenShift网络》2.1。
10.2 本练习准备
1 [student@workstation ~]$ lab secure-review setup
10.3 创建用户
1 [root@master ~]# htpasswd /etc/origin/master/htpasswd user-review 2 New password: 【redhat】 3 Re-type new password: 【redhat】
10.4 修改策略
1 [student@workstation ~]$ oc login -u admin -p redhat 2 [student@workstation ~]$ oc adm policy remove-cluster-role-from-group 3 self-provisioner system:authenticated system:authenticated:oauth 4 禁用所有常规用户的项目创建功能
10.5 确认验证
1 [student@workstation ~]$ oc login -u user-review -p redhat 2 [student@workstation ~]$ oc new-project test #普通用户无法创建项目 3 Error from server (Forbidden): You may not request a new project via this API.
10.6 创建项目
1 [student@workstation ~]$ oc login -u admin -p redhat 2 [student@workstation ~]$ oc new-project secure-review #使用管理员创建项目
10.7 授权用户
1 [student@workstation ~]$ oc project secure-review 2 Already on project "secure-review" on server "https://master.lab.example.com:443". 3 [student@workstation ~]$ oc policy add-role-to-user edit user-review #将edit的role和user-review进行关联
10.8 测试访问
1 [student@workstation ~]$ oc login -u user-review -p redhat 2 [student@workstation ~]$ oc project secure-review #测试访问 3 Already on project "secure-review" on server "https://master.lab.example.com:443".
10.9 检查模板
1 [student@workstation ~]$ cd /home/student/DO280/labs/secure-review/ 2 [student@workstation secure-review]$ less mysql-ephemeral.yml
模板解读:
该mysql-ephemeral.yml模板文件,包含openshift项目中的mysql临时模板,pod所需的其他环境变量由模板参数初始化,并具有默认值。
但没有secret定义,后续操作将手动创建模板所需的secret。
根据模板的要求,创建一个包含MySQL容器image使用的凭证的secret,将这个secret命名为mysql。
- 应用程序访问的数据库用户名由database-user定义。
- 数据库用户的密码由database-password定义。
- 数据库管理员密码由database-root-password定义
使用user-review developer用户创建一个名为mysql的secret。这个secret应该存储用户名mysql、密码redhat和数据库管理员密码do280-admin。
数据库用户名由database-user定义。此用户的密码由mysql secret密钥定义。
数据库管理员密码由database-root-password定义。
10.10 创建secret
1 [student@workstation secure-review]$ oc create secret generic mysql 2 --from-literal='database-user'='mysql' 3 --from-literal='database-password'='redhat' 4 --from-literal='database-root-password'='do280-admin' 5 [student@workstation secure-review]$ oc get secret mysql -o yaml #确认验证secret
10.11 部署应用
1 [student@workstation secure-review]$ oc new-app --file=mysql-ephemeral.yml 2 [student@workstation secure-review]$ oc get pods 3 NAME READY STATUS RESTARTS AGE 4 mysql-1-2lr7t 1/1 Running 0 31s
10.12 转发端口
1 [student@workstation ~]$ oc port-forward mysql-1-2lr7t 3306:3306
10.13 测试访问
1 [student@workstation ~]$ mysql -umysql -predhat -h127.0.0.1
10.14 部署phpmyadmin应用
使用内部仓库registry.lab.example.com的image部署phpmyadmin:4.7容器。phpmyadmin:4.7容器需要名为PMA_HOST的环境变量来提供MySQL服务器的IP地址。
使用模板创建一个基于FQND的MySQL pod的service。
为使用模板创建的MySQL服务器pod使用服务FQDN,该模板是mysql.secure-review.svc.cluster.local。
1 [student@workstation ~]$ oc new-app --name=phpmyadmin 2 --docker-image=registry.lab.example.com/phpmyadmin/phpmyadmin:4.7 3 -e PMA_HOST=mysql.secure-review.svc.cluster.local
结论:该命令会发出警告,提示需要root特权。默认情况下,OpenShift不支持使用操作系统的root用户运行容器。
10.15 查看pod
1 [student@workstation ~]$ oc get pods 2 NAME READY STATUS RESTARTS AGE 3 mysql-1-2lr7t 1/1 Running 0 8m 4 phpmyadmin-1-v7tl7 0/1 Error 2 1m 5 因为没有root权限,因此部署失败,需要提权。
10.16 授予权限
1 [student@workstation ~]$ oc login -u admin -p redhat #使用管理员登录 2 [student@workstation ~]$ oc create serviceaccount phpmyadmin-account #首先创建服务账户 3 [student@workstation ~]$ oc adm policy add-scc-to-user anyuid -z phpmyadmin-account 4 scc "anyuid" added to: ["system:serviceaccount:secure-review:phpmyadmin-account"] #将服务帐户与anyuid安全上下文关联
10.17 更新应用
1 [student@workstation ~]$ oc patch dc phpmyadmin --patch='{"spec":{"template":{"spec":{"serviceAccountName": "phpmyadmin-account"}}}}'
#更新负责管理phpmyadmin的dc资源,任何开发人员用户都可以执行此操作。
本环境中,相关操作命令可以从/home/student/DO280/labs/secure-review文件夹中的patch-dc.sh脚本运行或复制。
10.18 确认验证
1 [student@workstation ~]$ oc login -u user-review -p redhat 2 [student@workstation ~]$ oc get pods #确认pod是否正常 3 NAME READY STATUS RESTARTS AGE 4 mysql-1-2lr7t 1/1 Running 0 13m 5 phpmyadmin-2-bdjvq 1/1 Running 0 1m
10.19 暴露服务
1 [student@workstation ~]$ oc expose svc phpmyadmin --hostname=phpmyadmin.apps.lab.example.com
10.20 访问测试
1 [student@workstation ~]$ curl -s http://phpmyadmin.apps.lab.example.com
10.21 确认及删除
1 [student@workstation ~]$ lab secure-review grade #环境脚本判断 2 [student@workstation ~]$ oc login -u admin -p redhat 3 [student@workstation ~]$ oc adm policy add-cluster-role-to-group 4 self-provisioner system:authenticated system:authenticated:oauth 5 [student@workstation ~]$ oc delete project secure-review 6 [student@workstation ~]$ ssh root@master htpasswd -D 7 /etc/origin/master/htpasswd user-review #删除用户 8 [student@workstation ~]$ oc delete user user-review #删除项目