开发人员指南
OpenShift Container Platform 3.11 开发人员参考
摘要
第 1 章 概述
本指南面向应用程序开发人员,提供设置和配置工作站在 OpenShift Container Platform 云环境中开发和部署应用程序的说明。这包括帮助开发人员的详细说明和示例:
第 2 章 应用程序生命周期管理
2.1. 规划您的开发流程
2.1.1. 概述
OpenShift Container Platform 专为构建和部署应用程序而设计。根据开发过程中涉及的 OpenShift Container Platform 量,您可以选择:
- 专注于 OpenShift Container Platform 项目中的开发,使用它从头开始构建应用,然后持续开发和管理其生命周期,或者
- 使应用程序(如二进制、容器镜像、源代码)已在单独的环境中开发,并将其部署到 OpenShift Container Platform。
2.1.2. 使用 OpenShift Container Platform 作为您的开发环境
您可以直接使用 OpenShift Container Platform 从头开始开始应用程序的开发。在规划此类型的开发过程中请考虑以下步骤:
初始规划
- 您的应用程序有什么作用?
- 将在什么编程语言中开发?
访问 OpenShift Container Platform
- OpenShift Container Platform 应该由您自己或您所在机构的管理员安装。
开发
- 使用您的编辑器或选择的 IDE,创建一个应用程序的基本框架。它应该足以告知 OpenShift Container Platform 是什么应用程序。
- 将代码推送到您的 Git 存储库。
Generate
-
使用
oc new-app
命令创建基本应用程序。OpenShift Container Platform 生成构建和部署配置。
管理
- 开始开发您的应用程序代码。
- 确保您的应用构建成功。
- 继续在本地开发和管理您的代码。
- 将您的代码推送到 Git 存储库。
- 是否需要额外的配置?更多相关信息,请参阅开发人员指南。
验证
-
您可以通过多种方法验证您的应用程序。您可以将更改推送到应用程序的 Git 存储库,并使用 OpenShift Container Platform 重建并重新部署应用程序。另外,您可以使用
rsync
热部署将代码更改同步到正在运行的 pod。
2.1.3. 使应用程序能够部署到 OpenShift Container Platform
另一种可能的应用程序开发策略是在本地开发,然后使用 OpenShift Container Platform 部署您完全开发的应用程序。如果计划已有应用程序代码,请使用以下步骤,然后在完成后构建并部署到 OpenShift Container Platform 安装中:
初始规划
- 您的应用程序有什么作用?
- 将在什么编程语言中开发?
开发
- 使用您的编辑器或您选择的 IDE 开发您的应用程序代码。
- 本地构建并测试应用程序代码。
- 将您的代码推送到 Git 存储库。
访问 OpenShift Container Platform
- OpenShift Container Platform 应该由您自己或您所在机构的管理员安装。
Generate
-
使用
oc new-app
命令创建基本应用程序。OpenShift Container Platform 生成构建和部署配置。
验证
- 确保已在以上 Generate 步骤中构建和部署的应用程序在 OpenShift Container Platform 上成功运行。
管理
- 继续开发应用程序代码,直到您对此结果很满意。
- 在 OpenShift Container Platform 中重新构建您的应用程序,以接受任何新推送的代码。
- 是否需要额外的配置?更多相关信息,请参阅开发人员指南。
2.2. 创建新应用程序
2.2.1. 概述
您可以使用 OpenShift CLI 或 Web 控制台,从包括源代码或二进制代码、镜像和/或模板在内的组件创建一个新的 OpenShift Container Platform 应用程序。
2.2.2. 使用 CLI 创建应用程序
2.2.2.1. 从源代码创建应用程序
您可以使用 new-app
命令从本地或远程 Git 存储库中的源代码创建应用程序。
使用本地目录中的 Git 存储库创建应用程序:
$ oc new-app /path/to/source/code
如果使用本地 Git 存储库,该存储库应具有一个名为 origin 的远程源,指向 OpenShift Container Platform 集群可访问的 URL。如果没有 recognized remote,new-app
将创建一个 二进制构建。
使用远程 Git 存储库创建应用程序:
$ oc new-app https://github.com/sclorg/cakephp-ex
使用私有远程 Git 存储库创建应用程序:
$ oc new-app https://github.com/youruser/yourprivaterepo --source-secret=yoursecret
如果使用私有远程 Git 存储库,您可以使用 --source-secret
标志指定一个现有的 source clone secret,该 secret 将注入到 BuildConfig
中以访问存储库。
您可以通过指定 --context-dir
标志来使用源代码存储库的子目录。使用远程 Git 存储库和上下文子目录创建应用程序:
$ oc new-app https://github.com/sclorg/s2i-ruby-container.git \ --context-dir=2.0/test/puma-test-app
另外,在指定远程 URL 时,您可以通过在 URL 末尾附加 #<branch_name>
来指定要使用的 Git 分支:
$ oc new-app https://github.com/openshift/ruby-hello-world.git#beta4
new-app
命令将创建一个构建配置,它本身会从您的源代码中创建一个新的应用程序镜像。new-app
命令通常还会创建用于部署新镜像的部署配置,以及为运行您的镜像的部署提供负载均衡访问的服务。
OpenShift Container Platform 会自动 检测 是否应使用 Docker
、Pipeline
或 Source
构建策略,如果进行 Source
构建,则 检测相应的语言构建器镜像。
构建策略检测
在创建新应用程序时,如果源存储库的根目录或指定上下文目录中存在 Jenkinsfile,则 OpenShift Container Platform 会生成 Pipeline
构建策略。否则,如果找到 Dockerfile,OpenShift Container Platform 会生成 Docker
构建策略。否则,它会生成 Source
构建策略。
您可以通过将 --strategy
标志设置为 docker
、pipeline
或 source
来覆盖构建策略。
$ oc new-app /home/user/code/myapp --strategy=docker
oc
命令要求包含构建源的文件在远程 Git 存储库中可用。对于所有 Source 构建,您必须使用 git remote -v
。
语言检测
如果使用 Source
构建策略,new-app
会尝试根据存储库根目录或指定上下文目录中是否存在特定文件来确定要使用的语言构建器:
语言 | 文件 |
---|---|
| project.json, *.csproj |
| pom.xml |
| app.json, package.json |
| cpanfile, index.pl |
| composer.json, index.php |
| requirements.txt, setup.py |
| Gemfile, Rakefile, config.ru |
| build.sbt |
| Godeps, main.go |
检测了语言后,new-app
会在 OpenShift Container Platform 服务器上搜索具有与所检测语言匹配的支持
注解的镜像流标签,或与所检测语言名称匹配 的镜像流。如果找不到匹配项,new-app
会在 Docker Hub registry 中搜索名称上与所检测语言匹配的镜像。
您可以通过指定镜像(镜像流或容器规格)和存储库(以 ~
作为分隔符),来覆盖构建器用于特定源存储库的镜像。请注意,如果这样做,不会执行 构建策略检测和语言检测。
例如,将 myproject/my-ruby 镜像流与远程存储库中的源一起使用:
$ oc new-app myproject/my-ruby~https://github.com/openshift/ruby-hello-world.git
使用 openshift/ruby-20-centos7:latest 容器镜像流以及本地仓库中的源:
$ oc new-app openshift/ruby-20-centos7:latest~/home/user/code/my-ruby-app
语言检测需要在本地安装 Git 客户端,以便克隆并检查您的存储库。如果 Git 不可用,您可以使用 <image>~<repository>
语法指定要与存储库搭配使用的构建器镜像,以避免语言检测步骤。
调用 -i <image> <repository>
要求 new-app
尝试克隆 repository
,从而能判断其工件类型;如果 Git 不可用,此操作会失败。
使用 -i <image> --code <repository>
要求 new-app
克隆 repository
,从而能判断 image
应用作源代码的构建器,还是另外部署(使用数据库镜像时)。
2.2.2.2. 从镜像创建应用程序
您可以从现有镜像部署应用程序。镜像可以来自 OpenShift Container Platform 服务器中的镜像流、特定 registry 或 Docker Hub registry 中的镜像,或本地 Docker 服务器中的镜像。
new-app
命令尝试确定传递给它的参数中指定的镜像类型。但是,您可以明确告知 new-app
镜像是容器镜像(使用 --docker-image
参数)还是镜像流(使用 -i|--image
参数)。
如果指定本地 Docker 存储库中的镜像,必须确保同一镜像可供 OpenShift Container Platform 节点使用。
例如,从 DockerHub MySQL 镜像创建应用程序:
$ oc new-app mysql
要使用私有 registry 中的镜像创建应用程序,请指定完整容器镜像规格:
$ oc new-app myregistry:5000/example/myimage
如果包含镜像的 registry 没有使用 SSL 保护,集群管理员必须确保 OpenShift Container Platform 节点主机上的 Docker 守护进程使用指向该 registry 的 --insecure-registry
标志运行。您还必须告知 new-app
镜像来自带有 --insecure-registry
标志的不安全 registry。
$ oc new-app my-stream:v1
2.2.2.3. 从模板创建应用程序
您可以通过将 模板名称 指定为参数,从之前存储的模板或模板文件创建应用程序。例如,您可以存储一个示例应用程序模板,并使用它来创建应用程序。
从存储的模板创建应用程序:
$ oc create -f examples/sample-app/application-template-stibuild.json $ oc new-app ruby-helloworld-sample
要直接使用本地文件系统中的模板,而不先将它保存到 OpenShift Container Platform 中,请使用 -f|--file
参数:
$ oc new-app -f examples/sample-app/application-template-stibuild.json
模板参数
在基于模板创建应用程序时,请使用 -p|--param
参数来设置模板定义的参数值:
$ oc new-app ruby-helloworld-sample \ -p ADMIN_USERNAME=admin -p ADMIN_PASSWORD=mypassword
您可以将参数保存到文件中,然后在实例化模板时通过 --param-file
来使用该文件。如果要从标准输入中读取参数,请使用 --param-file=-
:
$ cat helloworld.params ADMIN_USERNAME=admin ADMIN_PASSWORD=mypassword $ oc new-app ruby-helloworld-sample --param-file=helloworld.params $ cat helloworld.params | oc new-app ruby-helloworld-sample --param-file=-
2.2.2.4. 进一步修改应用程序创建
new-app
命令生成将构建、部署和运行正在创建应用程序的 OpenShift Container Platform 对象。通常,这些对象使用从输入源存储库或输入镜像派生的名称在当前项目中创建。但是,new-app
允许您修改此行为。
由 new-app
创建的对象集合取决于作为输入传递的工件,如输入源存储库、镜像或模板。
对象 | 描述 |
---|---|
|
为命令行中指定的每个源存储库创建一个 |
|
对于 |
|
创建一个 |
|
|
其他 | 根据模板,可在实例化模板时生成其他对象。 |
2.2.2.4.1. 指定环境变量
从模板、源 或 镜像 生成应用程序时,您可以在运行时使用 -e|--env
参数将环境变量传递给应用程序容器:
$ oc new-app openshift/postgresql-92-centos7 \ -e POSTGRESQL_USER=user \ -e POSTGRESQL_DATABASE=db \ -e POSTGRESQL_PASSWORD=password
这些变量可使用 --env-file
参数从文件中读取:
$ cat postgresql.env POSTGRESQL_USER=user POSTGRESQL_DATABASE=db POSTGRESQL_PASSWORD=password $ oc new-app openshift/postgresql-92-centos7 --env-file=postgresql.env
另外,也可使用 --env-file=-
在标准输入上给定环境变量:
$ cat postgresql.env | oc new-app openshift/postgresql-92-centos7 --env-file=-
如需更多信息,请参阅管理环境变量。
在 new-app
处理过程中创建的任何 BuildConfig
对象,都不能使用通过 -e|--env
或 --env-file
参数传递的环境变量进行更新。
2.2.2.4.2. 指定构建环境变量
从模板、源 或 镜像 生成应用程序时,您可以在运行时使用 --build-env
参数将环境变量传递给构建容器:
$ oc new-app openshift/ruby-23-centos7 \ --build-env HTTP_PROXY=http://myproxy.net:1337/ \ --build-env GEM_HOME=~/.gem
这些变量可使用 --build-env-file
参数从文件中读取:
$ cat ruby.env HTTP_PROXY=http://myproxy.net:1337/ GEM_HOME=~/.gem $ oc new-app openshift/ruby-23-centos7 --build-env-file=ruby.env
另外,也可使用 --build-env-file=-
在标准输入上给定环境变量:
$ cat ruby.env | oc new-app openshift/ruby-23-centos7 --build-env-file=-
2.2.2.4.3. 指定标签
从源、镜像或模板生成 应用程序时,您可以使用 -l|--label
参数向创建的对象添加标签。借助标签,您可以轻松地集中选择、配置和删除与应用程序关联的对象。
$ oc new-app https://github.com/openshift/ruby-hello-world -l name=hello-world
2.2.2.4.4. 查看输出(不创建)
要查看要创建的 new-app
的空运行,您可以使用 -o|--output
参数及 yaml
或 json
值。然后,您可以使用输出来预览要创建的对象,或者将其重定向到您可以编辑的文件。满意后,您可以使用 oc create
创建 OpenShift Container Platform 对象。
将 new-app
工件输出到文件中,编辑工件,再创建工件:
$ oc new-app https://github.com/openshift/ruby-hello-world \ -o yaml > myapp.yaml $ vi myapp.yaml $ oc create -f myapp.yaml
2.2.2.4.5. 使用不同名称创建对象
new-app
创建的对象通常命名自用于生成它们的源存储库或镜像。您可以通过在命令中添加 --name
标志来设置生成的对象名称:
$ oc new-app https://github.com/openshift/ruby-hello-world --name=myapp
2.2.2.4.6. 在不同的项目中创建对象
通常,new-app
会在当前项目中创建对象。但是,您可以使用 -n|--namespace
参数在有权访问的不同项目中创建对象:
$ oc new-app https://github.com/openshift/ruby-hello-world -n myproject
2.2.2.4.7. 创建多个对象
new-app
命令允许创建多个应用程序,为 new-app
指定多个参数便可实现。命令行中指定的标签将应用到单一命令创建的所有对象。环境变量应用到从源或镜像创建的所有组件。
从源存储库和 Docker Hub 镜像创建应用程序:
$ oc new-app https://github.com/openshift/ruby-hello-world mysql
如果以独立参数形式指定源代码存储库和构建器镜像,new-app
会将构建器镜像用作源代码存储库的构建器。如果这不是您的用意,请使用 ~
分隔符为源指定所需的构建器镜像。
2.2.2.4.8. 在单个 Pod 中对镜像和源进行分组
new-app
命令允许在一个 pod 中一起部署多个镜像。要指定哪些镜像要分组在一起,请使用 +
分隔符。也可使用 --group
命令行参数来指定应分组在一起的镜像。要将源存储库中构建的镜像与其他镜像一起分组,请在组中指定其构建器镜像:
$ oc new-app ruby+mysql
将通过源构建的镜像和外部镜像一起部署:
$ oc new-app \ ruby~https://github.com/openshift/ruby-hello-world \ mysql \ --group=ruby+mysql
2.2.2.4.9. 搜索镜像、模板和其他输入
要搜索镜像、模板和 oc new-app
命令的其他输入,使用 --search
和 --list
。例如,查找包含 PHP 的所有镜像或模板:
$ oc new-app --search php
2.2.3. 使用 Web 控制台创建应用程序
在所需项目中,点击 Add to Project :
从项目中的镜像列表或从服务目录中选择构建程序镜像。
注意只有其注解中列出 builder 标签的 image stream tags 才会出现在此列表中,如下所示:
kind: "ImageStream" apiVersion: "v1" metadata: name: "ruby" creationTimestamp: null spec: dockerImageRepository: "registry.redhat.io/openshift3/ruby-20-rhel7" tags: - name: "2.0" annotations: description: "Build and run Ruby 2.0 applications" iconClass: "icon-ruby" tags: "builder,ruby" 1 supports: "ruby:2.0,ruby" version: "2.0"
- 1
- 此处包含 builder 可确保该
ImageStreamTag
作为构建程序出现在 web 控制台中。
修改新应用程序屏幕中的设置,以配置对象来支持您的应用程序:
2.3. 在跨环境中提升应用程序
2.3.1. 概述
应用程序提升意味着通过各种运行时环境迁移应用程序,通常具有更高程度的成熟度。例如,应用程序可能会在开发环境中启动,然后提升到暂存环境以进一步进行测试,然后才会出现在生产环境中。随着应用中引入的变化,再次更改将在开发中开始,并在 stage 和生产环境中推广。
当今的"应用程序"不仅仅是使用 Java、Perl 和 Python 等编写的源代码。现在,它比静态 Web 内容、集成脚本或应用特定运行时的相关配置更多。它不仅仅是由那些语言特定运行时使用的应用程序特定存档。
在 OpenShift Container Platform 及其 Kubernetes 和 Docker 的组合部分中,额外的应用程序工件包括:
- 带有大量元数据和相关工具的容器镜像。
- 注入容器的环境变量以供应用程序使用。
API 对象 (也称为资源定义);请参阅 OpenShift Container Platform 的核心概念,它:
- 注入到容器中供应用使用。
- OpenShift Container Platform 如何管理容器和 pod。
在 OpenShift Container Platform 中如何推广应用程序,这个主题将:
- 详细阐述引入到应用程序定义中的这些新工件。
- 描述您可以为应用程序提升管道分离不同的环境。
- 讨论用于管理这些新工件的方法和工具。
- 提供将各种概念、构建、方法和工具应用到应用程序提升的示例。
2.3.2. 应用程序组件
2.3.2.1. API 对象
对于 OpenShift Container Platform 和 Kubernetes 资源定义(新向应用程序清单引入的项目),这些 API 对象有几个关键设计点,在考虑应用程序提升主题时,需要重新查看这些 API 对象。
首先,作为在 OpenShift Container Platform 文档中突出显示的,每个 API 对象可以通过 JSON 或 YAML 来表达,从而可以通过传统的源控制和脚本管理这些资源定义。
另外,API 对象也被设计为设计为存在部分对象,用于指定系统所需状态,其他部分则反映了系统的状态或当前状态。这可以被认为为输入和输出。以 JSON 或 YAML 格式表示的输入部分,特别是作为源控制管理(SCM)工件自然而符合的项目。
请记住,API 对象的输入或规格部分可以全面静态或动态,该变量在实例化时 可以通过模板处理替换。
与 API 对象相关的结果是,其表达式用作 JSON 或 YAML 文件,您可以将应用程序的配置视为代码。
可以说,几乎所有 API 对象都可能会被视为您的机构的应用程序工件。下面是与部署和管理应用程序最常见相关的对象:
- BuildConfig
-
在应用程序提升的情况下是一个特殊情况资源。虽然
BuildConfig
是应用程序的一部分,特别是开发人员透视图中,但通常BuildConfig
不会通过管道来提升。它会生成通过管道提升(以及其他项目)的镜像
。 - 模板
-
在应用程序提升方面,
模板
可以充当在给定暂存环境中设置资源的起点,特别是参数化功能。当应用程序通过提升管道进行移动时,额外的后后修改会非常有效。有关此方面的更多信息,请参阅场景和示例。 - Routes
-
这些是应用程序提升管道中阶段阶段的最典型资源,作为通过其
Route
对应用程序的不同阶段进行测试。另外,请记住,您拥有与手动规格或自动生成主机名相关的选项,以及Route
的 HTTP 级别的安全性。 - 服务
-
对于给定应用程序提升阶段存在避免
Routers
和Routes
的原因(例如在开发的早期阶段为开发人员提供简便),可以通过集群
IP 地址和端口访问应用程序。如果是这种情况,则在不同阶段之间的地址和端口的某些管理可能需要保证。 - Endpoints
-
某些应用程序级别服务(例如,许多企业中的数据库实例)可能无法由 OpenShift Container Platform 管理。如果是这样,则自行创建这些
端点
,以及对相关服务
(忽略Service
上的选择器字段)的修改已启用(基于您的具体环境,在不同阶段之间重复或共享)。 - Secrets
-
当相应实体(由 OpenShift Container Platform 管理的
服务
或 OpenShift Container Platform 之外的外部服务管理的服务)时,由Secret
封装的敏感信息是在暂存环境之间共享的。如果您的应用程序提升管道的不同阶段有不同版本的实体,则可能需要在管道的每个阶段维护不同的Secret
,或者在它遍历管道时对其进行修改。另外,请注意,如果您在 SCM 中将Secret
存储为 JSON 或 YAML,则可能会对一些加密格式进行加密,以保护敏感信息。 - DeploymentConfig
- 此对象是用于定义和缩进给定应用程序提升管道阶段的环境的主要资源;它控制应用程序启动的方式。虽然所有不同阶段都很常见,但为了加快应用程序的提升管道进行,但撤销会对这个对象进行修改,以反映每个阶段的不同环境的不同,或者系统行为的变化,以协助测试应用程序必须支持的不同场景。
- ImageStream、ImageStreamTags 和 ImageStreamImage
- 在 Images 和 Image Streams 部分中详述,这些对象是管理容器镜像的 OpenShift Container Platform 补充。
- ServiceAccounts 和 RoleBindings
-
OpenShift Container Platform 中其他 API 对象的权限管理以及外部服务,用于管理您的应用程序。与
Secrets
类似,ServiceAccounts
和RoleBindings
对象可能会因您需要共享或隔离这些不同环境的需求在应用程序提升管道的不同阶段之间共享的不同而有所不同。 - PersistentVolumeClaims
- 与数据库等有状态服务相关,不同的应用程序提升阶段将共享量与您的组织共享或隔离应用程序数据副本的关联。
- ConfigMaps
-
从
Pod
本身分离Pod
配置的一个实用性(思考环境变量风格配置)可在需要一致的Pod
行为时由各种暂存环境共享。它们也可以在阶段修改,以更改Pod
行为(通常因为应用程序的不同方面被检查到不同的阶段)。
2.3.2.2. 镜像
如前所述,容器镜像现在是应用程序的工件。事实上,新应用工件、镜像和管理是应用程序提升的关键部分。在某些情况下,镜像可能会封装整个应用,应用提升流程则专门管理镜像。
镜像通常不在 SCM 系统中管理,因为应用二进制文件不在以前的系统中。但是,就像使用二进制、可安装工件和相应的存储库(如 RPM、RPM 存储库或 Nexus)一样,与 SCM 相同的语义一样。因此,与 SCM 类似的镜像管理构建和术语发生:
- 镜像 registry == SCM 服务器
- 镜像存储库 == SCM 存储库
当镜像位于 registry 中时,需要确保 registry 中存在适当的镜像,这些镜像可从需要运行该镜像代表的应用程序的环境中访问。
应用程序定义通常抽象到镜像流的引用,而不是直接引用镜像。这意味着镜像流将是组成应用程序组件的另一个 API 对象。有关镜像流的详情,请参阅 核心概念。
2.3.2.3. 概述
现在,在 OpenShift Container Platform 内应用程序推广应用程序工件、镜像和 API 对象的应用程序工件已包括在 OpenShift Container Platform 中,您在提升管道的不同阶段运行应用程序的行为是接下来讨论的。
2.3.3. 部署环境
在这种情况下,部署环境描述了在 CI/CD 管道的特定阶段运行应用程序的不同空间。典型环境包括 开发、测试、stage 和生产,例如:环境边界可以以不同的方式定义,例如:
- 通过单一项目中的标签和唯一命名。
- 通过集群中的不同项目。
- 通过不同的集群。
它取决于您的组织是否全部利用了所有三个产品。
2.3.3.1. 注意事项
通常,您会在部署环境结构时考虑以下 heuristics:
- 共享您的提升流程的不同阶段的资源量允许
- 隔离您的提升流程的不同阶段需要多少
- 如何集中位置(或地理位置分散的)促销流程的不同阶段
另外,一些重要的提醒有关 OpenShift Container Platform 集群和项目与镜像 registry 的关系:
- 同一集群中的多个项目可以访问同一镜像流。
- 多个集群可以访问同一外部 registry。
- 只有 OpenShift Container Platform 内部镜像 registry 通过路由公开时,集群才可以共享 registry。
2.3.3.2. 概述
定义了部署环境后,可以实施管道中的下线阶段的提升流程。构造这些提升流实施的方法和工具是下一个讨论点。
2.3.4. 方法和工具
从根本上而言,应用程序提升是一种将上述应用程序组件从一个环境移至另一个环境的过程。以下小节概述了可用于手动移动各种组件的工具,然后再讨论用于自动化应用程序提升的完整解决方案。
构建和部署过程中都提供了很多插入点。它们在 BuildConfig
和 DeploymentConfig
API 对象中定义。这些 hook 允许调用与部署的组件(如数据库和 OpenShift Container Platform 集群本身)交互的自定义脚本。
因此,可以使用这些 hook 来执行组件管理操作,在环境间有效移动应用程序,例如,从 hook 中执行镜像标签操作。但是,各种 hook 得分最适合在给定环境中管理应用程序的生命周期(例如,在部署新版本的应用程序时执行数据库架构迁移),而不是在环境之间移动应用程序组件。
2.3.4.1. 管理 API 对象
在单一环境中定义的资源将导出为 JSON 或 YAML 文件内容,以准备将其导入到新环境中。因此,当您通过应用程序管道提升 API 对象时,作为 JSON 或 YAML 的表达式作为工作单元。oc
CLI 用于导出和导入此内容。
虽然在 OpenShift Container Platform 中不需要提升流,但 JSON 或 YAML 存储在文件中,但您可以考虑从 SCM 系统中存储和检索内容。这可让您利用 SCM 的与版本相关的功能,包括创建分支,以及针对与版本关联的不同标签或标签分配和查询。
2.3.4.1.1. 导出 API 对象状态
API 对象规格应该被 oc get --export
捕获。此操作会从对象定义(如当前命名空间或分配的 IP 地址)中移除环境特定数据,允许在不同环境中重新创建它们(与 oc get
操作不同,它输出对象的不过滤状态)。
使用 oc label
,它允许在 API 对象上添加、修改或删除标签,这在组织为提升流程而收集的一组对象时很有用,因为标签允许在单一操作中选择和管理 pod 组。这样可以更轻松地导出正确组的对象,因为标签将在新环境中创建对象时向前工作,所以它们还可以更轻松地管理每个环境中的应用程序组件。
API 对象通常包含引用 Secret
的 DeploymentConfig
等。当将 API 对象从一个环境迁移到另一个环境时,您必须确保这样的引用也会移到新环境中。
同样,DeploymentConfig
等 API 对象通常包含引用外部 registry 的 ImageStream
的引用。当将 API 对象从一个环境移到另一个环境时,您必须确保在新环境中可以解析此类引用,这意味着引用必须可以被解析,并且 ImageStream
必须引用新环境中可访问的 registry。如需了解更多详细信息,请参阅 Moving Images 和 Promotion Caveats。
2.3.4.1.2. 导入 API 对象状态
2.3.4.1.2.1. 初始创建
当应用程序第一次出现在新环境中时,使用 JSON 或 YAML 来表达 API 对象规格,并运行 oc create
在适当的环境中创建它们。使用 oc create
时,请记住 --save-config
选项。在其注解列表中保存对象的配置元素有助于稍后使用 oc apply
修改对象。
2.3.4.1.2.2. 迭代修改
最初建立各种暂存环境后,在提升周期开始并且应用程序从阶段移到 stage 后,对应用程序的更新会包括修改作为应用程序一部分的 API 对象。这些 API 对象中的更改是可激活的,因为它们代表 OpenShift Container Platform 系统的配置。这种变化的动机包括:
- 衡量暂存环境之间的环境差异。
- 验证应用支持的各种场景。
API 对象传输到下一阶段的环境可以通过 oc
CLI 来完成。虽然存在修改 API 对象的多组 oc
命令,但此主题侧重于 oc apply
,其计算并应用对象之间的差别。
特别是,您可以把 oc apply
作为三向合并,在文件或 stdin 中取为输入以及现有的对象定义。它执行三向合并:
- 命令的输入,
- 对象的当前版本,以及
- 最近的用户指定的对象定义存储为当前对象中的注解。
然后,使用结果更新现有对象。
如果需要进一步自定义 API 对象,如在源和目标环境之间对象不能相同时,可以使用 oc set
等 oc
命令在应用来自上游环境的最新对象定义后修改对象。
某些特定的用途在 Scenarios 和示例中加以控制。
2.3.4.2. 管理镜像和镜像流
OpenShift Container Platform 中的镜像也通过一系列 API 对象进行管理。但是,管理镜像是应用程序提升的核心,讨论这些工具和 API 对象最直接关联镜像保证了单独讨论。存在手动和自动化的形式,可帮助您管理镜像提升(通过管道传播镜像)。
2.3.4.2.1. 移动镜像
有关管理镜像的所有详细信息,请参阅管理镜像主题。
2.3.4.2.1.2. 当 Staging 环境使用不同的 registry 时
当 staging 环境使用不同的 OpenShift Container Platform registry 时,会进行更高级的使用。
访问内部 registry 会详细介绍这些步骤,但总体来说您可以:
-
使用
docker
命令组合获取 OpenShift Container Platform 访问令牌,以提供docker login
命令。 -
登录 OpenShift Container Platform registry 后,请使用
docker pull
、docker tag
和docker push
来传输镜像。 -
在管道下一环境的 registry 中提供了镜像后,根据需要使用
oc tag
来填充任何镜像流。
2.3.4.2.2. 部署
无论是更改底层应用程序镜像还是配置应用程序的 API 对象,部署通常需要提取升级的更改。如果应用程序的镜像改变(例如,由于 oc tag
操作或 docker push
作为从上游环境提升镜像的一部分),则您的 DeploymentConfig
上的 ImageChangeTriggers
可以触发新部署。同样,如果 DeploymentConfig
API 对象本身被更改,则当由提升步骤更新 API 对象时,ConfigChangeTrigger
可以启动部署(如 oc apply
)。
否则,有助于手动部署的 oc
命令包括:
-
oc rollout
:管理部署的新方法,包括暂停和恢复有关管理历史记录的语义和丰富的功能。 -
oc rollback
:允许将版本重新升级到以前的部署;在提升情景中,如果测试新版本遇到问题,请确认它仍能与上一版本合作。
2.3.4.2.3. 使用 Jenkins 自动化促销流
在了解了应用程序的组件后,在提升环境以及移动组件所需的步骤时需要在环境间进行移动后,您可以开始编配和自动化工作流。OpenShift Container Platform 提供了一个 Jenkins 镜像和插件来解决此问题。
使用镜像 (image)中详细介绍了 OpenShift Container Platform Jenkins 镜像,其中包括有助于 Jenkins 集成 Jenkins 和 Jenkins Pipelines 的 OpenShift Container Platform 以插件集。另外,Pipeline 构建策略 有助于集成 Jenkins Pipelines 和 OpenShift Container Platform。所有这些侧重于启用 CI/CD 的各个方面,包括应用程序提升。
在手动执行应用程序提升步骤外,应该考虑 OpenShift Container Platform 提供的与 Jenkins 相关的功能:
- OpenShift Container Platform 提供了一个 Jenkins 镜像,它被定制来大大简化 OpenShift Container Platform 集群中的部署。
- Jenkins 镜像包含 OpenShift Pipeline 插件,它为实施提升工作流提供构建块。这些构建块包括 Jenkins 任务触发作为镜像流更改,以及在这些作业中触发构建和部署。
-
采用 OpenShift Container Platform Jenkins Pipeline 构建策略的
BuildConfig
可执行基于 Jenkinsfile 的 Jenkins 管道作业。Pipeline 作业是 Jenkins 中用于复杂提升流程的战略方向,可以利用 OpenShift Pipeline 插件提供的步骤。
2.3.4.2.4. Promotion Caveats
2.3.4.2.4.1. API 对象参考
API 对象可以引用其他对象。这种情况的一个常见用途是具有引用镜像流的 DeploymentConfig
,但也有其他引用关系。
将 API 对象从一个环境复制到另一个环境时,所有引用仍可以在目标环境中解析。有几个参考场景需要考虑:
- 引用是项目的"本地"。在这种情况下,引用的对象位于与引用它的对象位于同一项目中。通常,要进行的正确操作是,请确保将引用的对象复制到与引用对象相同的项目中的目标环境中。
引用是另一个项目中的对象。当共享项目中的镜像流被多个应用项目使用时,这比较典型。在这种情况下,当将引用对象复制到新环境中时,您必须根据需要更新引用,以便在目标环境中解析它。这可能意味着:
- 如果共享项目在目标环境中具有不同的名称,则更改引用指向的项目。
- 将引用对象从目标环境中的本地项目移动到本地项目,并将主对象移到目标环境中时,将引用更新为指向本地项目。
- 将引用对象复制到目标环境中的某些其他组合,并更新对其的引用。
通常,其指导是考虑复制到新环境中的对象引用的对象,并确保引用可在目标环境中解析。如果没有,采取适当的操作来修复引用,并使目标环境中有引用的对象可用。
2.3.4.2.4.2. 镜像 Registry 参考
镜像流指向镜像存储库,以指明它们所代表的镜像源。当镜像流从一个环境移到另一个环境时,务必要考虑 registry 和存储库引用是否还应更改:
- 如果使用不同的镜像 registry 来在测试环境和生产环境之间断言隔离。
- 如果使用不同的镜像存储库来分隔测试和生产就绪的镜像。
如果其中任何一个情况是,在从源环境复制到目标环境时,必须修改镜像流,以便其解析为正确的镜像。这还执行 Scenarios 和 Examples 中描述的步骤,将镜像从一个 registry 和 repository 复制到另一个。
2.3.4.3. 概述
此时定义了以下内容:
- 组成已部署应用程序的新应用程序工件。
- 将应用程序提升活动与 OpenShift Container Platform 提供的工具和概念关联。
- OpenShift Container Platform 和 CI/CD 管道引擎 Jenkins 之间的集成。
将应用程序提升流的示例放在 OpenShift Container Platform 中,是本主题的最后一步。
2.3.5. 场景和示例
在 Docker、Kubernetes 和 OpenShift Container Platform 生态系统中定义了新的应用程序工件组件,本节介绍了如何使用 OpenShift Container Platform 提供的机制和工具在环境之间提升这些组件。
镜像是组成应用程序的组件的主要工件。采用该内部环境并将其扩展至应用程序提升、核心、基本应用程序提升模式是映像提升,其中工作单元是镜像。大多数应用程序促销方案通过提升管道管理和传播镜像。
仅仅通过管道管理和传播镜像的简单场景。随着推广方案的范围广泛,其他应用程序工件(特别是 API 对象)都包含在通过管道进行管理和传播的项目清单中。
本主题介绍了一些有关使用手动和自动化方法来提升镜像以及 API 对象的特定示例。但请注意以下设置应用程序提升管道的环境。
2.3.5.1. 为提升设置
完成应用程序初始修订的开发后,下一步是打包应用程序的内容,以便您可以转移到提升管道的后续暂存环境。
首先,将您查看的所有 API 对象作为传输进行分组,并为它们应用通用
标签
:labels: promotion-group: <application_name>
如前文所述,
oc label
命令协助使用各种 API 对象管理标签。提示如果您最初在 OpenShift Container Platform 模板中定义 API 对象,您可以轻松确保所有相关对象在导出以准备提升时用于查询。
您可以在后续查询中使用该标签。例如,请考虑以下一组
oc
命令调用,然后达到应用程序的 API 对象的传输:$ oc login <source_environment> $ oc project <source_project> $ oc get -o yaml --export dc,is,svc,route,secret,sa -l promotion-group=<application_name> > export.yaml $ oc login <target_environment> $ oc new-project <target_project> 1 $ oc create -f export.yaml
- 1
- 或者,如果已存在则为
oc project <target_project>
。
注意在
oc get --export
命令中,无论您是否包含镜像流的is
类型都取决于您如何选择在管道中不同环境中管理镜像、镜像流和 registry。下文将讨论有关此问题的注意事项。另请参阅 管理镜像 主题。您还必须获取针对提升管道中不同暂存环境中使用的每个 registry 操作所需的令牌。对于每个环境:
登录到环境:
$ oc login <each_environment_with_a_unique_registry>
使用以下命令获取访问令牌:
$ oc whoami -t
- 复制并粘贴令牌值供以后使用。
2.3.5.2. 可重复提升流程
在为您的管道进行另一个暂存环境的初始设置后,通过提升管道验证应用程序的每个迭代可以启动一组可重复的步骤。每次源环境中的镜像或 API 对象改变时会执行这些基本步骤:
移动更新的镜像 → Move updated API 对象 → Apply 环境特定自定义
通常,第一步是将与应用程序关联的镜像的任何更新提升到管道中的下一阶段。如上面所述,提升镜像的关键差异化是 OpenShift Container Platform registry 是否在暂存环境间共享。
如果 registry 共享,则只利用
oc tag
:$ oc tag <project_for_stage_N>/<imagestream_name_for_stage_N>:<tag_for_stage_N> <project_for_stage_N+1>/<imagestream_name_for_stage_N+1>:<tag_for_stage_N+1>
如果没有共享 registry,您可以在登录到源和目标 registry 时利用每个提升管道 registry 的访问令牌,相应地拉取、标记和推送应用程序镜像:
登录到源环境 registry:
$ docker login -u <username> -e <any_email_address> -p <token_value> <src_env_registry_ip>:<port>
拉取应用程序的镜像:
$ docker pull <src_env_registry_ip>:<port>/<namespace>/<image name>:<tag>
将应用程序的镜像标记到目标 registry 的位置,根据需要更新命名空间、名称和标签,以符合目标暂存环境:
$ docker tag <src_env_registry_ip>:<port>/<namespace>/<image name>:<tag> <dest_env_registry_ip>:<port>/<namespace>/<image name>:<tag>
登录到目标暂存环境 registry:
$ docker login -u <username> -e <any_email_address> -p <token_value> <dest_env_registry_ip>:<port>
将镜像推送到其目的地:
$ docker push <dest_env_registry_ip>:<port>/<namespace>/<image name>:<tag>
提示要从外部 registry 自动导入镜像的新版本,
oc tag
命令有一个--scheduled
选项。如果使用,则ImageStreamTag
引用的镜像将定期从托管镜像的 registry 中拉取。
接下来,在有些情况下,应用程序的发展需要对您的 API 对象进行基本更改,或者从组成应用程序的 API 对象集合中移除。当应用程序 API 对象出现这种演变时,OpenShift Container Platform CLI 提供了广泛的选项来从一个暂存环境转移到下一个阶段。
从最初设置提升管道时启动的方式相同:
$ oc login <source_environment> $ oc project <source_project> $ oc get -o yaml --export dc,is,svc,route,secret,sa -l promotion-group=<application_name> > export.yaml $ oc login <target_environment> $ oc <target_project>
更新它们,而不是简单地在新环境中创建资源。您可以按照几种不同的方式实现:
更保守的方法是使用
oc apply
并合并对目标环境中每个 API 对象的新更改。要做到这一点,您可以在实际更改对象前--dry-run=true
选项并检查生成的对象:$ oc apply -f export.yaml --dry-run=true
如果满意,则实际运行
apply
命令:$ oc apply -f export.yaml
apply
命令可以选择使用额外的参数,以帮助实现更复杂的场景。如需了解更多详细信息,请参阅oc apply --help
。或者,更简单但更积极的方法是使用
oc replace
。没有使用此更新且替换的空运行。在最基本的形式中,这涉及执行:$ oc replace -f export.yaml
与
apply
一样,replace
(可选)为更复杂的行为采用附加参数。如需了解更多详细信息,请参阅oc replace --help
。
-
前面的步骤会自动处理引入的新 API 对象,但如果从源环境中删除 API 对象,必须使用
oc delete
从目标环境中手动删除它们。 对于任何 API 对象而言,可能需要调整环境变量,因为这些对象所需的值可能会在暂存环境之间有所不同。为此,请使用
oc set env
:$ oc set env <api_object_type>/<api_object_ID> <env_var_name>=<env_var_value>
-
最后,使用
oc rollout
命令或上方 Deployments 部分中讨论的其他机制之一来触发更新的应用程序的新部署。
2.3.5.3. 使用 Jenkins 可重复提升过程
用于 OpenShift Container Platform 的 Jenkins Docker 镜像 中定义的 OpenShift Sample 作业是一个在 Jenkins 构造中 OpenShift Container Platform 中的镜像提升示例。本示例的设置位于 OpenShift Origin 源存储库中。
这个示例包括:
- 使用 Jenkins 作为 CI/CD 引擎。
-
将 OpenShift Pipeline 插件用于 Jenkins。此插件提供了
oc
CLI 为打包为 Jenkins Freestyle 和 DSL 作业步骤的 oc CLI 提供的功能子集。请注意,oc
二进制文件也包含在用于 OpenShift Container Platform 的 Jenkins Docker 镜像中,也可用于与 Jenkins 任务中的 OpenShift Container Platform 交互。 - OpenShift Container Platform 提供的 Jenkins 的模板。适用于临时存储和持久存储的模板。
-
示例应用 :在 OpenShift Origin 源存储库 中定义,此应用利用
ImageStreams
、imageChangeTriggers
、ImageStreamTags
、BuildConfigs
和与提升管道中不同阶段对应的DeploymentConfig
和服务
。
下面将更加详细地检查 OpenShift Sample 作业的各种部分:
-
第一步是 等同于
oc scale dc frontend --replicas=0
调用。此步骤旨在关闭可能正在运行的应用程序镜像的任何早期版本。 -
第二个步骤 等同于
oc start-build frontend
调用。 -
第三个步骤 等同于
oc rollout latest dc/frontend
调用。 - 第四个步骤是本例的"测试"步骤。它确保此应用程序的相关服务实际上可从网络角度访问。在覆盖范围内,针对与 OpenShift Container Platform 服务关联的 IP 地址和端口尝试套接字连接。当然,可以添加额外的测试(如果没有通过 OpenShift Pipepline 插件步骤),然后通过使用 Jenkins Shell 步骤来利用操作系统级命令和脚本来测试应用程序。
-
第五个步骤开始假设测试通过的应用程序,因此希望将镜像标记为"就绪"。在这一步中,会从 latest 镜像为应用镜像创建一个新的 prod 标签。随着 frontend
DeploymentConfig
有一个为该标签定义的ImageChangeTrigger
,则会启动对应的"production"部署。 - 第六个和最后一个步骤 是一个验证步骤,插件确认 OpenShift Container Platform 为 "production" 部署启动了所需的副本数。
第 3 章 身份验证
3.1. Web 控制台身份验证
从位于 <master_public_addr>:8443 的浏览器访问 Web 控制台时,您会自动重定向到登录页面。
查看可用于访问 Web 控制台的 浏览器版本和操作系统。
您可以在此页面中提供您的登录凭证,以获取令牌来发出 API 调用。登录后,您可以使用 Web 控制台 导航到项目。
3.2. CLI 身份验证
您可以在命令行中使用 CLI 命令 oc login
进行身份验证。您可以在没有选项的情况下运行这个命令来 开始使用 CLI :
$ oc login
命令的交互式流可帮助您使用提供的凭证建立到 OpenShift Container Platform 服务器的会话。如果没有提供成功登录到 OpenShift Container Platform 服务器所需的信息,命令会根据需要提示用户输入。配置会自动保存,然后用于后续命令。
oc login --help
中列出的 oc login
命令的所有配置选项都是可选的。以下示例显示一些常见选项的使用:
$ oc login [-u=<username>] \ [-p=<password>] \ [-s=<server>] \ [-n=<project>] \ [--certificate-authority=</path/to/file.crt>|--insecure-skip-tls-verify]
下表描述了这些通用选项:
选项 | 语法 | 描述 |
---|---|---|
|
$ oc login -s=<server> | 指定 OpenShift Container Platform 服务器的主机名。如果通过此标志提供服务器,命令不会以交互方式询问服务器。如果您已有 CLI 配置文件并希望登录并切换到其他服务器,也可以使用此标志。 |
|
$ oc login -u=<username> -p=<password> | 允许您指定凭证登录 OpenShift Container Platform 服务器。如果通过这些标志提供用户名和密码,命令不会以互动方式询问。如果您已建立会话令牌的配置文件并希望登录并切换到另一个用户名,也可以使用这些标志。 |
|
$ oc login -u=<username> -p=<password> -n=<project> |
一个全局 CLI 选项,它用于 |
|
$ oc login --certificate-authority=<path/to/file.crt> | 使用 HTTPS 的 OpenShift Container Platform 服务器正确且安全地进行身份验证。必须提供证书颁发机构文件的路径。 |
|
$ oc login --insecure-skip-tls-verify |
允许与 HTTPS 服务器交互绕过服务器证书检查,但请注意,这不太安全。如果您尝试 |
通过 CLI 配置文件,您可以轻松管理多个 CLI 配置文件。
第 4 章 授权
4.1. 概述
本主题包含应用程序开发人员及其功能的授权任务,具体由集群管理员规定。
4.2. 检查用户是否可以创建 Pod
使用 scc-review
和 scc-subject-review
选项,您可以看到单个用户或特定服务帐户下的用户能否创建或更新 pod。
使用 scc-review
选项,您可以检查服务帐户是否可以创建或更新 pod。命令输出接受该资源的安全性上下文约束。
例如,要检查具有 system:serviceaccount:projectname:default
服务帐户的用户是否可以创建一个 pod:
$ oc policy scc-review -z system:serviceaccount:projectname:default -f my_resource.yaml
您还可以使用 scc-subject-review
选项检查特定用户是否可以创建或更新 pod:
$ oc policy scc-subject-review -u <username> -f my_resource.yaml
要检查属于特定组的用户是否可以在特定文件中创建 pod:
$ oc policy scc-subject-review -u <username> -g <groupname> -f my_resource.yaml
4.3. 确定您可以作为经过身份验证的用户执行什么操作
在 OpenShift Container Platform 项目中,您可以决定对所有命名空间范围的资源(包括第三方资源)执行的操作 verbs。
can-i
命令选项测试用户和角色方面的范围。
$ oc policy can-i --list --loglevel=8
输出可帮助您确定提出哪些 API 请求来收集信息。
要以用户可读格式接收信息,请运行:
$ oc policy can-i --list
输出提供了一个完整的列表。
要确定您可以执行特定的操作动词,请运行:
$ oc policy can-i <verb> <resource>
用户范围 可以提供有关给定范围的更多信息。例如:
$ oc policy can-i <verb> <resource> --scopes=user:info
第 5 章 项目
5.1. 概述
通过项目(project),一个社区用户可以在与其他社区隔离的前提下组织和管理其内容。
5.2. 创建一个项目
如果集群管理员允许,您可以使用 CLI 或 Web 控制台 创建新项目。
5.2.1. 使用 Web 控制台
若要使用 Web 控制台创建新项目,请单击 Projects 面板或 Projects 页面上的 Create Project 按钮。
默认情况下会显示 Create Project 按钮,但可以选择进行隐藏或自定义。
5.2.2. 使用 CLI
使用 CLI 创建新项目:
$ oc new-project <project_name> \ --description="<description>" --display-name="<display_name>"
例如:
$ oc new-project hello-openshift \ --description="This is an example project to demonstrate OpenShift v3" \ --display-name="Hello OpenShift"
系统管理员可能会限制允许创建的项目数量。达到限制后,可能需要删除现有项目来创建新项目。
5.3. 查看项目
查看项目时,只能看到根据授权策略您有权访问的项目。
要查看项目列表,请运行:
$ oc get projects
您可以从当前项目更改到其他项目,以进行 CLI 操作。然后,所有操控项目范围内容的后续操作都会使用指定的项目:
$ oc project <project_name>
您还可以使用 Web 控制台在 项目之间查看和更改。身份验证并登录后,您会看到您有权访问的项目列表。
服务目录显示的右侧面板提供对最新访问的项目(最多五个项目)的快速访问。如需项目的完整列表,请使用右侧面板顶部的 View All 链接。
如果使用 CLI 创建新项目,您可以在浏览器中刷新页面以查看新项目。
选择一个项目可进入项目的项目概述。
点击特定项目的 kebab 菜单来为您提供以下选项:
5.4. 检查项目状态
oc status
命令提供当前项目的高级概述,及其组件及其关系。这个命令没有参数:
$ oc status
5.5. 按标签过滤
您可以使用资源标签过滤 Web 控制台中 的项目页面的内容。您可以从推荐的标签名称和值中选择,或者自行输入。可以添加多个过滤器。应用多个过滤器时,资源必须匹配所有过滤器才能保持可见。
按标签进行过滤:
选择标签类型:
任选以下一项:
exists
验证标签名称是否存在,但忽略其值。
does not exist
验证标签名称不存在,但忽略其值。
in
验证标签名称是否存在,并且等于所选值之一。
not in
验证标签名称不存在,或者不等于任何所选值。
如果选择 in 或 not in,选择一组值,然后选择 Filter:
添加过滤器后,您可以通过选择 Clear all 过滤器来停止过滤,或者点击单个过滤器来删除它们:
5.6. 书签页面状态
OpenShift Container Platform Web 控制台现在书签页状态,这有助于保存标签过滤器和其他设置。
当您执行更改页面的状态时,如在标签页间切换时,浏览器导航栏中的 URL 会被自动更新。
5.7. 删除项目
当您删除项目时,服务器会将项目状态从 Active 更新为 Terminating。然后,服务器会清除正在终止的项目中的所有内容,然后最终删除项目。在项目处于 Terminating 状态时,用户无法向项目添加新内容。可以从 CLI 或 Web 控制台删除项目。
使用 CLI 删除项目:
$ oc delete project <project_name>
第 6 章 迁移应用程序
6.1. 概述
本主题涵盖 OpenShift 版本 2(v2)应用迁移到 OpenShift 版本 3(v3)的迁移步骤。
本主题使用一些特定于 OpenShift v2 的术语。比较 OpenShift Enterprise 2 和 OpenShift Enterprise 3 可深入了解两个版本与所用的语言之间的差别。
要将 OpenShift v2 应用程序迁移到 OpenShift Container Platform v3,v2 应用程序中的所有cartridge 必须记录,因为每个 v2 cartridge 等同于 OpenShift Container Platform v3 中的相应镜像或模板,且必须单独迁移。对于每个 cartridge,还必须记录所有依赖项或所需软件包,因为它们必须包含在 v3 镜像中。
常规迁移步骤为:
备份 v2 应用。
- Web cartridge:源代码可以备份到 Git 存储库,例如通过推送到 GitHub 上的存储库。
-
数据库 cartridge:可使用转储命令(
mongodump
、mysqldump
、pg_dump
)备份数据库,以备份数据库。 Web 和数据库模块:
rhc
客户端工具提供备份多个模块的快照功能:$ rhc snapshot save <app_name>
快照是可以解压缩的 tar 文件,其内容是应用源代码和数据库转储。
- 如果应用程序有数据库 cartridge,请创建一个 v3 数据库应用程序,将数据库转储同步到新 v3 数据库应用程序的 pod,然后使用数据库恢复命令恢复 v3 数据库应用程序中的 v2 数据库。
- 对于 Web 框架应用程序,编辑应用源代码,使其与 v3 兼容。然后,添加 Git 存储库中的相应文件中所需的任何依赖项或软件包。将 v2 环境变量转换为对应的 v3 环境变量。
- 从源(您的 Git 存储库)或者从带有 Git URL 的快速入门中创建 v3 应用程序。另外,将数据库服务参数添加到新应用,将数据库应用链接到 Web 应用。
- 在 v2 中,有一个集成的 Git 环境,应用程序会在更改推送到 v2 Git 存储库时自动重新构建和重启。在 v3 中,若要由推送到公共 Git 存储库的源代码更改自动触发构建,您必须在 v3 的初始构建完成后设置 webhook。
6.2. 迁移数据库应用程序
6.2.1. 概述
本节复习如何将 MySQL、PostgreSQL 和 MongoDB 数据库应用程序从 OpenShift 版本 2(v2)迁移到 OpenShift 版本 3(v3)。
6.2.2. 支持的数据库
v2 | v3 |
---|---|
MongoDB:2.4 | MongoDB:2.4, 2.6 |
MySQL:5.5 | MySQL:5.5, 5.6 |
PostgreSQL:9.2 | PostgreSQL:9.2, 9.4 |
6.2.3. MySQL
将所有数据库导出到转储文件并将其复制到本地计算机(位于当前目录中):
$ rhc ssh <v2_application_name> $ mysqldump --skip-lock-tables -h $OPENSHIFT_MYSQL_DB_HOST -P ${OPENSHIFT_MYSQL_DB_PORT:-3306} -u ${OPENSHIFT_MYSQL_DB_USERNAME:-'admin'} \ --password="$OPENSHIFT_MYSQL_DB_PASSWORD" --all-databases > ~/app-root/data/all.sql $ exit
将 dbdump 下载到您的本地机器中:
$ mkdir mysqldumpdir $ rhc scp -a <v2_application_name> download mysqldumpdir app-root/data/all.sql
从模板创建 v3 mysql-persistent pod:
$ oc new-app mysql-persistent -p \ MYSQL_USER=<your_V2_mysql_username> -p \ MYSQL_PASSWORD=<your_v2_mysql_password> -p MYSQL_DATABASE=<your_v2_database_name>
检查 pod 是否准备就绪:
$ oc get pods
当 pod 上线并运行时,将数据库存档文件复制到您的 v3 MySQL pod 中:
$ oc rsync /local/mysqldumpdir <mysql_pod_name>:/var/lib/mysql/data
恢复运行 v3 的 pod 中的数据库:
$ oc rsh <mysql_pod> $ cd /var/lib/mysql/data/mysqldumpdir
在 v3 中,若要恢复您需要以 root 用户身份访问 MySQL 的数据库。
在 v2 中,
$OPENSHIFT_MYSQL_DB_USERNAME
对所有数据库具有完整权限。在 v3 中,您必须为每个数据库授予$MYSQL_USER
的权限。$ mysql -u root $ source all.sql
将 <dbname> 的所有权限授予
<your_v2_username>@localhost
,然后清空权限。从 pod 中删除转储目录:
$ cd ../; rm -rf /var/lib/mysql/data/mysqldumpdir
支持的 MySQL 环境变量
v2 | v3 |
---|---|
|
|
|
|
|
|
|
|
| |
| |
| |
| |
| |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
| |
| |
| |
| |
|
6.2.4. PostgreSQL
从 gear 备份 v2 PostgreSQL 数据库:
$ rhc ssh -a <v2-application_name> $ mkdir ~/app-root/data/tmp $ pg_dump <database_name> | gzip > ~/app-root/data/tmp/<database_name>.gz
将备份文件提取到本地机器:
$ rhc scp -a <v2_application_name> download <local_dest> app-root/data/tmp/<db-name>.gz $ gzip -d <database-name>.gz
注意将备份文件保存到单独的文件夹,以供第 4 步使用。
使用 v2 应用程序数据库名称、用户名和密码来创建 PostgreSQL 服务,以创建新服务:
$ oc new-app postgresql-persistent -p POSTGRESQL_DATABASE=dbname -p POSTGRESQL_PASSWORD=password -p POSTGRESQL_USER=username
检查 pod 是否准备就绪:
$ oc get pods
当 pod 上线并运行时,将备份目录同步到 pod:
$ oc rsync /local/path/to/dir <postgresql_pod_name>:/var/lib/pgsql/data
远程访问 pod:
$ oc rsh <pod_name>
恢复数据库:
psql dbname < /var/lib/pgsql/data/<database_backup_file>
删除不再需要的所有备份文件:
$ rm /var/lib/pgsql/data/<database-backup-file>
支持的 PostgreSQL 环境变量
v2 | v3 |
---|---|
|
|
|
|
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
6.2.5. MongoDB
- 对于 OpenShift v3:MongoDB shell 版本 3.2.6
- 对于 OpenShift v2:MongoDB shell 版本 2.4.9
通过
ssh
命令远程访问 v2 应用程序:$ rhc ssh <v2_application_name>
运行 mongodump,使用
-d <database_name> -c <collections>
指定单个数据库。如果没有这些选项,转储所有数据库。每个数据库在其自己的目录中转储:$ mongodump -h $OPENSHIFT_MONGODB_DB_HOST -o app-root/repo/mydbdump -u 'admin' -p $OPENSHIFT_MONGODB_DB_PASSWORD $ cd app-root/repo/mydbdump/<database_name>; tar -cvzf dbname.tar.gz $ exit
将 dbdump 下载到 mongodump 目录中的本地机器:
$ mkdir mongodump $ rhc scp -a <v2 appname> download mongodump \ app-root/repo/mydbdump/<dbname>/dbname.tar.gz
在 v3 中启动 MongoDB pod。由于最新的镜像(3.2.6)不包括 mongo-tools,若要使用
mongorestore
或mongoimport
命令,您需要编辑默认的 mongodb-persistent 模板,以指定包含mongo-tools, “mongodb:2.4”
的镜像标签。因此,需要以下oc get --export
命令并编辑:$ oc get -o json --export template mongodb-persistent -n openshift > mongodb-24persistent.json
编辑 mongodb-24persistent.json 的第 80 行;将
mongodb:latest
替换为mongodb:2.4
。$ oc new-app --template=mongodb-persistent -n <project-name-that-template-was-created-in> \ MONGODB_USER=user_from_v2_app -p \ MONGODB_PASSWORD=password_from_v2_db -p \ MONGODB_DATABASE=v2_dbname -p \ MONGODB_ADMIN_PASSWORD=password_from_v2_db $ oc get pods
当 mongodb pod 上线并运行时,将数据库存档文件复制到 v3 MongoDB pod 中:
$ oc rsync local/path/to/mongodump <mongodb_pod_name>:/var/lib/mongodb/data $ oc rsh <mongodb_pod>
在 MongoDB pod 中,为您要恢复的每个数据库完成以下内容:
$ cd /var/lib/mongodb/data/mongodump $ tar -xzvf dbname.tar.gz $ mongorestore -u $MONGODB_USER -p $MONGODB_PASSWORD -d dbname -v /var/lib/mongodb/data/mongodump
检查数据库是否已恢复:
$ mongo admin -u $MONGODB_USER -p $MONGODB_ADMIN_PASSWORD $ use dbname $ show collections $ exit
从 pod 中删除 mongodump 目录:
$ rm -rf /var/lib/mongodb/data/mongodump
支持的 MongoDB 环境变量
v2 | v3 |
---|---|
|
|
|
|
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
|
6.3. 迁移 Web 框架应用程序
6.3.1. 概述
本主题介绍了如何将 Python、Ruby、PHP、Perl、Node.js、WordPress、Ghost、JBoss EAP、JBoss WS(Tomcat)和 Wildfly 10(JBoss AS)Web 框架应用程序从 OpenShift 版本 2(v2)迁移到 OpenShift 版本 3(v3)。
6.3.2. Python
设置新的 GitHub 存储库,并将它作为远程分支添加到当前本地 v2 Git 存储库中:
$ git remote add <remote-name> https://github.com/<github-id>/<repo-name>.git
将本地 v2 源代码推送到新存储库:
$ git push -u <remote-name> master
确保所有重要文件(如 setup.py、wsgi.py、requirements.txt etc)都应推送到新存储库。
- 确定您的应用程序所需的所有软件包都包含在 requirements.txt 中。
使用
oc
命令从构建器镜像和源代码中启动新的 Python 应用程序:$ oc new-app --strategy=source python:3.3~https://github.com/<github-id>/<repo-name> --name=<app-name> -e <ENV_VAR_NAME>=<env_var_value>
支持的 Python 版本
v2 | v3 |
---|---|
python:2.6, 2.7, 3.3 | |
Django | Django-psql-example(快速入门) |
6.3.3. Ruby
设置新的 GitHub 存储库,并将它作为远程分支添加到当前本地 v2 Git 存储库中:
$ git remote add <remote-name> https://github.com/<github-id>/<repo-name>.git
将本地 v2 源代码推送到新存储库:
$ git push -u <remote-name> master
如果您没有 Gemfile 并运行一个简单的机架应用程序,请将这个 Gemfile 复制到您的源的根目录中:
https://github.com/sclorg/ruby-ex/blob/master/Gemfile
注意支持 Ruby 2.0 的 rack gem 的最新版本是 1.6.4,因此需要将 Gemfile 修改为
gem 'rack', “1.6.4”
。对于 Ruby 2.2 或更高版本,使用 rack gem 2.0 或更高版本。
使用
oc
命令从构建器镜像和源代码中启动新的 Ruby 应用程序:$ oc new-app --strategy=source ruby:2.0~https://github.com/<github-id>/<repo-name>.git
支持的 Ruby 版本
v2 | v3 |
---|---|
Ruby:1.8, 1.9, 2.0 | |
Ruby on Rails:3, 4 | Rails-postgresql-example(快速入门) |
Sinatra |
6.3.4. PHP
设置新的 GitHub 存储库,并将它作为远程分支添加到当前本地 v2 Git 存储库中:
$ git remote add <remote-name> https://github.com/<github-id>/<repo-name>
将本地 v2 源代码推送到新存储库:
$ git push -u <remote-name> master
使用
oc
命令从构建器镜像和源代码中启动新的 PHP 应用程序:$ oc new-app https://github.com/<github-id>/<repo-name>.git --name=<app-name> -e <ENV_VAR_NAME>=<env_var_value>
支持的 PHP 版本
v2 | v3 |
---|---|
PHP:5.3, 5.4 | |
带有 Zend Server 6.1 的 PHP 5.4 | |
CodeIgniter 2 | |
HHVM | |
Laravel 5.0 | |
cakephp-mysql-example (quickstart) |
6.3.5. Perl
设置新的 GitHub 存储库,并将它作为远程分支添加到当前本地 v2 Git 存储库中:
$ git remote add <remote-name> https://github.com/<github-id>/<repo-name>
将本地 v2 源代码推送到新存储库:
$ git push -u <remote-name> master
编辑本地 Git 存储库并推送上游更改,使其与 v3 兼容:
在 v2 中,CPAN 模块驻留在 .openshift/cpan.txt 中。在 v3 中,s2i 构建器在源的根目录中查找名为 cpanfile 的文件。
$ cd <local-git-repository> $ mv .openshift/cpan.txt cpanfile
编辑 cpanfile,因为它的格式略有不同:
cpanfile 格式 cpan.txt 格式 需要 'cpan::mod';
cpan::mod
需要"Dancer";
Dancer
需要 'YAML';
YAML
删除 .openshift 目录
注意在 v3 中,action_hooks 和 cron 任务的支持方式不同。如需更多信息,请参阅 Action Hook。
-
使用
oc
命令从构建器镜像和源代码中启动新的 Perl 应用程序:
$ oc new-app https://github.com/<github-id>/<repo-name>.git
支持的 Perl 版本
v2 | v3 |
---|---|
Perl:5.10 | |
dancer-mysql-example(Quickstart) |
6.3.6. Node.js
设置新的 GitHub 存储库,并将它作为远程分支添加到当前本地 Git 存储库:
$ git remote add <remote-name> https://github.com/<github-id>/<repo-name>
将本地 v2 源代码推送到新存储库:
$ git push -u <remote-name> master
编辑本地 Git 存储库并推送上游更改,使其与 v3 兼容:
删除 .openshift 目录。
注意在 v3 中,action_hooks 和 cron 任务的支持方式不同。如需更多信息,请参阅 Action Hook。
编辑 server.js。
- L116 server.js: 'self.app = express();'
- L25 server.js: self.ipaddress = '0.0.0.0';
L26 server.js: self.port = 8080;
注意行(L)来自基础 V2 cartridge server.js。
使用
oc
命令从构建器镜像和源代码中启动新的 Node.js 应用程序:$ oc new-app https://github.com/<github-id>/<repo-name>.git --name=<app-name> -e <ENV_VAR_NAME>=<env_var_value>
支持的 Node.js 版本
v2 | v3 |
---|---|
Node.js 0.10 | |
nodejs-mongodb-example。此快速入门模板只支持 Node.js 版本 6。 |
6.3.7. WordPress
目前,迁移 WordPress 应用程序的支持仅由社区提供,而不受红帽支持提供。
有关将 WordPress 应用程序迁移到 OpenShift Container Platform v3 的指南,请参阅 OpenShift 博客。
6.3.8. Ghost
目前,对迁移 Ghost 应用程序的支持仅由社区提供,而不受红帽支持。
有关将 Ghost 应用程序迁移到 OpenShift Container Platform v3 的指导,请参阅 OpenShift 博客。
6.3.9. JBoss EAP
设置新的 GitHub 存储库,并将它作为远程分支添加到当前本地 Git 存储库:
$ git remote add <remote-name> https://github.com/<github-id>/<repo-name>
将本地 v2 源代码推送到新存储库:
$ git push -u <remote-name> master
- 如果存储库包含预构建的 .war 文件,它们需要驻留在存储库的根目录的 deployments 目录中。
使用 JBoss EAP 7 构建器镜像(jboss-eap70-openshift)和来自 GitHub 的源代码存储库创建新应用:
$ oc new-app --strategy=source jboss-eap70-openshift:1.6~https://github.com/<github-id>/<repo-name>.git
6.3.10. JBoss WS(Tomcat)
设置新的 GitHub 存储库,并将它作为远程分支添加到当前本地 Git 存储库:
$ git remote add <remote-name> https://github.com/<github-id>/<repo-name>
将本地 v2 源代码推送到新存储库:
$ git push -u <remote-name> master
- 如果存储库包含预构建的 .war 文件,它们需要驻留在存储库的根目录的 deployments 目录中。
使用 JBoss Web 服务器 3(Tomcat 7)构建器镜像(jboss-webserver30-tomcat7)和来自 GitHub 的源代码存储库创建新应用程序:
$ oc new-app --strategy=source jboss-webserver30-tomcat7-openshift~https://github.com/<github-id>/<repo-name>.git --name=<app-name> -e <ENV_VAR_NAME>=<env_var_value>
6.3.11. JBoss AS (Wildfly 10)
设置新的 GitHub 存储库,并将它作为远程分支添加到当前本地 Git 存储库:
$ git remote add <remote-name> https://github.com/<github-id>/<repo-name>
将本地 v2 源代码推送到新存储库:
$ git push -u <remote-name> master
编辑本地 Git 存储库并推送上游更改,使其与 v3 兼容:
删除 .openshift 目录。
注意在 v3 中,action_hooks 和 cron 任务的支持方式不同。如需更多信息,请参阅 Action Hook。
- 将 deployments 目录添加到源存储库的根目录中。将 .war 文件移到 'deployments' 目录。
使用
oc
命令从构建器镜像和源代码中启动新的 Wildfly 应用程序:$ oc new-app https://github.com/<github-id>/<repo-name>.git --image-stream=”openshift/wildfly:10.0" --name=<app-name> -e <ENV_VAR_NAME>=<env_var_value>
注意参数
--name
是可选的,用于指定应用程序的名称。参数-e
是可选的,可添加构建和部署流程所需的环境变量,如OPENSHIFT_PYTHON_DIR
。
6.3.12. 支持的 JBoss 版本
v2 | v3 |
---|---|
JBoss App Server 7 | |
Tomcat 6(JBoss EWS 1.0) | |
Tomcat 7(JBoss EWS 2.0) | |
Vert.x 2.1 | |
WildFly App Server 10 | |
WildFly App Server 8.2.1.Final | |
WildFly App Server 9 | |
CapeDwarf | |
JBoss Data Virtualization 6 | |
JBoss Enterprise App Platform(EAP)6 | |
JBoss Unified Push Server 1.0.0.Beta1, Beta2 | |
JBoss BPM 套件 | |
JBoss BRMS | |
jboss-eap70-openshift:1.3-Beta | |
eap64-https-s2i | |
eap64-mongodb-persistent-s2i | |
eap64-mysql-persistent-s2i | |
eap64-psql-persistent-s2i |
6.4. Quickstart 示例
6.4.1. 概述
虽然 v2 quickstart to v3 Quickstart 没有清晰的迁移路径,但 v3 当前有以下快速入门。如果您的应用程序带有数据库,而不是使用 oc new-app
创建应用程序,则 oc new-app
会再次启动一个单独的数据库服务并使用通用环境变量将这两个应用程序链接到一起,您可以使用以下方法一次性从包含您的源代码的 GitHub 存储库中实例化链接的应用程序和数据库。您可以使用 oc get templates -n openshift
列出所有可用模板:
CakePHP MySQL https://github.com/sclorg/cakephp-ex
- template: cakephp-mysql-example
Node.js MongoDB https://github.com/sclorg/nodejs-ex
- template: nodejs-mongodb-example
Django PosgreSQL https://github.com/sclorg/django-ex
- template: django-psql-example
Dancer MySQL https://github.com/sclorg/dancer-ex
- template: dancer-mysql-example
Rails PostgreSQL https://github.com/sclorg/rails-ex
- template: rails-postgresql-example
6.4.2. 工作流
本地运行上述模板 URL 的 git clone
。添加并提交应用程序源代码并推送 GitHub 存储库,然后从上面列出的其中一个模板启动 v3 Quickstart 应用程序:
- 为您的应用程序创建 GitHub 存储库。
克隆快速入门模板,并将 GitHub 存储库添加为远程:
$ git clone <one-of-the-template-URLs-listed-above> $ cd <your local git repository> $ git remote add upstream <https://github.com/<git-id>/<quickstart-repo>.git> $ git push -u upstream master
将您的源代码提交并推送到 GitHub:
$ cd <your local repository> $ git commit -am “added code for my app” $ git push origin master
在 v3 中创建一个新应用程序:
$ oc new-app --template=<template> \ -p SOURCE_REPOSITORY_URL=<https://github.com/<git-id>/<quickstart_repo>.git> \ -p DATABASE_USER=<your_db_user> \ -p DATABASE_NAME=<your_db_name> \ -p DATABASE_PASSWORD=<your_db_password> \ -p DATABASE_ADMIN_PASSWORD=<your_db_admin_password> 1
- 1
- 仅适用于 MongoDB。
您现在应该有 2 个 pod 运行、Web 框架 Pod 和数据库 Pod。Web 框架 pod 环境应当与数据库 pod 环境匹配。您可以使用
oc set env pod/<pod_name> --list
列出环境变量:-
DATABASE_NAME
现在为<DB_SERVICE>_DATABASE
-
DATABASE_USER
现在是<DB_SERVICE>_USER
-
DATABASE_PASSWORD
现在为<DB_SERVICE>_PASSWORD
DATABASE_ADMIN_PASSWORD
现在是MONGODB_ADMIN_PASSWORD
(仅适用于 MongoDB)如果没有指定
SOURCE_REPOSITORY_URL
,该模板将使用上面列出的模板 URL(https://github.com/openshift/<quickstart>-ex)作为源存储库,并且将 hello-welcome 应用启动。
-
如果您要迁移数据库,请将数据库导出到转储文件,并在新的 v3 数据库 pod 中恢复数据库。请参阅 Database Applications 中介绍的步骤,跳过
oc new-app
步骤,因为数据库 pod 已启动并在运行。
6.5. 持续集成和部署(CI/CD)
6.5.1. 概述
本节回顾 OpenShift 版本 2(v2)和 OpenShift 版本 3(v3)之间的持续集成和部署(CI/CD)应用的不同,以及如何将这些应用程序迁移到 v3 环境中。
6.5.2. Jenkins
OpenShift 版本 2(v2)和 OpenShift 版本 3(v3)中的 Jenkins 应用会因为架构中的基本差异而进行不同的配置。例如,在 v2 中,应用程序使用托管在 gear 中的集成 Git 存储库来存储源代码。在 v3 中,源代码位于托管在 pod 之外的公共或私有 Git 存储库中。
另外,在 OpenShift v3 中,Jenkins 作业只能被源代码更改触发,还由 ImageStream 中的更改,后者会更改用于构建应用的镜像及其源代码。因此,强烈建议您通过在 v3 中创建新的 Jenkins 应用来手动迁移 Jenkins 应用,然后使用适合 OpenShift v3 环境的配置重新创建作业。
请参考这些资源以了解有关如何创建 Jenkins 应用程序、配置作业和正确使用 Jenkins 插件的更多信息:
6.6. Webhook 和 Action Hook
6.6.1. 概述
本节回顾 OpenShift 版本 2(v2)和 OpenShift 版本 3(v3)之间的 webhook 和操作 hook,以及如何将这些应用迁移到 v3 环境中。
6.6.2. Webhook
从 GitHub 存储库创建
BuildConfig
后,请运行:$ oc describe bc/<name-of-your-BuildConfig>
这将输出一个 Webhook GitHub URL,如下所示:
<https://api.starter-us-east-1.openshift.com:443/oapi/v1/namespaces/nsname/buildconfigs/bcname/webhooks/secret/github>.
- 从 GitHub Web 控制台将此 URL 剪切并粘贴到 GitHub 中。
- 在 GitHub 存储库中,从 Settings → Webhooks & Services 中选择 Add Webhook。
- 将 URL 输出(与上方相似)粘贴到 Payload URL 字段。
-
将 Content Type 设置为
application/json
。 - 点击 Add webhook。
您应该看到一条来自 GitHub 的消息,说明您的 Webhook 已配置成功。
现在,每当您将更改推送到 GitHub 存储库时,新构建会自动启动,成功构建后也会启动新部署。
如果删除或重新创建应用程序,您必须使用新的 BuildConfig
webhook url 更新 GitHub 中的 Payload URL 字段。
6.6.3. 操作 Hook
在 OpenShift 版本 2(v2)中,有构建、部署、post_deploy 和 pre_build 脚本或 action_hooks 位于 .openshift/action_hooks 目录中。虽然 v3 中没有适用于这些功能的一个一对一映射,但 v3 中的 S2I 工具有添加可自定义脚本的选项,在指定的 URL 或您的源存储库的 .s2i/bin 目录中。
OpenShift 版本 3(v3)还提供 post-build hook,用于运行镜像构建后镜像的基本测试,然后再推送到 registry。部署 hook 在部署配置中配置。
在 v2 中,action_hooks 通常用于设置环境变量。在 v2 中,任何环境变量都应该传递:
$ oc new-app <source-url> -e ENV_VAR=env_var
或:
$ oc new-app <template-name> -p ENV_VAR=env_var
另外,也可使用以下方法添加或更改环境变量:
$ oc set env dc/<name-of-dc> ENV_VAR1=env_var1 ENV_VAR2=env_var2’
6.7. S2I 工具
6.7.1. 概述
Source-to-Image(S2I)工具将应用源代码注入到容器镜像中,最终产品是一个新的、可直接运行的容器镜像,它融合了构建器镜像和构建的源代码。S2I 工具可以安装到本地机器上,而没有来自存储库的 OpenShift Container Platform。
S2I 工具是一个非常强大的工具,用于在 OpenShift Container Platform 上使用应用程序之前在本地测试和验证应用程序和镜像。
6.7.2. 创建容器镜像
- 识别应用所需的构建器镜像。红帽为不同的语言提供多个构建器镜像,包括 Python、Ruby、Perl、PHP 和 Node.js。其他镜像可从社区空间获取。
S2I 可以从本地文件系统中的源代码或从 Git 存储库构建镜像。从构建器镜像和源代码构建新容器镜像:
$ s2i build <source-location> <builder-image-name> <output-image-name>
注意<source-location>
可以是 Git 存储库 URL,也可以是本地文件系统中源代码的目录。使用 Docker 守护进程测试构建的镜像:
$ docker run -d --name <new-name> -p <port-number>:<port-number> <output-image-name> $ curl localhost:<port-number>
- 将新镜像推送到 OpenShift registry。
使用
oc
命令从 OpenShift registry 中的镜像创建新应用程序:$ oc new-app <image-name>
6.8. 支持指南
6.8.1. 概述
本主题回顾了 OpenShift 版本 2(v2)和 OpenShift 版本 3(v3)支持的语言、框架、数据库和标记。
如需有关 OpenShift Container Platform 客户使用的通用组合的更多信息,请参阅 OpenShift Container Platform 测试的集成。
6.8.2. 支持的数据库
请参阅 Database Applications 的支持的 Databases 部分。
6.8.3. 支持的语言
6.8.4. 支持的框架
v2 | v3 |
---|---|
Jenkins 服务器 | jenkins-persistent |
Drupal 7 | |
Ghost 0.7.5 | |
WordPress 4 | |
Ceylon | |
Go | |
MEAN |
6.8.5. 支持的标记
v2 | v3 |
---|---|
pip_install | 如果您的存储库包含 requirements.txt,则默认调用 pip。否则,不使用 pip。 |
v2 | v3 |
---|---|
disable_asset_compilation |
这可以通过在 buildconfig 策略定义中将 |
v2 | v3 |
---|---|
enable_cpan_tests |
这可以通过在构建配置中将 |
v2 | v3 |
---|---|
use_composer | 如果源存储库在根目录中包含 composer.json,则始终使用 Composer。 |
v2 | v3 |
---|---|
NODEJS_VERSION | N/A |
use_npm |
npm 总是用于启动应用程序,除非将 |
v2 | v3 |
---|---|
enable_debugging |
这个选项通过设置部署配置上设置的 |
skip_maven_build | 如果存在 pom.xml,则会运行 maven。 |
java7 | N/A |
java8 | JavaEE 使用 JDK8。 |
v2 | v3 |
---|---|
enable_debugging | N/A |
v2 | v3 |
---|---|
force_clean_build | v3 中有一个类似的概念,因为 buildconfig 中的 noCache 字段会强制容器构建重新运行每个层。在 S2I 构建中,incremental 标记默认为 false,这代表 清理构建。 |
hot_deploy | |
enable_public_server_status | N/A |
disable_auto_scaling | 在默认情况下,自动缩放功能可以通过 pod 自动扩展来开启。 |
6.8.6. 支持的环境变量
第 7 章 教程
7.1. 概述
本节组包含如何在 OpenShift Container Platform 中启动并运行应用程序的信息,涵盖了不同的语言及其框架。
7.2. Quickstart 模板
7.2.1. 概述
快速入门是 OpenShift Container Platform 上运行的应用程序的基本示例。Quickstarts 提供多种语言和框架,并在模板中定义,模板由一组服务、构建配置和部署配置组成。该模板引用了构建和部署应用程序所需的镜像和源存储库。
要探索快速入门,请从模板创建应用程序。您的管理员可能已在您的 OpenShift Container Platform 集群中安装了这些模板,在这种情况下,您只需从 web 控制台中选择即可。有关如何上传、从中创建和修改 模板 的更多信息,请参阅模板文档。
Quickstarts 是指包含应用程序源代码的源存储库。要自定义 Quickstart,请分叉存储库,并在从模板创建应用程序时,用分叉的存储库替换默认的源存储库名称。这将导致使用您的源代码而非所提供的示例源来执行构建。然后,您可以更新源存储库中的代码,并启动新的构建来查看反映在所部署的应用程序中的更改。
7.2.2. Web 框架 Quickstart 模板
这些快速入门提供了指定框架和语言的基本应用程序:
7.3. Ruby on Rails
7.3.1. 概述
Ruby on Rails 是使用 Ruby 编写的流行 web 框架。本指南介绍在 OpenShift Container Platform 上使用 Rails 4。
我们强烈建议您完成整个教程,以概述在 OpenShift Container Platform 上运行应用程序所需的所有步骤。如果遇到问题,请尝试通读整个教程,然后再回看问题。该教程还可用于审查您之前采取的步骤,以确保正确执行了所有步骤。
对于本指南,您需要:
- 基本 Ruby/Rails 知识
- 本地安装的 Ruby 2.0.0+ 版本、Rubygems、Bundler
- 基本的 Git 知识
- 运行 OpenShift Container Platform v3 实例
7.3.2. 本地工作站设置
首先,确保 OpenShift Container Platform 实例正在运行且可用。有关如何启动并运行 OpenShift Container Platform 的更多信息,请检查 安装方法。另外,确保已安装 oc
CLI 客户端,且可从命令 shell 访问命令,因此您可以使用您的电子邮件地址和密码使用它来 登录。
7.3.2.1. 设置数据库
Rails 应用程序几乎总是与数据库一同使用。对于本地开发,我们选择 PostgreSQL 数据库。要安装:
$ sudo yum install -y postgresql postgresql-server postgresql-devel
接下来,您需要使用以下方法初始化数据库:
$ sudo postgresql-setup initdb
该命令将创建 /var/lib/pgsql/data
目录,数据将存储在其中。
通过键入以下内容启动数据库:
$ sudo systemctl start postgresql.service
数据库运行时,创建 rails
用户:
$ sudo -u postgres createuser -s rails
请注意,我们创建的用户没有密码。
7.3.3. 编写应用程序
如果您要从头开始启动 Rails 应用程序,则需要首先安装 Rails gem。
$ gem install rails Successfully installed rails-4.2.0 1 gem installed
安装完 Rails gem 后,使用 PostgreSQL 创建一个新应用程序,作为数据库:
$ rails new rails-app --database=postgresql
然后,更改到您的新应用目录。
$ cd rails-app
如果您已有应用程序,请确保 Gemfile
中存在 pg
(postgresql) gem。如果没有通过添加 gem 来编辑 Gemfile
:
gem 'pg'
使用您的所有依赖项生成一个新的 Gemfile.lock
:
$ bundle install
除了将 postgresql
数据库与 pg
gem 结合使用外,还需要确保 config/database.yml
正在使用 postgresql
适配器。
请确保更新了 config/database.yml
文件中的 default
部分,如下所示:
default: &default adapter: postgresql encoding: unicode pool: 5 host: localhost username: rails password:
使用此 rake
命令创建应用程序的开发和测试数据库:
$ rake db:create
这将在您的 PostgreSQL 服务器中创建 development
和 test
数据库。
7.3.3.1. 创建欢迎页面
由于 Rails 4 在生产中不再提供静态 public/index.html
页面,因此我们需要创建一个新的 root 页面。
要具有自定义欢迎页面,需要执行以下步骤:
- 使用索引操作创建 controller
-
为
welcome
控制器index
操作创建 view 页面 - 使用所创建的 controller 和 view 创建一个提供应用程序 root 页面的 route
Rails 提供了一个生成器,可为您执行所有必要的步骤。
$ rails generate controller welcome index
现在,已创建所有必需的文件,现在只需要在 config/routes.rb
文件中编辑行 2,如下所示:
root 'welcome#index'
运行 rails 服务器以验证页面是否可用。
$ rails server
在浏览器中访问 http://localhost:3000 即可查看您的页面。如果没有看到该页面,请检查输出至服务器的日志进行调试。
7.3.3.2. 为 OpenShift Container Platform 配置应用程序
要让您的应用程序与将在 OpenShift Container Platform 中运行的 PostgreSQL 数据库服务通信,您需要编辑 config/database.yml
中的 default
部分,以便在创建数据库服务时使用环境变量。
您编辑的 config/database.yml
中的 default
部分和预定义的变量应类似于如下:
<% user = ENV.key?("POSTGRESQL_ADMIN_PASSWORD") ? "root" : ENV["POSTGRESQL_USER"] %> <% password = ENV.key?("POSTGRESQL_ADMIN_PASSWORD") ? ENV["POSTGRESQL_ADMIN_PASSWORD"] : ENV["POSTGRESQL_PASSWORD"] %> <% db_service = ENV.fetch("DATABASE_SERVICE_NAME","").upcase %> default: &default adapter: postgresql encoding: unicode # For details on connection pooling, see rails configuration guide # http://guides.rubyonrails.org/configuring.html#database-pooling pool: <%= ENV["POSTGRESQL_MAX_CONNECTIONS"] || 5 %> username: <%= user %> password: <%= password %> host: <%= ENV["#{db_service}_SERVICE_HOST"] %> port: <%= ENV["#{db_service}_SERVICE_PORT"] %> database: <%= ENV["POSTGRESQL_DATABASE"] %>
有关最终文件应该如何查找的示例,请参阅 Ruby on Rails 示例应用程序 config/database.yml。
7.3.3.3. 将应用程序存储在 Git 中
如果您尚未安装 OpenShift Container Platform,则需要安装 git。
在 OpenShift Container Platform 中构建应用程序通常需要将源代码存储在 git 存储库中,因此如果您还没有 git
,则需要安装 git。
运行 ls -1
命令,确保已在 Rails 应用程序目录中。命令输出应类似于:
$ ls -1 app bin config config.ru db Gemfile Gemfile.lock lib log public Rakefile README.rdoc test tmp vendor
现在,在 Rails 应用程序目录中运行这些命令以初始化代码并将其提交给 git:
$ git init $ git add . $ git commit -m "initial commit"
提交应用程序后,您需要将其推送(push)到远程存储库。为此,您将需要一个 GitHub 帐户,用于 创建新存储库。
设置指向 git
存储库的远程存储库:
$ git remote add origin git@github.com:<namespace/repository-name>.git
之后,将应用程序推送到远程 git 存储库。
$ git push
7.3.4. 将应用程序部署到 OpenShift Container Platform
要部署 Ruby on Rails 应用程序,为应用程序创建一个新项目:
$ oc new-project rails-app --description="My Rails application" --display-name="Rails Application"
创建 rails-app
项目 后,您将自动切换到新的项目命名空间。
在 OpenShift Container Platform 中部署应用程序涉及三个步骤:
- 从 OpenShift Container Platform 的 PostgreSQL 镜像创建数据库服务。
- 从 OpenShift Container Platform 的 Ruby 2.0 构建器镜像和用来与数据库服务进行连接的 Ruby on Rails 源代码创建一个前端 service
- 为应用程序创建路由。
7.3.4.1. 创建数据库服务
您的 Rails 应用程序需要一个正在运行的 数据库服务。对于此服务,请使用 PostgeSQL 数据库镜像。
要创建 数据库服务,请使用 oc new-app 命令。您必须将一些要在数据库容器内使用的必要环境变量传递给此命令。设置用户名、密码和数据库名称需要这些环境变量。您可随意更改这些环境变量的值。我们将设置的变量如下:
- POSTGRESQL_DATABASE
- POSTGRESQL_USER
- POSTGRESQL_PASSWORD
设置这些变量可确保:
- 存在具有指定名称的数据库
- 存在具有指定名称的用户
- 用户可以使用指定密码访问指定数据库
例如:
$ oc new-app postgresql -e POSTGRESQL_DATABASE=db_name -e POSTGRESQL_USER=username -e POSTGRESQL_PASSWORD=password
若也要为数据库管理员设置密码,请将以下内容附加至上一命令中:
-e POSTGRESQL_ADMIN_PASSWORD=admin_pw
监控这个命令的进度:
$ oc get pods --watch
7.3.4.2. 创建 Frontend 服务
要将应用程序添加到 OpenShift Container Platform 中,您需要再次使用 oc new-app
命令指定应用程序所处的存储库,该仓库需要在创建数据库服务中设置数据库相关的环境变量 :
$ oc new-app path/to/source/code --name=rails-app -e POSTGRESQL_USER=username -e POSTGRESQL_PASSWORD=password -e POSTGRESQL_DATABASE=db_name -e DATABASE_SERVICE_NAME=postgresql
通过此命令,OpenShift Container Platform 会获取源代码,设置构建器镜像,构建应用程序镜像,并将新创建的镜像与 指定的环境变量 一起部署。该应用程序命名为 rails-app
。
您可以通过查看 rails-app
DeploymentConfig 的 JSON 文档来验证环境变量是否已添加:
$ oc get dc rails-app -o json
您应看到以下部分:
env": [ { "name": "POSTGRESQL_USER", "value": "username" }, { "name": "POSTGRESQL_PASSWORD", "value": "password" }, { "name": "POSTGRESQL_DATABASE", "value": "db_name" }, { "name": "DATABASE_SERVICE_NAME", "value": "postgresql" } ],
检查构建过程:
$ oc logs -f build/rails-app-1
构建完成后,您可以查看 OpenShift Container Platform 中运行的 pod。
$ oc get pods
您应看到其中一行命令以 myapp-<number>-<hash>
开头,这是您在 OpenShift Container Platform 中运行的应用程序。
在应用程序正常工作前,您需要通过运行数据库迁移脚本来初始化数据库。具体可通过两种方式实现:
- 从正在运行的前端容器手动实现:
首先,您需要使用 rsh 命令执行到 frontend 容器:
$ oc rsh <FRONTEND_POD_ID>
从容器内部运行迁移:
$ RAILS_ENV=production bundle exec rake db:migrate
如果在 development
或 test
环境中运行 Rails 应用程序,则不必指定 RAILS_ENV
环境变量。
7.3.4.3. 为您的应用程序创建路由
要通过向服务提供外部可访问的主机名(如 www.example.com
)来公开服务,请使用 OpenShift Container Platform 路由。对于您的情况,需要通过键入以下命令来公开前端服务:
$ oc expose service rails-app --hostname=www.example.com
这是用户的责任来确保它们指定的主机名解析为路由器的 IP 地址。如需更多信息,请参阅 OpenShift Container Platform 文档:
7.4. 为 Maven 设置 Nexus 镜像
7.4.1. 简介
使用 Java 和 Maven 开发应用时,您很可能会构建多次。为了缩短容器集的构建时间,可将 Maven 依赖项缓存在本地 Nexus 存储库中。本教程将指导您在群集上创建 Nexus 存储库。
本教程假设您正在处理已经设置用于 Maven 的项目。如果您有兴趣将 Maven 与 Java 项目搭配使用,则强烈建议您查阅 其指南。
另外,请确定检查应用程序的镜像以获取 Maven 镜像功能。使用 Maven 的许多镜像都有 MAVEN_MIRROR_URL
环境变量,可用于简化此过程。如果它没有这一功能,请阅读 Nexus 文档 以正确配置您的构建。
另外,请确保为每个 pod 有足够的资源才能正常工作。您可能必须 编辑 Nexus 部署配置中的 Pod 模板,以请求更多资源。
7.4.2. 设置 Nexus
下载并部署官方 Nexus 容器镜像:
oc new-app sonatype/nexus
通过公开新创建的 Nexus 服务来创建路由:
oc expose svc/nexus
使用 oc get routes 查找 pod 的新外部地址。
oc get routes
输出应类似:
NAME HOST/PORT PATH SERVICES PORT TERMINATION nexus nexus-myproject.192.168.1.173.xip.io nexus 8081-tcp
- 通过导航到 HOST/PORT 下的 URL,以确认 Nexus 正在运行。若要登录 Nexus,默认的管理员用户名是 admin,密码则为 admin123。
Nexus 预配置了中央存储库,但您可能需要其他应用程序。对于许多红帽镜像,建议在 Maven 存储库中添加 jboss-ga 存储库。
7.4.2.1. 使用探测检查成功
这是设置 就绪度和存活度探测 的良好时机。这些将定期检查以查看 Nexus 是否正确运行。
$ oc set probe dc/nexus \ --liveness \ --failure-threshold 3 \ --initial-delay-seconds 30 \ -- echo ok $ oc set probe dc/nexus \ --readiness \ --failure-threshold 3 \ --initial-delay-seconds 30 \ --get-url=http://:8081/nexus/content/groups/public
7.4.2.2. 在 Nexus 中添加持久性
如果您不想持久存储,请继续 连接到 Nexus。但是,因为任何原因,您的缓存的依赖项和任何配置自定义都会丢失。
为 Nexus 创建持久卷声明(PVC),以便在运行服务器的容器集终止时不会丢失缓存的依赖项。PVC 需要集群中的可用持久性卷(PV)。如果没有 PV 可用,且您没有集群中的管理员访问权限,请系统管理员为您创建 Read/Write 持久性卷。
否则 ,请参阅 OpenShift Container Platform 中的持久性存储部分。
在 Nexus 部署配置中添加 PVC。
$ oc set volume dc/nexus --add \ --name 'nexus-volume-1' \ --type 'pvc' \ --mount-path '/sonatype-work/' \ --claim-name 'nexus-pv' \ --claim-size '1G' \ --overwrite
这会移除之前用于部署配置的 emptyDir 卷,并为挂载于 /sonatype-work
的 1GB 持久性存储添加一个声明(即存储依赖项的位置)。由于配置更改,Nexus 容器集将自动重新部署。
要验证 Nexus 是否正在运行,请在浏览器中刷新 Nexus 页面。您可以使用以下方法监控部署的进度:
$ oc get pods -w
7.4.3. 连接到 Nexus
后续步骤中演示定义使用新的 Nexus 存储库的构建。教程的其余部分将这个示例存储库 与 wildfly-100-centos7 一起用作构建器,但这些更改应该可用于任何项目。
示例构建器镜像 支持 MAVEN_MIRROR_URL
作为其环境的一部分,因此我们可以使用此 将构建器镜像指向我们的 Nexus 存储库。如果您的镜像不支持使用环境变量来配置 Maven 镜像,您可能需要修改构建器镜像,以提供正确的 Maven 设置以指向 Nexus 镜像。
$ oc new-build openshift/wildfly-100-centos7:latest~https://github.com/openshift/jee-ex.git \ -e MAVEN_MIRROR_URL='http://nexus.<Nexus_Project>:8081/nexus/content/groups/public' $ oc logs build/jee-ex-1 --follow
将 <Nexus_Project>
替换为 Nexus 存储库的项目名称。如果该项目与正在使用的应用程序位于同一个项目中,您可以删除 <Nexus_Project>.
。在 OpenShift Container Platform 中了解更多有关 DNS 解析的信息。
7.4.4. 确认是否成功
在 Web 浏览器中,导航到 http://<NexusIP>:8081/nexus/content/groups/public,以确认它已存储了应用程序的依赖项。您还可以检查构建日志,以查看 Maven 是否使用 Nexus 镜像。如果成功,您应该会看到引用 URL http://nexus:8081 的输出。
7.4.5. 其它资源
7.5. OpenShift Pipeline 构建
7.5.1. 简介
无论您创建简单的网站还是复杂的微服务 Web,请使用 OpenShift Pipelines 在 OpenShift 中构建、测试、部署和推进您的应用程序。
除了标准的 Jenkins 管道语法外,OpenShift Jenkins 镜像还提供 OpenShift 域特定语言(DSL)(通过 OpenShift Jenkins 客户端插件),其旨在提供易读、简洁、全面和流畅的语法,以便与 OpenShift API 服务器进行丰富的交互,甚至能更好地控制 OpenShift 集群上的应用程序的构建、部署和推广。
本例演示如何创建 OpenShift Pipeline,以使用 nodejs-mongodb.json
模板构建、部署和验证 Node.js/MongoDB
应用程序。
7.5.2. 创建 Jenkins Master
要创建 Jenkins master,请运行:
$ oc project <project_name> 1 $ oc new-app jenkins-ephemeral 2
如果在集群中启用了 Jenkins 自动配置,您不需要对 Jenkins master 进行任何自定义,您可以跳过上一步。
有关 Jenkins 自动置备的更多信息,请参阅配置管道执行。
7.5.3. Pipeline 构建配置
现在 Jenkins master 已启动并运行,请创建一个 BuildConfig,它将使用 Jenkins Pipeline 策略来构建、部署和扩展 Node.js/MongoDB
示例应用程序。
使用以下内容,创建名为 nodejs-sample-pipeline.yaml 的文件:
kind: "BuildConfig" apiVersion: "v1" metadata: name: "nodejs-sample-pipeline" spec: strategy: jenkinsPipelineStrategy: jenkinsfile: <pipeline content from below> type: JenkinsPipeline
有关配置 Pipeline 构建策略的更多信息,请参阅 Pipeline 策略选项。
7.5.4. Jenkinsfile
使用 jenkinsPipelineStrategy
创建 BuildConfig 后,通过使用内联 jenkinsfile
告知管道做什么。本例没有为应用程序设置 Git 存储库。
以下 jenkinsfile
内容使用 OpenShift DSL 以 Groovy 语言编写。在本例中,请使用 YAML Literal Style 在 BuildConfig 中包含内联内容,但首选的方法是使用源存储库中的 jenkinsfile
。
完成的 BuildConfig 可以在示例目录 nodejs-sample-pipeline.yaml
中的 OpenShift Origin 存储库中查看。
def templatePath = 'https://raw.githubusercontent.com/openshift/nodejs-ex/master/openshift/templates/nodejs-mongodb.json' 1 def templateName = 'nodejs-mongodb-example' 2 pipeline { agent { node { label 'nodejs' 3 } } options { timeout(time: 20, unit: 'MINUTES') 4 } stages { stage('preamble') { steps { script { openshift.withCluster() { openshift.withProject() { echo "Using project: ${openshift.project()}" } } } } } stage('cleanup') { steps { script { openshift.withCluster() { openshift.withProject() { openshift.selector("all", [ template : templateName ]).delete() 5 if (openshift.selector("secrets", templateName).exists()) { 6 openshift.selector("secrets", templateName).delete() } } } } } } stage('create') { steps { script { openshift.withCluster() { openshift.withProject() { openshift.newApp(templatePath) 7 } } } } } stage('build') { steps { script { openshift.withCluster() { openshift.withProject() { def builds = openshift.selector("bc", templateName).related('builds') timeout(5) { 8 builds.untilEach(1) { return (it.object().status.phase == "Complete") } } } } } } } stage('deploy') { steps { script { openshift.withCluster() { openshift.withProject() { def rm = openshift.selector("dc", templateName).rollout().latest() timeout(5) { 9 openshift.selector("dc", templateName).related('pods').untilEach(1) { return (it.object().status.phase == "Running") } } } } } } } stage('tag') { steps { script { openshift.withCluster() { openshift.withProject() { openshift.tag("${templateName}:latest", "${templateName}-staging:latest") 10 } } } } } } }
- 1
- 要使用的模板的路径。
- 2
- 要创建的模板的名称。
- 3
- 启动
node.js
slave Pod,以运行此构建。 - 4
- 为此管道设置 20 分钟超时。
- 5
- 使用此模板标签删除所有内容。
- 6
- 使用此模板标签删除任何 secret。
- 7
- 从
templatePath
创建一个新应用程序。 - 8
- 等待最多五分钟以完成构建。
- 9
- 等待最多五分钟以完成部署。
- 10
- 如果其余部分都成功,则将
$ {templateName}:latest
镜像标记为$ {templateName}-staging:latest
。staging 环境的管道 BuildConfig 可以监控$ {templateName}-staging:latest
镜像更改,然后将其部署到 stage 环境中。
上例使用 declarative pipeline 风格编写,但较旧的 scripted pipeline 风格也受到支持。
7.5.5. 创建管道
您可以通过运行以下命令,在 OpenShift 集群中创建 BuildConfig:
$ oc create -f nodejs-sample-pipeline.yaml
如果您不想自行创建文件,可以通过运行以下命令来使用 Origin 存储库中的示例:
$ oc create -f https://raw.githubusercontent.com/openshift/origin/master/examples/jenkins/pipeline/nodejs-sample-pipeline.yaml
有关此处使用的 OpenShift DSL 语法的更多信息,请参阅 OpenShift Jenkins 客户端插件。
7.5.6. 启动管道
使用以下命令启动管道:
$ oc start-build nodejs-sample-pipeline
此外,也可以通过 OpenShift Web 控制台启动管道,方法是导航到 Builds → Pipeline 部分并点击 Start Pipeline,或者访问 Jenkins 控制台,再导航到您创建的管道并点击 Build Now。
管道启动之后,您应该看到项目中执行了以下操作:
- 在 Jenkins 服务器上创建了作业实例。
- 启动了 slave Pod(如果管道需要)。
管道在 slave Pod 上运行;如果不需要 slave,则管道在 master上运行。
-
将删除之前创建的具有
template=nodejs-mongodb-example
标签的所有资源。 -
从
nodejs-mongodb-example
模板创建一个新应用程序及其所有相关资源。 使用
nodejs-mongodb-example
BuildConfig 启动构建。- 管道将等待到构建完成后触发下一阶段。
使用
nodejs-mongodb-example
部署配置启动部署。- 管道将等待到部署完成后触发下一阶段。
-
如果构建和部署都成功,则
nodejs-mongodb-example:latest
镜像将标记为nodejs-mongodb-example:stage
。
-
将删除之前创建的具有
- slave Pod(如果管道过去需要)被删除。
视觉化管道执行的最佳方法是在 OpenShift Web 控制台中查看它。您可以通过登录到 web 控制台并导航到 Builds → Pipelines 来查看管道。
7.5.7. OpenShift Pipelines 的高级选项
使用 OpenShift Pipelines,您可以在一个项目中启动 Jenkins,然后让 OpenShift 同步插件监控开发人员在其中工作的一组项目。以下小节概述了完成此过程的步骤。
避免从运行 OpenShift 同步插件的多个 Jenkins 部署中监控同一项目。这些实例之间没有协调,可能会发生不可预测的结果。
7.6. 二进制构建
7.6.1. 简介
OpenShift 中的二进制构建功能使开发人员能够将源或工件直接上传到构建中,而不是从 Git 存储库 URL 中拉取源。任何带有 source、Docker 或 custom 的 BuildConfig 都可以作为二进制构建启动。从本地工件启动构建时,现有源引用将被替换为来自本地用户机器的源。
源可以通过几种方法提供,它们对应于使用 start-build 命令时可用的参数:
-
来自一个文件(
--from-file
):构建整个源都由一个文件组成,就会出现这种情况。例如,它可能是用于 Wildfly 构建的 Docker 构建、pom.xml
的Dockerfile
,或用于 Ruby 构建的Gemfile
。 -
来自一个目录(
--directory
):当源位于本地目录且未提交到 Git 存储库时,请使用此选项。start-build
命令将创建给定目录的存档,并将它上传到构建器,作为来源。 -
来自存档(
--from-archive
):当存档和源已存在时,请使用此选项。归档可以是tar
、tar.gz
或zip
格式。 -
来自 Git 存储库(
--from-repo
):这是用于当前用户本地计算机上的 Git 存储库一部分的源。当前存储库的 HEAD 提交将存档,并发送到 OpenShift 以进行构建。
7.6.1.1. 使用案例
二进制构建删除了构建从现有 Git 存储库拉取源的要求。使用二进制构建的原因包括:
- 构建和测试本地代码更改.可以从公共存储库中的源克隆,可以将本地更改上传到 OpenShift 中以进行构建。本地更改不必在任何位置提交或推送。
- 构建私有代码.新的构建可以从头开始作为二进制构建。然后源可以直接从本地工作站上传到 OpenShift,而无需将其签入到 SCM。
- 使用来自其他源的工件构建镜像。使用 Jenkins 管道时,二进制构建可用于将构建工件与 Maven 或 C 编译器等工具组合使用这些构建的运行时镜像。
7.6.1.2. 限制:
- 二进制构建不可重复。因为二进制构建需要用户在启动时上传工件,所以 OpenShift 无法重复同一构建,而无需用户每次都重复执行相同的上传。
- 无法自动触发二进制构建。只有当用户上传所需的二进制工件时,才能手动启动。
作为二进制构建启动的构建可能也具有配置的源 URL。如果是这种情况,触发器将成功启动构建,但源来自配置的源 URL,而不是用户上次运行构建时提供的源 URL。
7.6.2. 教程概述
以下教程假设您有一个可用的 OpenShift 集群,并且具有可在创建工件的项目。它需要在本地同时拥有 git
和 oc
。
7.6.2.1. 教程:构建本地代码更改
根据现有源存储库创建新应用,并为它创建路由:
$ oc new-app https://github.com/openshift/ruby-hello-world.git $ oc expose svc/ruby-hello-world
通过导航到路由的主机,等待初始构建完成并查看应用程序的页面。您应会收到欢迎页面:
$ oc get route ruby-hello-world
本地克隆存储库:
$ git clone https://github.com/openshift/ruby-hello-world.git $ cd ruby-hello-world
-
更改应用程序视图。使用您最喜欢的编辑器编辑
view/main.rb
:将<body>
标签更改为<body style="background-color:blue">
。 使用您的本地修改源启动新构建。在仓库的本地目录中运行:
---- $ oc start-build ruby-hello-world --from-dir="." --follow ----
构建完成后,应用程序重新部署后,导航到应用程序的路由主机会导致页面具有蓝色背景。
您可以在本地进行更改,并使用 oc start-build --from-dir
来构建代码。
您还可以创建代码分支,在本地提交更改,并使用存储库的 HEAD 作为构建的源:
$ git checkout -b my_branch $ git add . $ git commit -m "My changes" $ oc start-build ruby-hello-world --from-repo="." --follow
7.6.2.2. 教程:构建私有代码
创建存放您的代码的本地目录:
$ mkdir myapp $ cd myapp
在目录中,创建一个名为
Dockerfile
的文件,其内容如下:FROM centos:centos7 EXPOSE 8080 COPY index.html /var/run/web/index.html CMD cd /var/run/web && python -m SimpleHTTPServer 8080
创建名为
index.html
的文件,其内容如下:<html> <head> <title>My local app</title> </head> <body> <h1>Hello World</h1> <p>This is my local application</p> </body> </html>
为您的应用程序创建新构建:
$ oc new-build --strategy docker --binary --docker-image centos:centos7 --name myapp
使用本地目录的内容启动一个二进制构建:
$ oc start-build myapp --from-dir . --follow
使用
new-app
部署应用程序,然后为其创建路由:$ oc new-app myapp $ oc expose svc/myapp
获取路由的主机名并导航到它:
$ oc get route myapp
在构建并部署您的代码后,您可以通过调用 oc start-build myapp --from-dir
,对本地文件进行更改并启动新的构建。构建后,代码将被自动部署,当您刷新页面时,更改将会被反映到您的浏览器中。
7.6.2.3. 教程:来自管道的二进制工件
OpenShift 上的 Jenkins 允许在适当的工具中使用从属镜像来构建您的代码。例如,您可以使用 maven
slave 从代码存储库构建 WAR。但是,构建此工件后,您需要将其提交到包含运行代码的适当运行时工件的镜像。二进制构建可用于将这些工件添加到运行时镜像中。在以下教程中,我们将创建一个 Jenkins 管道,以使用 maven
slave 构建 WAR,然后使用带有 Dockerfile
的二进制构建将该 WAR 添加到 wildfly 运行时镜像中。
为您的应用程序创建新目录:
$ mkdir mavenapp $ cd mavenapp
创建一个
Dockerfile
,它将 WAR 复制到 wildfly 镜像内部的适当位置,以进行执行。将以下内容复制到名为Dockerfile
的本地文件中:FROM wildfly:latest COPY ROOT.war /wildfly/standalone/deployments/ROOT.war CMD $STI_SCRIPTS_PATH/run
为该 Dockerfile 创建新的 BuildConfig:
注意这将自动启动构建,该构建最初将失败,因为
ROOT.war
构件还不可用。以下管道将使用二进制构建将该 WAR 传递给构建。$ cat Dockerfile | oc new-build -D - --name mavenapp
使用 Jenkins 管道创建 BuildConfig,它将构建 WAR,然后使用该 WAR 使用之前创建的
Dockerfile
构建镜像。同一模式可用于由一组工具构建二进制工件的其他平台,然后与最终软件包的不同运行时镜像组合。将以下代码保存到mavenapp-pipeline.yml
:apiVersion: v1 kind: BuildConfig metadata: name: mavenapp-pipeline spec: strategy: jenkinsPipelineStrategy: jenkinsfile: |- pipeline { agent { label "maven" } stages { stage("Clone Source") { steps { checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [ [$class: 'RelativeTargetDirectory', relativeTargetDir: 'mavenapp'] ], userRemoteConfigs: [[url: 'https://github.com/openshift/openshift-jee-sample.git']] ]) } } stage("Build WAR") { steps { dir('mavenapp') { sh 'mvn clean package -Popenshift' } } } stage("Build Image") { steps { dir('mavenapp/target') { sh 'oc start-build mavenapp --from-dir . --follow' } } } } } type: JenkinsPipeline triggers: []
创建管道构建。如果 Jenkins 没有部署到项目中,使用管道创建 BuildConfig 将导致 Jenkins 部署。Jenkins 准备好构建管道前可能需要几分钟时间。您可以通过调用
oc rollout status dc/jenkins
检查 Jenkins rollout 的状态:$ oc create -f ./mavenapp-pipeline.yml
Jenkins 就绪后,启动前面定义的管道:
$ oc start-build mavenapp-pipeline
当管道完成构建后,使用 new-app 部署新应用程序并公开其路由:
$ oc new-app mavenapp $ oc expose svc/mavenapp
使用您的浏览器,进入应用程序的路由:
$ oc get route mavenapp
第 8 章 Builds
8.1. 构建如何工作
8.1.1. 什么是构建?
OpenShift Container Platform 中的 构建 是将输入参数转换为结果对象的过程。大多数情况下,构建用于将源代码转换为可运行的容器镜像。
构建配置或 BuildConfig
的特征就是构建策略和一个或多个源。策略决定上述过程,而源则提供输入。
构建策略有:
- Source-to-Image (S2I) (description, options)
- Pipeline (description, options)
- Docker (description, options)
- Custom (description, options)
有六种类型的源作为构建输入提供 :
每个构建策略最多可考虑或忽略特定类型的源,并确定要使用方法。Binary 和 Git 是互斥源类型。Dockerfile 和镜像可以单独单独使用,也可以与 Git 或 Binary 一起使用。Binary 源类型在 向系统指定选项中的其它选项 中是唯一的。
8.1.2. BuildConfig 是什么?
构建配置描述了单个构建定义,以及应该创建新构建时的一组 触发器。构建配置通过 BuildConfig
定义,它是一种 REST 对象,可在对 API 服务器的 POST 中使用以创建新实例。
根据您选择使用 OpenShift Container Platform 创建应用程序的方式,如果使用 Web 控制台或 CLI,通常会自动生成 BuildConfig
,并且可以随时对其进行编辑。如果选择稍后手动调整配置,则了解 BuildConfig
的组成部分及其可用选项可能会有所帮助。
以下示例 BuildConfig
在每次容器镜像标签或源代码改变时产生新的构建:
BuildConfig Object Definition
kind: "BuildConfig" apiVersion: "v1" metadata: name: "ruby-sample-build" 1 spec: runPolicy: "Serial" 2 triggers: 3 - type: "GitHub" github: secret: "secret101" - type: "Generic" generic: secret: "secret101" - type: "ImageChange" source: 4 git: uri: "https://github.com/openshift/ruby-hello-world" strategy: 5 sourceStrategy: from: kind: "ImageStreamTag" name: "ruby-20-centos7:latest" output: 6 to: kind: "ImageStreamTag" name: "origin-ruby-sample:latest" postCommit: 7 script: "bundle exec rake test"
- 1
- 此规格将创建一个名为 ruby-sample-build 的新
BuildConfig
。 - 2
runPolicy
字段控制从此构建配置创建的构建能否同时运行。默认值为Serial
,即新构建将按顺序运行,而不是同时运行。- 3
- 您可以指定导致创建新构建的触发器的列表。
- 4
source
部分定义构建的来源。源类型决定主要的输入源,可以是Git
(指向代码库存储位置)、Dockerfile
(从内联 Dockerfile 构建)或Binary
(接受二进制有效负载)。可以同时拥有多个源,请参考每种源类型的文档。- 5
strategy
部分描述用于执行构建的构建策略。您可以在此处指定Source
、Docker
或Custom
策略。上面的示例使用ruby-20-centos7
容器镜像,Source-To-Image 将用于应用程序构建。- 6
- 成功构建容器镜像后,它将被推送到
output
部分中描述的存储库。 - 7
postCommit
部分定义一个可选的 构建 hook。
8.2. 基本构建操作
8.2.1. 启动构建
使用以下命令,从当前项目中的现有构建配置手动启动新构建:
$ oc start-build <buildconfig_name>
使用 --from-build
标志重新运行构建:
$ oc start-build --from-build=<build_name>
指定 --follow
标志,在 stdout 中流传输构建日志:
$ oc start-build <buildconfig_name> --follow
指定 --env
标志来为构建设置任何所需的环境变量:
$ oc start-build <buildconfig_name> --env=<key>=<value>
您可以通过直接推送源来启动构建,而不依赖于 Git 源拉取或构建的 Dockerfile;源可以是 Git 或 SVN 工作目录的内容、您想要部署的一组预构建二进制工件,或者单个文件。这可以通过为 start-build
命令指定以下选项之一来完成:
选项 | 描述 |
---|---|
| 指定将要存档并用作构建的二进制输入的目录。 |
| 指定将成为构建源中唯一文件的单个文件。该文件放在空目录的根目录中,其文件名与提供的原始文件相同。 |
|
指定用作构建二进制输入的本地存储库的路径。添加 |
将任何这些选项直接传递给构建时,内容将流传输到构建中并覆盖当前的构建源设置。
从二进制输入触发的构建不会在服务器上保留源,因此基础镜像更改触发的重新构建将使用构建配置中指定的源。
例如,以下命令将发送本地 Git 存储库的内容作为标签 v2
的存档,再启动构建:
$ oc start-build hello-world --from-repo=../hello-world --commit=v2
8.2.2. 取消构建
使用 Web 控制台或以下 CLI 命令手动取消构建:
$ oc cancel-build <build_name>
同时取消多个构建:
$ oc cancel-build <build1_name> <build2_name> <build3_name>
取消从构建配置创建的所有构建:
$ oc cancel-build bc/<buildconfig_name>
取消给定状态下的所有构建(如 new 或 pending状态),忽略其他状态下的构建:
$ oc cancel-build bc/<buildconfig_name> --state=<state>
8.2.3. 删除 BuildConfig
使用以下命令删除 BuildConfig
:
$ oc delete bc <BuildConfigName>
这也会删除从此 BuildConfig
实例化的所有构建。如果您不想删除构建,请指定 --cascade=false
标志:
$ oc delete --cascade=false bc <BuildConfigName>
8.2.4. 查看构建详情
您可以使用 Web 控制台或 oc describe
CLI 命令查看构建详情:
$ oc describe build <build_name>
这将显示诸如以下信息:
- 构建源
- 构建策略
- 输出目的地
- 目标 registry 中的镜像摘要
- 构建的创建方式
如果构建采用 Docker
或 Source
策略,则 oc describe
输出还包括用于构建的源修订的相关信息,包括提交 ID、作者、提交者和消息等。
8.2.5. 访问构建日志
您可以使用 Web 控制台或 CLI 访问构建日志。
直接使用构建来流传输日志:
$ oc logs -f build/<build_name>
流传输构建配置的最新构建的日志:
$ oc logs -f bc/<buildconfig_name>
返回构建配置的给定版本构建的日志:
$ oc logs --version=<number> bc/<buildconfig_name>
日志详细程度
要启用更为详细的输出,请传递 BUILD_LOGLEVEL
环境变量作为 BuildConfig
中 sourceStrategy
或 dockerStrategy
的一部分:
sourceStrategy:
...
env:
- name: "BUILD_LOGLEVEL"
value: "2" 1
- 1
- 将此值调整为所需的日志级别。
平台管理员可以通过为 BuildDefaults
准入控制器配置 env/BUILD_LOGLEVEL
来设置整个 OpenShift Container Platform 实例的默认构建详细程度。此默认值可以通过在给定的 BuildConfig
中指定 BUILD_LOGLEVEL
来覆盖。您可以通过将 --build-loglevel
传递给 oc start-build
,在命令行中为非二进制构建指定优先级更高的覆盖。
Source 构建的可用日志级别如下:
0 级 | 生成运行 assemble 脚本的容器的输出,以及所有遇到的错误。这是默认值。 |
1 级 | 生成有关已执行进程的基本信息。 |
2 级 | 生成有关已执行进程的非常详细的信息。 |
3 级 | 生成有关已执行进程的非常详细的信息,以及存档内容的列表。 |
4 级 | 目前生成与 3 级相同的信息。 |
5 级 | 生成以上级别中包括的所有内容,另外还提供 Docker 推送消息。 |
8.3. 构建输入
8.3.1. 构建输入如何工作
构建输入提供构建操作的源内容。在 OpenShift Container Platform 中,可以通过几种方法提供源。顺序排列:
不同的输入可以合并为一个构建。由于内联 Dockerfile 具有优先权,它可覆盖由另一个输入提供的名为 Dockerfile 的任何其他文件。二进制(本地)和 Git 存储库是互斥的输入。
当您不希望在构建生成的最终应用程序镜像中提供构建期间使用的某些资源或凭证,或者想要消耗在 Secret
资源中定义的值时,输入 secret 很有用。外部工件可用于拉取不以其他任一构建输入类型提供的额外文件。
每当运行构建时:
- 构造工作目录,并将所有输入内容放进工作目录中。例如,把输入 Git 存储库克隆到工作目录中,并且把由输入镜像指定的文件通过目标目录复制到工作目录中。
-
构建过程将目录更改到
contextDir
(若已指定)。 - 内联 Dockerfile(若有)写入当前目录中。
-
当前目录中的内容提供给构建过程,供 Dockerfile、自定义构建器逻辑或 assemble 脚本引用。这意味着,构建将忽略所有驻留在
contextDir
之外的输入内容。
以下源定义示例包括多种输入类型,以及它们如何组合的说明。如需有关如何定义各种输入类型的更多详细信息,请参阅每种输入类型的具体小节。
source: git: uri: https://github.com/openshift/ruby-hello-world.git 1 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
8.3.2. Dockerfile 源
提供 dockerfile
值时,此字段的内容将写到磁盘上,存为名为 Dockerfile 的文件。这是处理完其他输入源之后完成的;因此,如果输入源存储库的根目录中包含 Dockerfile,它会被此内容覆盖。
此字段的典型用途是为 Docker 策略构建 提供 Dockerfile
。
源定义是 BuildConfig
的 spec
部分的一部分:
source:
dockerfile: "FROM centos:7\nRUN yum install -y httpd" 1
- 1
dockerfile
字段包含将要构建的内联 Dockerfile。
8.3.3. 镜像源
可以通过镜像为构建过程提供额外的文件。输入镜像的引用方式与定义 From
和 To
镜像目标的方式相同。这意味着可以引用容器镜像和 镜像流标签。在使用镜像时,必须提供一个或多个路径对,以指示要复制镜像的文件或目录的路径以及构建上下文中要放置它们的目的地。
源路径可以是指定镜像内的任何绝对路径。目的地必须是相对目录路径。构建时会加载镜像,并将指定的文件和目录复制到构建过程上下文目录中。这与源存储库内容(若有)要克隆到的目录相同。如果源路径以 /. 结尾,则复制目录的内容,但不在目的地上创建该目录本身。
镜像输入在 BuildConfig
的 source
定义中指定:
source: git: uri: https://github.com/openshift/ruby-hello-world.git 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
使用 Custom 策略的构建不支持此功能。
8.3.4. Git Source
指定后,将从提供的位置获取源代码。
如果提供了内联 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
设为默认分支(如 master
)的名称。
8.3.4.1. 使用代理
如果 Git 存储库需要使用代理才能访问,您可以在 BuildConfig
的 source
部分中定义要使用的代理。您可以配置要使用的 HTTP 和 HTTPS 代理。两个字段都是可选的。也可以通过 NoProxy 字段指定不应执行代理的域。
源 URI 必须使用 HTTP 或 HTTPS 协议才可以正常工作。
source: git: uri: "https://github.com/openshift/ruby-hello-world" httpProxy: http://proxy.example.com httpsProxy: https://proxy.example.com noProxy: somedomain.com, otherdomain.com
集群管理员也可使用 Ansible 为 Git 克隆配置全局代理。
对于 Pipeline 策略构建,因为 Jenkins Git 插件当前限制的缘故,通过 Git 插件执行的任何 Git 操作都不会利用 BuildConfig
中定义的 HTTP 或 HTTPS 代理。Git 插件将仅使用 Plugin Manager 面板上 Jenkins UI 中配置的代理。然后,在所有任务中,此代理都会被用于 Jenkins 内部与 git 的所有交互。您可以在 JenkinsBehindProxy 上找到有关如何通过 Jenkins UI 配置代理的说明。
8.3.4.2. 源克隆 secret
构建器 pod 需要访问定义为构建源的任何 Git 存储库。源克隆 secret 为构建器 pod 提供了通常无权访问的资源的访问权限,例如私有存储库或具有自签名或不可信 SSL 证书的存储库。
支持以下源克隆 secret 配置。
您还可以 组合使用 这些配置来满足特定的需求。
使用 builder 服务帐户运行构建,该帐户必须能够访问所使用的任何源克隆 secret。使用以下命令授予访问权限:
$ oc secrets link builder mysecret
默认情况下,“将 secret 仅限于引用它们的服务帐户”的功能被禁用。这意味着,如果在主配置文件中将 serviceAccountConfig.limitSecretReferences
设置为 false
(默认设置),则不需要将 secret 连接到一个特定的服务。
8.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/*'
8.3.4.2.2. 手动添加源克隆 secret
通过将 sourceSecret
字段添加到 BuildConfig
内的 source
部分,并将它设置为您要创建的 secret
的名称(本例中为 basicsecret
),您可以手动将源克隆 secret 添加到构建配置中。
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:
$ oc set build-secret --source bc/sample-build basicsecret
在 BuildConfig 中定义 Secret 提供了有关此主题的更多信息。
8.3.4.2.3. .gitconfig 文件
如果克隆应用程序依赖于 .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
8.3.4.2.4. 安全 Git 的 .gitconfig 文件
如果 Git 服务器使用双向 SSL 和用户名进行保护,您必须将证书文件添加到源构建中,并在 .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
为避免必须再次输入密码,请务必在构建中指定 S2I 镜像。但是,如果无法克隆存储库,您仍然需要指定用户名和密码来推进构建。
8.3.4.2.5. 基本身份验证
基本身份验证需要 --username
和 --password
的组合或 token
才能与 SCM 服务器进行身份验证。
先创建 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
8.3.4.2.6. SSH 密钥身份验证
基于 SSH 密钥的身份验证需要 SSH 私钥。
存储库密钥通常位于 $HOME/.ssh/ 目录中,但默认名称为 id_dsa.pub
、id_ecdsa.pub
、id_ed25519.pub
或 id_rsa.pub
。使用以下命令生成 SSH 密钥凭证:
$ ssh-keygen -t rsa -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
文件中包含源代码主机条目。
8.3.4.2.7. 可信证书颁发机构
git clone
操作期间受信任的 TLS 证书颁发机构集合内置于 OpenShift Container Platform 基础架构镜像中。如果 Git 服务器使用自签名证书或由镜像不信任的颁发机构签名的证书,您可以创建包含证书的 secret 或者禁用 TLS 验证。
如果为 CA 证书
创建 secret,OpenShift Container Platform 会在 git clone
操作期间使用它来访问您的 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。
禁用 Git TLS 验证。
在构建配置的相应 strategy 部分中,将
GIT_SSL_NO_VERIFY
环境变量设置为true
。您可以使用oc set env
命令管理BuildConfig
环境变量。
8.3.4.2.8. 组合
以下是如何组合上述方法的几个示例,以便根据您的特定需求创建源克隆 secret。
使用 .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
创建组合了 .gitconfig 文件和 CA 证书的 secret:
$ oc create secret generic <secret_name> \ --from-file=ca.crt=<path/to/certificate> \ --from-file=<path/to/.gitconfig>
使用 CA 证书文件创建基本身份验证 secret:
$ oc create secret generic <secret_name> \ --from-literal=username=<user_name> \ --from-literal=password=<password> \ --from-file=ca.crt=</path/to/file> \ --type=kubernetes.io/basic-auth
使用 .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
使用 .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.crt=</path/to/file> \ --type=kubernetes.io/basic-auth
8.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
字段的值将解释为存档中的子目录,并且在有效时,构建器将在执行构建之前更改到该子目录。
8.3.6. 输入 Secret 和 ConfigMap
有时候,构建操作需要凭证或其他配置数据才能访问依赖的资源,但又不希望将这些信息放在源代码控制中。您可以定义输入 secret 和输入 ConfigMap 来实现这一目的。
例如,在通过 Maven 构建 Java 应用程序时,您可以设置通过私钥访问的 Maven Central 或 JCenter 的私有镜像。要从该私有镜像下载库,您必须提供以下内容:
- 配置了镜像的 URL 和连接设置的 settings.xml 文件。
- 设置文件中引用的私钥,例如 ~/.ssh/id_rsa。
为安全起见,不应在应用程序镜像中公开您的凭证。
示例中描述的是 Java 应用程序,但您可以使用相同的方法将 SSL 证书添加到 /etc/ssl/certs 目录,以及添加 API 密钥或令牌、许可证文件等。
8.3.6.1. 添加输入 Secret 和 ConfigMap
将输入 secret 和/或 ConfigMap 添加到现有的 BuildConfig
中:
如果 ConfigMap 不存在,则进行创建:
$ oc create configmap settings-mvn \ --from-file=settings.xml=<path/to/settings.xml>
这会创建一个名为 settings-mvn 的新 ConfigMap,其包含 settings.xml 文件的纯文本内容。
如果 secret 不存在,则进行创建:
$ oc create secret generic secret-mvn \ --from-file=id_rsa=<path/to/.ssh/id_rsa>
这会创建一个名为 secret-mvn 的新 secret,其包含 id_rsa 私钥的 base64 编码内容。
将 ConfigMap 和 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 和 ConfigMap,请运行以下命令:
$ 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目录中。请注意,对于 Docker 策略,目标目录必须是相对路径。
8.3.6.2. Source-to-Image 策略
采用 Source
策略时,所有定义的输入 secret 都复制到对应的 destinationDir
中。如果 destinationDir
留空,则 secret 会放置到构建器镜像的工作目录中。
destinationDir
是相对路径时采用相同的规则;secret 将放置到相对于镜像工作目录的路径中。如果构建器镜像中不存在 destinationDir
路径中的最终目录,则会创建该目录。destinationDir
中的所有上述目录都必须存在,否则会发生错误。
输入 secret 将以全局可写(具有 0666
权限)形式添加,并且在执行 assemble 脚本后其大小会被截断为零。也就是说,生成的镜像中会包括这些 secret 文件,但出于安全原因,它们将为空。
assemble 脚本完成后不会截断输入 ConfigMap。
8.3.6.3. Docker 策略
采用 Docker
策略时,您可以使用 Dockerfile 中的 ADD
和 COPY
指令,将所有定义的输入 secret 添加到容器镜像中。
如果没有为 secret 指定 destinationDir
,则文件将复制到 Dockerfile 所在的同一目录中。如果将一个相对路径指定为 destinationDir
,则 secret 将复制到相对于 Dockerfile 所在位置的这个目录中。这样,secret 文件可供 Docker 构建操作使用,作为构建期间使用的上下文目录的一部分。
例 8.1. 引用 secret 和 ConfigMap 数据的 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 本身的一部分。
8.3.6.4. Custom 策略
使用 Custom
策略时,所有定义的输入 secret 和 ConfigMap 都位于 /var/run/secrets/openshift.io/build 目录下的构建器容器内。自定义构建镜像负责适当地使用这些 secret 和 ConfigMap。Custom
策略还允许按照 Custom 策略选项 中所述定义 secret。
现有策略 secret 与输入 secret 之间没有技术差异。但是,构建器镜像可以区分它们并以不同的方式加以使用,具体取决于您的构建用例。
输入 secret 始终挂载到 /var/run/secrets/openshift.io/build 目录中,或您的构建器可以解析 $BUILD
环境变量(包含完整构建对象)。
8.3.7. 使用外部 Artifacts
建议不要将二进制文件存储在源存储库中。因此,您可能会发现有必要定义一个构建,在构建过程中拉取其他文件(如 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
有关如何控制 Source 构建使用哪个 assemble 和 run 脚本的更多信息,请参阅覆盖构建器镜像脚本。
对于 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
明确提供 (仅适用于手动触发的构建)
8.3.8. 将 Docker 凭证用于私有 registry
您可以为构建提供 .docker/config.json 文件,在文件中包含私有容器 registry 的有效凭证。这样,您可以将输出镜像推送到私有容器镜像 registry 中,或从需要身份验证的私有容器镜像 registry 中拉取构建器镜像。
对于 OpenShift Container Platform 容器镜像 registry,这不是必需的,因为 OpenShift Container Platform 会自动为您生成 secret。
默认情况下,.docker/config.json 文件位于您的主目录中,并具有如下格式:
auths: https://index.docker.io/v1/: 1 auth: "YWRfbGzhcGU6R2labnRib21ifTE=" 2 email: "user@example.com" 3
您可以在此文件中定义多个容器镜像 registry 条目。或者,也可以通过运行 docker login
命令将身份验证条目添加到此文件中。如果文件不存在,则会创建此文件。
Kubernetes 提供 Secret
对象,可用于存储配置和密码。
从本地 .docker/config.json 文件创建 secret:
$ oc create secret generic dockerhub \ --from-file=.dockerconfigjson=<path/to/.docker/config.json> \ --type=kubernetes.io/dockerconfigjson
这将生成名为
dockerhub
的 secret 的 JSON 规格并创建该对象。创建 secret 后,将其添加到 builder 服务帐户。所有构建都使用
builder
角色来运行,因此您必须使用以下命令使其能访问您的 secret:$ oc secrets link builder dockerhub
将
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
通过指定
pullSecret
字段(构建策略定义的一部分),从私有容器镜像 registry 拉取构建器容器镜像:strategy: sourceStrategy: from: kind: "DockerImage" name: "docker.io/user/private_repository" pullSecret: name: "dockerhub"
您还可以使用
oc set build-secret
命令在构建配置上设置 pull secret:$ oc set build-secret --pull bc/sample-build dockerhub
本例在 Source 构建中使用 pullSecret
,但也适用于 Docker 构建和 Custom 构建。
8.4. 构建输出
8.4.1. 构建输出概述
使用 Docker
或 Source
策略的构建会创建新的容器镜像。镜像而后被推送到由 Build
规格的 output
部分中指定的容器镜像 registry 中。
如果输出类型是 ImageStreamTag
,则镜像将推送到集成的 OpenShift Container Platform registry,并在指定的镜像流中标记。如果输出类型是 DockerImage
,则输出引用的名称将用作 Docker 推送规格。规格中可以包含 registry;如果没有指定 registry,则默认为 DockerHub。如果 Build 规格的 output 部分为空,则构建结束时不推送镜像。
输出到 ImageStreamTag
spec: output: to: kind: "ImageStreamTag" name: "sample-image:latest"
输出到 Docker 推送规范
spec: output: to: kind: "DockerImage" name: "my-registry.mycompany.com:5000/myimages/myimage:tag"
8.4.2. 输出镜像环境变量
Docker
和 Source
策略构建在输出镜像上设置以下环境变量:
变量 | 描述 |
---|---|
| 构建的名称 |
| 构建的命名空间 |
| 构建的源 URL |
| 构建中使用的 Git 引用 |
| 构建中使用的源提交 |
此外,任何用户定义的环境变量(例如,通过 Source
或 Docker
策略选项配置的环境变量)也将是输出镜像环境变量列表的一部分。
8.4.3. 输出镜像标签
Docker
和 Source
构建在输出镜像上设置以下标签:
标签 | 描述 |
---|---|
| 构建中使用的源提交的作者 |
| 构建中使用的源提交的日期 |
| 构建中使用的源提交的哈希值 |
| 构建中使用的源提交的消息 |
| 源中指定的分支或引用 |
| 构建的源 URL |
您还可以使用 BuildConfig.spec.output.imageLabels
字段指定将应用到从 BuildConfig
构建的每个镜像的自定义标签列表。
应用到所构建镜像的自定义标签
spec: output: to: kind: "ImageStreamTag" name: "my-image:latest" imageLabels: - name: "vendor" value: "MyCompany" - name: "authoritative-source-url" value: "registry.mycompany.com"
8.4.4. 输出镜像 Digest
构建的镜像可由其 digest 唯一识别,后来可用于通过 digest(无论其当前标签是什么)来拉取镜像。
Docker
和 Source
构建会在镜像推送到 registry 后将摘要存储在 Build.status.output.to.imageDigest
中。摘要在 registry 中计算。因此,它可能无法始终存在,例如当 registry 没有返回摘要时,或者构建器镜像不知道其格式时。
在 registry 的 Successful Push 后构建镜像 Digest
status: output: to: imageDigest: sha256:29f5d56d12684887bdfa50dcd29fc31eea4aaf4ad3bec43daf19026a7ce69912
8.4.5. 将 Docker 凭证用于私有 registry
要将镜像推送到私有容器镜像 registry,可以使用 secret 来提供凭证。具体步骤请参阅构建输入。
8.5. 构建策略选项
8.5.1. Source-to-Image 策略选项
以下选项特定于 S2I 构建策略 :
8.5.1.1. 强制 Pull
默认情况下,如果构建配置中指定的构建器镜像在节点上本地可用,则将使用该镜像。但是,要覆盖本地镜像并从镜像流指向的 registry 中刷新它,请创建一个 BuildConfig
,将 forcePull
标志设为 true :
strategy: sourceStrategy: from: kind: "ImageStreamTag" name: "builder-image:latest" 1 forcePull: true 2
8.5.1.2. 增量构建
S2I 可以执行增量构建,也就是能够重复利用过去构建的镜像中的工件。要创建增量构建,请创建 BuildConfig
并对策略定义进行以下修改:
strategy: sourceStrategy: from: kind: "ImageStreamTag" name: "incremental-image:latest" 1 incremental: true 2
有关如何创建支持增量构建的构建器镜像的信息,请参阅 S2I 要求 主题。
8.5.1.3. 覆盖构建器镜像脚本
您可以通过以下两种方式之一覆盖构建器镜像提供的 assemble、run 和 save-artifacts S2I 脚本。任一:
- 在应用程序源存储库的 .s2i/bin 目录中提供 assemble、run、和/或 save-artifacts 脚本,或者
- 提供包含脚本的目录的 URL,作为策略定义的一部分。例如:
strategy:
sourceStrategy:
from:
kind: "ImageStreamTag"
name: "builder-image:latest"
scripts: "http://somehost.com/scripts_directory" 1
- 1
- 此路径会将 run、assemble 和 save-artifacts 附加到其中。如果找到任何或所有脚本,将使用它们代替镜像中提供的同名脚本。
8.5.1.4. 环境变量
可以通过两种方式将环境变量提供给源构建过程和生成的镜像。环境文件和 BuildConfig 环境 值。提供的变量将存在于构建过程和输出镜像中。
8.5.1.4.1. 环境文件
利用源代码构建,您可以在应用程序内设置环境值(每行一个),方法是在源存储库中的 .s2i/environment 文件中指定它们。此文件中指定的环境变量存在于构建过程和输出镜像。各个镜像的文档中有完整的支持环境变量列表。
如果在源存储库中提供 .s2i/environment 文件,则 S2I 会在构建期间读取此文件。这允许自定义构建行为,因为 assembe 脚本可能会使用这些变量。
例如,如果要禁用 Rails 应用程序的资产编译,您可以在 .s2i/environment 文件中添加 DISABLE_ASSET_COMPILATION=true
,这样就可以在构建期间跳过资产编译。
除了构建之外,指定的环境变量也可以在运行的应用程序本身中使用。例如,您可以在 .s2i/environment 文件中添加 RAILS_ENV=development
,使 Rails 应用程序以 开发模式
而非 生产
模式启动。
8.5.1.4.2. BuildConfig Environment
您可以在 BuildConfig
的 sourceStrategy
定义中添加环境变量。这里定义的环境变量可在 assemble 脚本执行期间看到,也会在输出镜像中定义,使它们能够供 run 脚本和应用程序代码使用。
例如,禁用 Rails 应用程序的资产编译:
sourceStrategy: ... env: - name: "DISABLE_ASSET_COMPILATION" value: "true"
构建环境部分提供了更多高级指导。
您还可以使用 oc set env
命令管理 BuildConfig
中定义的环境变量。
8.5.1.5. 通过 Web 控制台添加 Secret
在构建配置中添加 secret 使其能访问私有存储库:
- 创建一个新的 OpenShift Container Platform 项目。
- 创建一个包含用于访问私有源代码存储库的凭证的 secret。
- 创建 Source-to-Image(S2I)构建配置。
-
在构建配置编辑器页面上或在 Web 控制台的
create app from builder image
页面中,设置 Source Secret。 - 点 Save 按钮。
8.5.1.5.1. 启用拉取和推送
通过在构建配置中设置 Pull Secret
来启用拉取到私有 registry,并通过设置 Push Secret
来启用推送。
8.5.1.6. 忽略源文件
Source-to-Image 支持 .s2iignore
文件,该文件包含了需要被忽略的文件列表。构建工作目录中的文件(由各种 输入源 提供)与 .s2iignore
文件中提供的模式匹配,将不会提供给 assemble
脚本使用。
如需有关 .s2iignore
文件格式的更多详细信息,请参阅 Source-to-image 文档。
8.5.2. Docker 策略选项
以下选项特定于 Docker 构建策略 :
8.5.2.1. FROM 镜像
Dockerfile 的 FROM
指令将被 BuildConfig
中的 from
替换:
strategy: dockerStrategy: from: kind: "ImageStreamTag" name: "debian:latest"
8.5.2.2. Dockerfile 路径
默认情况下,Docker 构建使用位于 BuildConfig.spec.source.contextDir
字段中指定的上下文的根目录的 Dockerfile(名为 Dockerfile)。
dockerfilePath
字段允许构建使用不同的路径来定位 Dockerfile,该路径相对于 BuildConfig.spec.source.contextDir
字段。它可以只是默认 Dockerfile 以外的其他文件名(如 MyDockerfile),或子目录中 Dockerfile 的路径(如 dockerfiles/app1/Dockerfile):
strategy: dockerStrategy: dockerfilePath: dockerfiles/app1/Dockerfile
8.5.2.3. No Cache
Docker 构建通常重复使用执行构建的主机上找到的缓存层。将 noCache
选项设置为 true 会强制构建忽略缓存的层并重新运行 Dockerfile 的所有步骤:
strategy: dockerStrategy: noCache: true
8.5.2.4. 强制 Pull
默认情况下,如果构建配置中指定的构建器镜像在节点上本地可用,则将使用该镜像。但是,要覆盖本地镜像并从镜像流指向的 registry 中刷新它,请创建一个 BuildConfig
,将 forcePull
标志设为 true :
strategy:
dockerStrategy:
forcePull: true 1
- 1
- 此标志会导致本地构建器镜像被忽略,并从镜像流指向的 registry 中拉取新版本。将
forcePull
设置为 false 将导致默认行为是遵守本地存储的镜像。
8.5.2.5. 环境变量
要将环境变量提供给 Docker 构建过程和生成的镜像使用,您可以在 BuildConfig
的 dockerStrategy
定义中添加环境变量。
这里定义的环境变量作为单个 ENV
Dockerfile 指令直接插入到 FROM
指令后,以便稍后可在 Dockerfile 内引用该变量。
变量在构建期间定义并保留在输出镜像中,因此它们也会出现在运行该镜像的任何容器中。
例如,定义要在构建和运行时使用的自定义 HTTP 代理:
dockerStrategy: ... env: - name: "HTTP_PROXY" value: "http://myproxy.net:5187/"
集群管理员也可使用 Ansible 配置全局构建设置。
您还可以使用 oc set env
命令管理 BuildConfig
中定义的环境变量。
8.5.2.6. 通过 Web 控制台添加 Secret
在构建配置中添加 secret 使其能访问私有存储库
- 创建一个新的 OpenShift Container Platform 项目。
- 创建一个包含用于访问私有源代码存储库的凭证的 secret。
- 创建 docker 构建配置。
- 在构建配置编辑器页面上或在 Web 控制台的 fromimage 页面中设置 Source Secret。
- 点 Save 按钮。
8.5.2.7. Docker 构建参数
要设置 Docker 构建参数,请在 BuildArgs
中添加条目,它位于 BuildConfig
的 dockerStrategy
定义中。例如:
dockerStrategy: ... buildArgs: - name: "foo" value: "bar"
构建参数将在构建启动时传递给 Docker。
8.5.2.7.1. 启用拉取和推送
通过在构建配置中设置 Pull Secret
来启用拉取到私有 registry,并通过设置 Push Secret
来启用推送。
8.5.3. Custom 策略选项
以下选项特定于 Custom 构建策略。
8.5.3.1. FROM 镜像
使用 customStrategy.from
部分来指示要用于自定义构建的镜像:
strategy: customStrategy: from: kind: "DockerImage" name: "registry.access.redhat.com/openshift3/ose-docker-builder"
8.5.3.2. 公开 Docker 套接字
为了能运行 Docker 命令并从容器内构建容器镜像,构建容器必须绑定到可访问的套接字。要做到这一点,将 exposeDockerSocket
选项设置为 true :
strategy: customStrategy: exposeDockerSocket: true
8.5.3.3. Secrets
除了可以添加到所有构建类型的源和镜像的 secret 之外,自定义策略还允许向构建器 Pod 添加任意 secret 列表。
每个 secret 都可以挂载到特定位置:
strategy: customStrategy: secrets: - secretSource: 1 name: "secret1" mountPath: "/tmp/secret1" 2 - secretSource: name: "secret2" mountPath: "/tmp/secret2"
8.5.3.3.1. 通过 Web 控制台添加 Secret
在构建配置中添加 secret 使其能访问私有存储库:
- 创建一个新的 OpenShift Container Platform 项目。
- 创建一个包含用于访问私有源代码存储库的凭证的 secret。
- 创建自定义构建配置。
- 在构建配置编辑器页面上或在 Web 控制台的 fromimage 页面中设置 Source Secret。
- 点 Save 按钮。
8.5.3.3.2. 启用拉取和推送
通过在构建配置中设置 Pull Secret
来启用拉取到私有 registry,并通过设置 Push Secret
来启用推送。
8.5.3.4. 强制 Pull
默认情况下,在设置构建 pod 时,构建控制器会检查构建配置中指定的镜像是否本地可用。如果是这样,则使用该镜像。但是,要覆盖本地镜像并从镜像流指向的 registry 中刷新它,请创建一个 BuildConfig
,将 forcePull
标志设为 true :
strategy:
customStrategy:
forcePull: true 1
- 1
- 此标志会导致本地构建器镜像被忽略,并从镜像流指向的 registry 中拉取新版本。将
forcePull
设置为 false 将导致默认行为是遵守本地存储的镜像。
8.5.3.5. 环境变量
要将环境变量提供给 Custom 构建过程使用,您可以在 BuildConfig
的 customStrategy
定义中添加环境变量。
这里定义的环境变量将传递给运行自定义构建的 Pod。
例如,定义在构建期间使用的自定义 HTTP 代理:
customStrategy: ... env: - name: "HTTP_PROXY" value: "http://myproxy.net:5187/"
集群管理员也可使用 Ansible 配置全局构建设置。
您还可以使用 oc set env
命令管理 BuildConfig
中定义的环境变量。
8.5.4. Pipeline 策略选项
以下选项特定于 Pipeline 构建策略。
8.5.4.1. 提供 Jenkinsfile
您可以通过两种方式之一提供 Jenkinsfile:
- 在构建配置中嵌入 Jenkinsfile。
- 在构建配置中包含对含有 Jenkinsfile 的 Git 存储库的引用。
嵌入式定义
kind: "BuildConfig" apiVersion: "v1" metadata: name: "sample-pipeline" spec: strategy: jenkinsPipelineStrategy: jenkinsfile: |- node('agent') { stage 'build' openshiftBuild(buildConfig: 'ruby-sample-build', showBuildLogs: 'true') stage 'deploy' openshiftDeploy(deploymentConfig: 'frontend') }
引用 Git 存储库
kind: "BuildConfig"
apiVersion: "v1"
metadata:
name: "sample-pipeline"
spec:
source:
git:
uri: "https://github.com/openshift/ruby-hello-world"
strategy:
jenkinsPipelineStrategy:
jenkinsfilePath: some/repo/dir/filename 1
- 1
- 可选的
jenkinsfilePath
字段指定要使用的文件的名称,其路径相对于源contextDir
。如果省略了contextDir
,则默认为存储库的根目录。如果省略了jenkinsfilePath
,则默认为 Jenkinsfile。
8.5.4.2. 环境变量
要将环境变量提供给 Pipeline 构建过程使用,您可以在 BuildConfig
的 jenkinsPipelineStrategy
定义中添加环境变量。
定义后,环境变量将设置为与 BuildConfig
关联的任何 Jenkins 任务的参数。
例如:
jenkinsPipelineStrategy: ... env: - name: "FOO" value: "BAR"
您还可以使用 oc set env
命令管理 BuildConfig
中定义的环境变量。
8.5.4.2.1. BuildConfig 环境变量和 Jenkins 任务参数之间的映射
基于对 Pipeline 策略的 BuildConfig
的更改创建或更新 Jenkins 任务时,BuildConfig
中的任何环境变量都会映射到 Jenkins 任务参数定义,其中 Jenkins 任务参数定义的默认值是相关联的环境变量的当前值。
在 Jenkins 任务初始创建之后,您仍然可以从 Jenkins 控制台向任务添加其他参数。参数名称与 BuildConfig
中的环境变量名称不同。为这些 Jenkins 任务启动构建时,将遵循这些参数。
为 Jenkins 任务启动构建的方式决定了如何设置参数。如果使用 oc start-build
启动,则 BuildConfig
中环境变量的值是为对应任务实例设置的参数。您在 Jenkins 控制台中对参数默认值所做的更改都将被忽略。BuildConfig
值具有优先权。
如果使用 oc start-build -e
启动,则 -e
选项中指定的环境变量值具有优先权。而且,如果指定没有列在 BuildConfig
中的环境变量,它们将添加为 Jenkins 任务参数定义。此外,您从 Jenkins 控制台对与环境变量对应的参数所做的更改都将被忽略。BuildConfig
以及您通过 oc start-build -e
指定的值将具有优先权。
如果通过 Jenkins 控制台启动 Jenkins 任务,则您可以通过 Jenkins 控制台控制参数的设置,作为启动任务构建的一部分。
在 BuildConfig
中指定所有可能的环境变量和作业参数会减少磁盘 I/O,并在 Jenkins 处理过程中提高性能。
8.6. 构建环境
8.6.1. 概述
与 pod 环境变量一样,可以使用 Downward API 在引用其他资源/变量时定义构建环境变量。但是,有几个例外情况如下。
您还可以使用 oc set env
命令管理 BuildConfig
中定义的环境变量。
8.6.2. 使用构建字段作为环境变量
您可以注入构建对象的信息,使用 fieldPath
环境变量源指定要获取值的字段的 JsonPath
。
env: - name: FIELDREF_ENV valueFrom: fieldRef: fieldPath: metadata.name
Jenkins Pipeline 策略不支持将 valueFrom
语法用于环境变量。
8.6.3. 使用容器资源作为环境变量
不支持在构建环境变量中使用 valueFrom
引用容器资源,因为这种引用在创建容器之前解析。
8.6.4. 使用 Secret 作为环境变量
您可以使用 valueFrom
语法,将 secret 的键值作为环境变量提供。
apiVersion: v1 kind: BuildConfig metadata: name: secret-example-bc spec: strategy: sourceStrategy: env: - name: MYVAL valueFrom: secretKeyRef: key: myval name: mysecret
8.7. 触发构建
8.7.1. 构建触发器概述
在定义 BuildConfig
时,您可以定义触发器来控制应该运行 BuildConfig
的环境。可用的构建触发器如下:
8.7.2. Webhook 触发器
Webhook 触发器通过发送请求到 OpenShift Container Platform API 端点来触发新构建。您可以使用 GitHub、GitLab、Bitbucket 或通用 Webhook 来定义这些触发器。
目前,OpenShift Container Platform Webhook 仅支持各种基于 Git 的源代码管理系统 (SCM) 的推送事件的类同版本。所有其他事件类型都会忽略。
处理推送事件时,会确认事件内的分支引用是否与相应 BuildConfig
中的分支引用匹配。如果匹配,则针对 OpenShift Container Platform 构建签出 Webhook 事件中记录的准确提交引用。如果不匹配,则不触发构建。
oc new-app
和 oc new-build
将自动创建 GitHub 和通用 Webhook 触发器,但其他所需的 Webhook 触发器都必须手动添加(请参阅设置触发器)。
对于所有 Webhook,您必须使用名为 WebHookSecretKey
的键定义 Secret
,并且其值是调用 Webhook 时要提供的值。然后,Webhook 定义必须引用该 secret。secret可确保 URL 的唯一性,防止他人触发构建。键的值将与 Webhook 调用期间提供的 secret 进行比较。
例如,此处的 GitHub Webhook 具有对名为 mysecret
的 secret 的引用:
type: "GitHub" github: secretReference: name: "mysecret"
该 secret 的定义如下。注意 secret 的值采用 base64 编码,如 Secret
对象的 data
字段所要求。
- kind: Secret apiVersion: v1 metadata: name: mysecret creationTimestamp: data: WebHookSecretKey: c2VjcmV0dmFsdWUx
8.7.2.1. GitHub Webhook
当存储库更新时,GitHub Webhook 处理 GitHub 发出的调用。在定义触发器时,您必须指定一个 secret
,它将是您在配置 Webhook 时提供给 GitHub 的 URL 的一部分。
GitHub Webhook 定义示例:
type: "GitHub" github: secretReference: name: "mysecret"
Webhook 触发器配置中使用的 secret 与在 GitHub UI 中配置 Webhook 时遇到的 secret
字段不同。前者使 Webhook URL 唯一且难以预测,后者是一个可选的字符串字段,用于创建正文的 HMAC 十六进制摘要,作为 X-Hub-Signature
标头来发送。
oc describe
命令将有效负载 URL 返回为 GitHub Webhook URL(请参阅显示 Webhook URL),其结构如下:
https://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/github
配置 GitHub Webhook:
从 GitHub 存储库创建
BuildConfig
后,请运行:$ oc describe bc/<name-of-your-BuildConfig>
这会生成一个 Webhook GitHub URL,如下所示:
<https://api.starter-us-east-1.openshift.com:443/oapi/v1/namespaces/nsname/buildconfigs/bcname/webhooks/<secret>/github>.
- 从 GitHub Web 控制台将此 URL 剪切并粘贴到 GitHub 中。
- 在 GitHub 存储库中,从 Settings → Webhooks & Services 中选择 Add Webhook。
- 将 URL 输出(与上方相似)粘贴到 Payload URL 字段。
-
将 Content Type 从 GitHub 默认的
application/x-www-form-urlencoded
更改为application/json
。 - 点击 Add webhook。
您应该看到一条来自 GitHub 的消息,说明您的 Webhook 已配置成功。
现在,每当您将更改推送到 GitHub 存储库时,新构建会自动启动,成功构建后也会启动新部署。
Gogs 支持与 GitHub 相同的 Webhook 有效负载格式。因此,如果您使用 Gogs 服务器,您可以在 BuildConfig
中定义 GitHub Webhook 触发器,并通过 Gogs 服务器触发它。
根据包含有效 JSON 有效负载的文件,如 payload.json
,您可以通过 curl
手动触发 Webhook:
$ curl -H "X-GitHub-Event: push" -H "Content-Type: application/json" -k -X POST --data-binary @payload.json https://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/github
只有在 API 服务器没有适当签名的证书时,才需要 -k
参数。
8.7.2.2. GitLab Webhooks
当存储库更新时,GitLab Webhook 处理 GitLab 发出的调用。与 GitHub 触发器一样,您必须指定一个 secret
。以下示例是 BuildConfig
中的触发器定义 YAML:
type: "GitLab" gitlab: secretReference: name: "mysecret"
oc describe
命令将有效负载 URL 返回为 GitLab Webhook URL(请参阅显示 Webhook URL),其结构如下:
https://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/gitlab
配置 GitLab Webhook:
描述构建配置以获取 Webhook URL:
$ oc describe bc <name>
-
复制 Webhook URL,将
<secret>
替换为您的 secret 值。 - 按照 GitLab 设置说明,将 Webhook URL 粘贴到 GitLab 存储库设置中。
根据包含有效 JSON 有效负载的文件,如 payload.json
,您可以通过 curl
手动触发 Webhook:
$ curl -H "X-GitLab-Event: Push Hook" -H "Content-Type: application/json" -k -X POST --data-binary @payload.json https://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/gitlab
只有在 API 服务器没有适当签名的证书时,才需要 -k
参数。
8.7.2.3. Bitbucket Webhook
当存储库更新时,Bitbucket Webhook 处理 Bitbucket 发出的调用。与前面的触发器类似,您必须指定一个 secret
。以下示例是 BuildConfig
中的触发器定义 YAML:
type: "Bitbucket" bitbucket: secretReference: name: "mysecret"
oc describe
命令将有效负载 URL 返回为 Bitbucket Webhook URL(请参阅显示 Webhook URL),其结构如下:
https://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/bitbucket
配置 Bitbucket Webhook:
描述构建配置以获取 Webhook URL:
$ oc describe bc <name>
-
复制 Webhook URL,将
<secret>
替换为您的 secret 值。 - 按照 Bitbucket 设置说明,将 Webhook URL 粘贴到 Bitbucket 存储库设置中。
根据包含有效 JSON 有效负载的文件,如 payload.json
,您可以通过 curl
手动触发 Webhook:
$ curl -H "X-Event-Key: repo:push" -H "Content-Type: application/json" -k -X POST --data-binary @payload.json https://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/bitbucket
只有在 API 服务器没有适当签名的证书时,才需要 -k
参数。
8.7.2.4. 通用 Webhook
通用 Webhook 可从能够发出 Web 请求的任何系统调用。与其他 Webhook一样,您必须指定一个 secret,该 secret 将成为调用者必须用于触发构建的 URL 的一部分。secret可确保 URL 的唯一性,防止他人触发构建。如下是 BuildConfig
中的示例触发器定义 YAML:
type: "Generic"
generic:
secretReference:
name: "mysecret"
allowEnv: true 1
- 1
- 设置为
true
,以允许通用 Webhook 传入环境变量。
要设置调用者,请为调用系统提供构建的通用 Webhook 端点的 URL:
https://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/generic
调用者必须以 POST
操作形式调用 Webhook。
要手动调用 Webhook,您可以使用 curl
:
$ curl -X POST -k https://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/generic
HTTP 操作动词必须设置为 POST
。指定了不安全 -k
标志以忽略证书验证。如果集群拥有正确签名的证书,则不需要此第二个标志。
端点可以接受具有以下格式的可选有效负载:
git:
uri: "<url to git repository>"
ref: "<optional git reference>"
commit: "<commit hash identifying a specific git commit>"
author:
name: "<author name>"
email: "<author e-mail>"
committer:
name: "<committer name>"
email: "<committer e-mail>"
message: "<commit message>"
env: 1
- name: "<variable name>"
value: "<variable value>"
- 1
- 与
BuildConfig
环境变量 类似,此处定义的环境变量也可供您的构建使用。如果这些变量与BuildConfig
环境变量发生冲突,则以这些变量为准。默认情况下,通过 Webhook 传递的环境变量将被忽略。在 Webhook 定义上将allowEnv
字段设为true
即可启用此行为。
要使用 curl
传递此有效负载,请在名为 payload_file.yaml 的文件中进行定义,再运行以下命令:
$ curl -H "Content-Type: application/yaml" --data-binary @payload_file.yaml -X POST -k https://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/generic
参数与前一个示例相同,但添加了标头和 payload。-H
参数将 Content-Type
标头设置为 application/yaml
或 application/json
,具体取决于您的 payload 格式。--data-binary
参数用于通过 POST
请求发送带有换行符的二进制 payload。
即使出示了无效的请求 payload(例如,无效的内容类型,或者无法解析或无效的内容等),OpenShift Container Platform 也允许通用 Webhook 触发构建。保留此行为是为了向后兼容。如果出示无效的请求 payload,OpenShift Container Platform 将以 JSON 格式返回警告,作为其 HTTP 200 OK
响应的一部分。
8.7.2.5. 显示 Webhook URL
使用以下命令来显示与构建配置关联的任何 Webhook URL:
$ oc describe bc <name>
如果上述命令不显示任何 Webhook URL,则不会为该构建配置定义任何 Webhook 触发器。请参阅 设置触发器 来手动添加触发器。
8.7.3. 镜像更改触发器
通过镜像更改触发器,您可以在上游镜像有新版本可用时自动调用构建。例如,如果构建以 RHEL 镜像为基础,那么您可以触发该构建在 RHEL 镜像更改时运行。因此,应用程序镜像始终在最新的 RHEL 基础镜像上运行。
配置镜像更改触发器需要以下操作:
定义指向要触发的上游镜像的
ImageStream
:kind: "ImageStream" apiVersion: "v1" metadata: name: "ruby-20-centos7"
这将定义绑定到位于 <system-registry>/<namespace>/ruby-20-centos7 的容器镜像存储库的镜像流。<system-registry> 定义为 OpenShift Container Platform 中运行的名为
docker-registry
的服务。如果镜像流是构建的基础镜像,请将构建策略中的 from 字段设置为指向镜像流:
strategy: sourceStrategy: from: kind: "ImageStreamTag" name: "ruby-20-centos7:latest"
在这种情形中,
sourceStrategy
定义将消耗此命名空间中名为ruby-20-centos7
的镜像流的latest
标签。使用指向镜像流的一个或多个触发器定义构建:
type: "ImageChange" 1 imageChange: {} type: "ImageChange" 2 imageChange: from: kind: "ImageStreamTag" name: "custom-image:latest"
将镜像更改触发器用于策略镜像流时,生成的构建会获得一个不可变 docker 标签,指向与该标签对应的最新镜像。在执行构建时,策略将使用此新镜像引用。
对于不引用策略镜像流的其他镜像更改触发器,系统会启动新构建,但不会使用唯一镜像引用来更新构建策略。
在上例中,如果策略有镜像更改触发器,生成的构建将是:
strategy: sourceStrategy: from: kind: "DockerImage" name: "172.30.17.3:5001/mynamespace/ruby-20-centos7:<immutableid>"
这将确保触发的构建使用刚才推送到存储库的新镜像,并且可以使用相同的输入随时重新运行构建。
您可以暂停镜像更改触发器,以便在构建开始之前对引用的镜像流进行多次更改。在将 ImageChangeTrigger
添加到 BuildConfig
时,您也可以将 paused
属性设为 true,以避免立即触发构建。
type: "ImageChange" imageChange: from: kind: "ImageStreamTag" name: "custom-image:latest" paused: true
除了设置适用于所有 Strategy
类型的镜像字段外,自定义构建还需要检查 OPENSHIFT_CUSTOM_BUILD_BASE_IMAGE
环境变量。如果不存在,则使用不可变镜像引用来创建它。如果存在,则使用不可变镜像引用进行更新。
如果因为 Webhook 触发器或手动请求而触发构建,则创建的构建将使用从 Strategy
引用的 ImageStream
解析而来的 <immutableid>
。这将确保使用一致的镜像标签来执行构建,以方便再生。
指向 v1 容器 registry 中的容器镜像的镜像流仅在镜像流标签可用时触发一次构建,后续镜像更新时则不会触发。这是因为 v1 容器 registry 中缺少可唯一标识的镜像。
8.7.4. 配置更改触发器
通过配置更改触发器,您可以在创建新 BuildConfig
时立即自动调用构建。如下是 BuildConfig
中的示例触发器定义 YAML:
type: "ConfigChange"
配置更改触发器目前仅在创建新 BuildConfig
时运作。在未来的版本中,配置更改触发器也可以在每当 BuildConfig
更新时启动构建。
8.7.4.1. 手动设置触发器
您可以使用 oc set triggers
在构建配置中添加和移除触发器。例如,要在构建配置上设置 GitHub Webhook 触发器,请使用:
$ oc set triggers bc <name> --from-github
要设置镜像更改触发器,请使用:
$ oc set triggers bc <name> --from-image='<image>'
要移除触发器,请添加 --remove
:
$ oc set triggers bc <name> --from-bitbucket --remove
如果 Webhook 触发器已存在,再次添加它会重新生成 Webhook secret。
如需更多信息,请使用 oc set triggers --help
来查阅帮助文档
8.8. 构建 Hook
8.8.1. 构建 hook 概述
通过构建 hook,可以将行为注入到构建过程中。
BuildConfig
对象的 postCommit
字段在运行构建输出镜像的临时容器内执行命令。Hook 的执行时间是紧接在提交镜像的最后一层后,并且在镜像推送到 registry 之前。
当前工作目录设置为镜像的 WORKDIR
,即容器镜像的默认工作目录。对于大多数镜像,这是源代码所处的位置。
如果脚本或命令返回非零退出代码,或者启动临时容器失败,则 hook 将失败。当 hook 失败时,它会将构建标记为失败,并且镜像也不会推送到 registry。可以通过查看构建日志来检查失败的原因。
构建 hook 可用于运行单元测试,以在构建标记为完成并在 registry 中提供镜像之前验证镜像。如果所有测试都通过并且测试运行器返回退出代码 0,则构建标记为成功。如果有任何测试失败,则构建标记为失败。在所有情况下,构建日志将包含测试运行器的输出,这可用于识别失败的测试。
postCommit
hook 不仅限于运行测试,也可用于运行其他命令。由于它在临时容器内运行,因此 hook 所做的更改不会持久存在;也就是说,hook 执行无法对最终镜像造成影响。除了其他用途外,也可借助此行为来安装和使用会自动丢弃并且不出现在最终镜像中的测试依赖项。
8.8.2. 配置 Post Commit 构建 hook
配置提交后构建 hook 的方法有多种。以下示例中所有形式具有同等作用,也都执行 bundle exec rake test --verbose
:
Shell 脚本:
postCommit: script: "bundle exec rake test --verbose"
script
值是通过/bin/sh -ic
执行的 shell 脚本。当 shell 脚本适合执行构建 hook 时可使用此选项。例如,用于运行前文所述的单元测试。若要控制镜像入口点,或者如果镜像没有/bin/sh
,可使用command
和/或args
。注意引入的额外
-i
标志用于改进搭配 CentOS 和 RHEL 镜像时的体验,未来的发行版中可能会剔除。命令作为镜像入口点:
postCommit: command: ["/bin/bash", "-c", "bundle exec rake test --verbose"]
在这种形式中,
command
是要运行的命令,它会覆盖 exec 形式中的镜像入口点,如 Dockerfile 引用中所述。如果镜像没有/bin/sh
,或者您不想使用 shell,则需要这样做。在所有其他情形中,使用script
可能更为方便。将参数传递给默认入口点:
postCommit: args: ["bundle", "exec", "rake", "test", "--verbose"]
在这种形式中,
args
是提供给镜像的默认入口点的参数列表。镜像入口点必须能够处理参数。Shell 脚本带有参数:
postCommit: script: "bundle exec rake test $1" args: ["--verbose"]
如果您需要在 shell 脚本中正确传递参数,请使用此表单。在
script
中,$0
将为 "/bin/sh",$1
,$2
等是args
中的位置参数。命令带有参数:
postCommit: command: ["bundle", "exec", "rake", "test"] args: ["--verbose"]
这种形式相当于将参数附加到
command
。
同时提供 script
和 command
会产生无效的构建 hook。
8.8.2.1. 使用 CLI
oc set build-hook
命令可用于为构建配置设置构建 hook。
将命令设置为提交后构建 hook:
$ oc set build-hook bc/mybc \ --post-commit \ --command \ -- bundle exec rake test --verbose
将脚本设置为提交后构建 hook:
$ oc set build-hook bc/mybc --post-commit --script="bundle exec rake test --verbose"
8.9. 构建运行策略
8.9.1. 构建运行策略概述
构建运行策略描述从构建配置创建的构建应运行的顺序。这可以通过更改 Build
规格的 spec
部分中的 runPolicy
字段的值来完成。
也可以更改现有构建配置的 runPolicy
值。
-
如果将
Parallel
改为Serial
或SerialLatestOnly
,并从此配置触发新构建,这会导致新构建需要等待所有并行构建完成,因为串行构建只能单独运行。 -
如果将
Serial
更改为SerialLatestOnly
并触发新构建,这会导致取消队列中的所有现有构建,但当前正在运行的构建和最近创建的构建除外。最新的构建接着就会执行。
8.9.2. 串行运行策略
将 runPolicy
字段设置为 Serial
将会导致从 Build
配置创建的所有新构建按顺序运行。这意味着每次只有一个构建运行,每次新构建将等候到上一构建完成。使用此策略将导致一致且可预测的构建输出。这是默认的 runPolicy
。
使用 Serial
策略从 sample-build 配置触发三个构建将导致:
NAME TYPE FROM STATUS STARTED DURATION sample-build-1 Source Git@e79d887 Running 13 seconds ago 13s sample-build-2 Source Git New sample-build-3 Source Git New
当 sample-build-1 构建完成时,sample-build-2 构建将运行:
NAME TYPE FROM STATUS STARTED DURATION sample-build-1 Source Git@e79d887 Completed 43 seconds ago 34s sample-build-2 Source Git@1aa381b Running 2 seconds ago 2s sample-build-3 Source Git New
8.9.3. SerialLatestOnly Run Policy
将 runPolicy
字段设置为 SerialLatestOnly
将使 Build
配置创建的所有新构建都按顺序运行,这与使用 Serial
run 策略相同。区别在于,当当前运行的构建完成时,将运行的下一个构建是最新构建。换句话说,您不会等待排队的构建运行,因为跳过它们。跳过的构建标记为 Cancelled。此策略可用于快速迭代开发。
使用 SerialLatestOnly
策略从 sample-build 配置触发三个构建将导致:
NAME TYPE FROM STATUS STARTED DURATION sample-build-1 Source Git@e79d887 Running 13 seconds ago 13s sample-build-2 Source Git Cancelled sample-build-3 Source Git New
sample-build-2 构建将被取消(skipped),在 sample-build-1 完成后运行的下一个构建将是 sample-build-3 构建:
NAME TYPE FROM STATUS STARTED DURATION sample-build-1 Source Git@e79d887 Completed 43 seconds ago 34s sample-build-2 Source Git Cancelled sample-build-3 Source Git@1aa381b Running 2 seconds ago 2s
8.9.4. 并行运行策略
将 runPolicy
字段设置为 Parallel
会导致从 Build
配置创建的所有新构建并行运行。这可以产生无法预计的结果,因为第一次创建的构建可以最后完成,这会替换之前由最后一个构建生成的推送容器镜像。
在您不关心构建完成的顺序时,请使用并行 run 策略。
使用 Parallel
策略从 sample-build 配置触发三个构建将导致三个同时构建:
NAME TYPE FROM STATUS STARTED DURATION sample-build-1 Source Git@e79d887 Running 13 seconds ago 13s sample-build-2 Source Git@a76d881 Running 15 seconds ago 3s sample-build-3 Source Git@689d111 Running 17 seconds ago 3s
无法保证完成顺序:
NAME TYPE FROM STATUS STARTED DURATION sample-build-1 Source Git@e79d887 Running 13 seconds ago 13s sample-build-2 Source Git@a76d881 Running 15 seconds ago 3s sample-build-3 Source Git@689d111 Completed 17 seconds ago 5s
8.10. 高级构建操作
8.10.1. 设置构建资源
默认情况下,构建由 Pod 使用未绑定的资源(如内存和 CPU)来完成。通过在项目的默认容器限值中指定资源限值来限制这些资源。
您还可以在构建配置中指定资源限值来限制资源使用。在以下示例中,每个 resources
、cpu
和 memory
参数都是可选的。
apiVersion: "v1" kind: "BuildConfig" metadata: name: "sample-build" spec: resources: limits: cpu: "100m" 1 memory: "256Mi" 2
但是,如果您的项目定义了 配额,则需要以下两项之一:
否则,构建 Pod 创建将失败,说明无法满足配额要求。
8.10.2. 设置最大持续时间
定义 BuildConfig
时,您可以通过设置 completionDeadlineSeconds
字段来定义其最长持续时间。以秒为单位指定,默认情况下不设置。若未设置,则不强制执行最长持续时间。
最长持续时间从构建 Pod 调度到系统中的时间开始计算,并且定义它在多久时间内处于活跃状态,这包括拉取构建器镜像所需的时间。达到指定的超时后,OpenShift Container Platform 将终止构建。
下例显示了 BuildConfig
的部分内容,它指定了值为 30 分钟的 completionDeadlineSeconds
字段:
spec: completionDeadlineSeconds: 1800
Pipeline 策略选项不支持此设置。
8.10.3. 将构建分配给特定的节点
通过在构建配置的 nodeSelector
字段中指定标签,可以将构建定位到在特定节点上运行。nodeSelector
值是一组键/值对,在调度构建 Pod 时与 node
标签匹配。
apiVersion: "v1"
kind: "BuildConfig"
metadata:
name: "sample-build"
spec:
nodeSelector:1
key1: value1
key2: value2
- 1
- 与此构建配置关联的构建将仅在具有
key1=value2
和key2=value2
标签的节点上运行。
nodeSelector
值也可以由集群范围的默认值和覆盖值控制。只有构建配置没有为 nodeSelector
定义任何键/值对,也没有为 nodeSelector:{}
定义显式的空映射值,才会应用默认值。覆盖值将逐个键地替换构建配置中的值。
如需更多信息,请参阅配置全局构建默认值和覆盖。
如果指定的 NodeSelector
无法与具有这些标签的节点匹配,则构建仍将无限期地保持在 Pending
状态。
8.10.4. 串联构建
对于编译语言(Go、C、C ++、Java 等),在应用程序镜像中包含编译所需的依赖项可能会增加镜像的大小,或者引入可被利用的漏洞。
为避免这些问题,可以将两个构建串联在一起:一个用于生成编译的工件,另一个将该工件放置在运行工件的独立镜像中。在以下示例中,Source-to-Image 构建与 Docker 构建相结合,以编译工件并将其置于单独的运行时镜像中。
虽然本例串联了 Source-to-Image 构建和 Docker 构建,但第一个构建可以使用任何策略来生成包含所需工件的镜像,第二个构建则可以使用任何策略来消耗镜像中的输入内容。
第一个构建获取应用程序源,并生成含有 WAR 文件的镜像。镜像推送到 artifact-image
镜像流。输出工件的路径将取决于所用 Source-to-Image 构建器的 assemble 脚本。在本例中,它将输出到 /wildfly/standalone/deployments/ROOT.war。
apiVersion: v1 kind: BuildConfig metadata: name: artifact-build spec: output: to: kind: ImageStreamTag name: artifact-image:latest source: git: uri: https://github.com/openshift/openshift-jee-sample.git type: Git strategy: sourceStrategy: from: kind: ImageStreamTag name: wildfly:10.1 namespace: openshift type: Source
第二个构建使用带有指向第一个构建中输出镜像内的 WAR 文件的路径的镜像源。内联 Dockerfile 将该 WAR 文件复制到运行时镜像中。
apiVersion: v1 kind: BuildConfig metadata: name: image-build spec: output: to: kind: ImageStreamTag name: image-build:latest source: type: Dockerfile dockerfile: |- FROM jee-runtime:latest COPY ROOT.war /deployments/ROOT.war images: - from: 1 kind: ImageStreamTag name: artifact-image:latest paths: 2 - sourcePath: /wildfly/standalone/deployments/ROOT.war destinationDir: "." strategy: dockerStrategy: from: 3 kind: ImageStreamTag name: jee-runtime:latest type: Docker triggers: - imageChange: {} type: ImageChange
此设置的结果是,第二个构建的输出镜像不需要包含创建 WAR 文件所需的任何构建工具。此外,由于第二个构建包含镜像更改触发器,因此每当运行第一个构建并生成含有二进制工件的新镜像时,将自动触发第二个构建,以生成包含该工件的运行时镜像。所以,两个构建表现为一个具有两个阶段的构建。
8.10.5. 构建修剪
默认情况下,生命周期已结束的构建将无限期保留。您可以通过为 successfulBuildsHistoryLimit
或 failedBuildsHistoryLimit
提供正整数值来限制保留的旧构建数量,如以下示例构建配置中所示。
apiVersion: "v1" kind: "BuildConfig" metadata: name: "sample-build" spec: successfulBuildsHistoryLimit: 2 1 failedBuildsHistoryLimit: 2 2
构建修剪由以下操作触发:
- 更新构建配置。
- 构建可以完成其生命周期。
构建按其创建时间戳排序,首先修剪最旧的构建。
管理员可以使用 'oc adm' object pruning command 来手动修剪构建。
8.11. 构建故障排除
8.11.1. 请求对资源的访问
- 问题
构建失败并显示以下信息:
requested access to the resource is denied
- 解决方案
您已超过项目中设置的某一镜像配额。检查当前的配额,并验证应用的限值和正在使用的存储:
$ oc describe quota
第 9 章 Deployments
9.1. 部署如何工作
9.1.1. 部署是什么?
OpenShift Container Platform 部署提供对常见用户应用程序的精细管理。它们使用三个独立的 API 对象进行描述:
- 部署配置,它将应用程序特定组件的所需状态描述为 pod 模板。
- 一个或多个复制控制器,其中包含部署配置状态作为 pod 模板的时间点记录。
- 一个或多个 pod,,表应用程序某一特定版本的实例。
用户不需要操作由部署配置拥有的复制控制器或 pod。部署系统可确保正确传播对部署配置的更改。如果现有部署策略不适用于您的用例,而且您需要在部署的生命周期内执行手动步骤,那么应考虑创建自定义策略。
在创建部署配置时,会创建一个复制控制器来代表部署配置的 pod 模板。如果部署配置更改,则使用最新的 pod 模板创建一个新的复制控制器,并运行部署过程来缩减旧复制控制器并扩展新的复制控制器。
在创建时,自动从服务负载均衡器和路由器中添加和移除应用程序的实例。只要您的应用程序支持收到 TERM 信号时 安全关闭,您可以确保运行的用户连接能够正常完成。
部署系统提供的功能:
9.1.2. 创建部署配置
部署配置是 deploymentConfig
OpenShift Container Platform API 资源,可以像任何其他资源一样通过 oc
命令进行管理。以下是 deploymentConfig
资源的示例:
kind: "DeploymentConfig" apiVersion: "v1" metadata: name: "frontend" spec: template: 1 metadata: labels: name: "frontend" spec: containers: - name: "helloworld" image: "openshift/origin-ruby-sample" ports: - containerPort: 8080 protocol: "TCP" replicas: 5 2 triggers: - type: "ConfigChange" 3 - type: "ImageChange" 4 imageChangeParams: automatic: true containerNames: - "helloworld" from: kind: "ImageStreamTag" name: "origin-ruby-sample:latest" strategy: 5 type: "Rolling" paused: false 6 revisionHistoryLimit: 2 7 minReadySeconds: 0 8
- 1
frontend
部署配置的 pod 模板描述了一个简单的 Ruby 应用程序。- 2
frontend
将有 5 个副本。- 3
- 配置更改触发器会在每次 Pod 模板更改时创建新复制控制器。
- 4
- 镜像更改触发器会在每次有新版本的
origin-ruby-sample:latest
镜像流标签时触发新复制控制器的创建。 - 5
- Rolling 策略是部署 Pod 的默认方法。可以省略。
- 6
- 暂停部署配置。这将禁用所有触发器的功能,并允许在实际部署 pod 模板前对 pod 模板进行多次更改。
- 7
- 修订历史记录限制是您要保留的旧复制控制器的限制,用于回滚。可以省略。如果省略,则不会清理旧的复制控制器。
- 8
- pod 被视为可用前等待的最短秒数(在就绪度检查成功后)。默认值为 0。
9.2. 基本部署操作
9.2.1. 启动部署
您可以使用 Web 控制台或 CLI 手动启动新的部署过程:
$ oc rollout latest dc/<name>
如果部署过程已在进行中,命令将显示一条消息,不会部署新的复制控制器。
9.2.2. 查看部署
要获取有关应用程序所有可用修订的基本信息:
$ oc rollout history dc/<name>
这将显示有关所有最近为提供的部署配置创建的复制控制器的详细信息,包括任何当前运行的部署过程。
您可以使用 --revision
标志查看特定于修订版本的详情:
$ oc rollout history dc/<name> --revision=1
如需有关部署配置和最新修订的详细信息:
$ oc describe dc <name>
Web 控制台在 Browse 标签页中显示部署。
9.2.3. 重试部署
如果部署配置的当前修订无法部署,您可以使用以下方法重启部署过程:
$ oc rollout retry dc/<name>
如果成功部署了最新的修订,命令会显示一条消息,且不会重试部署过程。
重试部署会重启部署过程,且不创建新的部署修订。重启的复制控制器将具有与失败时相同的配置。
9.2.4. 回滚部署
回滚将应用恢复到上一修订,可通过 REST API、命令行或 Web 控制台进行。
回滚到配置的最近一次部署成功的修订:
$ oc rollout undo dc/<name>
将恢复部署配置的模板以匹配 undo 命令中指定的部署修订,并且会启动新的复制控制器。如果没有通过 --to-revision
指定修订,则使用上一次成功部署的版本。
在回滚过程中,部署配置的镜像更改触发器会被禁用,以防止在回滚完成不久后意外启动新的部署过程。重新启用镜像更改触发器:
$ oc set triggers dc/<name> --auto
部署配置也支持最新部署过程失败时自动回滚到配置的最近一次成功修订。这时,系统会原样保留部署失败的最新模板,由用户来修复其配置。
9.2.5. 在容器内执行命令
您可以为容器添加命令,用来覆盖决镜像的 ENTRYPOINT
设置来改变容器的启动行为。这与生命周期 hook 不同,后者在每个部署的指定时间点上运行一次。
在部署配置的 spec
字段中添加 command
参数。您也可以添加 args
字段来修改 command
(如果 command
不存在,则修改 ENTRYPOINT
)。
... spec: containers: - name: <container_name> image: 'image' command: - '<command>' args: - '<argument_1>' - '<argument_2>' - '<argument_3>' ...
例如,使用 -jar
和 /opt/app-root/springboots2idemo.jar 参数执行 java
命令:
... spec: containers: - name: example-spring-boot image: 'image' command: - java args: - '-jar' - /opt/app-root/springboots2idemo.jar ...
9.2.6. 查看部署日志
输出给定部署配置的最新修订的日志:
$ oc logs -f dc/<name>
如果最新的修订正在运行或失败,oc logs
将返回负责部署 pod 的进程的日志。如果成功,oc logs
会从应用程序的 pod 返回日志。
您还可以查看来自旧的失败部署进程的日志,只要存在这些进程(旧的复制控制器及其部署器 pod)并且没有手动清理或删除:
$ oc logs --version=1 dc/<name>
有关获取日志的更多选项,请参阅:
$ oc logs --help
9.2.7. 设置部署触发器
部署配置可以包含触发器,推动创建新部署过程以响应集群内的事件。
如果在部署配置上没有定义任何触发器,则默认添加 ConfigChange
触发器。如果触发器定义为空白字段,则必须手动启动部署。
9.2.7.1. 配置更改触发器
每当部署配置的容器集模板中检测到更改时,ConfigChange
触发器都会生成新的复制控制器。
如果在部署配置上定义了 ConfigChange
触发器,则在部署配置本身创建后会自动创建第一个复制控制器,且不会暂停。
一个 ConfigChange 触发器
triggers: - type: "ConfigChange"
9.2.7.2. ImageChange Trigger
ImageChange
触发器会在镜像流标签内容更改时( 推送镜像的新版本时 )产生新的复制控制器。
ImageChange 触发器
triggers:
- type: "ImageChange"
imageChangeParams:
automatic: true 1
from:
kind: "ImageStreamTag"
name: "origin-ruby-sample:latest"
namespace: "myproject"
containerNames:
- "helloworld"
- 1
- 如果
imageChangeParams.automatic
字段设置为false
,则触发器被禁用。
在上例中,当 origin-ruby-sample 镜像流的 latest
标签值更改并且新镜像值与部署配置的 helloworld 容器中指定的当前镜像不同时,会使用 helloworld 容器的新镜像创建新的复制控制器。
如果在部署配置上定义了 ImageChange
触发器(带有 ConfigChange
触发器和 automatic=false
,或者 automatic=true
)并且 ImageChange
触发器指向的 ImageStreamTag
尚不存在,则初始部署过程将在镜像导入时或由构建推送到 ImageStreamTag
时立即自动启动。
9.2.7.2.1. 使用命令行
oc set triggers
命令可以用来为部署配置设置部署触发器。在上例中,您可以使用以下命令设置 ImageChangeTrigger
:
$ oc set triggers dc/frontend --from-image=myproject/origin-ruby-sample:latest -c helloworld
如需更多信息,请参阅:
$ oc set triggers --help
9.2.8. 设置部署资源
部署由部署 Pod 完成。默认情况下,部署 pod 会在调度它的计算节点上消耗无限的节点资源。在大多数情况下,未绑定资源消耗不会导致问题,因为部署 pod 会消耗较低资源,并在短时间内运行。如果项目指定了默认容器限值,则部署 Pod 使用的资源以及其他 pod 数(针对这些限制)。
您可以通过在部署配置中通过部署策略限制部署 Pod 使用的资源。部署 pod 的资源限制可与 Recreate、Rolling 或 Custom 部署策略一起使用。
只有在管理员启用了临时存储技术预览功能时,才能限制 临时存储。此功能默认为禁用。
在以下示例中,resources
、cpu
、memory
和 ephemeral-storage
中每一个都是可选的:
type: "Recreate" resources: limits: cpu: "100m" 1 memory: "256Mi" 2 ephemeral-storage: "1Gi" 3
- 1
cpu
以 CPU 单元表示:100m
代表 0.1 CPU 单元(100 * 1e-3)。- 2
内存
以字节为单位:256Mi
代表 268435456 字节(256 * 2 ^ 20)。- 3
ephemeral-storage
以字节为单位:1Gi
表示 1073741824 字节(2 ^ 30)。只有管理员启用了临时存储技术预览功能时,才会提供ephemeral
-storage 参数。
不过,如果您的项目定义了配额,则需要以下两项之一:
设定了显式
requests
的resources
部分:type: "Recreate" resources: requests: 1 cpu: "100m" memory: "256Mi" ephemeral-storage: "1Gi"
- 1
requests
对象包含与配额中资源列表对应的资源列表。
请参阅 quota 和 Limit Ranges,以了解更多有关计算资源和请求与限值之间的区别的信息。
-
项目中定义的限值范围,其中
LimitRange
对象中的默认值应用到部署过程中创建的 pod。
否则,部署 pod 创建将失败,显示无法满足配额要求。
9.2.9. 手动扩展
除了回滚外,您还可以对 Web 控制台中的副本数量进行精细控制,或者使用 oc scale
命令进行精细的控制。例如,以下命令将部署配置 frontend
中的副本设置为 3。
$ oc scale dc frontend --replicas=3
副本数量最终会传播到部署配置 frontend
配置的部署的预期和当前状态。
也可以使用 oc autoscale
命令自动扩展 Pod。如需了解更多详细信息,请参阅 Pod 自动扩展。
9.2.10. 将 Pod 分配给特定的节点
您可以结合使用节点选择器和带标签的节点来控制 pod 的放置。
集群管理员可为项目设置默认节点选择器,以便将 pod 放置限制到特定的节点。作为 OpenShift Container Platform 开发人员,您可以设置 pod 配置的节点选择器来进一步限制节点。
要在创建 pod 时添加节点选择器,请编辑 pod 配置并添加 nodeSelector
值。这可添加到单个 pod 配置中,也可以添加到 pod 模板中:
apiVersion: v1 kind: Pod spec: nodeSelector: disktype: ssd ...
具有节点选择器时创建的 Pod 会分配给带有指定标签的节点。
这里指定的标签将与集群管理员添加的标签结合使用。
例如,如果项目中包含由集群管理员添加的 type=user-node
和 region=east
标签,并且您将上述 disktype: ssd
标签添加到某一 pod,则 pod 只会调度到具有所有这三个标签的节点上。
标签只能设置为一个值,因此在具有管理员设置的默认值 region=east
的 pod 配置中设置节点选择器 region=west
,这会导致 pod 永不会被调度。
9.2.11. 使用不同服务帐户运行 Pod
您可以使用非默认服务帐户运行 pod:
编辑部署配置:
$ oc edit dc/<deployment_config>
将
serviceAccount
和serviceAccountName
参数添加到spec
字段,再指定您要使用的服务帐户:spec: securityContext: {} serviceAccount: <service_account> serviceAccountName: <service_account>
9.2.12. 从 Web 控制台将 secret 添加到部署配置
将 secret 添加到部署配置中,以便它可以访问私有存储库。
9.3. 部署策略
9.3.1. 什么是部署策略?
部署策略是更改或升级应用程序的方法。其目的是在无需停机的前提下进行修改,从而使用户几乎不会注意到这些变化。
最常见的 策略是使用蓝绿部署。新版本(蓝色版本)上线进行测试和评估,同时用户仍然使用稳定版本(绿色版本)。准备就绪后,用户切换到蓝色版本。如果出现问题,您可以切回到绿色版本。
常见的替代策略是使用同时活跃的 A/B 版本,有些用户使用一个版本,而一些用户使用另一个版本。这可用于试验用户界面变化和其他功能,以获取用户反馈。它还可用来在影响有限用户的生产环境中验证正确的操作。
Canary 部署会测试新版本,但在检测到问题时,迅速回退到上一版本。这可以通过以上两个策略实现。
基于路由的部署策略不会缩放服务中的 pod 数量。为了保持所需的性能特性,部署配置可能需要扩展。
选择部署策略时需要考虑一些事项。
- 长时间运行的连接需要被安全处理。
- 数据库转换会很棘手,需要与应用程序一起执行并回滚。
- 如果应用是微服务混合且传统组件停机时间,则可能需要完成转换。
- 您需要基础架构来做到这一点。
- 如果您的测试环境没有被隔离,则可能会破坏到新版本和旧版本。
由于最终用户通常通过由路由器控制的路由访问应用程序,因此部署策略侧重于部署配置的功能或路由功能。
注重部署配置的策略会影响所有使用该应用程序的路由。侧重于路由功能的策略则会影响到单个的路由。
许多部署策略通过部署配置支持,一些额外的策略则通过路由器功能支持。本节将讨论基于部署配置的策略。
- Rolling 策略和 Canary 部署
- Recreate 策略
- Custom 策略
- 使用路由 进行蓝绿部署
- 使用路由进行/B Deployment 和 Canary 部署
- 一个 Service,多个部署配置
如果在部署配置上没有指定任何策略,则 Rolling 策略是使用的默认策略。
部署策略使用 就绪度检查 来确定新 pod 是否准备就绪。如果就绪度检查失败,部署配置将重试运行 Pod,直到超时为止。默认超时为 10m
,其值在 dc.spec.strategy.*params
的 TimeoutSeconds
中设置。
9.3.2. Rolling 策略
滚动部署会逐渐将应用程序旧版本实例替换为应用程序的新版本实例。在缩减旧组件前,滚动部署通常会借助 readiness check 等待新 Pod 变为 ready。如果发生严重问题,可以中止 Rolling 部署。
9.3.2.1. Canary 部署
OpenShift Container Platform 中的所有滚动部署都属于 Canary 部署;在替换所有旧实例前测试新的版本(Canary)。如果就绪度检查永不成功,则移除 Canary 实例,并且自动回滚部署配置。就绪度检查是应用代码的一部分,可能根据需要复杂,以确保新实例就绪可用。如果您需要对应用程序进行更复杂的检查(如向新实例发送真实用户工作负载),请考虑实施自定义部署 或使用蓝绿部署 策略。
9.3.2.2. 使用 Rolling 部署
- 希望在应用程序更新过程中不需要停机时。
- 应用程序同时支持运行旧代码和新代码时。
滚动部署意味着您同时运行旧版和新版本的代码。这通常需要您的应用程序可以处理 N-1 兼容性。
以下是 Rolling 策略的示例:
strategy: type: Rolling rollingParams: updatePeriodSeconds: 1 1 intervalSeconds: 1 2 timeoutSeconds: 120 3 maxSurge: "20%" 4 maxUnavailable: "10%" 5 pre: {} 6 post: {}
Rolling 策略将:
-
执行任何
pre
生命周期 hook。 - 根据数量扩展新的复制控制器。
- 根据最大不可用数,缩减旧的复制控制器。
- 重复这个扩展,直到新的复制控制器达到所需的副本数,并且旧的复制控制器已缩减为零。
-
执行任何
post
生命周期 hook。
在缩减时,Rolling 策略会等待 pod 准备就绪,以便它能决定进一步缩放是否会影响到可用性。如果扩展 pod 永不就绪,部署过程将最终超时并导致部署失败。
maxUnavailable
参数是在更新过程中不可用的 pod 的最大数量。maxSurge
参数是原始 pod 数量之上最多可以调度的 pod 数量。这两个参数可以设定为百分比(如 10%
)或绝对值(如 2
)。两者的默认值都是 25%
。
这些参数允许对部署的可用性和速度进行调优。例如:
-
maxUnavailable=0
和maxSurge=20%
可确保在更新和快速扩展过程中保持全部容量。 -
maxUnavailable=10%
和maxSurge
=0 使用没有额外容量(原位更新)来执行更新。 -
maxUnavailable=10%
和maxSurge=10%
,会快速扩展和缩减容量损失。
一般而言,如果您想要快速推出部署,请使用 maxSurge
。如果您需要考虑资源配额并可以接受资源部分不可用的情况,请使用 maxUnavailable
。
9.3.2.3. 滚动示例
在 OpenShift Container Platform 中,Rolling 部署是默认设置。要查看滚动更新,请按照以下步骤执行:
根据 DockerHub 中找到的示例部署镜像创建一个应用程序:
$ oc new-app openshift/deployment-example
如果您安装了路由器,请通过路由(或直接使用服务 IP)提供应用程序。
$ oc expose svc/deployment-example
通过
deployment-example.<project>.<router_domain>
访问应用程序,验证您能否看到 v1 镜像。将部署配置扩展至三个副本:
$ oc scale dc/deployment-example --replicas=3
通过为示例的新版本标上
latest
标签(tag),自动触发新部署:$ oc tag deployment-example:v2 deployment-example:latest
- 在浏览器中刷新页面,直到您看到 v2 镜像。
如果使用 CLI,以下命令会显示版本 1 上的 pod 数以及版本 2 上的数量。在 Web 控制台中,您应该会看到 pod 缓慢添加到 v2 中,并从 v1 中删除。
$ oc describe dc deployment-example
在部署过程中,新复制控制器以递增方式扩展。新 pod 标记为 ready (通过就绪度检查)后,部署过程将继续。如果 pod 尚未就绪,该过程将中止,并且部署配置将回滚到之前的版本。
9.3.3. Recreate 策略
Recreate 策略具有基本的推出部署行为,并支持用于注入代码到部署流程的生命周期 hook。
以下是 Recreate 策略的示例:
strategy: type: Recreate recreateParams: 1 pre: {} 2 mid: {} post: {}
Recreate 策略将:
-
执行任何
pre
生命周期 hook。 - 将上一部署缩减为零。
-
执行任何
mid
生命周期 hook。 - 扩展新部署。
-
执行任何
post
生命周期 hook。
在扩展过程中,如果部署副本数大于一,则先对部署的第一副本进行就绪状态验证,然后再全面扩展部署。如果第一副本验证失败,部署将被视为失败。
9.3.3.1. 何时使用 Recreate 部署
- 需要在新代码启动前进行迁移或进行其他数据转换时。
- 不支持同时运行应用程序代码的新旧版本时。
- 当使用 RWO 卷时,不支持在多个副本间共享该卷。
重新创建部署会导致停机,这是因为在短时间内没有运行应用程序实例。然而,旧代码和新代码不会被同时运行。
9.3.4. Custom 策略
Custom 策略允许您提供自己的部署行为。
以下是 Custom 策略的示例:
strategy: type: Custom customParams: image: organization/strategy command: [ "command", "arg1" ] environment: - name: ENV_1 value: VALUE_1
在上例中,organization/strategy
容器镜像提供部署行为。可选的 command
数组覆盖镜像的 Dockerfile 中指定的任何 CMD
指令。提供的可选环境变量添加到策略过程的执行环境中。
另外,OpenShift Container Platform 为部署过程提供以下环境变量:
环境变量 | 描述 |
---|---|
| 新部署(复制控制器)的名称。 |
| 新部署的命名空间。 |
新部署的副本数最初为零。该策略负责使新部署积极使用最能满足用户需求的逻辑。
了解有关 高级部署策略 的更多信息.
另外,也可使用 customParams
将自定义部署逻辑注入现有的部署策略中。提供自定义 shell 脚本逻辑并调用 openshift-deploy
二进制文件。用户不必提供自定义部署器容器镜像,但需要使用默认的 OpenShift Container Platform 部署器镜像:
strategy: type: Rolling customParams: command: - /bin/sh - -c - | set -e openshift-deploy --until=50% echo Halfway there openshift-deploy echo Complete
这会导致以下部署:
Started deployment #2 --> Scaling up custom-deployment-2 from 0 to 2, scaling down custom-deployment-1 from 2 to 0 (keep 2 pods available, don't exceed 3 pods) Scaling custom-deployment-2 up to 1 --> Reached 50% (currently 50%) Halfway there --> Scaling up custom-deployment-2 from 1 to 2, scaling down custom-deployment-1 from 2 to 0 (keep 2 pods available, don't exceed 3 pods) Scaling custom-deployment-1 down to 1 Scaling custom-deployment-2 up to 2 Scaling custom-deployment-1 down to 0 --> Success Complete
如果自定义部署策略过程需要访问 OpenShift Container Platform API 或 Kubernetes API,执行该策略的容器可以使用容器中的服务帐户令牌进行身份验证。
9.3.5. 生命周期 Hook
Recreate 和 Rolling 策略支持生命周期 hook,它允许在策略的预定义点将行为注入到部署过程中:
以下是 pre
生命周期 hook 示例:
pre:
failurePolicy: Abort
execNewPod: {} 1
- 1
execNewPod
是基于 pod 的生命周期 hook。
每个 hook 都有 failurePolicy
,定义在遇到 hook 失败时策略应执行的操作:
| 如果 hook 失败,部署过程将被视为失败。 |
| 应重试 hook 执行过程,直到成功为止。 |
| 所有 hook 失败都应忽略,部署应继续进行。 |
Hook 具有特定类型的字段,用于描述如何执行 Hook。目前,pod-based hooks 是唯一受支持的 hook 类型,通过 execNewPod
字段指定。
9.3.5.1. 基于 Pod 的生命周期 Hook
基于 Pod 的生命周期 hook 在从部署配置中模板派生的新 pod 中执行 hook 代码。
以下简化的部署配置示例使用了 Rolling 策略。为简明起见,省略了触发器和其他一些次要的细节:
kind: DeploymentConfig apiVersion: v1 metadata: name: frontend spec: template: metadata: labels: name: frontend spec: containers: - name: helloworld image: openshift/origin-ruby-sample replicas: 5 selector: name: frontend strategy: type: Rolling rollingParams: pre: failurePolicy: Abort execNewPod: containerName: helloworld 1 command: [ "/usr/bin/command", "arg1", "arg2" ] 2 env: 3 - name: CUSTOM_VAR1 value: custom_value1 volumes: - data 4
在本例中,将使用 helloworld 容器中的 openshift/origin-ruby-sample 镜像在新 pod 中执行 pre
hook。hook pod 将具有以下属性:
-
hook 命令将是
/usr/bin/command arg1 arg2
。 -
hook 容器将具有
CUSTOM_VAR1=custom_value1
环境变量。 -
hook 失败策略是
Abort
,这意味着如果 hook 失败,部署过程将失败。 -
hook pod 将从部署配置 pod 中继承
data
卷。
9.3.5.2. 使用命令行
oc set deployment-hook
命令可用于为部署配置设置部署 hook。在上例中,您可以使用以下命令设置部署前 hook:
$ oc set deployment-hook dc/frontend --pre -c helloworld -e CUSTOM_VAR1=custom_value1 \ -v data --failure-policy=abort -- /usr/bin/command arg1 arg2
9.4. 高级部署策略
9.4.1. 高级部署策略
部署策略 为应用程序的演进提供了一个途径。有些策略使用 部署配置 进行解析到应用程序的所有路由用户可见的更改。其他策略,如此处描述的那样,使用路由器功能影响特定路由。
9.4.2. 蓝绿部署
蓝绿部署涉及同时运行应用程序的两个版本,并将流量从生产版本(绿色版本)移动到更新版本(蓝色版本)。您可以使用 滚动策略 或切换路由中的服务。
由于许多应用程序依赖于持久数据,因此您将需要有一个支持 N-1 兼容性 的应用程序,这意味着您可以通过创建数据层的两个副本在数据库、存储或磁盘间共享数据并实现实时迁移。
以测试新版本时使用的数据为例。如果是生产数据,新版本中的错误可能会破坏生产版本。
9.4.2.1. 使用蓝绿部署
蓝绿部署使用两个部署配置。这两者都在运行,生产环境中的部署配置依赖于路由指定的服务,每个部署配置公开给不同的服务。您可以创建指向新版本的新路由并进行测试。准备就绪后,将生产路由中的服务更改为指向新服务和新的 blue 版本。
如果需要,可以通过将服务切回到之前的版本以回滚到老的绿色版本。
使用路由和两个服务
这个示例设置了两个部署配置:一个用于稳定版本(绿色版本),另一个用于较新的版本(蓝色版本)。
路由指向某个服务,可以随时更改为指向不同服务。作为开发人员,您可以在生产流量路由到前连接到新服务来测试新版代码。
路由适用于 Web(HTTP 和 HTTPS)流量,因此这种技术最适合 Web 应用程序。
创建示例应用程序的两个副本:
$ oc new-app openshift/deployment-example:v1 --name=example-green $ oc new-app openshift/deployment-example:v2 --name=example-blue
这会创建两个独立的应用程序组件:一个在
example-green
服务下运行 v1 镜像,另一个使用example-blue
服务下的 v2 镜像。创建指向旧服务的路由:
$ oc expose svc/example-green --name=bluegreen-example
-
通过
example-green.<project>.<router_domain>
访问应用程序,验证您能否看到 v1 镜像。 编辑路由并将服务名称改为
example-blue
:$ oc patch route/bluegreen-example -p '{"spec":{"to":{"name":"example-blue"}}}'
- 要验证路由是否已改变,请刷新浏览器直到您看到 v2 镜像。
9.4.3. A/B 部署
A/B 部署策略允许您在生产环境中以有限的方式尝试应用程序的新版本。您可以指定生产版本获得大多数用户请求,同时让有限比例的请求进入新版本。由于您控制对每个版本的请求部分,在测试过程中,您可以增加对新版本的请求的比例,最终停止使用上一版本。当您调整每个版本的请求负载时,可能需要扩展各个服务中的 pod 数量,以提供预期的性能。
除了升级软件外,您还可以使用此功能来试验用户界面的不同版本。由于部分用户会使用旧版本,而另外的一部分用户会使用新版本,因此您可以评估用户对不同版本的反应,以做出明智的设计决策。
要实现这一目的,旧的和新版本需要足够相似,两者可以同时运行。这常用于对程序错误修复的发布,也适用于新功能不会影响到旧功能的情况。版本需要 N-1 兼容性 才能正常工作。
OpenShift Container Platform 通过 Web 控制台和命令行界面支持 N-1 兼容性。
9.4.3.1. A/B 测试的负载均衡
用户设置使用多个服务设置路由。每个服务负责应用程序的一个版本。
每个服务分配到一个 weight
,进入每个服务的请求的比例等于 service_weight
除以 sum_of_weights
。每个服务的 weight
分布到该服务的端点,使得端点 weight
的总和等于服务 weight
。
路由最多可有四个服务。服务的 weight
可以在 0
到 256
范围内。当 weight
等于 0
时,服务不参与负载均衡,但继续为现有的持久连接服务。当服务 weight
不为 0
时,每个端点的最小 weight
为 1
。因此,拥有大量端点的服务会得到高于必要值的 weight
。这时,可以减少 pod 数量来获得所需的负载均衡 weight
。如需更多信息,请参阅 Alternate Backends 和 Weights 部分。
Web 控制台允许用户设置权重并在它们之间显示平衡:
设置 A/B 环境:
创建两个应用程序并使用不同的名称。每一个都会创建一个部署配置。应用程序是同一程序的不同版本;一个是当前生产版本,另一个是提议的新版本:
$ oc new-app openshift/deployment-example1 --name=ab-example-a $ oc new-app openshift/deployment-example2 --name=ab-example-b
公开部署配置以创建服务:
$ oc expose dc/ab-example-a --name=ab-example-A $ oc expose dc/ab-example-b --name=ab-example-B
此时两个应用都已部署,并且正在运行并且具有服务。
通过路由对外提供应用程序。此时可以公开任何服务,公开当前生产版本和后来修改路由以添加新版本。
$ oc expose svc/ab-example-A
通过
ab-example.<project>.<router_domain>
访问应用程序,验证您能否看到所需的版本。当您部署路由时,路由器将根据为服务指定的
weight
来均衡流量。此时,有一个带有默认weight=1
的单个服务,因此所有请求都会进入该服务。将其他服务添加为alternateBackend
,调整weight
会使 A/B 设置生效。这可通过oc set route-backends
命令或编辑路由来完成。将
oc set route-backend
设置为 0 意味着服务不参与负载均衡,而是继续为现有的持久连接服务。注意对路由的更改只会改变流量进入各个服务的比例。您可能需要扩展部署配置,以调整 pod 数量,以处理预期的负载。
若要编辑路由,请运行:
$ oc edit route <route-name> ... metadata: name: route-alternate-service annotations: haproxy.router.openshift.io/balance: roundrobin spec: host: ab-example.my-project.my-domain to: kind: Service name: ab-example-A weight: 10 alternateBackends: - kind: Service name: ab-example-B weight: 15 ...
9.4.3.1.1. 使用 Web 控制台管理 Weights
- 导航到 Route 详情页面 (Applications/Routes)。
- 从 Actions 菜单中选择 Edit。
- 选中 Split traffic across multiple services。
Service Weights 滑块设置发送到各个服务的流量的百分比。
如果在超过两个服务之间进行流量分割,各个服务的相对权重通过 0 到 256 范围内的整数来指定。
在分割流量的应用程序的展开行中 Overview 上会显示流量加权情况。
9.4.3.1.2. 使用 CLI 管理 Weights
此命令会由路由管理服务和对应的权重负载均衡。
$ oc set route-backends ROUTENAME [--zero|--equal] [--adjust] SERVICE=WEIGHT[%] [...] [options]
例如,以下命令将 ab-example-A
设置为主服务,weight=198
和 ab-example-B
作为第一个替代服务,值为 weight=2
:
$ oc set route-backends web ab-example-A=198 ab-example-B=2
这意味着 99% 的流量将发送到服务 ab-example-A
,1% 发送到服务 ab-example-B
。
此命令不扩展部署配置。您可能需要进行此操作,才能有足够的 pod 来处理请求负载。
不带标志的命令会显示当前的配置。
$ oc set route-backends web NAME KIND TO WEIGHT routes/web Service ab-example-A 198 (99%) routes/web Service ab-example-B 2 (1%)
--adjust
标志可让您更改单个服务相对于自身或主服务的权重。指定百分比将调整相对于主服务或第一个替代服务(如果指定了主服务)的服务。如果还有其他后端,它们的权重会与更改的比例保持比例。
$ oc set route-backends web --adjust ab-example-A=200 ab-example-B=10 $ oc set route-backends web --adjust ab-example-B=5% $ oc set route-backends web --adjust ab-example-B=+15%
--equal
标志将所有服务的权重
设置为 100
$ oc set route-backends web --equal
--zero
标志将所有服务的 weight
设为 0。所有请求都将返回 503 错误。
并非所有路由器都支持多个后端或加权后端。
9.4.3.1.3. 一个 Service,多个部署配置
如果您安装了路由器,请通过路由(或直接使用服务 IP)提供应用程序:
$ oc expose svc/ab-example
通过 ab-example.<project>.<router_domain>
访问应用程序,验证您能否看到 v1 镜像。
根据与第一个分片相同的源镜像创建第二个分片,但使用不同的标记版本,并设置唯一值:
$ oc new-app openshift/deployment-example:v2 --name=ab-example-b --labels=ab-example=true SUBTITLE="shard B" COLOR="red"
编辑新创建的分片,以设置对所有分片通用的
ab-example=true
标签:$ oc edit dc/ab-example-b
在编辑器中,将
spec.selector
和spec.template.metadata.labels
所在的ab-example: "true"
行与现有的deploymentconfig=ab-example-b
标签一起添加。保存并退出编辑器。触发第二个分片的重新部署以获取新标签:
$ oc rollout latest dc/ab-example-b
在这一刻,路由下同时提供了两组 pod。但是,由于两个浏览器(通过保持连接打开)和路由器(默认为 Cookie)将尝试保留与后端服务器的连接,所以您可能不会看到两个分片都返回给您。要将浏览器强制到其中一个分片,请使用 scale 命令:
$ oc scale dc/ab-example-a --replicas=0
刷新浏览器应该会显示 v2 和 shard B (红色)。
$ oc scale dc/ab-example-a --replicas=1; oc scale dc/ab-example-b --replicas=0
刷新浏览器应该会显示 v1 和 shard A (蓝色)。
如果您在任一分片上触发部署,则只有该分片中的 pod 会受到影响。您可以通过
oc edit dc/ab-example-a
或oc edit dc/ab-example-b
更改SUBTITLE
环境变量来轻松地触发部署。您可以通过重复步骤 5-7 来添加额外的分片。注意这些步骤将在以后的 OpenShift Container Platform 版本中简化。
9.4.4. 代理分片/流量分割
在生产环境中,您可以精确控制特定分片上的流量分布。在处理大量实例时,可以使用相对比例的独立分片来实现基于百分比的流量分布。这可与代理分片良好结合,将接收到的流量转发或分割到在其他位置运行的单独服务或应用程序。
在最简单的配置中,代理会原封不动转发请求。在比较复杂的设置中,可以复制传入的请求,同时将它们发送到独立集群以及应用程序的本地实例,并且比较其结果。其他模式包括使 DR 安装的缓存保持活跃,或抽样传入的流量来满足分析需要。
虽然实施超出本例的范围,但任何 TCP(或 UDP)代理都可以在所需分片下运行。使用 oc scale
命令更改代理分片下服务请求的相对数量。对于更复杂的流量管理,请考虑使用比例平衡功能自定义 OpenShift Container Platform 路由器。
9.4.5. N-1 兼容性
同时运行新旧代码的应用程序必须要谨慎处理,以确保新代码写入的数据能被旧版代码读取和处理(或恰当忽略)。这有时被称为架构演进,而且是一个复杂的问题。
这可以采用磁盘上、数据库、临时缓存或者作为用户浏览器会话的一部分存储在磁盘上的多个形式。虽然大多数 Web 应用程序都支持滚动部署,但务必要测试并设计您的应用程序以便能处理它。
在一些应用程序中,同时运行新旧代码的时间是短暂的,因此程序错误或一些用户事务失败是可以接受的。至于其他应用程序,失败模式可能会导致整个应用程序无法运作。
验证 N-1 兼容性的一种方法是使用 A/B 部署。在测试环境中以受控的方式同时运行旧代码和新代码,并验证流到新部署的流量不会导致旧部署失败。
9.4.6. 正常终止
OpenShift Container Platform 和 Kubernetes 会留出时间,让应用程序实例关机后再从负载均衡轮转中移除。但是,应用程序必须保证在用户退出前彻底终止用户连接。
在关闭时,OpenShift Container Platform 会将 TERM 信号发送到容器中的进程。接收 SIGTERM 时的应用程序代码应该停止接受新的连接。这将确保负载均衡器将流量路由到其他活跃实例。然后,应用程序代码应等到所有打开的连接都关闭(或在下次机会出现时恰当终止独立的连接)后再退出。
在恰当终止期限到期后,未退出的进程将发送 KILL 信号,该信号会立即结束该进程。pod 或 pod 模板的 terminationGracePeriodSeconds
属性控制恰当终止期限(默认值 30 秒),并可根据需要自定义每个应用程序。
9.5. Kubernetes Deployments 支持
9.5.1. 部署对象类型
Kubernetes 在 OpenShift Container Platform 中提供了一流的对象类型,名为 deployments。此对象类型(这里称为 Kubernetes 部署 )用作部署配置对象类型的后代。
与部署配置一样,Kubernetes 部署将应用程序特定组件的所需状态描述为 pod 模板。Kubernetes 部署创建 副本集 ( 复制控制器迭代),用于编配 pod 生命周期。
例如,此 Kubernetes 部署的定义会创建一个副本集来启动一个 hello-openshift pod:
Kubernetes 部署定义 hello-openshift-deployment.yaml示例
apiVersion: apps/v1 kind: Deployment metadata: name: hello-openshift spec: replicas: 1 selector: matchLabels: app: hello-openshift template: metadata: labels: app: hello-openshift spec: containers: - name: hello-openshift image: openshift/hello-openshift:latest ports: - containerPort: 80
将定义保存到本地文件后,就可以使用它来创建 Kubernetes 部署:
$ oc create -f hello-openshift-deployment.yaml
您可以使用 CLI 检查并运行 Kubernetes 部署,以及与其他对象类型一样的副本集,如 Common Operations(例如 get
和 describe
)所述。对于对象类型,为 Kubernetes 部署使用 deployments
或 deploy
,为副本集使用 replicasets
或 rs
。
如需有关 Deployment 和 Replica Sets 的更多详细信息,请参阅 Kubernetes 文档,在 CLI 用法示例中使用 oc
替换 kubectl
。
9.5.2. Kubernetes Deployments 和部署配置
由于在 Kubernetes 1.2 中添加了部署之前,OpenShift Container Platform 中存在部署配置,因此后者的对象类型与之前稍有的稍有不同。OpenShift Container Platform 中的长期目标是访问 Kubernetes 部署中的完整功能奇偶校验,并通过应用程序将其切换到使用单一的对象类型来提供精细管理。
支持 Kubernetes 部署,以确保使用新对象类型的上游项目和示例可以在 OpenShift Container Platform 上平稳运行。根据当前的 Kubernetes 部署功能集,如果不计划使用以下任一操作,则在 OpenShift Container Platform 中使用它们而不是部署配置:
以下部分详细阐述两种对象类型之间的区别,以进一步协助您决定何时想通过部署配置使用 Kubernetes 部署。
9.5.2.1. 部署配置特定功能
9.5.2.1.1. 自动回滚
Kubernetes 部署不支持在出现故障时自动回滚到上次成功部署的副本集。此功能会很快被添加。
9.5.2.1.2. 触发器
Kubernetes 部署有一个隐式 ConfigChange
触发器,每次更改部署的 Pod 模板都会自动触发新的推出部署。如果您不想在 Pod 模板更改时进行新的推出部署,请暂停部署:
$ oc rollout pause deployments/<name>
目前,Kubernetes 部署不支持 ImageChange
触发器。上游建议了一个通用触发机制,但如果它被接受,则代表未知。最终,OpenShift Container Platform 的特定机制可以实施为 Kubernetes 部署之上的层,但最好作为 Kubernetes 内核的一部分存在。
9.5.2.1.3. 生命周期 Hook
Kubernetes 部署不支持任何生命周期 hook。
9.5.2.1.4. 自定义策略
Kubernetes 部署尚不支持用户指定的自定义部署策略。
9.5.2.1.5. Canary 部署
Kubernetes 部署还没有作为新推出部署的一部分运行。
9.5.2.1.6. 测试部署
Kubernetes 部署不支持运行测试跟踪。
9.5.2.2. 特定于 Kubernetes 部署的功能
9.5.2.2.1. 滚动
Kubernetes 部署的部署过程是由控制器循环推动的,这与使用部署器 Pod 进行每次新推出部署的部署配置相反。这意味着,Kubernetes 部署可以拥有尽可能多的活跃副本集,最终部署控制器将缩减所有旧副本集,并扩展最新的副本集。
部署配置最多可以有一个部署器 pod 运行,否则多个部署器最终会相互努力以扩展它们认为是最新的复制控制器。因此,任何时间点上只能有两个复制控制器处于活跃状态。最终,这会转化为 Kubernetes 部署的快速推出部署。
9.5.2.2.2. 按比例扩展
因为 Kubernetes 部署控制器是部署所拥有的新旧副本集的大小的唯一来源,所以它可以扩展正在进行的推出部署。额外副本会根据每个副本集的大小按比例分发。
当一个推出部署(rollout)正在进行时无法扩展部署配置,因为部署配置控制器最终与部署器进程有关新复制控制器的大小。
9.5.2.2.3. 暂停 Mid-rollout
Kubernetes 部署可以在任何时间点上暂停,这意味着您可以暂停正在进行的推出部署。另一方面,当前无法暂停部署器 Pod。因此,如果您尝试在推出部署进行期间暂停部署配置,则部署器进程不受影响,它会继续运行直到完成为止。
第 10 章 模板
10.1. 概述
模板描述了一组可参数化和处理的对象,用于生成对象列表,供 OpenShift Container Platform 用于创建。可对模板进行处理,以创建您有权在项目中创建的任何内容,如 服务、构建配置和部署配置。模板还可定义一系列标签(label),以应用到该模板中定义的每个对象。
您可以使用 CLI 从模板创建对象列表,或者如果模板已上传至项目或全局模板库,则可使用 web 控制台来创建。有关一组策展的模板,请参阅 OpenShift 镜像流和模板库。
10.2. 上传模板
如果您有定义模板的 JSON 或 YAML 文件,如 本例中所示,您可以使用 CLI 将模板上传到项目。此操作将模板保存到项目,供任何有适当权限访问该项目的用户重复使用。本主题后面会介绍如何编写自己的模板。
要将模板上传到当前项目的模板库,请使用以下命令传递 JSON 或 YAML 文件:
$ oc create -f <filename>
您可以使用 -n
选项以及项目名称将模板上传到其他项目:
$ oc create -f <filename> -n <project>
现在可使用 web 控制台或 CLI 选择该模板。
10.3. 使用 Web 控制台从模板创建
请参阅使用 Web 控制台创建应用程序。
10.4. 使用 CLI 从模板创建
您可以使用 CLI 来处理模板,并使用所生成的配置来创建对象。
10.4.1. 标签
标签 (label)用于管理和组织生成的对象,如 pod。模板中指定的标签应用于从模板生成的每个对象。
也可以从命令行在模板中添加标签。
$ oc process -f <filename> -l name=otherLabel
10.4.2. 参数
模板的 parameter
部分列出了可覆盖的参数列表。您可以使用以下命令并指定要使用的文件来通过 CLI 列出它们:
$ oc process --parameters -f <filename>
或者,如果模板已上传:
$ oc process --parameters -n <project> <template_name>
例如,下面显示了在默认 openshift 项目中列出其中一个 Quickstart 模板的参数时的输出:
$ oc process --parameters -n openshift rails-postgresql-example NAME DESCRIPTION GENERATOR VALUE SOURCE_REPOSITORY_URL The URL of the repository with your application source code https://github.com/sclorg/rails-ex.git SOURCE_REPOSITORY_REF Set this to a branch name, tag or other ref of your repository if you are not using the default branch CONTEXT_DIR Set this to the relative path to your project if it is not in the root of your repository APPLICATION_DOMAIN The exposed hostname that will route to the Rails service rails-postgresql-example.openshiftapps.com GITHUB_WEBHOOK_SECRET A secret string used to configure the GitHub webhook expression [a-zA-Z0-9]{40} SECRET_KEY_BASE Your secret key for verifying the integrity of signed cookies expression [a-z0-9]{127} APPLICATION_USER The application user that is used within the sample application to authorize access on pages openshift APPLICATION_PASSWORD The application password that is used within the sample application to authorize access on pages secret DATABASE_SERVICE_NAME Database service name postgresql POSTGRESQL_USER database username expression user[A-Z0-9]{3} POSTGRESQL_PASSWORD database password expression [a-zA-Z0-9]{8} POSTGRESQL_DATABASE database name root POSTGRESQL_MAX_CONNECTIONS database max connections 10 POSTGRESQL_SHARED_BUFFERS database shared buffers 12MB
该输出标识了在处理模板时使用类似正则表达式的生成器生成的几个参数。
10.4.3. 生成对象列表
使用 CLI,您可以处理定义模板的文件,以将对象列表返回到标准输出:
$ oc process -f <filename>
或者,如果模板已上传到当前项目:
$ oc process <template_name>
您可以通过处理模板并将输出传送至 oc create
来从模板创建对象:
$ oc process -f <filename> | oc create -f -
或者,如果模板已上传到当前项目:
$ oc process <template> | oc create -f -
您可以为每个要覆盖的 <name>=<value>
对添加 -p
选项,以覆盖文件中定义的任何参数值。参数引用可能会出现在模板项目内的任何文本字段中。
例如,在以下部分中,模板的 POSTGRESQL_USER
和 POSTGRESQL_DATABASE
参数被覆盖,以输出带有自定义环境变量的配置:
例 10.1. 从模板创建对象列表
$ oc process -f my-rails-postgresql \ -p POSTGRESQL_USER=bob \ -p POSTGRESQL_DATABASE=mydatabase
JSON 文件可重定向到文件,也可直接应用,而无需通过将已处理的输出传送到 oc create
命令来上传模板:
$ oc process -f my-rails-postgresql \ -p POSTGRESQL_USER=bob \ -p POSTGRESQL_DATABASE=mydatabase \ | oc create -f -
如有大量参数,可将其保存到文件中,然后将此文件传递到 oc process
:
$ cat postgres.env POSTGRESQL_USER=bob POSTGRESQL_DATABASE=mydatabase $ oc process -f my-rails-postgresql --param-file=postgres.env
此外,您还可使用 "-"
作为 --param-file
的参数,从标准输入中读取环境:
$ sed s/bob/alice/ postgres.env | oc process -f my-rails-postgresql --param-file=-
10.5. 修改上传的模板
您可以使用以下命令编辑已上传至项目中的模板:
$ oc edit template <template>
10.6. 使用 Instant App 和 Quickstart Templates
OpenShift Container Platform 提供很多默认的 Instant App 和 Quickstart 模板,有助于快速开始为不同语言创建新应用程序。提供了适用于 Rails (Ruby)、Django (Python)、Node.js、CakePHP (PHP) 和 Dancer (Perl) 的模板。您的集群管理员应已在默认的全局 openshift 项目中创建了这些模板,以便您访问。您可通过以下命令列出可用的默认 Instant App 和 Quickstart 模板:
$ oc get templates -n openshift
如果没有这些内容,请推荐集群管理员参阅 Loading the Default Image Streams and Templates 中的内容。
默认情况下,模板会使用 GitHub 上包含所需应用程序代码的公共源存储库进行构建。要修改源并构建您自己的应用程序版本,您必须:
-
对模板默认的
SOURCE_REPOSITORY_URL
参数引用的存储库进行分叉。 -
在从模板创建时,覆盖
SOURCE_REPOSITORY_URL
参数的值,从而指定您的分叉而非默认值。
这样,模板创建的构建配置将指向应用程序代码的分叉,您可随意修改代码和重新构建应用程序。
使用 Web 控制台进行这个过程的内容包括在开发人员入门:Web 控制台。
某些 Instant App 和 Quickstart 模板会定义一个 数据库部署配置。它们定义的配置对数据库内容使用临时存储。这些模板仅限于演示目的,因为如果数据库 pod 因任何原因重启,所有数据库数据都将丢失。
10.7. 编写模板
您可以定义新模板,以便轻松重新创建应用程序的所有对象。该模板将定义由其创建的对象以及一些元数据,以指导创建这些对象。
例 10.2. 简单模板对象定义(YAML)
apiVersion: v1 kind: Template metadata: name: redis-template annotations: description: "Description" iconClass: "icon-redis" tags: "database,nosql" objects: - apiVersion: v1 kind: Pod metadata: name: redis-master spec: containers: - env: - name: REDIS_PASSWORD value: ${REDIS_PASSWORD} image: dockerfile/redis name: master ports: - containerPort: 6379 protocol: TCP parameters: - description: Password used for Redis authentication from: '[A-Z0-9]{8}' generate: expression name: REDIS_PASSWORD labels: redis: master
10.7.1. 描述
模板描述向用户介绍模板的作用,有助于用户在 web 控制台中搜索查找模板。除模板名称以外的其他元数据均为可选,但若有则会非常有用。除常规描述性信息外,元数据还应包含一组标签。实用标签包括与模板相关的语言名称(如 java、php、ruby 等)。
例 10.3. 模板描述元数据
kind: Template apiVersion: v1 metadata: name: cakephp-mysql-example 1 annotations: openshift.io/display-name: "CakePHP MySQL Example (Ephemeral)" 2 description: >- An example CakePHP application with a MySQL database. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/cakephp-ex/blob/master/README.md. WARNING: Any data stored will be lost upon pod destruction. Only use this template for testing." 3 openshift.io/long-description: >- This template defines resources needed to develop a CakePHP application, including a build configuration, application deployment configuration, and database deployment configuration. The database is stored in non-persistent storage, so this configuration should be used for experimental purposes only. 4 tags: "quickstart,php,cakephp" 5 iconClass: icon-php 6 openshift.io/provider-display-name: "Red Hat, Inc." 7 openshift.io/documentation-url: "https://github.com/sclorg/cakephp-ex" 8 openshift.io/support-url: "https://access.redhat.com" 9 message: "Your admin credentials are ${ADMIN_USERNAME}:${ADMIN_PASSWORD}" 10
- 1
- 模板的唯一名称。
- 2
- 可由用户界面使用的简单、用户友好型名称。
- 3
- 模板的描述。包含充足的详细信息,供用户了解所部署的内容以及部署前须知的注意事项。此外,还应提供其他信息链接,如 README 文件。可包括换行符来创建段落。
- 4
- 其他模板描述。例如,这可按照服务目录显示。
- 5
- 6
- 在 web 控制台中与模板一同显示的图标。尽可能从现有 徽标图标 中进行选择。也可使用 FontAwesome 和 PatternFly 中的图标。另外,也可通过 CSS 自定义 提供图标,它们可添加到使用模板的 OpenShift Container Platform 集群中。您必须指定一个存在的图标类,否则它将阻止回退到通用图标。
- 7
- 提供模板的个人或组织的名称。
- 8
- 用于参考更多模板文档的 URL。
- 9
- 用于获取模板支持的 URL。
- 10
- 模板实例化时显示的说明消息。该字段应向用户介绍如何使用新建资源。显示消息前,对消息进行参数替换,以便输出中包含所生成的凭据和其他参数。其中包括用户应遵守的所有后续步骤文档链接。
10.7.2. 标签
模板可包含一组标签。这些标签将添加至模板实例化时创建的各个对象中。采用这种方式定义标签可方便用户查找和管理从特定模板创建的所有对象。
10.7.3. 参数
允许用户提供一个值或在实例化模板时生成一个值作为参数。然后,该值将在引用参数的任意位置上被替换。可在对象列表字段中的任意字段中定义引用。这有助于生成随机密码,或允许用户提供自定义模板时所需的主机名或其他用户特定值。可通过以下两种方式引用参数:
- 作为字符串值,将格式为 ${PARAMETER_NAME} 的值放在模板的任意字符串字段中。
- 作为 json/yaml 值,将格式为 ${PARAMETER_NAME} 的值放在模板的任意字段中。
使用 ${PARAMETER_NAME} 语法时,可将多个参数引用合并到一个字段中,并可将引用嵌入到固定数据中,如 "http://${PARAMETER_1}${PARAMETER_2}"。两个参数值均将被替换,结果值将是一个带引号的字符串。
使用 ${{PARAMETER_NAME}} 语法时,仅允许单个参数引用,不允许使用前导/尾随字符。执行替换后,结果值将不加引号,除非结果不是有效的 json 对象。如果结果不是有效的 json 值,则结果值将加引号并被视为标准字符串。
单个参数可在模板中多次引用,且可在单个模板中使用两种替换语法来引用。
可提供默认值,如果用户未提供其他值则使用默认值:
例 10.5. 将一个明确的值设置为默认值
parameters: - name: USERNAME description: "The user name for Joe" value: joe
也可通过参数定义中指定的规则生成参数值:
例 10.6. 生成参数值
parameters: - name: PASSWORD description: "The random user password" generate: expression from: "[a-zA-Z0-9]{12}"
在上例中,处理将生成一个由大小写字母和数字组成的 12 个字符长的随机密码。
可用语法并非完整的正则表达式语法。但是,您可以使用 \w
、\d
和 \a
修饰符:
-
[\w]{10}
生成 10 个字母字符、数字和下划线。它遵循 PCRE 标准,等同于[a-zA-Z0-9_]{10}
。 -
[\d]{10}
生成 10 个数字。等同于[0-9]{10}
。 -
[\a]{10}
生成 10 个字母字符。这等同于[a-zA-Z]{10}
。
下面是附带参数定义和参考的完整模板示例:
例 10.7. 带有参数定义和参考的完整模板
kind: Template apiVersion: v1 metadata: name: my-template objects: - kind: BuildConfig apiVersion: v1 metadata: name: cakephp-mysql-example annotations: description: Defines how to build the application spec: source: type: Git git: uri: "${SOURCE_REPOSITORY_URL}" 1 ref: "${SOURCE_REPOSITORY_REF}" contextDir: "${CONTEXT_DIR}" - kind: DeploymentConfig apiVersion: v1 metadata: name: frontend spec: replicas: "${{REPLICA_COUNT}}" 2 parameters: - name: SOURCE_REPOSITORY_URL 3 displayName: Source Repository URL 4 description: The URL of the repository with your application source code 5 value: https://github.com/sclorg/cakephp-ex.git 6 required: true 7 - name: GITHUB_WEBHOOK_SECRET description: A secret string used to configure the GitHub webhook generate: expression 8 from: "[a-zA-Z0-9]{40}" 9 - name: REPLICA_COUNT description: Number of replicas to run value: "2" required: true message: "... The GitHub webhook secret is ${GITHUB_WEBHOOK_SECRET} ..." 10
- 1
- 模板实例化时,该值将被替换为
SOURCE_REPOSITORY_URL
参数的值。 - 2
- 模板实例化时,该值将被替换为
REPLICA_COUNT
参数的不加引号值。 - 3
- 参数的名称。该值用于引用模板中的参数。
- 4
- 参数的用户友好型名称。这将对用户显示。
- 5
- 参数的描述。出于参数目的提供更详细的信息,包括对预期值的任何限制。描述应当按照控制台的文本标准使用完整句子。不可与显示名称重复。
- 6
- 如果用户实例化该模板时未覆盖该值,则将使用该参数的默认值。密码之类避免使用默认值,而应结合使用生成的参数与 Secret。
- 7
- 指示此参数为必填项,表示用户无法用空白值覆盖它。如果该参数未提供默认值或生成值,则用户必须提供一个值。
- 8
- 生成其值的参数。
- 9
- 生成器的输入。这种情况下,生成器会生成一个 40 个字符的字母数字值,其中包括大写和小写字符。
- 10
- 参数可包含在模板消息中。此项告知用户生成的值。
10.7.4. 对象列表
模板主要部分为对象列表,将在模板实例化时创建。这可以是任何有效的 API 对象,如 BuildConfig
、DeploymentConfig
、Service
等。该对象将完全按照此处定义创建,创建前替换任意参数值。这些对象的定义可引用前面定义的参数。
kind: "Template"
apiVersion: "v1"
metadata:
name: my-template
objects:
- kind: "Service" 1
apiVersion: "v1"
metadata:
name: "cakephp-mysql-example"
annotations:
description: "Exposes and load balances the application pods"
spec:
ports:
- name: "web"
port: 8080
targetPort: 8080
selector:
name: "cakephp-mysql-example"
- 1
- 将由该模板创建的
Service
的定义。
如果对象定义的元数据包含固定的 namespace
字段值,则在模板实例化过程中,该字段将从定义中剥离出来。如果 namespace
字段包含参数引用,则将执行正常的参数替换,并参数替换将值解析到的任何命名空间中创建对象,假定用户有权在该命名空间中创建对象。
10.7.5. 将模板标记为可绑定
模板服务代理在目录中为其了解的每个模板对象公告一个服务。默认情况下,每个服务均会公告为“可绑定”,表示允许最终用户绑定制备的服务。
模板创建者可将注解 template.openshift.io/bindable: "false"
添加到模板中,防止最终用户绑定从给定模板制备的服务。
10.7.6. 公开对象字段
模板创建者可指定模板中的特定对象字段应公开。模板服务代理识别 ConfigMap、Secret、Service 和 Route 上的公开字段,并在用户绑定代理支持的服务时返回公开字段的值。
要公开对象的一个或多个字段,请在模板中为对象添加以 template.openshift.io/expose-
或 template.openshift.io/base64-expose-
为前缀的注解。
每个移除前缀的注解键均会被传递成为 bind
响应中的一个键。
每个注解值是一个 Kubernetes JSONPath 表达式,它会在绑定时解析,以指示应在 bind
响应中返回值的对象字段。
Bind
响应键/值对可在系统其他部分用作环境变量。因此,建议删除前缀的每个注解键均应为有效的环境变量名称,以字符 A-Z
、a-z
或下划线开头,后跟 0 个或多个 A-Z
、a-z
、0-9
或下划线字符。
使用 template.openshift.io/expose-
注解来以字符串形式返回字段值。这样很方便,尽管没有处理任意二进制数据。如果要返回二进制数据,请在返回前使用 template.openshift.io/base64-expose-
注解对数据进行 base64 编码。
除非用反斜杠转义,否则 Kubernetes 的 JSONPath 实现会将 .
、@
字符等解析为元字符,而无关其在表达式中的位置。因此,例如要引用名为 my.key
的 ConfigMap
数据,所需 JSONPath 表达式应为 {.data['my\.key']}
。根据 JSONPath 表达式在 YAML 中的编写方式,可能需要额外增加反斜杠,如 "{.data['my\\.key']}"
。
以下是被公开的不同对象字段的示例:
kind: Template apiVersion: v1 metadata: name: my-template objects: - kind: ConfigMap apiVersion: v1 metadata: name: my-template-config annotations: template.openshift.io/expose-username: "{.data['my\\.username']}" data: my.username: foo - kind: Secret apiVersion: v1 metadata: name: my-template-config-secret annotations: template.openshift.io/base64-expose-password: "{.data['password']}" stringData: password: bar - kind: Service apiVersion: v1 metadata: name: my-template-service annotations: template.openshift.io/expose-service_ip_port: "{.spec.clusterIP}:{.spec.ports[?(.name==\"web\")].port}" spec: ports: - name: "web" port: 8080 - kind: Route apiVersion: v1 metadata: name: my-template-route annotations: template.openshift.io/expose-uri: "http://{.spec.host}{.spec.path}" spec: path: mypath
下面是在遵守上述部分模板情况下,对 bind
操作的一个响应示例:
{ "credentials": { "username": "foo", "password": "YmFy", "service_ip_port": "172.30.12.34:8080", "uri": "http://route-test.router.default.svc.cluster.local/mypath" } }
10.7.7. 等待模板就绪
模板创建者可指定:在服务目录、Template Service Broker 或 TemplateInstance API 进行的模板实例化被视为完成之前,应等待模板中的某些对象。
要使用该功能,请使用以下注解在模板中标记一个或多个Build
、BuildConfig
、Deployment
、DeploymentConfig
、Job
或 StatefulSet
类型的对象:
"template.alpha.openshift.io/wait-for-ready": "true"
直到标有注解的所有对象报告就绪时,模板实例化才算完成。同样,如果任何注解的对象报告失败,或者模板未能在一小时的固定超时内就绪,则模板实例化将失败。
就实例化而言,各种对象类型的就绪和失败定义如下:
类型 | 就绪 | 失败 |
---|---|---|
| 对象报告阶段完成 | 对象报告阶段取消、错误或失败 |
| 最新关联构建对象报告阶段完成 | 最新关联构建对象报告阶段取消、错误或失败 |
| 对象报告新的 ReplicaSet 和部署可用(这遵循对象上定义的就绪探针) | 对象报告进度状况为错误 |
| 对象报告新的 ReplicationController 和部署可用(这遵循对象上定义的就绪探针) | 对象报告进度状况为错误 |
| 对象报告完成 | 对象报告出现一个或多个故障 |
| 对象报告所有副本就绪(这遵循对象上定义的就绪探针) | 不适用 |
以下是使用 wait-for-ready
注解的模板提取示例。更多示例可在 OpenShift quickstart 模板中找到。
kind: Template apiVersion: v1 metadata: name: my-template objects: - kind: BuildConfig apiVersion: v1 metadata: name: ... annotations: # wait-for-ready used on BuildConfig ensures that template instantiation # will fail immediately if build fails template.alpha.openshift.io/wait-for-ready: "true" spec: ... - kind: DeploymentConfig apiVersion: v1 metadata: name: ... annotations: template.alpha.openshift.io/wait-for-ready: "true" spec: ... - kind: Service apiVersion: v1 metadata: name: ... spec: ...
10.7.8. 其他建议
10.7.9. 从现有对象创建模板
您可以 YAML 格式从项目中导出现有对象,然后通过添加参数和其他自定义作为模板表单来修改 YAML,而无需从头开始编写整个模板。要以 YAML 格式导出项目中的对象,请运行:
$ oc get -o yaml --export all > <yaml_filename>
您还可替换特定资源类型或多个资源,而非 all
资源。运行 oc get -h
获取更多示例。
oc get --export all
中包括的对象类型是:
- BuildConfig
- Build
- DeploymentConfig
- ImageStream
- Pod
- ReplicationController
- Route
- 服务
第 11 章 打开远程 shell 至容器
11.1. 概述
oc rsh
命令允许您在本地访问和管理系统中的工具。安全 shell(SSH)是底层技术和行业标准,可提供到应用程序的安全连接。使用 shell 环境访问应用程序通过安全增强型 Linux(SELinux)策略受到保护限制。
11.2. 启动 Secure Shell 会话
打开到容器的远程 shell 会话:
$ oc rsh <pod>
在远程 shell 中,您可以像在容器内部一样发出命令进行内部操作,如监控、故障调试等,并执行特定于容器中运行的项的 CLI 命令。
例如,在 MySQL 容器中,您可以通过调用 mysql
命令 来计算数据库中的记录数量,然后使用 提示符在 SELECT
命令中键入。您还可以使用 ps(1)
和 ls(1)
等命令进行验证。
BuildConfig
和 DeployConfigs
用于定义您需要的项,pod(内部使用容器)会根据需要被创建或销毁。您的更改不持久。如果您直接在容器内进行更改,且该容器被销毁并重新构建,则您的更改将不再存在。
oc exec
可用于远程执行命令。但是,oc rsh
命令提供了一种更容易地打开远程 shell 的方法。
11.3. Secure Shell 会话帮助
有关使用、选项以及查看示例的帮助信息:
$ oc rsh -h
第 12 章 服务帐户
12.1. 概述
当用户使用 OpenShift Container Platform CLI 或 Web 控制台时,其 API 令牌向 OpenShift API 进行身份验证。但是,当普通用户的凭据不可用时,组件通常会单独进行 API 调用。例如:
- 复制控制器进行 API 调用来创建或删除容器集。
- 容器内的应用程序可能会发出 API 调用来进行发现。
- 外部应用程序可以发出 API 调用来进行监控或集成。
服务帐户为控制 API 访问提供了灵活的方式,不需要共享常规用户的凭证。
12.2. 用户名和组
每个服务帐户都有一个关联的用户名,可以像普通用户一样被授予角色。用户名派生自其项目和名称:
system:serviceaccount:<project>:<name>
例如,将 view 角色添加到 top-secret 项目中的 robot 服务帐户:
$ oc policy add-role-to-user view system:serviceaccount:top-secret:robot
如果要向项目中的特定服务帐户授予访问权限,您可以使用 -z
标志。在服务帐户所属的项目中,使用 -z
标志并指定 <serviceaccount_name>
。强烈建议您这样做,因为它有助于防止拼写错误,并确保只为指定的服务帐户授予访问权限。例如:
$ oc policy add-role-to-user <role_name> -z <serviceaccount_name>
如果没有在项目中,请使用 -n
选项来指示它应用到的项目命名空间,如下例所示。
每一服务帐户也是以下两个组的成员:
- system:serviceaccounts
- 包含系统中的所有服务帐户。
- system:serviceaccounts:<project>
- 包含指定项目中的所有服务帐户。
例如,允许所有项目中的所有服务帐户查看 top-secret 项目中的资源:
$ oc policy add-role-to-group view system:serviceaccounts -n top-secret
允许 managers 项目中的所有服务帐户编辑 top-secret 项目中的资源:
$ oc policy add-role-to-group edit system:serviceaccounts:managers -n top-secret
12.3. 默认服务帐户和角色
每个项目中会自动创建三个服务帐户:
服务帐户 | 使用方法 |
---|---|
builder | 由构建 Pod 使用。被授予 system:image-builder 角色,允许使用内部 Docker registry 将镜像推送到项目中的任何镜像流。 |
deployer | 部署 Pod 使用并被授予 system:deployer 角色,它允许查看和修改项目中的复制控制器和 pod。 |
default | 用来运行其他所有 Pod,除非指定了不同的服务帐户。 |
项目中的所有服务帐户都会被授予 system:image-puller 角色,允许使用内部容器镜像 registry 从项目中的任何镜像流拉取镜像。
12.4. 管理服务帐户
服务帐户是各个项目中存在的 API 对象。要管理服务帐户,您可以使用 oc
命令和 sa
或 serviceaccount
对象类型,或者使用 Web 控制台。
获取当前项目中现有服务帐户的列表:
$ oc get sa NAME SECRETS AGE builder 2 2d default 2 2d deployer 2 2d
要创建新服务帐户,请执行以下操作:
$ oc create sa robot serviceaccount "robot" created
一旦创建了服务帐户,会自动向其中添加两个 secret:
- API 令牌
- OpenShift Container Registry 的凭证
可以通过描述服务帐户来查看它们:
$ oc describe sa robot Name: robot Namespace: project1 Labels: <none> Annotations: <none> Image pull secrets: robot-dockercfg-qzbhb Mountable secrets: robot-token-f4khf robot-dockercfg-qzbhb Tokens: robot-token-f4khf robot-token-z8h44
系统确保服务帐户始终具有 API 令牌和 registry 凭据。
生成的 API 令牌和 registry 凭据不会过期,但可通过删除 secret 来撤销。删除 secret 时,会自动生成一个新 secret 来代替它。
12.5. 管理允许的机密
除了提供 API 凭证外,pod 的服务帐户也决定允许 pod 使用哪些 secret。
Pod 以两种方式使用 secret:
- 镜像拉取 secret,提供用于为 pod 容器拉取镜像的凭证
- 可挂载 secret,将 secret 的内容作为环境变量注入容器中
要允许由服务帐户的 pod 使用 secret 作为镜像 pull secret,请运行:
$ oc secrets link --for=pull <serviceaccount-name> <secret-name>
要允许由服务帐户的 pod 挂载 secret,请运行:
$ oc secrets link --for=mount <serviceaccount-name> <secret-name>
默认情况下,“将 secret 仅限于引用它们的服务帐户”的功能被禁用。这意味着,如果在 master 配置文件中将 serviceAccountConfig.limitSecretReferences
设置为 false
(默认设置),则不需要将 secret 挂载到服务帐户的 pod 中,且不需要使用 --for=mount
选项。但是,无论 serviceAccountConfig.limitSecretReferences
值是什么,需要使用 --for=pull
选项启用镜像 pull secret。
这个示例创建并将 secret 添加到服务帐户中:
$ oc create secret generic secret-plans \ --from-file=plan1.txt \ --from-file=plan2.txt secret/secret-plans $ oc create secret docker-registry my-pull-secret \ --docker-username=mastermind \ --docker-password=12345 \ --docker-email=mastermind@example.com secret/my-pull-secret $ oc secrets link robot secret-plans --for=mount $ oc secrets link robot my-pull-secret --for=pull $ oc describe serviceaccount robot Name: robot Labels: <none> Image pull secrets: robot-dockercfg-624cx my-pull-secret Mountable secrets: robot-token-uzkbh robot-dockercfg-624cx secret-plans Tokens: robot-token-8bhpp robot-token-uzkbh
12.6. 在容器中使用服务帐户凭证
创建 pod 时,它指定一个服务帐户(或使用默认服务帐户),并使用该服务帐户的 API 凭证并引用 secret。
包含 pod 服务帐户的 API 令牌的文件会自动挂载到 /var/run/secrets/kubernetes.io/serviceaccount/token。
该令牌可用于发出 API 调用作为 pod 的服务帐户。这个示例调用 users/~ API 来获取有关令牌标识的用户的信息:
$ TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" $ curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ "https://openshift.default.svc.cluster.local/oapi/v1/users/~" \ -H "Authorization: Bearer $TOKEN" kind: "User" apiVersion: "user.openshift.io/v1" metadata: name: "system:serviceaccount:top-secret:robot" selflink: "/oapi/v1/users/system:serviceaccount:top-secret:robot" creationTimestamp: null identities: null groups: - "system:serviceaccount" - "system:serviceaccount:top-secret"
12.7. 从外部使用服务帐户的凭证
同一令牌可以分发到需要向 API 进行身份验证的外部应用程序。
使用以下语法查看服务帐户的 API 令牌:
$ oc describe secret <secret-name>
例如:
$ oc describe secret robot-token-uzkbh -n top-secret Name: robot-token-uzkbh Labels: <none> Annotations: kubernetes.io/service-account.name=robot,kubernetes.io/service-account.uid=49f19e2e-16c6-11e5-afdc-3c970e4b7ffe Type: kubernetes.io/service-account-token Data token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9... $ oc login --token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9... Logged into "https://server:8443" as "system:serviceaccount:top-secret:robot" using the token provided. You don't have any projects. You can try to create a new project, by running $ oc new-project <projectname> $ oc whoami system:serviceaccount:top-secret:robot
第 13 章 管理镜像
13.1. 概述
镜像流 包含由标签识别的任意数量的容器镜像。提供相关镜像的单一虚拟视图,类似于容器镜存储库。
通过监控镜像流,构建和部署可在添加或修改新镜像时收到通知,并通过分别执行构建或部署来作出反应。
您可以通过多种方式与镜像交互并设置镜像流,具体取决于镜像 registry 所处的位置、这些 registry 的任何身份验证要求以及您预期的构建和部署性能。以下部分涵盖了这些主题的范围。
13.2. 标记镜像
在使用 OpenShift Container Platform 镜像流及其标签前,它有助于首先了解容器镜像的上下文中的镜像标签。
容器镜像可向它们添加名称,以便更直观地确定它们所包含的内容,称为 标签。使用标签指定镜像中包含的内容版本是常见用例。如果您有一个名为 ruby 的镜像,则可以将名为 2.0 的 2.0 标签用于 Ruby,另一个名为 latest 来指示该仓库中最新构建的镜像。
使用 docker
CLI 直接与镜像交互时,docker tag
命令可以添加标签,后者本质上为由多个部分组成的镜像添加一个别名。这些部分包括:
<registry_server>/<user_name>/<image_name>:<tag>
如果镜像存储在带有内部 registry(OpenShift Container Registry)的 OpenShift Container Platform 环境中,则上面的 <user_name>
部分也可以引用一个项目或命名空间。
OpenShift Container Platform 提供 oc tag
命令,该命令类似于 docker tag
命令,但是在镜像流上运行,而非直接在镜像上运行。
如需有关直接使用 docker
CLI 标记镜像的更多信息,请参阅 Red Hat Enterprise Linux 7 的 Getting Started with Containers 文档。
13.2.1. 将标签添加到镜像流
请记住,OpenShift Container Platform 中的镜像流包含 0 个或更多由标签标识的容器镜像,您可以使用 oc tag
命令向镜像流中添加标签:
$ oc tag <source> <destination>
例如,要将 ruby 镜像流 static-2.0 标签配置为始终引用 ruby 镜像流 2.0 标签的当前镜像:
$ oc tag ruby:2.0 ruby:static-2.0
这会在 ruby 镜像流中创建名为 static-2.0 的新镜像流标签。运行 oc tag
时,新标签会直接引用 ruby:2.0 镜像流标签所指向的镜像 id,而所指向的镜像不会改变。
有各种不同类型的标签可用。默认行为是使用一个 持久 标签,指向一个特定的镜像;即使源有变化,新的(目标)标签不会改变。
跟踪标签表示,在导入源标签期间对目的地标签的元数据进行了更新。为确保目标标签在源标签更改时进行更新,请使用 --alias=true
标志:
$ oc tag --alias=true <source> <destination>
使用跟踪标签创建持久性别名(例如: latest
或 stable
)。该标签只在单一镜像流中正常工作。试图创建跨镜像流别名会出错。
您还可以添加 --scheduled=true
标志来定期刷新目的地标签(例如,重新导入)。周期在系统级别 进行全局配置。如需了解更多详细信息,请参阅导入标签和镜像元数据。
--reference
标志会创建一个非导入的镜像流标签。该标签持久指向源位置。
如果要指示 Docker 始终从集成的 registry 中获取标记的镜像,请使用 --reference-policy=local
。registry 使用 pull-through 功能 为客户端提供镜像。默认情况下,镜像 Blob 由 registry 在本地进行镜像。因此,下次需要时便可更快拉取(pull)。只要镜像流有一个 insecure annotation,或标签有一个 insecure import policy,该标志也允许从不安全的 registry 拉取(pull),无需向 Docker 守护进程提供 --insecure-registry
。
13.2.2. 建议的标记惯例
镜像随时间不断发展,其标签反应了这一点。镜像标签始终指向最新镜像构建。
如果标签名称中嵌入了太多信息(如 v2.0.1-may-2016
),标签仅指向镜像的某一个版本,永远不会更新。使用默认镜像修剪选项,此类镜像不会被删除。在庞大集群中,为每个修改后的镜像创建新标签这种模式最终可能会使用早已过期的镜像的多余标签元数据来填充 etcd 数据存储。
如果标签命名为 v2.0
,则更多镜像修订的可能性更大。这会导致 标签历史记录 较长,镜像修剪器更有可能删除旧和未使用的镜像。如需更多信息,请参阅修剪镜像。
您可自行决定标签命名惯例,下面提供了一些 <image_name>:<image_tag>
格式的示例:
描述 | 示例 |
---|---|
修订 |
|
架构 |
|
基础镜像 |
|
最新(可能不稳定) |
|
最新稳定 |
|
如果标签名称中需要日期,请定期检查旧的和不受支持的镜像以及 istags
,并予以删除。否则,您可能会遇到旧镜像导致的资源使用量增加。
13.2.3. 从镜像流中删除标签
要从镜像流运行中完全删除标签:
$ oc delete istag/ruby:latest
或:
$ oc tag -d ruby:latest
13.2.4. 引用镜像流中的镜像
可以使用以下引用类型在镜像流中引用镜像:
ImageStreamTag
用于引用或检索给定镜像流和标签的镜像。它的名称使用以下惯例:<image_stream_name>:<tag>
ImageStreamImage
用于引用或检索给定镜像流和镜像名称的镜像。它的名称使用以下惯例:<image_stream_name>@<id>
<id>
是针对特定镜像的不可变标识符,也称摘要。DockerImage
用于引用或检索给定外部 registry 的镜像。它使用标准 Docker 拉取规格 作为名称,例如:openshift/ruby-20-centos7:2.0
注意如果未指定标签,则会假定使用 latest标签。
此外,您还可引用第三方 registry:
registry.redhat.io/rhel7:latest
或者带有摘要的镜像:
centos/ruby-22-centos7@sha256:3a335d7d8a452970c5b4054ad7118ff134b3a6b50a2bb6d0c07c746e8986b28e
当查看镜像流定义示例时,如 CentOS 镜像流示例,您可能会注意到它们包含 ImageStreamTag
的定义以及 DockerImage
的引用,但不与 ImageStreamImage
相关。
这是因为当您将镜像导入或标记到镜像流时,OpenShift Container Platform 中会自动创建 ImageStreamImage
对象。您不必在用于创建镜像流的任何镜像流定义中显式定义 ImageStreamImage
对象。
您可以使用镜像流名称和 ID 检索 ImageStreamImage
定义,来查看镜像的对象定义:
$ oc get -o yaml --export isimage <image_stream_name>@<id>
您可以运行以下命令来找到给定镜像流的有效 <id>
值:
$ oc describe is <image_stream_name>
例如,在 ruby 镜像流中,要求 ImageStreamImage
的名称和 ID 为 ruby@3a335d7 :
通过 ImageStreamImage
检索镜像对象的定义
$ oc get -o yaml --export isimage ruby@3a335d7 apiVersion: v1 image: dockerImageLayers: - name: sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 size: 0 - name: sha256:ee1dd2cb6df21971f4af6de0f1d7782b81fb63156801cfde2bb47b4247c23c29 size: 196634330 - name: sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 size: 0 - name: sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 size: 0 - name: sha256:ca062656bff07f18bff46be00f40cfbb069687ec124ac0aa038fd676cfaea092 size: 177723024 - name: sha256:63d529c59c92843c395befd065de516ee9ed4995549f8218eac6ff088bfa6b6e size: 55679776 dockerImageMetadata: Architecture: amd64 Author: SoftwareCollections.org <sclorg@redhat.com> Config: Cmd: - /bin/sh - -c - $STI_SCRIPTS_PATH/usage Entrypoint: - container-entrypoint Env: - PATH=/opt/app-root/src/bin:/opt/app-root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - STI_SCRIPTS_URL=image:///usr/libexec/s2i - STI_SCRIPTS_PATH=/usr/libexec/s2i - HOME=/opt/app-root/src - BASH_ENV=/opt/app-root/etc/scl_enable - ENV=/opt/app-root/etc/scl_enable - PROMPT_COMMAND=. /opt/app-root/etc/scl_enable - RUBY_VERSION=2.2 ExposedPorts: 8080/tcp: {} Image: d9c3abc5456a9461954ff0de8ae25e0e016aad35700594714d42b687564b1f51 Labels: build-date: 2015-12-23 io.k8s.description: Platform for building and running Ruby 2.2 applications io.k8s.display-name: Ruby 2.2 io.openshift.builder-base-version: 8d95148 io.openshift.builder-version: 8847438ba06307f86ac877465eadc835201241df io.openshift.s2i.scripts-url: image:///usr/libexec/s2i io.openshift.tags: builder,ruby,ruby22 io.s2i.scripts-url: image:///usr/libexec/s2i license: GPLv2 name: CentOS Base Image vendor: CentOS User: "1001" WorkingDir: /opt/app-root/src ContainerConfig: {} Created: 2016-01-26T21:07:27Z DockerVersion: 1.8.2-el7 Id: 57b08d979c86f4500dc8cad639c9518744c8dd39447c055a3517dc9c18d6fccd Parent: d9c3abc5456a9461954ff0de8ae25e0e016aad35700594714d42b687564b1f51 Size: 430037130 apiVersion: "1.0" kind: DockerImage dockerImageMetadataVersion: "1.0" dockerImageReference: centos/ruby-22-centos7@sha256:3a335d7d8a452970c5b4054ad7118ff134b3a6b50a2bb6d0c07c746e8986b28e metadata: creationTimestamp: 2016-01-29T13:17:45Z name: sha256:3a335d7d8a452970c5b4054ad7118ff134b3a6b50a2bb6d0c07c746e8986b28e resourceVersion: "352" uid: af2e7a0c-c68a-11e5-8a99-525400f25e34 kind: ImageStreamImage metadata: creationTimestamp: null name: ruby@3a335d7 namespace: openshift selflink: /oapi/v1/namespaces/openshift/imagestreamimages/ruby@3a335d7
13.3. Kubernetes 资源使用镜像流
作为 OpenShift Container Platform 的原生资源,镜像流可以直接与 OpenShift Container Platform 中的所有其他原生资源一起来工作(如构建或部署)。当前,它也可能可以和其与原生 Kubernetes 资源一起工作,如作业、复制控制器、副本设置或 Kubernetes 部署。
集群管理员可以精确配置可以使用什么资源。
启用后,可以将镜像流的引用放在资源的 image
字段中。使用此功能时,只能引用位于与资源相同的项目中的镜像流。镜像流引用必须包含单个片段值,如 ruby:2.5
,其中 ruby
是镜像流的名称,它具有名为 2.5
的标签,并位于与进行引用的资源相同的项目中。
有两种方法可以做到这一点:
- 启用针对特定资源的镜像流解析。这只允许此资源使用 image 字段中的镜像流名称。
- 在镜像流上启用镜像流解析。这允许指向此镜像流的所有资源在 image 字段中使用它。
这两个操作都可使用 oc set image-lookup
来完成。例如,以下命令允许所有资源引用名为 mysql
的镜像流:
$ oc set image-lookup mysql
这会将 Imagestream.spec.lookupPolicy.local
字段设置为 true。
启用镜像查询的镜像流
apiVersion: v1 kind: ImageStream metadata: annotations: openshift.io/display-name: mysql name: mysql namespace: myproject spec: lookupPolicy: local: true
启用后,会为镜像流中的所有标签启用此行为。
您可以查询镜像流并查看是否设置了选项:
$ oc set image-lookup
您还可以在特定资源上启用镜像查找。此命令允许名为 mysql
的 Kubernetes 部署使用镜像流:
$ oc set image-lookup deploy/mysql
这会在部署上设置 alpha.image.policy.openshift.io/resolve-names
注解。
启用镜像查询部署
apiVersion: apps/v1 kind: Deployment metadata: name: mysql namespace: myproject spec: replicas: 1 template: metadata: annotations: alpha.image.policy.openshift.io/resolve-names: '*' spec: containers: - image: mysql:latest imagePullPolicy: Always name: mysql
要禁用镜像查找,使用 --enabled=false
:
$ oc set image-lookup deploy/mysql --enabled=false
13.4. 镜像拉取(pull)策略
Pod 中的每个容器均有容器镜像。您创建了镜像并将其推送(push)到 registry 后,即可在 Pod 中引用它。
当 OpenShift Container Platform 创建容器时,会使用容器的 imagePullPolicy
来决定是否应在启动容器前拉取(pull)镜像。imagePullPolicy
有三个可能的值:
-
Always
- 始终拉取(pull)镜像。 -
IfNotPresent
- 只有节点上不存在的镜像时才拉取镜像。 -
Never
- 永不拉取(pull)镜像。
您可以在全局构建配置中启用 forcePull
标志,以便在每次构建启动时强制从 registry 刷新镜像。这会强制镜像访问每个构建进行检查,从而可以避免用户访问他们没有访问权限的镜像的构建节点本地缓存。
如果没有指定容器的 imagePullPolicy
参数,OpenShift Container Platform 会根据镜像标签来设置它:
-
如果标签是 latest,OpenShift Container Platform 会将
imagePullPolicy
默认设置为Always
。 -
否则,OpenShift Container Platform 会将
imagePullPolicy
默认设置为IfNotPresent
。
使用 Never
Image Pull 策略时,您可以确保私有镜像只能供带有凭证的 pod 使用,以使用 AlwaysPullImages 准入控制器 拉取这些镜像。如果没有启用此准入控制器,节点上的任何用户的所有 pod 都可使用该镜像,而无需对镜像进行任何授权检查。
13.5. 访问内部 registry
您可以直接访问 OpenShift Container Platform 的内部 registry 来推送或拉取镜像。例如,如果您想 通过手动推送镜像来创建镜像流,或者只是直接进行 docker pull
,则这很有用。
内部 registry 使用与 OpenShift Container Platform API 相同的令牌进行身份验证。要针对内部 registry 执行 docker 登录
,您可以选择任何用户名和密码,但密码必须是有效的 OpenShift Container Platform 令牌。
登录到内部 registry:
登录到 OpenShift Container Platform:
$ oc login
获取您的访问令牌:
$ oc whoami -t
使用该令牌登录到内部 registry。在您的系统中必须安装 docker :
$ docker login -u <user_name> -e <email_address> \ -p <token_value> <registry_server>:<port>
注意如果您不知道要使用的 registry IP 或主机名和端口,请联络您的集群管理员。
若要拉取镜像,经过身份验证的用户必须具有所请求的 imagestreams/layers
的 get
权限。若要推送镜像,经过身份验证的用户必须具有所请求的 imagestreams/layers
的 update
权限。
默认情况下,一个项目中的所有服务帐户都有权拉取同一项目中的任何镜像,而 builder 服务帐户则有权在同一项目中推送任何镜像。
13.5.1. 列出软件仓库
/v2/_catalog
端点支持存储库列表或镜像流名称。
唯一的要求是经过身份验证的用户必须具有整个集群中 镜像流
的列表
权限。
要为用户授予列出镜像流的权限,请运行:
$ oc adm policy add-cluster-role-to-user registry-viewer user
列出软件仓库:
$ oc login -u user $ curl -v -u unused:$(oc whoami -t) https://<registry_server>:<port>/v2/_catalog?n=100
对于集群中的大量镜像流,这个 API 调用非常昂贵。建议您使用分页而不是列出所有镜像流。
13.6. 使用镜像提取 secret
Docker registries 可以被加以保护,以防止未授权方访问某些镜像。如果您在使用 OpenShift Container Platform 的内部 registry,且从位于同一项目中的镜像流拉取(pull),则您的 Pod 服务帐户应已具备正确权限,且无需额外操作。
然而,对于其他场景,例如在 OpenShift Container Platform 项目间或从安全 registry 引用镜像,则还需其他配置步骤。以下小节详细介绍了这些场景及其所需步骤。
13.6.1. 允许 Pod 在项目间引用镜像
使用内部 registry 时,要允许 project-a 中的 pod 引用 project-b 中的镜像,project-a 中的服务帐户必须绑定到 project-b 中的 system:image-puller
角色:
$ oc policy add-role-to-user \ system:image-puller system:serviceaccount:project-a:default \ --namespace=project-b
添加该角色后,project-a 中引用默认服务帐户的 pod 能够从 project-b 拉取(pull)镜像。
要允许访问 project-a 中的任意服务帐户,请使用组:
$ oc policy add-role-to-group \ system:image-puller system:serviceaccounts:project-a \ --namespace=project-b
13.6.2. 允许 Pod 引用其他安全 registry 中的镜像
.dockercfg 文件(或为较新的 Docker 客户端的 $HOME/.docker/config.json )是一个 Docker 凭证文件,如果您之前已登录安全或不安全的 registry,则该文件会保存您的信息。
要拉取(pull)并非来自 OpenShift Container Platform 内部 registry 的安全容器镜像,您必须从 Docker 凭证创建一个 pull secret,并将其添加到您的服务帐户中。
如果您已经为安全 registry 有一个 .dockercfg 文件,则可运行以下命令从该文件中创建 secret:
$ oc create secret generic <pull_secret_name> \ --from-file=.dockercfg=<path/to/.dockercfg> \ --type=kubernetes.io/dockercfg
或者,如果您有一个 $HOME/.docker/config.json 文件:
$ oc create secret generic <pull_secret_name> \ --from-file=.dockerconfigjson=<path/to/.docker/config.json> \ --type=kubernetes.io/dockerconfigjson
如果您还没有安全 registry 的 Docker 凭证文件,则可运行以下命令创建一个 secret:
$ oc create secret docker-registry <pull_secret_name> \ --docker-server=<registry_server> \ --docker-username=<user_name> \ --docker-password=<password> \ --docker-email=<email>
要使用 secret 为 Pod 拉取镜像,您必须将 secret 添加到您的服务帐户中。本例中服务帐户的名称应与 Pod 使用的服务帐户的名称匹配; default 是默认服务帐户:
$ oc secrets link default <pull_secret_name> --for=pull
要使用 secret 来推送和拉取(pull)构建镜像,该 secret 必须可在 pod 内挂载。您可通过运行以下命令实现这一目的:
$ oc secrets link builder <pull_secret_name>
13.6.2.1. 使用委托身份验证从私有 registry 拉取(pull)
私有 registry 可将身份验证委托给单独服务。这种情况下,必须为身份验证和 registry 端点定义镜像 pull secret。
Red Hat Container Catalog 中的第三方镜像由 Red Hat Connect Partner Registry(registry.connect.redhat.com
)提供。此 registry 将身份验证委托给 sso.redhat.com
,因此适用以下步骤。
为委托的身份验证服务器创建 secret:
$ oc create secret docker-registry \ --docker-server=sso.redhat.com \ --docker-username=developer@example.com \ --docker-password=******** \ --docker-email=unused \ redhat-connect-sso secret/redhat-connect-sso
为私有 registry 创建 secret:
$ oc create secret docker-registry \ --docker-server=privateregistry.example.com \ --docker-username=developer@example.com \ --docker-password=******** \ --docker-email=unused \ private-registry secret/private-registry
Red Hat Connect Partner Registry(registry.connect.redhat.com
)不接受自动生成的 dockercfg
secret 类型(BZ#1476330)。必须使用 docker login
命令生成的文件来创建基于文件的通用 secret:
$ docker login registry.connect.redhat.com --username developer@example.com Password: ************* Login Succeeded $ oc create secret generic redhat-connect --from-file=.dockerconfigjson=.docker/config.json $ oc secrets link default redhat-connect --for=pull
13.7. 导入标签和镜像元数据
镜像流可以被配置为从外部容器镜像 registry 中的镜像存储库导入标签和镜像元数据。您可以使用几种不同方法进行此操作。
您可以使用
--from
选项使用oc import-image
命令手动导入 tag 和镜像信息:$ oc import-image <image_stream_name>[:<tag>] --from=<docker_image_repo> --confirm
例如:
$ oc import-image my-ruby --from=docker.io/openshift/ruby-20-centos7 --confirm The import completed successfully. Name: my-ruby Created: Less than a second ago Labels: <none> Annotations: openshift.io/image.dockerRepositoryCheck=2016-05-06T20:59:30Z Docker Pull Spec: 172.30.94.234:5000/demo-project/my-ruby Tag Spec Created PullSpec Image latest docker.io/openshift/ruby-20-centos7 Less than a second ago docker.io/openshift/ruby-20-centos7@sha256:772c5bf9b2d1e8... <same>
您还可以添加
--all
标志来导入镜像的所有标签,而不只导入 latest。与 OpenShift Container Platform 中的大多数对象一样,您还可以将 JSON 或 YAML 定义写入文件,然后使用 CLI 创建对象。将
spec.dockerImageRepository
字段设置为镜像的 Docker pull spec:apiVersion: "v1" kind: "ImageStream" metadata: name: "my-ruby" spec: dockerImageRepository: "docker.io/openshift/ruby-20-centos7"
然后,创建对象:
$ oc create -f <file>
当您创建引用外部 Docker registry 中的镜像的镜像流时,OpenShift Container Platform 会在短时间内与外部 registry 通信,以便获取镜像的最新信息。
同步 tag 和镜像元数据后,镜像流对象将类似如下:
apiVersion: v1 kind: ImageStream metadata: name: my-ruby namespace: demo-project selflink: /oapi/v1/namespaces/demo-project/imagestreams/my-ruby uid: 5b9bd745-13d2-11e6-9a86-0ada84b8265d resourceVersion: '4699413' generation: 2 creationTimestamp: '2016-05-06T21:34:48Z' annotations: openshift.io/image.dockerRepositoryCheck: '2016-05-06T21:34:48Z' spec: dockerImageRepository: docker.io/openshift/ruby-20-centos7 tags: - name: latest annotations: null from: kind: DockerImage name: 'docker.io/openshift/ruby-20-centos7:latest' generation: 2 importPolicy: { } status: dockerImageRepository: '172.30.94.234:5000/demo-project/my-ruby' tags: - tag: latest items: - created: '2016-05-06T21:34:48Z' dockerImageReference: 'docker.io/openshift/ruby-20-centos7@sha256:772c5bf9b2d1e8e80742ed75aab05820419dc4532fa6d7ad8a1efddda5493dc3' image: 'sha256:772c5bf9b2d1e8e80742ed75aab05820419dc4532fa6d7ad8a1efddda5493dc3' generation: 2
您可以将标签设置为以调度的间隔查询外部 registry,从而通过设置 --scheduled=true
标志和 oc tag
命令(如将标签添加到镜像流中所述) 来同步标签和镜像元数据。
另外,您可以在标签的定义中将 importPolicy.scheduled
设置为 true :
apiVersion: v1 kind: ImageStream metadata: name: ruby spec: tags: - from: kind: DockerImage name: openshift/ruby-20-centos7 name: latest importPolicy: scheduled: true
13.7.1. 从 Insecure Registries 导入镜像
镜像流可以被配置为从不安全的镜像 registry 中导入标签和镜像元数据,如使用自签名证书签名的镜像元数据或使用普通 HTTP 而不是 HTTPS 进行签名的镜像元数据。
要配置此功能,请添加 openshift.io/image.insecureRepository
注释,并将它设为 true<