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 Container Platform 客户端配置文件、私有源代码库凭据等等。密钥将敏感内容与 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
对,这些对可以包含任意值。
您可以指定其他任意类型,例如 |
有关创建不同类型密钥的示例,请参阅了解如何创建密钥。
默认情况下,OpenShift Container Platform 为每个服务帐户创建一个镜像拉取密钥。
在 OpenShift Container Platform 4.16 之前,还会为创建的每个服务帐户生成一个长期有效的服务帐户 API 令牌密钥。从 OpenShift Container Platform 4.16 开始,不再创建此服务帐户 API 令牌密钥。 升级到 4.17 后,任何现有的长期有效的服务帐户 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 。如果为真,则指示驱动程序提供只读卷。 |
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。
当模板包含密钥定义时,模板使用提供的密钥的唯一方法是确保密钥卷源已验证,并且指定的對象引用实际指向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 Container Platform 配置为生成签名的服务证书/密钥对,您可以将其添加到项目中的密钥中。
服务服务证书密钥旨在支持需要开箱即用证书的复杂中间件应用程序。它与管理员工具为节点和主节点生成的服务器证书具有相同的设置。
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-
删除注释的命令在要删除的注释名称后带有 |