apiVersion: v1
kind: Secret
metadata:
name: test-secret
namespace: my-namespace
type: Opaque (1)
data: (2)
username: <username> (3)
password: <password>
stringData: (4)
hostname: myapp.mydomain.com (5)
某些应用程序需要敏感信息,例如密码和用户名,您不希望开发人员拥有这些信息。
作为管理员,您可以使用 `Secret` 对象提供此信息,而无需以明文形式公开该信息。
`Secret` 对象类型提供了一种机制来保存敏感信息,例如密码、OpenShift Dedicated 客户端配置文件、私有源代码库凭据等等。密钥将敏感内容与 Pod 解耦。您可以使用卷插件将密钥挂载到容器中,或者系统可以使用密钥代表 Pod 执行操作。
主要属性包括:
密钥数据可以独立于其定义进行引用。
密钥数据卷由临时文件存储设施 (tmpfs) 支持,并且永远不会在节点上持久化。
密钥数据可以在命名空间内共享。
apiVersion: v1
kind: Secret
metadata:
name: test-secret
namespace: my-namespace
type: Opaque (1)
data: (2)
username: <username> (3)
password: <password>
stringData: (4)
hostname: myapp.mydomain.com (5)
1 | 指示密钥名称和值的结构。 |
2 | `data` 字段中密钥的允许格式必须符合 Kubernetes 标识符词汇表 中 **DNS_SUBDOMAIN** 值的指南。 |
3 | `data` 映射中与密钥关联的值必须是 base64 编码的。 |
4 | `stringData` 映射中的条目将转换为 base64,然后该条目将自动移动到 `data` 映射。此字段是只写字段;该值仅通过 `data` 字段返回。 |
5 | `stringData` 映射中与密钥关联的值由纯文本字符串组成。 |
您必须先创建密钥,然后再创建依赖于该密钥的 Pod。
创建密钥时:
创建一个包含密钥数据的密钥对象。
更新 Pod 的服务帐户以允许引用密钥。
创建一个 Pod,它将密钥用作环境变量或文件(使用 `secret` 卷)。
type
字段的值指示密钥名称和值的结构。该类型可用于强制在密钥对象中存在用户名和密钥。如果您不希望进行验证,请使用默认的 opaque
类型。
指定以下类型之一以触发最小的服务器端验证,以确保密钥数据中存在特定的密钥名称
kubernetes.io/basic-auth
:与基本身份验证一起使用
kubernetes.io/dockercfg
:用作镜像拉取密钥
kubernetes.io/dockerconfigjson
:用作镜像拉取密钥
kubernetes.io/service-account-token
:用于获取旧版服务帐户 API 令牌
kubernetes.io/ssh-auth
:与 SSH 密钥身份验证一起使用
kubernetes.io/tls
:与 TLS 证书颁发机构一起使用
如果您不希望进行验证,请指定 type: Opaque
,这意味着密钥不声明符合任何密钥名称或值的约定。不透明密钥允许包含任意值的非结构化 key:value
对。
您可以指定其他任意类型,例如 |
有关创建不同类型密钥的示例,请参阅了解如何创建密钥。
默认情况下,OpenShift Dedicated 为每个服务帐户创建一个镜像拉取密钥。
在 OpenShift Dedicated 4.16 之前,还会为创建的每个服务帐户生成一个长期有效的服务帐户 API 令牌密钥。从 OpenShift Dedicated 4.16 开始,不再创建此服务帐户 API 令牌密钥。 升级到后,任何现有的长期有效的服务帐户 API 令牌密钥都不会被删除,并将继续运行。有关检测集群中正在使用的长期有效 API 令牌或在不需要时删除它们的信息,请参阅 Red Hat 知识库文章 OpenShift Container Platform 中的长期有效服务帐户 API 令牌。 |
此镜像拉取密钥对于将 OpenShift 镜像注册表集成到集群的用户身份验证和授权系统中是必要的。
但是,如果您没有启用 ImageRegistry
功能,或者如果您在集群镜像注册表操作员的配置中禁用了集成的 OpenShift 镜像注册表,则不会为每个服务帐户生成镜像拉取密钥。
当在以前启用了集成的 OpenShift 镜像注册表的集群上禁用它时,先前生成的镜像拉取密钥将自动删除。
作为管理员,您必须在开发人员创建依赖于该密钥的 Pod 之前创建密钥。
创建密钥时:
创建一个包含您要保密的 Secret 对象。以下各节描述了每种密钥类型所需的特定数据。
apiVersion: v1
kind: Secret
metadata:
name: test-secret
type: Opaque (1)
data: (2)
username: <username>
password: <password>
stringData: (3)
hostname: myapp.mydomain.com
secret.properties: |
property1=valueA
property2=valueB
1 | 指定密钥的类型。 |
2 | 指定编码的字符串和数据。 |
3 | 指定解码的字符串和数据。 |
使用 data
或 stringdata
字段,不要同时使用两者。
更新 Pod 的服务帐户以引用密钥
apiVersion: v1
kind: ServiceAccount
...
secrets:
- name: test-secret
创建一个 Pod,它将密钥用作环境变量或文件(使用 secret
卷)
apiVersion: v1
kind: Pod
metadata:
name: secret-example-pod
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: secret-test-container
image: busybox
command: [ "/bin/sh", "-c", "cat /etc/secret-volume/*" ]
volumeMounts: (1)
- name: secret-volume
mountPath: /etc/secret-volume (2)
readOnly: true (3)
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
volumes:
- name: secret-volume
secret:
secretName: test-secret (4)
restartPolicy: Never
1 | 为需要密钥的每个容器添加 volumeMounts 字段。 |
2 | 指定您希望密钥显示在其中的未使用目录名。密钥数据映射中的每个密钥都成为 mountPath 下的文件名。 |
3 | 设置为 true 。如果为 true,则指示驱动程序提供只读卷。 |
4 | 指定密钥的名称。 |
apiVersion: v1
kind: Pod
metadata:
name: secret-example-pod
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: secret-test-container
image: busybox
command: [ "/bin/sh", "-c", "export" ]
env:
- name: TEST_SECRET_USERNAME_ENV_VAR
valueFrom:
secretKeyRef: (1)
name: test-secret
key: username
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
restartPolicy: Never
1 | 指定使用密钥的的环境变量。 |
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
name: secret-example-bc
spec:
strategy:
sourceStrategy:
env:
- name: TEST_SECRET_USERNAME_ENV_VAR
valueFrom:
secretKeyRef: (1)
name: test-secret
key: username
from:
kind: ImageStreamTag
namespace: openshift
name: 'cli:latest'
1 | 指定使用密钥的的环境变量。 |
要使用密钥,Pod 需要引用该密钥。密钥可以通过三种方式与 Pod 一起使用
为容器填充环境变量。
作为挂载在其一个或多个容器上的卷中的文件。
在拉取 Pod 的镜像时由 kubelet 使用。
卷类型密钥使用卷机制将数据作为文件写入容器。镜像拉取密钥使用服务帐户将密钥自动注入命名空间中的所有 Pod。
当模板包含密钥定义时,模板使用提供的密钥的唯一方法是确保密钥卷源已验证,并且指定的 object 引用实际上指向 Secret
对象。因此,在任何依赖它的 Pod 之前都需要创建一个密钥。确保这一点最有效的方法是通过使用服务帐户自动注入它。
密钥 API 对象驻留在命名空间中。它们只能被同一命名空间中的 Pod 引用。
单个密钥的大小限制为 1MB。这是为了避免创建可能耗尽 apiserver 和 kubelet 内存的大型密钥。但是,创建许多较小的密钥也可能耗尽内存。
作为管理员,您可以创建一个不透明密钥,允许您存储包含任意值的非结构化 key:value
对。
在 YAML 文件中创建一个 Secret
对象。
例如
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque (1)
data:
username: <username>
password: <password>
1 | 指定不透明密钥。 |
使用以下命令创建 Secret
对象
$ oc create -f <filename>.yaml
要在 Pod 中使用密钥
更新 Pod 的服务帐户以引用密钥,如“了解如何创建密钥”部分所示。
创建 Pod,它将密钥用作环境变量或文件(使用 secret
卷),如“了解如何创建密钥”部分所示。
作为管理员,您可以创建一个旧版服务帐户令牌密钥,允许您将服务帐户令牌分发给必须对 API 进行身份验证的应用程序。
建议使用 TokenRequest API 获取绑定服务帐户令牌,而不是使用旧的服务帐户令牌密钥。只有在无法使用 TokenRequest API 并且可接受在可读的 API 对象中使用永不过期的令牌带来的安全风险时,才应创建服务帐户令牌密钥。 绑定服务帐户令牌比服务帐户令牌密钥更安全,原因如下:
工作负载会自动注入一个投影卷来获取绑定服务帐户令牌。如果您的工作负载需要额外的服务帐户令牌,请在您的工作负载清单中添加额外的投影卷。 更多信息,请参见“使用卷投影配置绑定服务帐户令牌”。 |
在 YAML 文件中创建一个 Secret
对象
Secret
对象示例apiVersion: v1
kind: Secret
metadata:
name: secret-sa-sample
annotations:
kubernetes.io/service-account.name: "sa-name" (1)
type: kubernetes.io/service-account-token (2)
1 | 指定现有服务帐户名称。如果您同时创建 ServiceAccount 和 Secret 对象,请先创建 ServiceAccount 对象。 |
2 | 指定服务帐户令牌密钥。 |
使用以下命令创建 Secret
对象
$ oc create -f <filename>.yaml
要在 Pod 中使用密钥
更新 Pod 的服务帐户以引用密钥,如“了解如何创建密钥”部分所示。
创建 Pod,它将密钥用作环境变量或文件(使用 secret
卷),如“了解如何创建密钥”部分所示。
作为管理员,您可以创建一个基本的认证密钥,允许您存储基本认证所需的凭据。使用此密钥类型时,Secret
对象的 data
参数必须包含以下使用 base64 格式编码的键:
username
:认证用户名
password
:认证密码或令牌
您可以使用 |
在 YAML 文件中创建一个 Secret
对象
secret
对象示例apiVersion: v1
kind: Secret
metadata:
name: secret-basic-auth
type: kubernetes.io/basic-auth (1)
data:
stringData: (2)
username: admin
password: <password>
1 | 指定基本的认证密钥。 |
2 | 指定要使用的基本认证值。 |
使用以下命令创建 Secret
对象
$ oc create -f <filename>.yaml
要在 Pod 中使用密钥
更新 Pod 的服务帐户以引用密钥,如“了解如何创建密钥”部分所示。
创建 Pod,它将密钥用作环境变量或文件(使用 secret
卷),如“了解如何创建密钥”部分所示。
作为管理员,您可以创建一个 SSH 认证密钥,允许您存储用于 SSH 认证的数据。使用此密钥类型时,Secret
对象的 data
参数必须包含要使用的 SSH 凭据。
在控制平面节点上的 YAML 文件中创建一个 Secret
对象
secret
对象示例apiVersion: v1
kind: Secret
metadata:
name: secret-ssh-auth
type: kubernetes.io/ssh-auth (1)
data:
ssh-privatekey: | (2)
MIIEpQIBAAKCAQEAulqb/Y ...
1 | 指定 SSH 认证密钥。 |
2 | 指定 SSH 密钥/值对作为要使用的 SSH 凭据。 |
使用以下命令创建 Secret
对象
$ oc create -f <filename>.yaml
要在 Pod 中使用密钥
更新 Pod 的服务帐户以引用密钥,如“了解如何创建密钥”部分所示。
创建 Pod,它将密钥用作环境变量或文件(使用 secret
卷),如“了解如何创建密钥”部分所示。
作为管理员,您可以创建一个 Docker 配置密钥,允许您存储访问容器镜像仓库的凭据。
kubernetes.io/dockercfg
。使用此密钥类型存储您的本地 Docker 配置文件。secret
对象的 data
参数必须包含使用 base64 格式编码的 .dockercfg
文件的内容。
kubernetes.io/dockerconfigjson
。使用此密钥类型存储您的本地 Docker 配置 JSON 文件。secret
对象的 data
参数必须包含使用 base64 格式编码的 .docker/config.json
文件的内容。
在 YAML 文件中创建一个 Secret
对象。
secret
对象示例apiVersion: v1
kind: Secret
metadata:
name: secret-docker-cfg
namespace: my-project
type: kubernetes.io/dockerconfig (1)
data:
.dockerconfig:bm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== (2)
1 | 指定密钥正在使用 Docker 配置文件。 |
2 | base64 编码的 Docker 配置文件输出 |
secret
对象示例apiVersion: v1
kind: Secret
metadata:
name: secret-docker-json
namespace: my-project
type: kubernetes.io/dockerconfig (1)
data:
.dockerconfigjson:bm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== (2)
1 | 指定密钥正在使用 Docker 配置 JSON 文件。 |
2 | base64 编码的 Docker 配置 JSON 文件输出 |
使用以下命令创建 Secret
对象
$ oc create -f <filename>.yaml
要在 Pod 中使用密钥
更新 Pod 的服务帐户以引用密钥,如“了解如何创建密钥”部分所示。
创建 Pod,它将密钥用作环境变量或文件(使用 secret
卷),如“了解如何创建密钥”部分所示。
您可以使用 Web 控制台创建密钥。
导航到**工作负载** → **密钥**。
点击**创建** → **从 YAML**。
手动编辑 YAML 以符合您的规范,或将文件拖放到 YAML 编辑器中。例如:
apiVersion: v1
kind: Secret
metadata:
name: example
namespace: <namespace>
type: Opaque (1)
data:
username: <base64 encoded username>
password: <base64 encoded password>
stringData: (2)
hostname: myapp.mydomain.com
1 | 此示例指定了一个不透明密钥;但是,您可能会看到其他密钥类型,例如服务帐户令牌密钥、基本身份验证密钥、SSH 身份验证密钥或使用 Docker 配置的密钥。 |
2 | `stringData` 映射中的条目将转换为 base64,然后该条目将自动移动到 `data` 映射。此字段是只写字段;该值仅通过 `data` 字段返回。 |
点击**创建**。
点击**将密钥添加到工作负载**。
从下拉菜单中,选择要添加的工作负载。
点击**保存**。
修改密钥的值时,值(由正在运行的 Pod 使用)不会动态更改。要更改密钥,必须删除原始 Pod 并创建一个新的 Pod(可能具有相同的 PodSpec)。
更新密钥的流程与部署新的容器镜像相同。您可以使用 kubectl rolling-update
命令。
引用密钥时,不会指定密钥中的 resourceVersion
值。因此,如果在 Pod 启动的同时更新密钥,则用于 Pod 的密钥版本未定义。
目前,无法检查创建 Pod 时使用的密钥对象的资源版本。计划让 Pod 报告此信息,以便控制器可以重新启动使用旧 |
作为管理员,您可以创建一个服务帐户令牌密钥。这允许您将服务帐户令牌分发给必须向 API 进行身份验证的应用程序。
通过运行以下命令在您的命名空间中创建一个服务帐户
$ oc create sa <service_account_name> -n <your_namespace>
将以下 YAML 示例保存到名为 service-account-token-secret.yaml
的文件中。该示例包含您可以用来生成服务帐户令牌的 Secret
对象配置
apiVersion: v1
kind: Secret
metadata:
name: <secret_name> (1)
annotations:
kubernetes.io/service-account.name: "sa-name" (2)
type: kubernetes.io/service-account-token (3)
1 | 将 <secret_name> 替换为您的服务令牌密钥的名称。 |
2 | 指定现有服务帐户名称。如果您同时创建 ServiceAccount 和 Secret 对象,请先创建 ServiceAccount 对象。 |
3 | 指定服务帐户令牌密钥类型。 |
通过应用文件生成服务帐户令牌
$ oc apply -f service-account-token-secret.yaml
通过运行以下命令从密钥获取服务帐户令牌
$ oc get secret <sa_token_secret> -o jsonpath='{.data.token}' | base64 --decode (1)
ayJhbGciOiJSUzI1NiIsImtpZCI6IklOb2dtck1qZ3hCSWpoNnh5YnZhSE9QMkk3YnRZMVZoclFfQTZfRFp1YlUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImJ1aWxkZXItdG9rZW4tdHZrbnIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiYnVpbGRlciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjNmZGU2MGZmLTA1NGYtNDkyZi04YzhjLTNlZjE0NDk3MmFmNyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmJ1aWxkZXIifQ.OmqFTDuMHC_lYvvEUrjr1x453hlEEHYcxS9VKSzmRkP1SiVZWPNPkTWlfNRp6bIUZD3U6aN3N7dMSN0eI5hu36xPgpKTdvuckKLTCnelMx6cxOdAbrcw1mCmOClNscwjS1KO1kzMtYnnq8rXHiMJELsNlhnRyyIXRTtNBsy4t64T3283s3SLsancyx0gy0ujx-Ch3uKAKdZi5iT-I8jnnQ-ds5THDs2h65RJhgglQEmSxpHrLGZFmyHAQI-_SjvmHZPXEc482x3SkaQHNLqpmrpJorNqh1M8ZHKzlujhZgVooMvJmWPXTb2vnvi3DGn2XI-hZxl1yD2yGH1RBpYUHA
1 | 将 <sa_token_secret> 替换为您的服务令牌密钥的名称。 |
使用您的服务帐户令牌向集群的 API 进行身份验证
$ curl -X GET <openshift_cluster_api> --header "Authorization: Bearer <token>" (1) (2)
1 | 将 <openshift_cluster_api> 替换为 OpenShift 集群 API。 |
2 | 将 <token> 替换为前面命令中输出的服务帐户令牌。 |
为了保护与您服务的通信,您可以配置 OpenShift Dedicated 生成一个签名的服务证书/密钥对,您可以将其添加到项目中的密钥中。
服务服务证书密钥旨在支持需要开箱即用证书的复杂中间件应用程序。它具有与管理员工具为节点和主节点生成的服务器证书相同的设置。
Pod
规范。apiVersion: v1
kind: Service
metadata:
name: registry
annotations:
service.beta.openshift.io/serving-cert-secret-name: registry-cert(1)
# ...
1 | 指定证书的名称 |
其他 Pod 可以通过使用自动安装在其 Pod 中的 /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt 文件中的 CA 捆绑包来信任集群创建的证书(这些证书仅针对内部 DNS 名称签名)。
此功能的签名算法是 x509.SHA256WithRSA
。要手动旋转,请删除生成的密钥。将创建一个新的证书。
要在 Pod 中使用签名的服务证书/密钥对,请创建或编辑服务以添加 service.beta.openshift.io/serving-cert-secret-name
注解,然后将密钥添加到 Pod。
要创建服务服务证书密钥
编辑服务的 Pod
规范。
添加service.beta.openshift.io/serving-cert-secret-name
注解,并使用您要用于密钥的名称。
kind: Service
apiVersion: v1
metadata:
name: my-service
annotations:
service.beta.openshift.io/serving-cert-secret-name: my-cert (1)
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
证书和密钥采用 PEM 格式,分别存储在tls.crt
和tls.key
中。
创建服务
$ oc create -f <file-name>.yaml
查看密钥以确保已创建
查看所有密钥的列表
$ oc get secrets
NAME TYPE DATA AGE
my-cert kubernetes.io/tls 2 9m
查看您的密钥详细信息
$ oc describe secret my-cert
Name: my-cert
Namespace: openshift-console
Labels: <none>
Annotations: service.beta.openshift.io/expiry: 2023-03-08T23:22:40Z
service.beta.openshift.io/originating-service-name: my-service
service.beta.openshift.io/originating-service-uid: 640f0ec3-afc2-4380-bf31-a8c784846a11
service.beta.openshift.io/expiry: 2023-03-08T23:22:40Z
Type: kubernetes.io/tls
Data
====
tls.key: 1679 bytes
tls.crt: 2595 bytes
使用该密钥编辑您的Pod
规范。
apiVersion: v1
kind: Pod
metadata:
name: my-service-pod
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: mypod
image: redis
volumeMounts:
- name: my-container
mountPath: "/etc/my-path"
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
volumes:
- name: my-volume
secret:
secretName: my-cert
items:
- key: username
path: my-group/my-username
mode: 511
可用后,您的 Pod 将运行。证书将对内部服务 DNS 名称<service.name>.<service.namespace>.svc
有效。
证书/密钥对会在接近过期时自动替换。在密钥上的service.beta.openshift.io/expiry
注解中查看过期日期,该日期采用 RFC3339 格式。
在大多数情况下,服务 DNS 名称 |
如果服务证书生成失败(服务的service.beta.openshift.io/serving-cert-generation-error
注解包含)
secret/ssl-key references serviceUID 62ad25ca-d703-11e6-9d6f-0e9c0057b608, which does not match 77b6dd80-d716-11e6-9d6f-0e9c0057b60
生成证书的服务不再存在,或者具有不同的serviceUID
。您必须通过删除旧密钥并清除服务上的以下注解来强制重新生成证书:service.beta.openshift.io/serving-cert-generation-error
,service.beta.openshift.io/serving-cert-generation-error-num
删除密钥
$ oc delete secret <secret_name>
清除注解
$ oc annotate service <service_name> service.beta.openshift.io/serving-cert-generation-error-
$ oc annotate service <service_name> service.beta.openshift.io/serving-cert-generation-error-num-
删除注解的命令在要删除的注解名称后带有 |