×

构建输入

构建输入为构建提供源内容。您可以使用以下构建输入在 AWS 上的 Red Hat OpenShift Service 中提供源,按优先级顺序排列:

  • 内联 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` 存储在 `/app/dir/injected/dir` 中。
3 构建的工作目录变为 `/app/dir`。
4 在 `/app/dir` 中创建一个包含此内容的 Dockerfile,覆盖任何具有该名称的现有文件。

Dockerfile 源码

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

源定义是 `BuildConfig` 中 `spec` 部分的一部分。

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

镜像源

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

如果您的集群使用 `ImageDigestMirrorSet`、`ImageTagMirrorSet` 或 `ImageContentSourcePolicy` 对象配置仓库镜像,则只能对镜像注册表使用全局拉取密钥。您不能向项目添加拉取密钥。

需要拉取密钥的镜像

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

$ oc secrets link builder dockerhub

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

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

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

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

  • 将输入密钥用作 `BuildConfig` 对象上的拉取密钥。

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

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

如果未提供ref值,AWS上的Red Hat OpenShift Service将执行浅克隆(--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 插件仅使用在插件管理器面板的 Jenkins UI 中配置的代理。然后,此代理将用于 Jenkins 中所有作业内的所有 git 交互。

附加资源
  • 您可以在JenkinsBehindProxy找到有关如何通过 Jenkins UI 配置代理的说明。

源克隆密钥

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

支持以下源克隆密钥配置:

  • .gitconfig文件

  • 基本身份验证

  • SSH 密钥身份验证

  • 受信任的证书颁发机构

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

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

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

要使用此功能,必须在稍后创建BuildConfig的命名空间中存在包含 Git 仓库凭据的密钥。此密钥必须包含一个或多个以build.openshift.io/source-secret-match-uri-为前缀的注释。这些注释的每个值都是一个统一资源标识符 (URI) 模式,定义如下:当创建没有源克隆密钥引用的BuildConfig且其 Git 源 URI 与密钥注释中的 URI 模式匹配时,AWS上的Red Hat OpenShift Service会自动在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 匹配,AWS上的Red Hat OpenShift Service将选择匹配最长的密钥。这允许进行基本的覆盖,如下例所示。

以下片段显示了两个部分源克隆密钥,第一个匹配通过 HTTPS 访问的mycorp.com域中的任何服务器,第二个覆盖对服务器mydev1.mycorp.commydev2.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.crtcacert.crtclient.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.pubid_ecdsa.pubid_ed25519.pubid_rsa.pub

步骤
  1. 生成 SSH 密钥凭据

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

    为 SSH 密钥创建密码短语会阻止 AWS 上的 Red Hat OpenShift Service 进行构建。当系统提示输入密码短语时,请留空。

    将创建两个文件:公钥和对应的私钥(id_dsaid_ecdsaid_ed25519id_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) 集已内置到 AWS 上的 Red Hat OpenShift Service 基础架构镜像中。如果您的 Git 服务器使用自签名证书或由镜像不受信任的机构签名的证书,您可以创建一个包含证书的密钥,或禁用 TLS 验证。

如果您为 CA 证书创建密钥,AWS 上的 Red Hat OpenShift Service 将在 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,该 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构建source-to-image构建策略中使用构建卷。

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

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

  1. 一个配置了镜像 URL 和连接设置的settings.xml文件。

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

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

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

什么是密钥?

Secret 对象类型提供了一种机制来保存敏感信息,例如密码、Red Hat OpenShift Service on AWS 客户端配置文件、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,它使用环境变量或使用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文件复制到源代码所在的目录。在AWS S2I构建器镜像上的Red Hat OpenShift Service中,这是镜像的工作目录,使用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脚本完成后,输入配置映射不会被截断。

外部工件

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

对于Source构建策略,您必须将相应的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文件。这允许您将输出镜像推送到私有容器镜像注册表,或从需要身份验证的私有容器镜像注册表中拉取构建器镜像。

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

对于AWS上的Red Hat OpenShift Service容器镜像注册表,不需要这样做,因为Red Hat OpenShift Service on AWS会自动为您生成密钥。

.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

    此示例在Source构建中使用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。

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

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

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