×

构建输入

构建输入为构建提供源内容。您可以使用以下构建输入在 OpenShift Container Platform 中提供源,按优先级顺序排列:

  • 内联 Dockerfile 定义

  • 从现有镜像中提取的内容

  • Git 仓库

  • 二进制(本地)输入

  • 输入密钥

  • 外部工件

您可以在单个构建中组合多个输入。但是,由于内联 Dockerfile 优先级最高,因此它可以覆盖另一个输入提供的任何其他名为 Dockerfile 的文件。二进制(本地)输入和 Git 仓库是互斥的输入。

当您不希望构建期间使用的某些资源或凭据在构建生成的最终应用程序镜像中可用,或者想要使用在密钥资源中定义的值时,可以使用输入密钥。外部工件可用于提取作为其他构建输入类型之一不可用的其他文件。

运行构建时

  1. 将构建工作目录,所有输入内容都将放置在工作目录中。例如,输入 Git 仓库将克隆到工作目录中,并使用目标路径将从输入镜像指定的复制到工作目录中。

  2. 如果定义了 contextDir,则构建过程将更改目录到 contextDir

  3. 如果存在内联 Dockerfile,则将其写入当前目录。

  4. 当前目录中的内容将提供给构建过程,供 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)
1 要克隆到构建工作目录中的仓库。
2 来自 myinputimage/usr/lib/somefile.jar 存储在 <workingdir>/app/dir/injected/dir 中。
3 构建的工作目录变为 <original_workingdir>/app/dir
4 <original_workingdir>/app/dir 中创建一个具有此内容的 Dockerfile,覆盖任何具有该名称的现有文件。

Dockerfile 源码

提供 dockerfile 值时,此字段的内容将写入磁盘,文件名命名为 dockerfile。这将在处理其他输入源后完成,因此如果输入源存储库在根目录中包含 Dockerfile,则此内容将覆盖它。

源定义是 BuildConfigspec 部分的一部分。

source:
  dockerfile: "FROM centos:7\nRUN yum install -y httpd" (1)
1 dockerfile 字段包含一个要构建的内联 Dockerfile。
其他资源
  • 此字段的典型用途是向 docker 策略构建提供 Dockerfile。

镜像源

您可以使用镜像向构建过程添加其他文件。输入镜像的引用方式与定义 FromTo 镜像目标的方式相同。这意味着可以引用容器镜像和镜像流标签。结合镜像,您必须提供一个或多个路径对,以指示要复制镜像的文件或目录的路径以及将它们放置在构建上下文中的目标位置。

源路径可以是图像中指定的任何绝对路径。目标必须是相对目录路径。在构建时,将加载图像并将指示的文件和目录复制到构建过程的上下文目录中。这与克隆源存储库内容的目录相同。如果源路径以/.结尾,则会复制目录的内容,但不会在目标位置创建该目录本身。

图像输入在BuildConfigsource定义中指定。

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
1 一个或多个输入图像和文件的数组。
2 对包含要复制文件的图像的引用。
3 源/目标路径数组。
4 构建过程可以访问文件的构建根目录的相对目录。
5 要从引用的图像中复制的文件的位置。
6 如果需要凭据才能访问输入图像,则提供一个可选的密钥。

如果您的集群使用ImageDigestMirrorSetImageTagMirrorSetImageContentSourcePolicy对象配置存储库镜像,则只能对镜像注册表使用全局拉取密钥。您不能向项目添加拉取密钥。

需要拉取密钥的镜像

使用需要拉取密钥的输入图像时,可以将拉取密钥链接到构建使用的服务帐户。默认情况下,构建使用builder服务帐户。如果密钥包含与托管输入图像的存储库匹配的凭据,则会自动将拉取密钥添加到构建中。要将拉取密钥链接到构建使用的服务帐户,请运行

$ oc secrets link builder dockerhub

此功能不支持使用自定义策略的构建。

镜像注册表上需要拉取密钥的镜像

使用镜像注册表中的输入图像时,如果收到build error: failed to pull image消息,您可以使用以下任一方法解决此错误

  • 创建一个输入密钥,其中包含构建器镜像的存储库和所有已知镜像的身份验证凭据。在这种情况下,请为图像注册表及其镜像的凭据创建拉取密钥。

  • BuildConfig对象上使用输入密钥作为拉取密钥。

