Deploying on OpenShift

Prerequisites

include::./_includes/prerequisites.adoc[]* 访问 OpenShift 集群(最小化是一个可行选项)* OpenShift CLI(可选,仅手动部署必需)

Bootstrapping the project

首先,我们需要一个包含 OpenShift 扩展的新项目。可以使用以下命令实现这一点:

CLI
quarkus create app {create-app-group-id}:{create-app-artifact-id} \
    --no-code
cd {create-app-artifact-id}

要创建一个 Gradle 项目,添加 --gradle--gradle-kotlin-dsl 选项。 有关如何安装和使用 Quarkus CLI 的详细信息,请参见 Quarkus CLI 指南。

Maven
mvn {quarkus-platform-groupid}:quarkus-maven-plugin:{quarkus-version}:create \
    -DprojectGroupId={create-app-group-id} \
    -DprojectArtifactId={create-app-artifact-id} \
    -DnoCode
cd {create-app-artifact-id}

要创建一个 Gradle 项目,添加 -DbuildTool=gradle-DbuildTool=gradle-kotlin-dsl 选项。

适用于 Windows 用户:

  • 如果使用 cmd,(不要使用反斜杠 \ ,并将所有内容放在同一行上)

  • 如果使用 Powershell,将 -D 参数用双引号引起来,例如 "-DprojectArtifactId={create-app-artifact-id}"

Quarkus 可自动生成基于健全默认值和用户提供的配置的 OpenShift 资源。OpenShift 扩展实际上是一个包装扩展,为 Kubernetes扩展配置了明智的默认值,使用户更容易在 OpenShift 上着手使用 Quarkus。

当我们将 OpenShift 扩展添加到以上命令行调用时,以下依赖关系会添加到 pom.xml

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-openshift</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-openshift")

Log Into the OpenShift Cluster

在我们构建并部署应用程序之前,我们需要登录到一个 OpenShift 集群。您可以通过 OpenShift CLI登录:

Log In - OpenShift CLI Example
oc login -u myUsername 1
1 系统将提示您提供必需的信息,如服务器 URL、密码等。

或者,您可以使用 API 令牌登录:

Log In - OpenShift CLI With API Token Example
oc login --token=myToken --server=myServerUrl

您可以通过 OpenShift Web 控制台中的 _Copy Login Command_链接请求令牌。

最后,您根本不需要使用 OpenShift CLI。相反,设置 `quarkus.kubernetes-client.api-server-url`配置属性并通过 `quarkus.kubernetes-client.token`或 `quarkus.kubernetes-client.username`和 `quarkus.kubernetes-client.password`分别进行验证:

include::./_includes/devtools/build.adoc[]:!build-additional-parameters:

Build and Deployment

您可以在一个步骤中触发构建和部署或首先构建容器镜像,然后根据需要手动配置 OpenShift 应用程序 more control over the deployment configuration

触发在一个步骤中构建和部署:

include::./_includes/devtools/build.adoc[]:!build-additional-parameters:

如果您想立即测试您的应用程序,则将 quarkus.openshift.route.expose`配置属性设置为 `true`至 expose the service automatically,例如,向上述命令添加 `-Dquarkus.openshift.route.expose=true

当使用 DeploymentConfig`和 Service Binding时,重新部署可能会删除 OpenShift 添加的配置,以允许服务发现。新的容器镜像构建会在 OpenShift 中触发 Quarkus 应用程序刷新: `-Dquarkus.container-image.build=true,这在大多数情况下可能就足够了。如果您需要更新 OpenShift 资源,则您需要先删除绑定,然后在新部署后再次创建它。

此命令将本地构建您的应用程序,然后触发容器镜像构建,最后自动应用所生成的 OpenShift 资源。生成的资源使用 Kubernetes Deployment,但仍然使用 OpenShift 特定的资源,如 Route、`BuildConfig`等。

自 OpenShift 4.14 起, DeploymentConfig object has been deprecated

