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
对象类型提供了一种机制来保存敏感信息,例如密码、Red Hat OpenShift Service on AWS 客户端配置文件、私有源代码库凭据等。密钥将敏感内容与 Pod 解耦。您可以使用卷插件将密钥挂载到容器中,或者系统可以使用密钥代表 Pod 执行操作。
主要属性包括:
密钥数据可以独立于其定义进行引用。
密钥数据卷由临时文件存储设施 (tmpfs) 支持,永远不会在节点上保存。
密钥数据可以在命名空间内共享。
Secret
对象定义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
对。
您可以指定其他任意类型,例如 |
有关创建不同类型密钥的示例,请参见了解如何创建密钥。
默认情况下,Red Hat OpenShift Service on AWS 为每个服务帐户创建一个镜像拉取密钥。
在 Red Hat OpenShift Service on AWS 4.16 之前,还会为创建的每个服务帐户生成一个长期存在的服务帐户 API 令牌密钥。从 Red Hat OpenShift Service on AWS 4.16 开始,不再创建此服务帐户 API 令牌密钥。 升级到之后,任何现有的长期存在的服务帐户 API 令牌密钥都不会被删除,并将继续发挥作用。有关检测集群中正在使用的长期存在的 API 令牌或在不需要时删除这些令牌的信息,请参见 Red Hat 知识库文章OpenShift Container Platform 中的长期存在的服务帐户 API 令牌。 |
此镜像拉取密钥对于将 OpenShift 镜像注册表集成到集群的用户身份验证和授权系统中是必要的。
但是,如果您未启用ImageRegistry
功能,或者在集群镜像注册表操作器的配置中禁用了集成的 OpenShift 镜像注册表,则不会为每个服务帐户生成镜像拉取密钥。
在先前启用了集成的 OpenShift 镜像注册表的集群上禁用它时,先前生成的镜像拉取密钥将自动删除。
作为管理员,您必须在开发人员创建依赖于该密钥的 Pod 之前创建密钥。
创建密钥时:
创建一个包含您要保密的密钥的对象。以下部分描述了每种密钥类型所需的具体数据。
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 一起使用:
填充容器的环境变量。
作为挂载到其一个或多个容器上的卷中的文件。
由 kubelet 在为 Pod 拉取镜像时使用。
卷类型密钥使用卷机制将数据作为文件写入容器。镜像拉取密钥使用服务帐户将密钥自动注入命名空间中的所有 Pod。
当模板包含密钥定义时,模板使用提供的密钥的唯一方法是确保密钥卷源已验证,并且指定的引用确实指向Secret
对象。因此,在任何依赖它的 Pod 之前都需要创建密钥。确保这一点最有效的方法是通过使用服务帐户自动注入它。
Secret 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> 替换为前面命令中输出的服务帐户令牌。 |
为了保护与您的服务的通信安全,您可以将 Red Hat OpenShift Service on AWS 配置为生成一个签名的服务证书/密钥对,您可以将其添加到项目中的密钥中。
服务服务证书密钥旨在支持需要开箱即用证书的复杂中间件应用程序。它与管理员工具为节点和主节点生成的服务器证书具有相同的设置。
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-
删除注解的命令在要删除的注解名称后带有 |