Git 源代码

指定后,将从提供的地址获取源代码。

如果提供内联Dockerfile,它将覆盖Git存储库的contextDir中的Dockerfile。

源定义是 BuildConfigspec 部分的一部分。

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)
1 git字段包含指向源代码远程Git存储库的统一资源标识符 (URI)。您必须指定ref字段的值才能检出特定的Git引用。有效的ref可以是SHA1标签或分支名称。ref字段的默认值为master
2 contextDir字段允许您覆盖构建在源代码存储库内查找应用程序源代码的默认位置。如果您的应用程序存在于子目录中,则可以使用此字段覆盖默认位置(根文件夹)。
3 如果提供了可选的dockerfile字段,则它应是一个包含Dockerfile的字符串,该字符串将覆盖源存储库中可能存在的任何Dockerfile。

如果ref字段表示拉取请求,则系统将使用git fetch操作,然后检出FETCH_HEAD

未提供ref值时,OpenShift Container Platform 将执行浅克隆 (--depth=1)。在这种情况下,仅下载与默认分支(通常为master)上最新提交关联的文件。这将导致存储库下载速度更快,但不会获得完整的提交历史记录。要执行指定存储库默认分支的完整git clone,请将ref设置为默认分支的名称(例如main)。

通过执行中间人 (MITM) TLS 劫持或对代理连接进行重新加密的代理进行的 Git 克隆操作不起作用。

使用代理

如果您的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配置代理的说明。

源克隆密钥

构建器Pod需要访问定义为构建源的任何Git存储库。源克隆密钥用于向构建器Pod提供它通常无法访问的访问权限,例如私有存储库或具有自签名或不受信任的SSL证书的存储库。

支持以下源克隆密钥配置

  • .gitconfig文件

  • 基本身份验证

  • SSH密钥身份验证

  • 受信任的证书颁发机构

您还可以组合使用这些配置来满足您的特定需求。

自动将源克隆密钥添加到构建配置

创建BuildConfig时,OpenShift Container Platform可以自动填充其源克隆密钥引用。此行为允许生成的构建自动使用存储在引用的密钥中的凭据来对远程Git存储库进行身份验证,而无需进一步配置。

要使用此功能,必须在稍后创建BuildConfig的命名空间中存在包含Git存储库凭据的密钥。此密钥必须包含一个或多个以build.openshift.io/source-secret-match-uri-为前缀的注释。这些注释的每个值都是一个统一资源标识符 (URI) 模式,其定义如下。创建没有源克隆密钥引用的BuildConfig并且其Git源URI与密钥注释中的URI模式匹配时,OpenShift Container Platform会自动将对该密钥的引用插入BuildConfig中。

先决条件