由于 Deployment`是 Kubernetes 资源而非 OpenShift 特定的资源,它不可能利用 `ImageStream`资源,就像 `DeploymentConfig`的情况一样。这意味着镜像引用需要包含承载镜像的容器镜像注册表。当镜像构建时,使用 OpenShift 构建(s2i 二进制和 Docker 策略),除非用户明确指定了另一个注册表,否则将使用 OpenShift 内部镜像注册表 `image-registry.openshift-image-registry.svc:5000。请注意,在内部注册表中,项目/名称空间名称被添加为镜像存储库的一部分: image-registry.openshift-image-registry.svc:5000/<project name>/<name>:<tag>,因此用户需要确保目标项目/名称空间名称与 `quarkus.container-image.group`保持一致。

deprecation document包含有关如何设置/使用自动回滚、触发、生命周期挂钩和自定义策略的其他信息。

quarkus.container-image.group=<project/namespace name>

您可以使用 OpenShift Web 控制台验证上述命令是否已创建图像流、服务资源并已部署应用程序。或者,您可以运行以下 OpenShift CLI 命令:

oc get is 1
oc get pods 2
oc get svc 3
1 列出创建的图像流。
2 获取 Pod 列表。
3 获取 Kubernetes 服务列表。

请注意,服务默认情况下不对外界公开。因此,除非您已使用 quarkus.openshift.route.expose 配置属性自动公开创建的服务,否则您需要手动公开服务。

Expose The Service - OpenShift CLI Example
oc expose svc/openshift-quickstart 1
oc get routes 2
curl http://<route>/hello 3
1 Expose the service.
2 获取已公开路由列表。
3 Access your application.

Configure the OpenShift Application Manually

如果您需要对部署配置拥有更多控制权,那么您可以首先构建容器图像,然后手动配置 OpenShift 应用程序。

要触发容器图像构建:

./mvnw clean package -Dquarkus.container-image.build=true

将执行的构建为 s2i binary 构建。构建的输入是已在本地构建的 jar,构建的输出是 ImageStream,该输出配置为自动触发部署。基本/构建器图像分别使用 base-jvm-imagebase-native-image 为 jvm 和本机模式指定。除非使用这些属性来引用内部 openshift 注册表中现有的 ImageStreamTag,否则将自动生成图像的 ImageStream。例如:

quarkus.openshift.base-jvm-image=image-registry.openshift-image-registry.svc:5000/some-project/openjdk-11:17.1.16.

在构建期间,您可能会发现由于自签名证书而导致 Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed 异常。要解决此问题,只需将以下行添加到您的 application.properties

quarkus.kubernetes-client.trust-certs=true

有关更多信息,请参阅 deploying to Kubernetes

构建完成后,我们可以从相关 ImageStream 创建一个新应用程序。

oc get is 1
oc new-app --name=greeting <project>/openshift-quickstart:1.0.0-SNAPSHOT 2
oc get svc
oc expose svc/greeting 3
oc get routes 4
curl http://<route>/hello 5
1 列出创建的图像流。我们应用程序的图像流应标记为 <project>/openshift-quickstart:1.0.0-SNAPSHOT。
2 从图像源创建新应用程序。
3 将服务公开到外界。
4 获取已公开路由列表。
5 Access your application.

完成此设置后,下一次构建容器图像时,将自动触发对 OpenShift 的部署。换句话说,您不必重复上述步骤。

Non-S2I Builds

开箱即用,OpenShift 扩展配置为使用 container-image-s2i。但是,仍然可以使用其他容器图像扩展,例如:

当使用非 s2i 容器映像扩展时,将创建一个 ImageStream,该容器指向外部 dockerImageRepository。该图像构建后将推送到注册表中,而 ImageStream 将填充 dockerImageRepository 中可用的标记。

选择用于构建图像的扩展:

quarkus.container-image.builder=docker

quarkus.container-image.builder=jib

Customizing

所有可用的定制选项都可在 OpenShift configuration options 中找到。

以下章节中提供了一些示例:

Exposing Routes

若要为 Quarkus 应用程序公开 Route

quarkus.openshift.route.expose=true

你无需在 application.properties 中添加此属性。你可以将其作为命令行参数传递:

./mvnw clean package -Dquarkus.openshift.route.expose=true

下面列出的所有属性都适用。

Securing the Route resource

