2.3. 创建构建输入
通过以下小节查看构建输入的概述,并了解如何使用输入提供构建操作的源内容,以及如何使用构建环境和创建 secret。
2.3.1. 构建输入
构建输入提供构建操作的源内容。您可以使用以下构建输入在 OpenShift Container Platform 中提供源,它们按优先顺序列出:
- 内联 Dockerfile 定义
- 从现有镜像中提取内容
- Git 存储库
- 二进制(本地)输入
- 输入 secret
- 外部工件 (artifact)
您可以在单个构建中组合多个输入。但是,由于内联 Dockerfile 具有优先权,它可能会覆盖任何由其他输入提供的名为 Dockerfile 的文件。二进制(本地)和 Git 存储库是互斥的输入。
如果不希望在构建生成的最终应用程序镜像中提供构建期间使用的某些资源或凭证,或者想要消耗在 secret 资源中定义的值,您可以使用输入 secret。外部工件可用于拉取不以其他任一构建输入类型提供的额外文件。
在运行构建时:
- 构造工作目录,并将所有输入内容放进工作目录中。例如,把输入 Git 存储库克隆到工作目录中,并且把由输入镜像指定的文件通过目标目录复制到工作目录中。
-
构建过程将目录更改到
contextDir
(若已指定)。 - 内联 Dockerfile(若有)写入当前目录中。
-
当前目录中的内容提供给构建过程,供 Dockerfile、自定义构建器逻辑或
assemble
脚本引用。这意味着,构建会忽略所有驻留在contextDir
之外的输入内容。
以下源定义示例包括多种输入类型,以及它们如何组合的说明。如需有关如何定义各种输入类型的更多详细信息,请参阅每种输入类型的具体小节。
source: git: uri: https://github.com/openshift/ruby-hello-world.git 1 ref: "master" images: - from: kind: ImageStreamTag name: myinputimage:latest namespace: mynamespace paths: - destinationDir: app/dir/injected/dir 2 sourcePath: /usr/lib/somefile.jar contextDir: "app/dir" 3 dockerfile: "FROM centos:7\nRUN yum install -y httpd" 4
2.3.2. Dockerfile 源
提供 dockerfile
值时,此字段的内容将写到磁盘上,存为名为 Dockerfile
的文件。这是处理完其他输入源之后完成的;因此,如果输入源存储库的根目录中包含 Dockerfile,它会被此内容覆盖。
源定义是 BuildConfig
的 spec
部分的一部分:
source:
dockerfile: "FROM centos:7\nRUN yum install -y httpd" 1
- 1
dockerfile
字段包含要构建的内联 Dockerfile。
其他资源
- 此字段的典型用途是为 Docker 策略构建提供 Dockerfile。
2.3.3. 镜像源
您可以使用镜像向构建过程添加其他文件。输入镜像的引用方式与定义 From
和 To
镜像目标的方式相同。这意味着可以引用容器镜像和镜像流标签。在使用镜像时,必须提供一个或多个路径对,以指示要复制镜像的文件或目录的路径以及构建上下文中要放置它们的目的地。
源路径可以是指定镜像内的任何绝对路径。目的地必须是相对目录路径。构建时会加载镜像,并将指定的文件和目录复制到构建过程上下文目录中。这与源存储库内容要克隆到的目录相同。如果源路径以 /.
结尾,则复制目录的内容,但不在目的地上创建该目录本身。
镜像输入在 BuildConfig
的 source
定义中指定:
source: git: uri: https://github.com/openshift/ruby-hello-world.git ref: "master" images: 1 - from: 2 kind: ImageStreamTag name: myinputimage:latest namespace: mynamespace paths: 3 - destinationDir: injected/dir 4 sourcePath: /usr/lib/somefile.jar 5 - from: kind: ImageStreamTag name: myotherinputimage:latest namespace: myothernamespace pullSecret: mysecret 6 paths: - destinationDir: injected/dir sourcePath: /usr/lib/somefile.jar
另外,如果输入镜像需要 pull secret,您可以将 pull secret 链接到构建所使用的服务帐户。默认情况下,构建使用 builder
服务帐户。如果 secret 包含与托管输入镜像的存储库匹配的凭证,pull secret 会自动添加到构建中。要将 pull secret 连接到构建使用的服务帐户,请运行:
$ oc secrets link builder dockerhub
使用自定义策略的构建不支持此功能。
2.3.4. Git 源
指定之后,从提供的位置获取源代码。
如果您提供内联 Dockerfile,它将覆盖 Git 存储库的 contextDir
中的 Dockerfile。
源定义是 BuildConfig
的 spec
部分的一部分:
source: git: 1 uri: "https://github.com/openshift/ruby-hello-world" ref: "master" contextDir: "app/dir" 2 dockerfile: "FROM openshift/ruby-22-centos7\nUSER example" 3
如果 ref
字段注明拉取请求,则系统将使用 git fetch
操作,然后 checkout FETCH_HEAD
。
如果未提供 ref
值,OpenShift Container Platform 将执行浅克隆 (--depth=1
)。这时,仅下载与默认分支(通常为 master
)上最近提交相关联的文件。这将使存储库下载速度加快,但不会有完整的提交历史记录。要执行指定存储库的默认分支的完整 git clone
,请将 ref
设置为默认分支的名称(如 main
)。
如果 Git 克隆操作要经过执行中间人 (MITM) TLS 劫持或重新加密被代理连接的代理,该操作不起作用。
2.3.4.1. 使用代理
如果 Git 存储库只能使用代理访问,您可以在构建配置的 source
部分中定义要使用的代理。您可以同时配置要使用的 HTTP 和 HTTPS 代理。两个字段都是可选的。也可以在 NoProxy
字段中指定不应执行代理的域。
源 URI 必须使用 HTTP 或 HTTPS 协议才可以正常工作。
source: git: uri: "https://github.com/openshift/ruby-hello-world" ref: "master" httpProxy: http://proxy.example.com httpsProxy: https://proxy.example.com noProxy: somedomain.com, otherdomain.com
对于 Pipeline 策略构建,因为 Jenkins Git 插件当前限制的缘故,通过 Git 插件执行的任何 Git 操作都不会利用 BuildConfig
中定义的 HTTP 或 HTTPS 代理。Git 插件将仅使用 Plugin Manager 面板上 Jenkins UI 中配置的代理。然后,在所有任务中,此代理都会被用于 Jenkins 内部与 git 的所有交互。
其他资源
- 您可以在 JenkinsBehindProxy 上找到有关如何通过 Jenkins UI 配置代理的说明。
2.3.4.2. 源克隆 secret
构建器 pod 需要访问定义为构建源的任何 Git 存储库。源克隆 secret 为构建器 pod 提供了通常无权访问的资源的访问权限,例如私有存储库或具有自签名或不可信 SSL 证书的存储库。
支持以下源克隆 secret 配置:
- .gitconfig 文件
- 基本身份验证
- SSH 密钥身份验证
- 可信证书颁发机构
您还可以组合使用这些配置来满足特定的需求。
2.3.4.2.1. 自动把源克隆 secret 添加到构建配置
创建 BuildConfig
,OpenShift Container Platform 可以自动填充其源克隆 secret 引用。这会使生成的构建自动使用存储在引用的 secret 中的凭证与远程 Git 存储库进行身份验证,而无需进一步配置。
若要使用此功能,包含 Git 存储库凭证的一个 secret 必须存在于稍后创建 BuildConfig
的命名空间中。此 secret 必须包含前缀为 build.openshift.io/source-secret-match-uri-
的一个或多个注解。这些注解中的每一个值都是统一资源标识符(URI)模式,其定义如下。如果 BuildConfig
是在没有源克隆 secret 引用的前提下创建的,并且其 Git 源 URI 与 secret 注解中的 URI 模式匹配,OpenShift Container Platform 将自动在 BuildConfig
插入对该 secret 的引用。
先决条件
URI 模式必须包含:
-
有效的方案包括:
*://
、git://
、http://
、https://
或ssh://
-
一个主机:*,或一个有效的主机名或 IP 地址(可选)在之前使用
*。
-
一个路径:
/*
,或/
(后面包括任意字符并可以包括*
字符)
在上述所有内容中,*
字符被认为是通配符。
URI 模式必须与符合 RFC3986 的 Git 源 URI 匹配。不要在 URI 模式中包含用户名(或密码)组件。
例如,如果使用 ssh://git@bitbucket.atlassian.com:7999/ATLASSIAN jira.git
作为 git 存储库 URL,则源 secret 必须指定为 ssh://bitbucket.atlassian.com:7999/*
(而非 ssh://git@bitbucket.atlassian.com:7999/*
)。
$ oc annotate secret mysecret \ 'build.openshift.io/source-secret-match-uri-1=ssh://bitbucket.atlassian.com:7999/*'
流程
如果多个 secret 与特定 BuildConfig
的 Git URI 匹配,OpenShift Container Platform 会选择匹配最多的 secret。这可以实现下例中所示的基本覆盖。
以下片段显示了两个部分源克隆 secret,第一个匹配通过 HTTPS 访问的 mycorp.com
域中的任意服务器,第二个则覆盖对服务器 mydev1.mycorp.com
和 mydev2.mycorp.com
的访问:
kind: Secret apiVersion: v1 metadata: name: matches-all-corporate-servers-https-only annotations: build.openshift.io/source-secret-match-uri-1: https://*.mycorp.com/* data: ... --- kind: Secret apiVersion: v1 metadata: name: override-for-my-dev-servers-https-only annotations: build.openshift.io/source-secret-match-uri-1: https://mydev1.mycorp.com/* build.openshift.io/source-secret-match-uri-2: https://mydev2.mycorp.com/* data: ...
使用以下命令将
build.openshift.io/source-secret-match-uri-
注解添加到预先存在的 secret:$ oc annotate secret mysecret \ 'build.openshift.io/source-secret-match-uri-1=https://*.mycorp.com/*'
2.3.4.2.2. 手动添加源克隆 secret
通过将 sourceSecret
字段添加到 BuildConfig
中的 source
部分,并将它设置为您创建的 secret 的名称,可以手动将源克隆 secret 添加到构建配置中。在本例中,是 basicsecret
。
apiVersion: "v1" kind: "BuildConfig" metadata: name: "sample-build" spec: output: to: kind: "ImageStreamTag" name: "sample-image:latest" source: git: uri: "https://github.com/user/app.git" sourceSecret: name: "basicsecret" strategy: sourceStrategy: from: kind: "ImageStreamTag" name: "python-33-centos7:latest"
流程
您还可以使用 oc set build-secret
命令在现有构建配置中设置源克隆 secret。
要在现有构建配置上设置源克隆 secret,请输入以下命令:
$ oc set build-secret --source bc/sample-build basicsecret
2.3.4.2.3. 从 .gitconfig 文件创建 secret
如果克隆应用程序要依赖于 .gitconfig
文件,您可以创建包含它的 secret。将它添加到 builder 服务帐户中,再添加到您的 BuildConfig
。
流程
-
从
.gitconfig
文件创建 secret:
$ oc create secret generic <secret_name> --from-file=<path/to/.gitconfig>
如果 .gitconfig
文件的 http
部分设置了 sslVerify=false
,则可以关闭 iVSSL 验证:
[http] sslVerify=false
2.3.4.2.4. 从 .gitconfig 文件为安全 Git 创建 secret
如果 Git 服务器使用双向 SSL 和用户名加密码进行保护,您必须将证书文件添加到源构建中,并在 .gitconfig
文件中添加对证书文件的引用。
先决条件
- 您必须具有 Git 凭证。
流程
将证书文件添加到源构建中,并在 gitconfig
文件中添加对证书文件的引用。
-
将
client.crt
、cacert.crt
和client.key
文件添加到应用程序源代码的/var/run/secrets/openshift.io/source/
目录中。 在服务器的
.gitconfig
文件中,添加下例中所示的[http]
部分:# cat .gitconfig
输出示例
[user] name = <name> email = <email> [http] sslVerify = false sslCert = /var/run/secrets/openshift.io/source/client.crt sslKey = /var/run/secrets/openshift.io/source/client.key sslCaInfo = /var/run/secrets/openshift.io/source/cacert.crt
创建 secret:
$ oc create secret generic <secret_name> \ --from-literal=username=<user_name> \ 1 --from-literal=password=<password> \ 2 --from-file=.gitconfig=.gitconfig \ --from-file=client.crt=/var/run/secrets/openshift.io/source/client.crt \ --from-file=cacert.crt=/var/run/secrets/openshift.io/source/cacert.crt \ --from-file=client.key=/var/run/secrets/openshift.io/source/client.key
为了避免必须再次输入密码,需要在构建中指定 source-to-image(S2I)镜像。但是,如果无法克隆存储库,您仍然必须指定用户名和密码才能推进构建。
其他资源
-
应用程序源代码中的
/var/run/secrets/openshift.io/source/
文件夹。
2.3.4.2.5. 从源代码基本身份验证创建 secret
基本身份验证需要 --username
和 --password
的组合,或者令牌方可与软件配置管理(SCM)服务器进行身份验证。
先决条件
- 用于访问私有存储库的用户名和密码。
流程
在使用
--username
和--password
访问私有存储库前首先创建 secret:$ oc create secret generic <secret_name> \ --from-literal=username=<user_name> \ --from-literal=password=<password> \ --type=kubernetes.io/basic-auth
使用令牌创建基本身份验证 secret:
$ oc create secret generic <secret_name> \ --from-literal=password=<token> \ --type=kubernetes.io/basic-auth
2.3.4.2.6. 从源代码 SSH 密钥身份验证创建 secret
基于 SSH 密钥的身份验证需要 SSH 私钥。
存储库密钥通常位于 $HOME/.ssh/
目录中,但默认名称为 id_dsa.pub
、id_ecdsa.pub
、id_ed25519.pub
或 id_rsa.pub
。
流程
生成 SSH 密钥凭证:
$ ssh-keygen -t ed25519 -C "your_email@example.com"
注意使用带有密语保护的 SSH 密钥会导致 OpenShift Container Platform 无法进行构建。提示输入密语(passphrase)时,请将其留空。
创建两个文件:公钥和对应的私钥(
id_dsa
、id_ecdsa
、id_ed25519
或id_rsa
之一)。这两项就位后,请查阅源代码控制管理 (SCM) 系统的手册来了解如何上传公钥。私钥用于访问您的私有存储库。在使用 SSH 密钥访问私有存储库之前,先创建 secret:
$ oc create secret generic <secret_name> \ --from-file=ssh-privatekey=<path/to/ssh/private/key> \ --from-file=<path/to/known_hosts> \ 1 --type=kubernetes.io/ssh-auth
- 1
- 可选:添加此字段可启用严格的服务器主机密钥检查。
警告在创建 secret 时跳过
known_hosts
文件会使构建容易受到中间人 (MITM) 攻击的影响。注意确保
known_hosts
文件中包含源代码主机条目。
2.3.4.2.7. 从源代码可信证书颁发机构创建 secret
在 Git 克隆操作期间受信任的 TLS 证书颁发机构(CA)集合内置于 OpenShift Container Platform 基础结构镜像中。如果 Git 服务器使用自签名证书或由镜像不信任的颁发机构签名的证书,您可以创建包含证书的 secret 或者禁用 TLS 验证。
如果您为 CA 证书创建 secret,OpenShift Container Platform 会在 Git 克隆操作过程中使用它来访问您的 Git 服务器。使用此方法比禁用 Git 的 SSL 验证要安全得多,后者接受所出示的任何 TLS 证书。
流程
使用 CA 证书文件创建 secret。
如果您的 CA 使用中间证书颁发机构,请合并
ca.crt
文件中所有 CA 的证书。使用以下命令:$ cat intermediateCA.crt intermediateCA.crt rootCA.crt > ca.crt
创建 secret:
$ oc create secret generic mycert --from-file=ca.crt=</path/to/file> 1
- 1
- 您必须使用密钥名称
ca.crt
。
2.3.4.2.8. 源 secret 组合
您可以组合使用不同的源克隆 secret 创建方法来满足特定的需求。
2.3.4.2.8.1. 使用 .gitconfig
文件创建基于 SSH 的身份验证 secret
您可以组合不同的方法开创建源克隆 secret 以满足特定的需求,例如使用 .gitconfig
文件的基于 SSH 的身份验证 secret。
先决条件
- SSH 身份验证
- .gitconfig 文件
流程
使用
.gitconfig
文件创建基于 SSH 的身份验证 secret:$ oc create secret generic <secret_name> \ --from-file=ssh-privatekey=<path/to/ssh/private/key> \ --from-file=<path/to/.gitconfig> \ --type=kubernetes.io/ssh-auth
2.3.4.2.8.2. 创建组合了 .gitconfig 文件和 CA 证书的 secret
您可以组合使用不同的源克隆 secret 创建方法来满足特定的需求,例如组合了 .gitconfig
文件和 CA 证书的 Secret。
先决条件
- .gitconfig 文件
- CA 证书
流程
创建组合了
.gitconfig
文件和 CA 证书的 secret:$ oc create secret generic <secret_name> \ --from-file=ca.crt=<path/to/certificate> \ --from-file=<path/to/.gitconfig>
2.3.4.2.8.3. 使用 CA 证书创建基本身份验证 secret
您可以组合使用不同的源克隆 secret 创建方法来满足特定的需求,例如组合了基本身份验证和 CA 证书的 secret。
先决条件
- 基本身份验证凭证
- CA 证书
流程
使用 CA 证书创建基本身份验证 secret:
$ oc create secret generic <secret_name> \ --from-literal=username=<user_name> \ --from-literal=password=<password> \ --from-file=ca-cert=</path/to/file> \ --type=kubernetes.io/basic-auth
2.3.4.2.8.4. 使用 .gitconfig 文件创建基本身份验证 secret
您可以组合使用不同的源克隆 secret 创建方法来满足特定的需求,例如组合了基本身份验证和 .gitconfig
文件的 secret。
先决条件
- 基本身份验证凭证
-
.gitconfig
文件
流程
使用
.gitconfig
文件创建基本身份验证 secret:$ oc create secret generic <secret_name> \ --from-literal=username=<user_name> \ --from-literal=password=<password> \ --from-file=</path/to/.gitconfig> \ --type=kubernetes.io/basic-auth
2.3.4.2.8.5. 使用 .gitconfig 文件和 CA 证书创建基本身份验证 secret
您可以组合使用不同的源克隆 secret 创建方法来满足特定的需求,例如组合了基本身份验证、.gitconfig
文件和证书颁发机构(CA)证书的 Secret。
先决条件
- 基本身份验证凭证
-
.gitconfig
文件 - CA 证书
流程
使用
.gitconfig
文件和 CA 证书创建基本身份验证 secret:$ oc create secret generic <secret_name> \ --from-literal=username=<user_name> \ --from-literal=password=<password> \ --from-file=</path/to/.gitconfig> \ --from-file=ca-cert=</path/to/file> \ --type=kubernetes.io/basic-auth
2.3.5. 二进制(本地)来源
从本地文件系统流传输内容到构建器称为 Binary
类型构建。对于此类构建,BuildConfig.spec.source.type
的对应值为 Binary
。
这种源类型的独特之处在于,它仅基于您对 oc start-build
的使用而加以利用。
二进制类型构建需要从本地文件系统流传输内容,因此无法自动触发二进制类型构建,如镜像更改触发器。这是因为无法提供二进制文件。同样,您无法从 web 控制台启动二进制类型构建。
要使用二进制构建,请使用以下选项之一调用 oc start-build
:
-
--from-file
:指定的文件内容作为二进制流发送到构建器。您还可以指定文件的 URL。然后,构建器将数据存储在构建上下文顶端的同名文件中。 -
--from-dir
和--from-repo
:内容存档下来,并作为二进制流发送给构建器。然后,构建器在构建上下文目录中提取存档的内容。使用--from-dir
时,您还可以指定提取的存档的 URL。 -
--from-archive
:指定的存档发送到构建器,并在构建器上下文目录中提取。此选项与--from-dir
的行为相同;只要这些选项的参数是目录,就会首先在主机上创建存档。
在上方列出的每种情形中:
-
如果
BuildConfig
已经定义了Binary
源类型,它会有效地被忽略并且替换成客户端发送的内容。 -
如果
BuildConfig
定义了Git
源类型,则会动态禁用它,因为Binary
和Git
是互斥的,并且二进制流中提供给构建器的数据将具有优先权。
您可以将 HTTP 或 HTTPS 方案的 URL 传递给 --from-file
和 --from-archive
,而不传递文件名。将 -from-file
与 URL 结合使用时,构建器镜像中文件的名称由 web 服务器发送的 Content-Disposition
标头决定,如果该标头不存在,则由 URL 路径的最后一个组件决定。不支持任何形式的身份验证,也无法使用自定义 TLS 证书或禁用证书验证。
使用 oc new-build --binary =true
时,该命令可确保强制执行与二进制构建关联的限制。生成的 BuildConfig
具有 Binary
源类型,这意味着为此 BuildConfig
运行构建的唯一有效方法是使用 oc start-build
和其中一个 --from
选项来提供必需的二进制数据。
Dockerfile 和 contextDir
源选项对二进制构建具有特殊含义。
Dockerfile 可以与任何二进制构建源一起使用。如果使用 Dockerfile 且二进制流是存档,则其内容将充当存档中任何 Dockerfile 的替代 Dockerfile。如果将 Dockerfile 与 --from-file
参数搭配 使用,且文件参数命名为 Dockerfile,则 Dockerfile 的值将替换二进制流中的值。
如果是二进制流封装提取的存档内容,contextDir
字段的值将解释为存档中的子目录,并且在有效时,构建器将在执行构建之前更改到该子目录。
2.3.6. 输入 secret 和配置映射
要防止输入 secret 和配置映射的内容出现在构建输出容器镜像中,请使用 Docker 构建和源至镜像构建策略中的构建 卷。
有时候,构建操作需要凭证或其他配置数据才能访问依赖的资源,但又不希望将这些信息放在源代码控制中。您可以定义输入 secret 和输入配置映射。
例如,在使用 Maven 构建 Java 应用程序时,可以设置通过私钥访问的 Maven Central 或 JCenter 的私有镜像。要从该私有镜像下载库,您必须提供以下内容:
-
配置了镜像的 URL 和连接设置的
settings.xml
文件。 -
设置文件中引用的私钥,例如
~/.ssh/id_rsa
。
为安全起见,不应在应用程序镜像中公开您的凭证。
示例中描述的是 Java 应用程序,但您可以使用相同的方法将 SSL 证书添加到 /etc/ssl/certs
目录,以及添加 API 密钥或令牌、许可证文件等。
2.3.6.1. 什么是 secret?
Secret
对象类型提供了一种机制来保存敏感信息,如密码、OpenShift Container Platform 客户端配置文件、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
2.3.6.1.1. secret 的属性
主要属性包括:
- Secret 数据可以独立于其定义来引用。
- Secret 数据卷由临时文件工具 (tmpfs) 支持,永远不会停留在节点上。
- secret 数据可以在命名空间内共享。
2.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 的创建者意在符合该类型的键/值要求。
2.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 的数据,而应创建具有不同名称的新数据。
2.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
2.3.6.3. 使用 secret
创建 secret 后,可以创建一个 Pod 来引用您的 secret,再获取日志,然后删除 Pod。
流程
创建要引用您的 secret 的 Pod:
$ 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
一个 Build Config 的 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
2.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 Container Platform 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
目录中。
2.3.6.5. Source-to-Image 策略
采用 Source
策略时,所有定义的输入 secret 都复制到对应的 destinationDir
中。如果 destinationDir
留空,则 secret 会放置到构建器镜像的工作目录中。
当 destinationDir
是一个相对路径时,使用相同的规则。secret 放置在相对于镜像工作目录的路径中。如果构建器镜像中不存在 destinationDir
路径中的最终目录,则会创建该目录。destinationDir
中的所有上述目录都必须存在,否则会发生错误。
输入 secret 将以全局可写(具有 0666
权限)形式添加,并且在执行 assemble
脚本后其大小会被截断为零。也就是说,生成的镜像中会包括这些 secret 文件,但出于安全原因,它们将为空。
assemble
脚本完成后不会截断输入配置映射。
2.3.6.6. Docker 策略
采用 docker 策略时,您可以使用 Dockerfile 中的 ADD
和 COPY
指令,将所有定义的输入 secret 添加到容器镜像中。
如果没有为 secret 指定 destinationDir
,则文件将复制到 Dockerfile 所在的同一目录中。如果将一个相对路径指定为 destinationDir
,则 secret 复制到相对于 Dockerfile 位置的该目录中。这样,secret 文件可供 Docker 构建操作使用,作为构建期间使用的上下文目录的一部分。
引用 secret 和配置映射数据的 Dockerfile 示例
FROM centos/ruby-22-centos7 USER root COPY ./secret-dir /secrets COPY ./config / # Create a shell script that will output secrets and ConfigMaps when the image is run RUN echo '#!/bin/sh' > /input_report.sh RUN echo '(test -f /secrets/secret1 && echo -n "secret1=" && cat /secrets/secret1)' >> /input_report.sh RUN echo '(test -f /config && echo -n "relative-configMap=" && cat /config)' >> /input_report.sh RUN chmod 755 /input_report.sh CMD ["/bin/sh", "-c", "/input_report.sh"]
用户应该从最终的应用程序镜像中移除输入 secret,以便从该镜像运行的容器中不会存在这些 secret。但是,secret 仍然存在于它们添加到的层中的镜像本身内。这一移除是 Dockerfile 本身的一部分。
为防止输入 secret 和配置映射的内容出现在构建输出容器镜像中并完全避免此移除过程,请在 Docker 构建策略中使用构建卷。
2.3.6.7. Custom 策略
使用 Custom 策略时,所有定义的输入 secret 和配置映射都位于 /var/run/secrets/openshift.io/build
目录中的构建器容器中。自定义构建镜像必须正确使用这些 secret 和配置映射。使用 Custom 策略时,您可以按照 Custom 策略选项中所述定义 secret。
现有策略 secret 与输入 secret 之间没有技术差异。但是,构建器镜像可以区分它们并以不同的方式加以使用,具体取决于您的构建用例。
输入 secret 始终挂载到 /var/run/secrets/openshift.io/build
目录中,或您的构建器可以解析 $BUILD
环境变量(包含完整构建对象)。
如果命名空间和节点上存在 registry 的 pull secret,构建会默认使用命名空间中的 pull secret。
2.3.7. 外部工件 (artifact)
建议不要将二进制文件存储在源存储库中。因此,您必须定义一个构建,在构建过程中拉取其他文件,如 Java .jar
依赖项。具体方法取决于使用的构建策略。
对于 Source 构建策略,必须在 assemble
脚本中放入适当的 shell 命令:
.s2i/bin/assemble
文件
#!/bin/sh APP_VERSION=1.0 wget http://repository.example.com/app/app-$APP_VERSION.jar -O app.jar
.s2i/bin/run
文件
#!/bin/sh exec java -jar app.jar
对于 Docker 构建策略,您必须修改 Dockerfile 并通过 RUN
指令 调用 shell 命令:
Dockerfile 摘录
FROM jboss/base-jdk:8 ENV APP_VERSION 1.0 RUN wget http://repository.example.com/app/app-$APP_VERSION.jar -O app.jar EXPOSE 8080 CMD [ "java", "-jar", "app.jar" ]
在实践中,您可能希望将环境变量用于文件位置,以便要下载的具体文件能够使用 BuildConfig
中定义的环境变量来自定义,而不必更新 Dockerfile 或 assemble
脚本。
您可以选择不同方法来定义环境变量:
-
使用
.s2i/environment
文件(仅适用于 Source 构建策略) -
在
BuildConfig
中设置 -
使用
oc start-build --env
明确提供(仅适用于手动触发的构建)
2.3.8. 将 docker 凭证用于私有容器镜像仓库
您可以为构建提供 .docker/config.json
文件,在文件中包含私有容器 registry 的有效凭证。这样,您可以将输出镜像推送到私有容器镜像 registry 中,或从需要身份验证的私有容器镜像 registry 中拉取构建器镜像。
您可以为同一 registry 中的多个存储库提供凭证,每个软件仓库都有特定于该 registry 路径的凭证。
对于 OpenShift Container Platform 容器镜像 registry,这不是必需的,因为 OpenShift Container Platform 会自动为您生成 secret。
默认情况下,.docker/config.json
文件位于您的主目录中,并具有如下格式:
auths: index.docker.io/v1/: 1 auth: "YWRfbGzhcGU6R2labnRib21ifTE=" 2 email: "user@example.com" 3 docker.io/my-namespace/my-user/my-image: 4 auth: "GzhYWRGU6R2fbclabnRgbkSp="" email: "user@example.com" docker.io/my-namespace: 5 auth: "GzhYWRGU6R2deesfrRgbkSp="" email: "user@example.com"
您可以定义多个容器镜像 registry,或在同一 registry 中定义多个存储库。或者,也可以通过运行 docker login
命令将身份验证条目添加到此文件中。如果文件不存在,则会创建此文件。
Kubernetes 提供Secret
对象,可用于存储配置和密码。
先决条件
-
您必须有一个
.docker/config.json
文件。
流程
从本地
.docker/config.json
文件创建 secret:$ oc create secret generic dockerhub \ --from-file=.dockerconfigjson=<path/to/.docker/config.json> \ --type=kubernetes.io/dockerconfigjson
这将生成名为
dockerhub
的 secret 的 JSON 规格并创建该对象。将
pushSecret
字段添加到BuildConfig
中的output
部分,并将它设为您创建的secret
的名称,上例中为dockerhub
:spec: output: to: kind: "DockerImage" name: "private.registry.com/org/private-image:latest" pushSecret: name: "dockerhub"
您可以使用
oc set build-secret
命令在构建配置上设置推送 secret:$ oc set build-secret --push bc/sample-build dockerhub
您还可以将 push secret 与构建使用的服务帐户链接,而不指定
pushSecret
字段。默认情况下,构建使用builder
服务帐户。如果 secret 包含与托管构建输出镜像的存储库匹配的凭证,则 push secret 会自动添加到构建中。$ oc secrets link builder dockerhub
通过指定
pullSecret
字段(构建策略定义的一部分),从私有容器镜像 registry 拉取构建器容器镜像:strategy: sourceStrategy: from: kind: "DockerImage" name: "docker.io/user/private_repository" pullSecret: name: "dockerhub"
您可以使用
oc set build-secret
命令在构建配置上设置拉取 secret:$ oc set build-secret --pull bc/sample-build dockerhub
注意本例在 Source 构建中使用
pullSecret
,但也适用于 Docker 构建和 Custom 构建。您还可以将 pull secret 链接到构建使用的服务帐户,而不指定
pullSecret
字段。默认情况下,构建使用builder
服务帐户。如果 secret 包含与托管构建的输入镜像的存储库匹配的凭证,pull secret 会自动添加到构建中。将 pull secret 链接到构建使用的服务帐户,而不指定pullSecret
字段:$ oc secrets link builder dockerhub
注意您必须在
BuildConfig
spec 中指定一个from
镜像,才能利用此功能。由oc new-build
或oc new-app
生成的 Docker 策略构建在某些情况下可能无法进行这个操作。
2.3.9. 构建环境
与 Pod 环境变量一样,可以定义构建环境变量,在使用 Downward API 时引用其他源或变量。需要注意一些例外情况。
您也可以使用 oc set env
命令管理 BuildConfig
中定义的环境变量。
不支持在构建环境变量中使用 valueFrom
引用容器资源,因为这种引用在创建容器之前解析。
2.3.9.1. 使用构建字段作为环境变量
您可以注入构建对象的信息,使用 fieldPath
环境变量源指定要获取值的字段的 JsonPath
。
Jenkins Pipeline 策略不支持将 valueFrom
语法用于环境变量。
流程
将
fieldPath
环境变量源设置为您有兴趣获取其值的字段的JsonPath
:env: - name: FIELDREF_ENV valueFrom: fieldRef: fieldPath: metadata.name
2.3.9.2. 使用 secret 作为环境变量
您可以使用 valueFrom
语法,将 secret 的键值作为环境变量提供。
此方法在构建容器集控制台的输出中以纯文本形式显示机密。要避免这种情况,请使用输入 secret 和配置映射。
流程
要将 secret 用作环境变量,请设置
valueFrom
语法:apiVersion: build.openshift.io/v1 kind: BuildConfig metadata: name: secret-example-bc spec: strategy: sourceStrategy: env: - name: MYVAL valueFrom: secretKeyRef: key: myval name: mysecret
其他资源
2.3.10. 服务用(service serving)证书 secret
服务用证书 secret 旨在支持需要开箱即用证书的复杂中间件应用程序。它的设置与管理员工具为节点和 master 生成的服务器证书相同。
流程
要保护与您服务的通信,请让集群生成的签名的服务证书/密钥对保存在您的命令空间的 secret 中。
在服务上设置
service.beta.openshift.io/serving-cert-secret-name
注解,并将值设置为您要用于 secret 的名称。然后,您的
PodSpec
可以挂载该 secret。当它可用时,您的 Pod 会运行。该证书对内部服务 DNS 名称<service.name>.<service.namespace>.svc
有效。证书和密钥采用 PEM 格式,分别存储在
tls.crt
和tls.key
中。证书/密钥对在接近到期时自动替换。在 secret 的service.beta.openshift.io/expiry
注解中查看过期日期,其格式为 RFC3339。
在大多数情形中,服务 DNS 名称 <service.name>.<service.namespace>.svc
不可从外部路由。<service.name>.<service.namespace>.svc
的主要用途是集群内或服务内通信,也用于重新加密路由。
其他 pod 可以信任由集群创建的证书,这些证书只为内部 DNS 名称签名,方法是使用 pod 中自动挂载的 /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt
文件中的证书颁发机构(CA)捆绑包。
此功能的签名算法是 x509.SHA256WithRSA
。要手动轮转,请删除生成的 secret。这会创建新的证书。
2.3.11. secret 限制
若要使用一个 secret,Pod 需要引用该 secret。可以通过三种方式将 secret 用于 Pod:
- 为容器产生环境变量。
- 作为挂载到一个或多个容器上的卷中的文件。
- 在拉取 Pod 的镜像时通过 kubelet 使用。
卷类型 secret 使用卷机制将数据作为文件写入到容器中。imagePullSecrets
使用服务帐户将 secret 自动注入到命名空间中的所有 Pod。
当模板包含 secret 定义时,模板使用提供的 secret 的唯一方法是确保验证 secret 卷源通过验证,并且指定的对象引用实际指向 Secret
类型的对象。因此,secret 需要在依赖它的任何 Pod 之前创建。确保这一点的最有效方法是通过使用服务帐户自动注入。
Secret API 对象驻留在命名空间中。它们只能由同一命名空间中的 pod 引用。
每个 secret 的大小限制为 1MB。这是为了防止创建可能会耗尽 apiserver 和 kubelet 内存的大型 secret。不过,创建大量较小的 secret 也可能耗尽内存。