URI模式必须由以下部分组成:

  • 有效的方案:*://git://http://https://ssh://

  • 主机:*或有效的域名或IP地址,前面可以选择加上*.

  • 路径:/*/后跟任何字符,可以选择包括*字符

在以上所有情况下,*字符都解释为通配符。

URI模式必须与符合RFC3986的Git源URI匹配。请勿在URI模式中包含用户名(或密码)组件。

例如,如果您对git存储库URL使用ssh://[email protected]:7999/ATLASSIAN jira.git,则必须将源密钥指定为ssh://bitbucket.atlassian.com:7999/*(而不是ssh://[email protected]:7999/*)。

$ oc annotate secret mysecret \
    'build.openshift.io/source-secret-match-uri-1=ssh://bitbucket.atlassian.com:7999/*'
步骤

如果多个密钥与特定BuildConfig的Git URI匹配,则OpenShift Container Platform将选择匹配最长的密钥。这允许进行基本覆盖,如下例所示。

以下片段展示了两个部分的源代码克隆密钥,第一个匹配通过 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-` 注解

    $ oc annotate secret mysecret \
        'build.openshift.io/source-secret-match-uri-1=https://*.mycorp.com/*'

手动添加源代码克隆密钥

可以通过在 `BuildConfig` 内的 `source` 部分添加 `sourceSecret` 字段并将其设置为创建的密钥名称来手动将源代码克隆密钥添加到构建配置中。在本例中,它是 `basicsecret`。

apiVersion: "build.openshift.io/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` 命令在现有构建配置上设置源代码克隆密钥。

  • 要在现有构建配置上设置源代码克隆密钥,请输入以下命令

    $ oc set build-secret --source bc/sample-build basicsecret

从 .gitconfig 文件创建密钥

如果应用程序的克隆依赖于 `.gitconfig` 文件,则可以创建一个包含它的密钥。将其添加到构建器服务帐户,然后添加到您的 `BuildConfig`。

步骤
  • 要从 `.gitconfig` 文件创建密钥

$ oc create secret generic <secret_name> --from-file=<path/to/.gitconfig>

如果在 `.gitconfig` 文件的 `http` 部分设置了 `sslVerify=false`,则可以关闭 SSL 验证。

[http]
        sslVerify=false

为安全的 Git 创建 .gitconfig 文件密钥

如果您的 Git 服务器使用双向 SSL 和用户名密码进行保护,则必须将证书文件添加到您的源构建中,并在 `.gitconfig` 文件中添加对证书文件的引用。

先决条件
  • 您必须拥有 Git 凭据。

步骤

将证书文件添加到源构建中,并在 `.gitconfig` 文件中添加对证书文件的引用。

  1. 将 `client.crt`、`cacert.crt` 和 `client.key` 文件添加到应用程序源代码中的 `/var/run/secrets/openshift.io/source/` 文件夹。

  2. 在服务器的 `.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
  3. 创建密钥

    $ 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
    1 用户的 Git 用户名。
    2 此用户的密码。

为避免再次输入密码,请确保在构建中指定源到镜像 (S2I) 镜像。但是,如果无法克隆存储库,则仍必须指定您的用户名和密码以启动构建。

其他资源
  • 应用程序源代码中的 `/var/run/secrets/openshift.io/source/` 文件夹。

从源代码基本身份验证创建密钥

基本身份验证需要 `--username` 和 `--password` 的组合,或者需要一个令牌来对软件配置管理 (SCM) 服务器进行身份验证。

先决条件
  • 访问私有存储库的用户名和密码。

步骤
  1. 使用 `--username` 和 `--password` 访问私有存储库之前,先创建密钥

    $ oc create secret generic <secret_name> \
        --from-literal=username=<user_name> \
        --from-literal=password=<password> \
        --type=kubernetes.io/basic-auth
  2. 使用令牌创建基本身份验证密钥

    $ oc create secret generic <secret_name> \
        --from-literal=password=<token> \
        --type=kubernetes.io/basic-auth

从源代码 SSH 密钥身份验证创建密钥

基于 SSH 密钥的身份验证需要一个私有 SSH 密钥。

存储库密钥通常位于 `$HOME/.ssh/` 目录中,默认情况下命名为 `id_dsa.pub`、`id_ecdsa.pub`、`id_ed25519.pub` 或 `id_rsa.pub`。

步骤
  1. 生成 SSH 密钥凭据

    $ ssh-keygen -t ed25519 -C "[email protected]"

    为 SSH 密钥创建密码短语会阻止 OpenShift Container Platform 进行构建。当提示输入密码短语时,请将其留空。

    将创建两个文件:公钥和相应的私钥(`id_dsa`、`id_ecdsa`、`id_ed25519` 或 `id_rsa` 之一)。有了这两个文件,请查阅您的源代码管理 (SCM) 系统手册,了解如何上传公钥。私钥用于访问您的私有存储库。

  2. 使用 SSH 密钥访问私有存储库之前,请创建密钥

    $ 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 可选:添加此字段可以启用严格的服务器主机密钥检查。

    在创建密钥时跳过 `known_hosts` 文件会使构建容易受到中间人 (MITM) 攻击。

    确保 `known_hosts` 文件包含源代码主机的主机条目。

从源代码受信任的证书颁发机构创建密钥

在 Git 克隆操作期间受信任的传输层安全 (TLS) 证书颁发机构 (CA) 集被构建到 OpenShift Container Platform 基础架构镜像中。如果您的 Git 服务器使用自签名证书或由镜像不受信任的机构签名的证书,则可以创建一个包含证书的密钥或禁用 TLS 验证。

如果为 CA 证书创建密钥,OpenShift Container Platform 将在 Git 克隆操作期间使用它来访问您的 Git 服务器。此方法比禁用 Git SSL 验证(接受任何显示的 TLS 证书)安全得多。

步骤

使用 CA 证书文件创建一个密钥。

  1. 如果您的 CA 使用中间证书颁发机构,请将所有 CA 的证书组合到 `ca.crt` 文件中。请输入以下命令

    $ cat intermediateCA.crt intermediateCA.crt rootCA.crt > ca.crt
  2. 通过输入以下命令创建密钥

    $ oc create secret generic mycert --from-file=ca.crt=</path/to/file> (1)
    1 您必须使用密钥名称 `ca.crt`。

源密钥组合

您可以结合不同的方法为您的特定需求创建源代码克隆密钥。

使用 `.gitconfig` 文件创建基于 SSH 的身份验证密钥

您可以结合不同的方法为您的特定需求创建源代码克隆密钥,例如使用 `.gitconfig` 文件的基于 SSH 的身份验证密钥。

先决条件
  • SSH 身份验证

  • .gitconfig文件

步骤
  • 要使用 `.gitconfig` 文件创建基于 SSH 的身份验证密钥,请输入以下命令

    $ 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
创建结合了 `.gitconfig` 文件和 CA 证书的密钥

您可以结合不同的方法为您的特定需求创建源代码克隆密钥,例如结合了 `.gitconfig` 文件和证书颁发机构 (CA) 证书的密钥。

先决条件
  • .gitconfig文件

  • CA 证书

步骤
  • 要创建结合了 `.gitconfig` 文件和 CA 证书的密钥,请输入以下命令

    $ oc create secret generic <secret_name> \
        --from-file=ca.crt=<path/to/certificate> \
        --from-file=<path/to/.gitconfig>
创建结合了基本身份验证和 CA 证书的密钥

您可以结合不同的方法为您的特定需求创建源代码克隆密钥,例如结合了基本身份验证和证书颁发机构 (CA) 证书的密钥。

先决条件
  • 基本身份验证凭据

  • CA 证书

步骤
  • 要创建结合了基本身份验证和 CA 证书的密钥,请输入以下命令

    $ 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
创建结合了基本身份验证和 Git 配置文件的密钥

您可以结合不同的方法为您的特定需求创建源代码克隆密钥,例如结合了基本身份验证和 `.gitconfig` 文件的密钥。

先决条件
  • 基本身份验证凭据

  • .gitconfig文件

步骤
  • 要使用.gitconfig文件创建基本的身份验证密钥,请输入以下命令

    $ 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
使用.gitconfig文件和CA证书创建基本的身份验证密钥

您可以结合不同的方法来创建适合您特定需求的源克隆密钥,例如结合基本的身份验证、.gitconfig文件和证书颁发机构 (CA) 证书的密钥。

先决条件
  • 基本身份验证凭据

  • .gitconfig文件

  • CA 证书

步骤
  • 要使用.gitconfig文件和CA证书创建基本的身份验证密钥,请输入以下命令

    $ 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

二进制(本地)源

从本地文件系统流式传输内容到构建器称为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源类型,则它将被动态禁用,因为BinaryGit是互斥的,提供给构建器的二进制流中的数据优先。

您可以将带有HTTP或HTTPS模式的URL传递给--from-file--from-archive,而不是文件名。当使用URL使用--from-file时,构建器映像中文件的名称由Web服务器发送的Content-Disposition标头确定,或者如果标头不存在,则由URL路径的最后一个组件确定。不支持任何形式的身份验证,并且无法使用自定义TLS证书或禁用证书验证。

使用oc new-build --binary=true时,该命令确保执行与二进制构建相关的限制。生成的BuildConfig具有Binary的源类型,这意味着运行此BuildConfig构建的唯一有效方法是使用oc start-build和其中一个--from选项来提供所需的二进制数据。

Dockerfile和contextDir源选项对二进制构建具有特殊含义。

Dockerfile可以与任何二进制构建源一起使用。如果使用Dockerfile并且二进制流是存档,则其内容将替换存档中任何Dockerfile。如果将Dockerfile与--from-file参数一起使用,并且文件参数名为Dockerfile,则来自Dockerfile的值将替换来自二进制流的值。

对于封装已提取存档内容的二进制流,contextDir字段的值将被解释为存档中的子目录,如果有效,则构建器在执行构建之前将更改为该子目录。

输入密钥和配置映射

要防止输入密钥和配置映射的内容出现在构建输出容器映像中,请在您的Docker构建源到镜像构建策略中使用构建卷。

在某些情况下,构建操作需要凭据或其他配置数据才能访问依赖资源,但不希望将这些信息放入源代码控制中。为此,您可以定义输入密钥和输入配置映射。

例如,当使用Maven构建Java应用程序时,您可以设置Maven Central或JCenter的私有镜像,该镜像由私钥访问。要从该私有镜像下载库,您必须提供以下内容:

  1. 使用镜像的URL和连接设置配置的settings.xml文件。

  2. 设置文件中引用的私钥,例如~/.ssh/id_rsa

出于安全原因,您不希望在应用程序映像中公开您的凭据。

此示例描述了一个Java应用程序,但您可以使用相同的方法将SSL证书添加到/etc/ssl/certs目录、API密钥或令牌、许可证文件等等。

什么是密钥?

Secret对象类型提供了一种机制来保存敏感信息,例如密码、OpenShift Container Platform客户端配置文件、dockercfg文件、私有源存储库凭据等等。密钥将敏感内容与Pod分离。您可以使用卷插件将密钥挂载到容器中,或者系统可以使用密钥代表Pod执行操作。

YAML 密钥对象定义
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映射中与密钥关联的值由纯文本字符串组成。

密钥的属性

主要属性包括:

  • 密钥数据可以独立于其定义进行引用。

  • 密钥数据卷由临时文件存储设施 (tmpfs) 支持,并且永远不会在节点上保存。

  • 密钥数据可以在命名空间内共享。

密钥类型

type字段中的值指示密钥的名称和值的结构。该类型可用于强制在密钥对象中存在用户名和密钥。如果您不希望进行验证,请使用opaque类型,这是默认类型。

指定以下类型之一以触发最小的服务器端验证,以确保密钥数据中存在特定的密钥名称:

  • 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,这意味着密钥不声称符合任何密钥名称或值的约定。opaque 密钥允许使用非结构化的key:value 对,这些对可以包含任意值。

您可以指定其他任意类型,例如example.com/my-secret-type。这些类型在服务器端未强制执行,但表明密钥的创建者打算符合该类型的键/值要求。

密钥更新

当您修改密钥的值时,已运行的 Pod 使用的值不会动态更改。要更改密钥,您必须删除原始 Pod 并创建一个新的 Pod,在某些情况下,需要使用相同的PodSpec

更新密钥的流程与部署新容器镜像相同。您可以使用kubectl rolling-update命令。

引用密钥时,不会指定密钥中的resourceVersion值。因此,如果在 Pod 启动的同时更新了密钥,则用于 Pod 的密钥版本未定义。

目前,无法检查创建 Pod 时使用的密钥对象的资源版本。计划让 Pod 报告此信息,以便控制器可以重新启动使用旧resourceVersion的 Pod。在此期间,请不要更新现有密钥的数据,而是创建具有不同名称的新密钥。

创建密钥

您必须在创建依赖于该密钥的 Pod 之前创建密钥。

创建密钥时

  • 创建一个包含密钥数据的密钥对象。

  • 更新 Pod 服务帐户以允许引用密钥。

  • 创建一个 Pod,该 Pod 使用环境变量或使用secret卷作为文件来使用密钥。

步骤
  • 要从 JSON 或 YAML 文件创建密钥对象,请输入以下命令

    $ oc create -f <filename>

    例如,您可以从本地.docker/config.json文件创建密钥

    $ oc create secret generic dockerhub \
        --from-file=.dockerconfigjson=<path/to/.docker/config.json> \
        --type=kubernetes.io/dockerconfigjson

    此命令生成名为dockerhub的密钥的 JSON 规范并创建该对象。

    YAML 不透明密钥对象定义
    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    type: Opaque (1)
    data:
      username: <username>
      password: <password>
    1 指定一个不透明密钥。
    Docker 配置 JSON 文件密钥对象定义
    apiVersion: v1
    kind: Secret
    metadata:
      name: aregistrykey
      namespace: myapps
    type: kubernetes.io/dockerconfigjson (1)
    data:
      .dockerconfigjson:bm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== (2)
    1 指定密钥正在使用 Docker 配置 JSON 文件。
    2 base64 编码的 Docker 配置 JSON 文件的输出。

使用密钥

创建密钥后,您可以创建一个 Pod 来引用您的密钥,获取日志并删除 Pod。

步骤
  1. 通过输入以下命令创建引用您密钥的 Pod

    $ oc create -f <your_yaml_file>.yaml
  2. 通过输入以下命令获取日志

    $ oc logs secret-example-pod
  3. 通过输入以下命令删除 Pod

    $ oc delete pod secret-example-pod
其他资源
  • 包含密钥数据的示例 YAML 文件

    将创建四个文件的密钥的 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
    1 文件包含解码后的值。
    2 文件包含解码后的值。
    3 文件包含提供的字符串。
    4 文件包含提供的数据。
    使用密钥数据填充卷中文件的 Pod 的 YAML 文件
    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 文件
    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 文件
    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

添加输入密钥和配置映射

要向构建提供凭据和其他配置数据,而无需将它们放在源代码控制中,您可以定义输入密钥和输入配置映射。

在某些情况下,构建操作需要凭据或其他配置数据才能访问依赖资源。要使这些信息可用,而无需将其放在源代码控制中,您可以定义输入密钥和输入配置映射。

步骤

要向现有的BuildConfig对象添加输入密钥、配置映射或两者,请执行以下操作

  1. 如果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>
  2. 如果Secret对象不存在,请通过输入以下命令创建它

    $ oc create secret generic secret-mvn \
        --from-file=ssh-privatekey=<path/to/.ssh/id_rsa> \
        --type=kubernetes.io/ssh-auth

    这将创建一个名为secret-mvn的新密钥,其中包含id_rsa私钥的 base64 编码内容。

    或者,您可以应用以下 YAML 来创建输入密钥

    apiVersion: core/v1
    kind: Secret
    metadata:
      name: secret-mvn
    type: kubernetes.io/ssh-auth
    data:
      ssh-privatekey: |
        # Insert ssh private key, base64 encoded
  3. 将配置映射和密钥添加到现有BuildConfig对象中的source部分

    source:
      git:
        uri: https://github.com/wildfly/quickstart.git
      contextDir: helloworld
      configMaps:
        - configMap:
            name: settings-mvn
      secrets:
        - secret:
            name: secret-mvn
  4. 要在新的BuildConfig对象中包含密钥和配置映射,请输入以下命令

    $ 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.xmlid_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目录中。

Source-to-image 策略

使用Source策略时,所有定义的输入密钥都会复制到各自的destinationDir。如果您将destinationDir留空,则密钥将放置在构建器镜像的工作目录中。

destinationDir是相对路径时,使用相同的规则。密钥放置在相对于镜像工作目录的路径中。如果构建器镜像中不存在destinationDir路径中的最终目录,则会创建它。destinationDir中的所有前导目录必须存在,否则会发生错误。

输入密钥被添加为世界可写,具有0666权限,并在执行assemble脚本后被截断为零大小。这意味着密钥文件存在于生成的镜像中,但出于安全原因,它们为空。

assemble脚本完成后,输入配置映射不会被截断。

Docker 策略

使用 Docker 策略时,您可以使用Dockerfile中的ADDCOPY指令将所有定义的输入密钥添加到您的容器镜像中。

如果您没有为密钥指定destinationDir,则文件将复制到Dockerfile所在的同一目录中。如果您指定相对路径作为destinationDir,则密钥将复制到相对于Dockerfile位置的该目录中。这使得密钥文件在构建期间作为构建过程中使用的上下文目录的一部分可用于 Docker 构建操作。

引用密钥和配置映射数据的 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"]

用户通常会从最终应用程序镜像中删除其输入密钥,以便在从该镜像运行的容器中不存在密钥。但是,密钥本身仍然存在于添加它们的层的镜像中。此删除过程是 Dockerfile 本身的一部分。

为了防止输入密钥和配置映射的内容出现在构建输出容器镜像中并完全避免此删除过程,请改用Docker 构建策略中的构建卷

自定义策略

使用自定义策略时,所有已定义的输入密钥和配置映射都可在构建容器的/var/run/secrets/openshift.io/build目录中访问。自定义构建镜像必须适当地使用这些密钥和配置映射。使用自定义策略,您可以按照自定义策略选项中所述定义密钥。

现有策略密钥和输入密钥之间没有技术差异。但是,您的构建器镜像可以根据您的构建用例区分它们并以不同的方式使用它们。

输入密钥始终挂载到/var/run/secrets/openshift.io/build目录中,或者您的构建器可以解析包含完整构建对象的$BUILD环境变量。

如果注册表的拉取密钥同时存在于命名空间和节点中,则构建默认使用命名空间中的拉取密钥。

外部制品

不建议在源代码仓库中存储二进制文件。因此,您必须定义一个构建,在构建过程中拉取其他文件,例如 Java .jar 依赖项。如何操作取决于您正在使用的构建策略。

对于源代码构建策略,您必须将适当的 shell 命令放入assemble脚本中

.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命令显式提供变量(仅适用于手动触发的构建)

使用 Docker 凭据访问私有注册表

您可以为构建提供一个包含私有容器注册表有效凭据的.docker/config.json文件。这允许您将输出镜像推送到私有容器镜像注册表,或从需要身份验证的私有容器镜像注册表拉取构建器镜像。

您可以在同一注册表中为多个存储库提供凭据,每个存储库都具有特定于该注册表路径的凭据。

对于 OpenShift Container Platform 容器镜像注册表,不需要此操作,因为 OpenShift Container Platform 会自动为您生成密钥。

.docker/config.json文件默认位于您的主目录中,并具有以下格式

auths:
  index.docker.io/v1/: (1)
    auth: "YWRfbGzhcGU6R2labnRib21ifTE=" (2)
    email: "[email protected]" (3)
  docker.io/my-namespace/my-user/my-image: (4)
    auth: "GzhYWRGU6R2fbclabnRgbkSp=""
    email: "[email protected]"
  docker.io/my-namespace: (5)
    auth: "GzhYWRGU6R2deesfrRgbkSp=""
    email: "[email protected]"
1 注册表的 URL。
2 加密密码。
3 登录的电子邮件地址。
4 命名空间中特定镜像的 URL 和凭据。
5 注册表命名空间的 URL 和凭据。

您可以定义多个容器镜像注册表,或在同一注册表中定义多个存储库。或者,您也可以通过运行docker login命令向此文件添加身份验证条目。如果文件不存在,则会创建该文件。

Kubernetes 提供Secret对象,可用于存储配置和密码。

先决条件
  • 您必须拥有一个.docker/config.json文件。

步骤
  1. 通过输入以下命令,从本地.docker/config.json文件创建密钥

    $ oc create secret generic dockerhub \
        --from-file=.dockerconfigjson=<path/to/.docker/config.json> \
        --type=kubernetes.io/dockerconfigjson

    这将生成名为dockerhub的密钥的 JSON 规范并创建该对象。

  2. BuildConfigoutput部分中添加pushSecret字段,并将其设置为您创建的secret的名称,在上例中为dockerhub

    spec:
      output:
        to:
          kind: "DockerImage"
          name: "private.registry.com/org/private-image:latest"
        pushSecret:
          name: "dockerhub"

    您可以使用oc set build-secret命令在构建配置上设置推送密钥。

    $ oc set build-secret --push bc/sample-build dockerhub

    您还可以将推送密钥链接到构建使用的服务帐户,而不是指定pushSecret字段。默认情况下,构建使用builder服务帐户。如果密钥包含与托管构建输出镜像的存储库匹配的凭据,则会自动将推送密钥添加到构建中。

    $ oc secrets link builder dockerhub
  3. 通过指定pullSecret字段(它是构建策略定义的一部分)从私有容器镜像注册表拉取构建器容器镜像

    strategy:
      sourceStrategy:
        from:
          kind: "DockerImage"
          name: "docker.io/user/private_repository"
        pullSecret:
          name: "dockerhub"

    您可以使用oc set build-secret命令在构建配置上设置拉取密钥。

    $ oc set build-secret --pull bc/sample-build dockerhub

    此示例在源代码构建中使用pullSecret,但也适用于 Docker 和自定义构建。

    您还可以将拉取密钥链接到构建使用的服务帐户,而不是指定pullSecret字段。默认情况下,构建使用builder服务帐户。如果密钥包含与托管构建输入镜像的存储库匹配的凭据,则会自动将拉取密钥添加到构建中。要将拉取密钥链接到构建使用的服务帐户,而不是指定pullSecret字段,请输入以下命令

    $ oc secrets link builder dockerhub

    您必须在BuildConfig规范中指定from镜像才能利用此功能。在某些情况下,由oc new-buildoc new-app生成的 Docker 策略构建可能不会这样做。

构建环境

与 Pod 环境变量一样,构建环境变量可以使用向下 API 根据对其他资源或变量的引用来定义。有一些例外情况,已注明。

您还可以使用oc set env命令管理在BuildConfig中定义的环境变量。

在构建环境变量中使用valueFrom引用容器资源不受支持,因为在创建容器之前会解析这些引用。

使用构建字段作为环境变量

您可以通过将fieldPath环境变量源设置为您感兴趣的字段的JsonPath来注入有关构建对象的信息。

Jenkins Pipeline 策略不支持环境变量的valueFrom语法。

步骤
  • fieldPath环境变量源设置为您感兴趣的字段的JsonPath

    env:
      - name: FIELDREF_ENV
        valueFrom:
          fieldRef:
            fieldPath: metadata.name

使用密钥作为环境变量

您可以使用valueFrom语法将密钥中的键值作为环境变量提供。

此方法会在构建 Pod 控制台的输出中显示密钥为纯文本。为避免这种情况,请改用输入密钥和配置映射。

步骤
  • 要将密钥用作环境变量,请设置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

服务证书密钥

服务证书密钥旨在支持需要开箱即用证书的复杂中间件应用程序。它与管理员工具为节点和主节点生成的服务器证书具有相同的设置。

步骤

为了保护与您服务的通信安全,请让集群在您的命名空间中将已签名的服务证书/密钥对生成到密钥中。

  • 在您的服务上设置service.beta.openshift.io/serving-cert-secret-name注释,并将值设置为要用于密钥的名称。

    然后,您的PodSpec可以挂载该密钥。密钥可用后,您的 Pod 将运行。证书对内部服务 DNS 名称<service.name>.<service.namespace>.svc有效。

    证书和密钥采用 PEM 格式,分别存储在tls.crttls.key中。证书/密钥对在接近过期时会自动替换。在密钥上的service.beta.openshift.io/expiry注释中查看过期日期,该日期采用 RFC3339 格式。

在大多数情况下,服务 DNS 名称<service.name>.<service.namespace>.svc不可外部路由。<service.name>.<service.namespace>.svc的主要用途是用于集群内或服务内通信,以及使用重新加密路由。

其他 Pod 可以通过使用自动挂载在其 Pod 中的/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt文件中的证书颁发机构 (CA) 捆绑包来信任集群创建的证书,这些证书仅针对内部 DNS 名称进行签名。

此功能的签名算法为x509.SHA256WithRSA。要手动轮换,请删除生成的密钥。将创建一个新的证书。

密钥限制

要使用密钥,Pod 需要引用该密钥。密钥可以通过三种方式与 Pod 一起使用

  • 填充容器的环境变量。

  • 作为挂载在一个或多个容器上的卷中的文件。

  • 在拉取 Pod 的镜像时由 kubelet 使用。

卷类型密钥使用卷机制将数据作为文件写入容器。imagePullSecrets使用服务帐户将密钥自动注入命名空间中的所有 Pod。

当模板包含密钥定义时,模板使用提供的密钥的唯一方法是确保密钥卷源已验证,并且指定的引用对象实际上指向Secret类型的对象。因此,在任何依赖它的 Pod 之前,都需要创建密钥。确保这一点最有效的方法是通过使用服务帐户使其自动注入。

密钥 API 对象驻留在命名空间中。它们只能被同一命名空间中的 Pod 引用。

单个密钥的大小限制为 1MB。这是为了避免创建会耗尽 apiserver 和 kubelet 内存的大型密钥。但是,创建许多较小的密钥也可能会耗尽内存。