Secrets概述
现代应用程序旨在松散地耦合代码、配置和数据。配置文件和数据未作为软件的一部分进行硬编码。而是由软件从外部源加载配置和数据。这样就可以将应用程序部署到不同的环境,而无需更改应用程序源代码。
通常,应用程序需要访问敏感信息。例如,后端Web应用程序需要访问数据库凭据才能执行数据库查询。
Kubernetes和OpenShift使用secret 资源来保存敏感信息,例如:
密码
敏感的配置文件。
外部资源的凭证,例如SSH密钥或OAuth令牌。
secret 可以存储任何类型的数据。 secret 中的数据是Base64编码的,因此不会以纯文本格式存储。 secret 数据未加密; 您可以解码Base64格式的密钥以访问原始数据。
尽管secret 可以存储任何类型的数据,但Kubernetes和OpenShift支持不同类型的secret 。 存在不同类型的secret 资源,包括service account令牌,SSH密钥和TLS证书。 当您以特定的secret 资源类型存储信息时,Kubernetes会验证数据是否符合secret 类型。
secret 的主要特征包括:
secret 数据可以在namespace内共享。
secret 数据的引用与secret 定义无关。管理员可以创建和管理secret 资源,其他团队成员可以在其部署配置中引用该secret 。
OpenShift创建Pod时,会将secret 数据注入Pod。您可以将secret 公开为环境变量或pods的挂载文件。
如果密钥的值在容器执行期间更改,则密钥数据不会在容器中更新。更改secret 值后,必须创建新的Pod来注入新的secret 数据。
OpenShift注入到Pod中的任何secret 数据都是短暂的。如果OpenShift将敏感数据作为环境变量暴露给Pod,则在Pod被销毁时那些变量将被销毁。
如果将secret 作为文件安装在容器中,则在容器被销毁时,文件也会被销毁。secret 数据卷由临时文件存储支持。
secret 的使用场景
secret 的两个主要用例是存储凭据和保护服务之间的通信。这些将在下面讨论。
-
Credentials:secret 存储敏感信息,例如密码和用户名。
如果应用程序希望从文件中读取敏感信息,则可以将secret 作为数据卷安装到Pod。应用程序可以将secret 作为普通文件读取以访问敏感信息。例如,某些数据库从文件中读取凭据以对用户进行身份验证。
一些应用程序使用环境变量来读取配置和敏感数据。您可以将secret 变量链接到部署配置中的pod环境变量。
-
传输层安全性(TLS)和密钥对
您可以通过使群集在项目名称空间内将签名的证书和密钥对生成为secret信息,来确保与服务的通信安全。证书和密钥对使用PEM格式存储在位于容器的secret数据卷中的文件astls.crtandtls.key中。
创建secret
如果Pod需要访问敏感信息,请在部署Pod之前为信息创建一个secret 。
创建secret :
使用机密数据创建secret 对象:
$oc create secret generic secret_name --from-literal key1=secret1 --from-literal key2=secret2
例如我创建一个secret:zhangsan 123 lisi 456
# oc create secret generic davidwei --from-literal zhangsan=123 --from-literal lisi=456
secret/davidwei created
创建成功以后,查看secret,是看不到value值的:
怎么解密:
# echo 'NDU2' | base64 --decode
456
# echo 'MTIz' | base64 --decode
123
更新pod service account 以允许引用该secret。例如,要允许在特定服务帐户下运行的Pod挂载secret,请执行以下操作:
$oc secrets add --for mount serviceaccount/serviceaccount-name secret/secret_name
要将Secrets公开到Pod,请首先创建该Secrets。 将每个敏感数据分配给一个键。 创建后,Secrets包含键值对。
以下命令使用两个密钥创建名为demo-secret的通用Secrets:具有demo-uservalue的用户名和具有= zT1KTgkvalue的root_password。Secrets包含单个键值对。
[user@demo ~]$oc create secret generic demo-secret --from-literal username=demo-user--from-literal root_password=zT1KTgk
作为Pod环境变量的secret :
env:
- name: MYSQL_ROOT_PASSWORD 1
valueFrom:
secretKeyRef:
name: demo-secret 2
key: root_password 3
1个 pod中的环境变量名称,其中包含来自secret的数据。
2包含所需敏感信息的secret名称。
3密钥中包含secret信息。
您还可以使用oc set env命令从秘密值设置应用程序环境变量:
$oc set env dc/demo --from=secret/demo-secret
前面的命令为secret中的每个密钥创建一个环境变量。 如果密钥为小写,则相应的环境变量将转换为大写。
以下命令在包含secret内容的容器中创建卷安装:
oc set volume dc/demo --add --type=secret --secret-name=demo-secret --mount-path=/app-secrets
安全上下文约束(SCC)
红帽OpenShift提供了安全上下文约束(SCC),一种安全机制,它限制对资源的访问,但不限制OpenShift中的操作。
SCC限制了从OpenShift中正在运行的Pod到主机环境的访问。SCC控制:
运行特权容器
向容器请求额外的功能
将主机目录用volume
更改容器的SELinux上下文
更改用户ID
社区开发的某些容器可能需要宽松的安全上下文约束来访问默认情况下禁止的资源,例如文件系统,套接字或访问SELinux上下文。
您可以以集群管理员身份运行以下命令,以列出由OpenShift定义的SCC:
要获取有关SCC的其他信息,请使用oc describe命令。
OpenShift创建的所有容器都使用命名为“ Restricted”的SCC,这提供了对OpenShift外部资源的有限访问。
对于anyuid SCC,以用户身份运行策略定义为RunAsAny,这意味着可以将pod作为容器中可用的任何用户标识来运行。这允许需要特定用户的容器使用特定用户ID运行命令。
查看另外一个scc:
要将容器更改为使用其他SCC运行,您需要创建绑定到Pod的service account。要创建服务帐户,要将服务帐户与SCC关联,请使用以下命令:
# oc create serviceaccount davidwei
serviceaccount/davidwei created
# oc adm policy add-scc-to-user anyuid -z davidwei
securitycontextconstraints.security.openshift.io/anyuid added to: ["davidwei"]
要确定哪个帐户可以创建需要更高安全性要求的Pod,请使用scc-subject-review子命令。这将返回所有可用来克服容器限制的安全上下文约束。例如:
# oc get pods example -o yaml | oc adm policy scc-subject-review -f -
RESOURCE ALLOWED BY
Pod/example anyuid
我们可以修改scc的内容:
oc edit scc restricted
把画箭头的从false改成true:
再次查看scc,发现已经成功改过来了:
特权容器
一些容器可能需要访问主机的运行时环境。例如,S2I构建器容器是一类特权容器,它们需要访问权限超出其自身容器的限制。这些容器可能会带来安全风险,因为它们可以使用OpenShift节点上的任何资源。通过创建具有特权访问权限的服务帐户,可以使用SCC启用对特权容器的访问。