3.6. 输入 secret 和配置映射
要防止输入 secret 和配置映射的内容出现在构建输出容器镜像中,请使用 Docker 构建和源至镜像构建策略中的构建 卷。
有时候,构建操作需要凭证或其他配置数据才能访问依赖的资源,但又不希望将这些信息放在源代码控制中。您可以定义输入 secret 和输入配置映射。
例如,在使用 Maven 构建 Java 应用程序时,可以设置通过私钥访问的 Maven Central 或 JCenter 的私有镜像。要从该私有镜像下载库,您必须提供以下内容:
-
配置了镜像的 URL 和连接设置的
settings.xml
文件。 -
设置文件中引用的私钥,例如
~/.ssh/id_rsa
。
为安全起见,不应在应用程序镜像中公开您的凭证。
示例中描述的是 Java 应用程序,但您可以使用相同的方法将 SSL 证书添加到 /etc/ssl/certs
目录,以及添加 API 密钥或令牌、许可证文件等。
3.6.1. 什么是 secret?
Secret
对象类型提供了一种机制来保存敏感信息,如密码、OpenShift Dedicated 客户端配置文件、dockercfg
文件、私有源存储库凭证等。secret 将敏感内容与 Pod 分离。您可以使用卷插件将 secret 信息挂载到容器中,系统也可以使用 secret 代表 Pod 执行操作。
YAML 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
3.6.1.1. secret 的属性
主要属性包括:
- Secret 数据可以独立于其定义来引用。
- Secret 数据卷由临时文件工具 (tmpfs) 支持,永远不会停留在节点上。
- secret 数据可以在命名空间内共享。
3.6.1.2. secret 的类型
type
字段中的值指明 secret 的键名称和值的结构。此类型可用于强制使 secret 对象中存在用户名和密钥。如果您不想进行验证,请使用 opaque
类型,这也是默认类型。
指定以下一种类型来触发最小服务器端验证,确保 secret 数据中存在特定的键名称:
-
kubernetes.io/service-account-token
。使用服务帐户令牌。 -
kubernetes.io/dockercfg
。将.dockercfg
文件用于所需的 Docker 凭证。 -
kubernetes.io/dockerconfigjson
。将.docker/config.json
文件用于所需的 Docker 凭证。 -
kubernetes.io/basic-auth
。与基本身份验证搭配使用。 -
kubernetes.io/ssh-auth
。搭配 SSH 密钥身份验证使用。 -
kubernetes.io/tls
。搭配 TLS 证书颁发机构使用。
如果不想进行验证,设置 type= Opaque
。这意味着,secret 不声明符合键名称或值的任何约定。opaque
secret 允许使用无结构 key:value
对,可以包含任意值。
您可以指定其他任意类型,如 example.com/my-secret-type
。这些类型不在服务器端强制执行,但代表 secret 的创建者意在符合该类型的键/值要求。
3.6.1.3. 更新 secret
当修改 secret 的值时,已在被运行的 Pod 使用的 secret 值不会被动态更新。要更改 secret,必须删除原始 pod 并创建一个新 pod,在某些情况下,具有相同的 PodSpec
。
更新 secret 遵循与部署新容器镜像相同的工作流。您可以使用 kubectl rolling-update
命令。
secret 中的 resourceVersion
值不在引用时指定。因此,如果在 pod 启动的同时更新 secret,则将不能定义用于 pod 的 secret 版本。
目前,无法检查 Pod 创建时使用的 secret 对象的资源版本。按照计划 Pod 将报告此信息,以便控制器可以重启使用旧 resourceVersion
的 Pod。在此期间,请勿更新现有 secret 的数据,而应创建具有不同名称的新数据。
3.6.2. 创建 secret
您必须先创建 secret,然后创建依赖于此 secret 的 Pod。
在创建 secret 时:
- 使用 secret 数据创建 secret 对象。
- 更新 pod 的服务帐户以允许引用该 secret。
-
创建以环境变量或文件(使用
secret
卷)形式消耗 secret 的 pod。
流程
要从 JSON 或 YAML 文件创建 secret 对象,请输入以下命令:
$ oc create -f <filename>
例如,您可以从本地的
.docker/config.json
文件创建一个 secret:$ oc create secret generic dockerhub \ --from-file=.dockerconfigjson=<path/to/.docker/config.json> \ --type=kubernetes.io/dockerconfigjson
此命令将生成名为
dockerhub
的 secret JSON 规格并创建该对象。YAML Opaque Secret 对象定义
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque 1 data: username: <username> password: <password>
- 1
- 指定一个 opaque secret。
Docker 配置 JSON 文件对象定义
apiVersion: v1 kind: Secret metadata: name: aregistrykey namespace: myapps type: kubernetes.io/dockerconfigjson 1 data: .dockerconfigjson:bm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== 2
3.6.3. 使用 secret
创建 secret 后,可以创建一个 Pod 来引用您的 secret,再获取日志,然后删除 Pod。
流程
输入以下命令创建 pod 来引用您的 secret:
$ oc create -f <your_yaml_file>.yaml
输入以下命令来获取日志:
$ oc logs secret-example-pod
输入以下命令删除 pod:
$ oc delete pod secret-example-pod
其他资源
带有 secret 数据的 YAML 文件示例:
将创建四个文件的 secret 的 YAML 文件
apiVersion: v1 kind: Secret metadata: name: test-secret data: username: <username> 1 password: <password> 2 stringData: hostname: myapp.mydomain.com 3 secret.properties: |- 4 property1=valueA property2=valueB
pod 的 YAML 文件使用 secret 数据填充卷中的文件
apiVersion: v1 kind: Pod metadata: name: secret-example-pod spec: containers: - name: secret-test-container image: busybox command: [ "/bin/sh", "-c", "cat /etc/secret-volume/*" ] volumeMounts: # name must match the volume name below - name: secret-volume mountPath: /etc/secret-volume readOnly: true volumes: - name: secret-volume secret: secretName: test-secret restartPolicy: Never
pod 的 YAML 文件使用 secret 数据填充环境变量
apiVersion: v1 kind: Pod metadata: name: secret-example-pod spec: containers: - name: secret-test-container image: busybox command: [ "/bin/sh", "-c", "export" ] env: - name: TEST_SECRET_USERNAME_ENV_VAR valueFrom: secretKeyRef: name: test-secret key: username restartPolicy: Never
BuildConfig
对象的 YAML 文件,用于在环境变量中填充 secret 数据apiVersion: build.openshift.io/v1 kind: BuildConfig metadata: name: secret-example-bc spec: strategy: sourceStrategy: env: - name: TEST_SECRET_USERNAME_ENV_VAR valueFrom: secretKeyRef: name: test-secret key: username
3.6.4. 添加输入 secret 和配置映射
要向构建提供凭证和其他配置数据,而不将其放在源控制中,您可以定义输入 secret 和输入配置映射。
在某些情况下,构建操作需要凭证或其他配置数据才能访问依赖的资源。要使该信息在不置于源控制中的情况下可用,您可以定义输入 secret 和输入配置映射。
流程
将输入 secret 和配置映射添加到现有的 BuildConfig
对象中:
如果
ConfigMap
对象不存在,请输入以下命令来创建它:$ oc create configmap settings-mvn \ --from-file=settings.xml=<path/to/settings.xml>
这会创建一个名为
settings-mvn
的新配置映射,其中包含settings.xml
文件的纯文本内容。提示您还可以应用以下 YAML 来创建配置映射:
apiVersion: core/v1 kind: ConfigMap metadata: name: settings-mvn data: settings.xml: | <settings> … # Insert maven settings here </settings>
如果
Secret
对象不存在,请输入以下命令来创建它:$ oc create secret generic secret-mvn \ --from-file=ssh-privatekey=<path/to/.ssh/id_rsa> \ --type=kubernetes.io/ssh-auth
这会创建一个名为
secret-mvn
的新 secret,其包含id_rsa
私钥的 base64 编码内容。提示您还可以应用以下 YAML 来创建输入 secret:
apiVersion: core/v1 kind: Secret metadata: name: secret-mvn type: kubernetes.io/ssh-auth data: ssh-privatekey: | # Insert ssh private key, base64 encoded
将配置映射和 secret 添加到现有
BuildConfig
对象的source
部分中:source: git: uri: https://github.com/wildfly/quickstart.git contextDir: helloworld configMaps: - configMap: name: settings-mvn secrets: - secret: name: secret-mvn
要在新
BuildConfig
对象中包含 secret 和配置映射,请输入以下命令:$ oc new-build \ openshift/wildfly-101-centos7~https://github.com/wildfly/quickstart.git \ --context-dir helloworld --build-secret “secret-mvn” \ --build-config-map "settings-mvn"
在构建期间,构建过程将
settings.xml
和id_rsa
文件复制到源代码所在的目录中。在 OpenShift Dedicated S2I 构建器镜像中,这是镜像工作目录,它使用Dockerfile
中的WORKDIR
指令设置。如果要指定其他目录,请在定义中添加destinationDir
:source: git: uri: https://github.com/wildfly/quickstart.git contextDir: helloworld configMaps: - configMap: name: settings-mvn destinationDir: ".m2" secrets: - secret: name: secret-mvn destinationDir: ".ssh"
您还可以输入以下命令在创建新
BuildConfig
对象时指定目标目录:$ oc new-build \ openshift/wildfly-101-centos7~https://github.com/wildfly/quickstart.git \ --context-dir helloworld --build-secret “secret-mvn:.ssh” \ --build-config-map "settings-mvn:.m2"
在这两种情况下,
settings.xml
文件都添加到构建环境的./.m2
目录中,而id_rsa
密钥则添加到./.ssh
目录中。
3.6.5. Source-to-Image 策略
采用 Source
策略时,所有定义的输入 secret 都复制到对应的 destinationDir
中。如果 destinationDir
留空,则 secret 会放置到构建器镜像的工作目录中。
当 destinationDir
是一个相对路径时,使用相同的规则。secret 放置在相对于镜像工作目录的路径中。如果构建器镜像中不存在 destinationDir
路径中的最终目录,则会创建该目录。destinationDir
中的所有上述目录都必须存在,否则会发生错误。
输入 secret 将以全局可写(具有 0666
权限)形式添加,并且在执行 assemble
脚本后其大小会被截断为零。也就是说,生成的镜像中会包括这些 secret 文件,但出于安全原因,它们将为空。
assemble
脚本完成后不会截断输入配置映射。