为保护传入连接,OpenShift 提供了几种类型的 TLS 终止来服务认证。您可以在 the official OpenShift guide 中阅读有关如何保护路由的更多信息。

让我们看一个示例,了解如何通过添加 "quarkus.openshift.route.tls" 属性利用直通终止配置安全路由:

quarkus.openshift.route.expose=true
quarkus.openshift.route.target-port=https
## Route TLS configuration:
quarkus.openshift.route.tls.termination=passthrough
quarkus.openshift.route.tls.insecure-edge-termination-policy=None

Labels

要在生成的资源中添加一个标签:

quarkus.openshift.labels.foo=bar

Annotations

要在生成的资源中添加注释:

quarkus.openshift.annotations.foo=bar

Environment variables

OpenShift 提供了多种定义环境变量的方法:

  • key/value pairs

  • 从 Secret 或 ConfigMap 导入所有值

  • 插入 Secret 或 ConfigMap 中某一给定字段所标识的单个值

  • 插入同一资源中某一字段的值

Environment variables from key/value pairs

要在生成的资源中添加键/值对作为环境变量:

quarkus.openshift.env.vars.my-env-var=foobar

以上的命令将添加 MY_ENV_VAR=foobar 作为环境变量。请注意,键 my-env-var 将转换为大写,且破折号将替换为下划线,从而得到 MY_ENV_VAR

Environment variables from Secret

要添加所有 Secret 键/值对作为环境变量,只需应用以下配置,并通过逗号 (,) 分隔用作源的每个 Secret

quarkus.openshift.env.secrets=my-secret,my-other-secret

这将在容器定义中生成以下内容:

envFrom:
  - secretRef:
      name: my-secret
      optional: false
  - secretRef:
      name: my-other-secret
      optional: false

以下内容从 my-secret Secret 中提取由 keyName`字段标识的值,并放入 `foo 环境变量:

quarkus.openshift.env.mapping.foo.from-secret=my-secret
quarkus.openshift.env.mapping.foo.with-key=keyName

这将在容器的 env 部分生成以下内容:

- env:
  - name: FOO
    valueFrom:
      secretKeyRef:
        key: keyName
        name: my-secret
        optional: false

Environment variables from ConfigMap

要将从 ConfigMap 中获取的所有键/值对用作环境变量,只需应用以下配置,并使用逗号 (,) 将各个 ConfigMap 分隔开以用作源:

quarkus.openshift.env.configmaps=my-config-map,another-config-map

这将在容器定义中生成以下内容:

envFrom:
  - configMapRef:
      name: my-config-map
      optional: false
  - configMapRef:
      name: another-config-map
      optional: false

以下配置从 my-config-map ConfigMap 中提取 keyName 字段标识的一个值,并将其放入 foo 环境变量中:

quarkus.openshift.env.mapping.foo.from-configmap=my-configmap
quarkus.openshift.env.mapping.foo.with-key=keyName

这将在容器的 env 部分生成以下内容:

- env:
  - name: FOO
    valueFrom:
      configMapKeyRef:
        key: keyName
        name: my-configmap
        optional: false

Environment variables from fields

还可以使用另一个字段中的值来添加新的环境变量,为此需要指定要作为源使用的字段的路径,如下所示:

quarkus.openshift.env.fields.foo=metadata.name

Changing the generated deployment resource

除了通过 Deployment 生成资源外,您还可以选择通过 application.properties 访问 DeploymentConfigStatefulSetJobCronJob 资源:

quarkus.openshift.deployment-kind=StatefulSet
Generating Job resources

要生成作业资源,您需要通过 application.properties 添加以下属性:

quarkus.openshift.deployment-kind=Job

如果您正在使用 Picocli 扩展,则默认情况下将生成 Job 资源。

您可以通过属性 quarkus.openshift.arguments 提供 Kubernetes Job 将使用的参数。例如,添加属性 quarkus.openshift.arguments=A,B

最后,Kubernetes Job 将在每次安装在 OpenShift 中时启动。您可以更多地了解如何在此处运行 Kubernetes Job link

您可以使用 quarkus.openshift.job.xxx 中的属性配置 Kubernetes Job 的其他配置(请参见 link)。

Generating CronJob resources

如果您想要生成 CronJob 资源,您需要通过 “@12” 添加下列属性:

quarkus.openshift.deployment-kind=CronJob
# Cron expression to run the job every hour
quarkus.openshift.cron-job.schedule=0 * * * *

CronJob 资源需要 Cron 表达式以通过属性 quarkus.openshift.cron-job.schedule 指定何时启动作业。如果不提供,则构建将失败。

您可以使用 quarkus.openshift.cron-job.xxx 中的属性配置 Kubernetes CronJob 的其他配置(请参见 link)。

Validation

如果两个定义有冲突,例如,错误地同时指定一个值和指定变量来源于一个字段,将在构建时出现错误,这样你就有机会在将应用程序部署到集群中,在诊断问题根源会变得更困难前解决问题。

同样,如果出现两个冗余定义,例如两次从同一个密钥中定义一个注入,则不会导致问题,但确实会报告一个警告,让你知道自己可能无意重复该定义。

Backwards compatibility

OpenShift 扩展的先前版本支持添加环境变量的不同语法。旧语法仍然受支持,但已弃用,建议您迁移到新语法。

Table 1. Old vs. new syntax

Old

New

Plain variable

quarkus.openshift.env-vars.my-env-var.value=foobar

quarkus.openshift.env.vars.my-env-var=foobar

From field

quarkus.openshift.env-vars.my-env-var.field=foobar

quarkus.openshift.env.fields.my-env-var=foobar

All from ConfigMap

quarkus.openshift.env-vars.xxx.configmap=foobar

quarkus.openshift.env.configmaps=foobar

All from Secret

quarkus.openshift.env-vars.xxx.secret=foobar

quarkus.openshift.env.secrets=foobar

From one Secret field

quarkus.openshift.env-vars.foo.secret=foobar

quarkus.openshift.env.mapping.foo.from-secret=foobar

quarkus.openshift.env-vars.foo.value=field

quarkus.openshift.env.mapping.foo.with-key=field

From one ConfigMap field

quarkus.openshift.env-vars.foo.configmap=foobar

quarkus.openshift.env.mapping.foo.from-configmap=foobar

quarkus.openshift.env-vars.foo.value=field

quarkus.openshift.env.mapping.foo.with-key=field

如果您重新定义相同的变量,同时使用新语法并保留旧语法,则会保留新版本,并发出警告以提醒您存在此问题。例如,如果您定义了 quarkus.openshift.env-vars.my-env-var.value=foobarquarkus.openshift.env.vars.my-env-var=newValue,则该扩展程序仅会生成环境变量 MY_ENV_VAR=newValue 并发出警告。

Mounting volumes

OpenShift 扩展程序允许用户为应用程序配置卷和装载。

可以通过简单配置装载任何卷:

quarkus.openshift.mounts.my-volume.path=/where/to/mount

这会针对路径 /where/to/mount 为卷 my-volume 添加一个装载到我的 Pod。

卷本身可按以下部分中所示进行配置:

Secret volumes

quarkus.openshift.secret-volumes.my-volume.secret-name=my-secret

ConfigMap volumes

quarkus.openshift.config-map-volumes.my-volume.config-map-name=my-config-map

Persistent Volume Claims

quarkus.openshift.pvc-volumes.my-pvc.claim-name=my-pvc

Knative - OpenShift Serverless

OpenShift 还提供了通过 OpenShift Serverless 功能使用 Knative 的能力。

首要任务是通过设置来指示 Quarkus 生成 Knative 资源:

quarkus.kubernetes.deployment-target=knative

为了利用 OpenShift S2I 在集群上构建容器映像并将生成的容器映像用于 Knative 应用程序,我们需要设置几个配置属性:

# set the Kubernetes namespace which will be used to run the application
quarkus.container-image.group=geoand
# set the container image registry - this is the standard URL used to refer to the internal OpenShift registry
quarkus.container-image.registry=image-registry.openshift-image-registry.svc:5000

然后可以通过启用标准 quarkus.kubernetes.deploy=true 属性将应用程序部署到 OpenShift Serverless。

Configuration Reference

@12: