Menu Close
第 5 章 Development
5.1. 无服务器应用程序
要使用 OpenShift Serverless 部署无服务器应用程序,必须创建 Knative 服务。Knative 服务是 Kubernetes 服务,由包括在一个 YAML 文件中的一个路由和一个配置定义。
Knative 服务 YAML 示例
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: hello 1 namespace: default 2 spec: template: spec: containers: - image: docker.io/openshift/hello-openshift 3 env: - name: RESPONSE 4 value: "Hello Serverless!"
5.1.1. 创建无服务器应用程序
使用以下任一方法创建一个无服务器应用程序:
- 从 OpenShift Container Platform web 控制台创建 Knative 服务。请参阅有关使用 Developer 视角创建应用程序 的文档。
-
使用
kn
CLI 创建 Knative 服务。 - 创建和应用 YAML 文件。
5.1.1.1. 使用 Knative CLI 创建无服务器应用程序
以下流程描述了如何使用 kn
CLI 创建基本无服务器应用程序。
先决条件
- 在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。
-
已安装
kn
CLI。
流程
创建 Knative 服务:
$ kn service create <service-name> --image <image> --env <key=value>
示例命令
$ kn service create event-display \ --image quay.io/openshift-knative/knative-eventing-sources-event-display:latest
输出示例
Creating service 'event-display' in namespace 'default': 0.271s The Route is still working to reflect the latest desired specification. 0.580s Configuration "event-display" is waiting for a Revision to become ready. 3.857s ... 3.861s Ingress has not yet been reconciled. 4.270s Ready to serve. Service 'event-display' created with latest revision 'event-display-bxshg-1' and URL: http://event-display-default.apps-crc.testing
5.1.1.1.1. Knative 客户端多容器支持
您可以使用 kn container add
命令将 YAML 容器 spec 打印到标准输出。此命令对多容器用例很有用,因为它可以与其他标准 kn
标志一起使用来创建定义。kn container add
命令接受与容器相关的所有标志,它们都支持与 kn service create
命令搭配使用。kn container add
命令也可以使用 UNIX 管道(|
)一次创建多个容器定义来串联。
5.1.1.1.1.1. 示例命令
从镜像添加容器并将其打印到标准输出中:
$ kn container add <container_name> --image <image_uri>
示例命令
$ kn container add sidecar --image docker.io/example/sidecar
输出示例
containers: - image: docker.io/example/sidecar name: sidecar resources: {}
将两个
kn container add
命令链接在一起,然后将它们传递给kn service create
命令创建带有两个容器的 Knative 服务:$ kn container add <first_container_name> --image <image_uri> | \ kn container add <second_container_name> --image <image_uri> | \ kn service create <service_name> --image <image_uri> --extra-containers -
--extra-containers -
指定一个特殊情况,kn
读取管道输入,而不是 YAML 文件。示例命令
$ kn container add sidecar --image docker.io/example/sidecar:first | \ kn container add second --image docker.io/example/sidecar:second | \ kn service create my-service --image docker.io/example/my-app:latest --extra-containers -
--extra-containers
标志也可以接受到 YAML 文件的路径:$ kn service create <service_name> --image <image_uri> --extra-containers <filename>
示例命令
$ kn service create my-service --image docker.io/example/my-app:latest --extra-containers my-extra-containers.yaml
5.1.1.2. 使用 YAML 创建无服务器应用程序
要使用 YAML 创建无服务器应用程序,您必须创建一个 YAML 文件来定义一个 Service
对象,然后使用 oc apply
来应用它。
流程
创建包含以下示例代码的 YAML 文件:
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: event-delivery namespace: default spec: template: spec: containers: - image: quay.io/openshift-knative/knative-eventing-sources-event-display:latest env: - name: RESPONSE value: "Hello Serverless!"
导航到包含 YAML 文件的目录,并通过应用 YAML 文件来部署应用程序:
$ oc apply -f <filename>
创建服务并部署应用程序后,Knative 会为应用程序的这个版本创建一个不可变的修订版本。Knative 还将执行网络操作,为您的应用程序创建路由、入口、服务和负载平衡器,并将根据流量(包括不活跃 pod)自动扩展或缩减 pod。
5.1.2. 使用 Knative CLI 更新无服务器应用程序
在以递增方式构建服务时,您可以使用 kn service update
命令进行命令行上的互动会话。与 kn service apply
命令不同,在使用 kn service update
命令时,只需要指定您要更新的更改,而不是指定 Knative 服务的完整配置。
示例命令
通过添加新环境变量来更新服务:
$ kn service update <service_name> --env <key>=<value>
通过添加新端口来更新服务:
$ kn service update <service_name> --port 80
通过添加新的请求和限制参数来更新服务:
$ kn service update <service_name> --request cpu=500m --limit memory=1024Mi --limit cpu=1000m
为修订版本分配
latest
标签:$ kn service update <service_name> --tag <revision_name>=latest
为服务的最新
READY
修订版本将标签从testing
更新为staging
:$ kn service update <service_name> --untag testing --tag @latest=staging
将
test
标签添加到接收 10% 流量的修订版本,并将其它流量发送到服务的最新READY
修订版本:$ kn service update <service_name> --tag <revision_name>=test --traffic test=10,@latest=90
5.1.3. 应用服务声明
您可以使用 kn service apply
命令声明性配置 Knative 服务。如果服务不存在,则使用已更改的选项更新现有服务。
kn service apply
命令对 shell 脚本或持续集成管道特别有用,因为用户通常希望在单个命令中完全指定服务的状态来声明目标状态。
使用 kn service apply
时,必须为 Knative 服务提供完整的配置。这与 kn service update
命令不同,它只在命令中指定您要更新的选项。
示例命令
创建服务:
$ kn service apply <service_name> --image <image>
将环境变量添加到服务:
$ kn service apply <service_name> --image <image> --env <key>=<value>
从 JSON 或 YAML 文件中读取服务声明:
$ kn service apply <service_name> -f <filename>
5.1.4. 使用 Knative CLI 描述无服务器应用程序
您可以使用 kn service describe
命令来描述 Knative 服务。
示例命令
描述服务:
$ kn service describe --verbose <service_name>
--verbose
标志是可选的,但可以包含它以提供更详细的描述。常规输出和详细输出之间的区别在以下示例中显示:没有
--verbose
标记的输出示例Name: hello Namespace: default Age: 2m URL: http://hello-default.apps.ocp.example.com Revisions: 100% @latest (hello-00001) [1] (2m) Image: docker.io/openshift/hello-openshift (pinned to aaea76) Conditions: OK TYPE AGE REASON ++ Ready 1m ++ ConfigurationsReady 1m ++ RoutesReady 1m
带有
--verbose
标记的输出示例Name: hello Namespace: default Annotations: serving.knative.dev/creator=system:admin serving.knative.dev/lastModifier=system:admin Age: 3m URL: http://hello-default.apps.ocp.example.com Cluster: http://hello.default.svc.cluster.local Revisions: 100% @latest (hello-00001) [1] (3m) Image: docker.io/openshift/hello-openshift (pinned to aaea76) Env: RESPONSE=Hello Serverless! Conditions: OK TYPE AGE REASON ++ Ready 3m ++ ConfigurationsReady 3m ++ RoutesReady 3m
以 YAML 格式描述服务:
$ kn service describe <service_name> -o yaml
以 JSON 格式描述服务:
$ kn service describe <service_name> -o json
仅输出服务 URL:
$ kn service describe <service_name> -o url
5.1.5. 验证无服务器应用程序的部署
要验证您的无服务器应用程序是否已成功部署,您必须获取 Knative 创建的应用程序的 URL,然后向该 URL 发送请求并检查其输出。
OpenShift Serverless 支持 HTTP 和 HTTPS URL,但 oc get ksvc
的输出始终会使用 http://
格式显示 URL。
流程
查找应用程序 URL:
$ oc get ksvc <service_name>
输出示例
NAME URL LATESTCREATED LATESTREADY READY REASON event-delivery http://event-delivery-default.example.com event-delivery-4wsd2 event-delivery-4wsd2 True
向集群发出请求并观察其输出。
HTTP 请求示例
$ curl http://event-delivery-default.example.com
HTTPS 请求示例
$ curl https://event-delivery-default.example.com
输出示例
Hello Serverless!
可选。如果您在证书链中收到与自签名证书相关的错误,可以在 curl 命令中添加
--insecure
标志来忽略以下错误:$ curl https://event-delivery-default.example.com --insecure
输出示例
Hello Serverless!
重要在生产部署中不能使用自签名证书。这个方法仅用于测试目的。
可选。如果 OpenShift Container Platform 集群配置有证书颁发机构 (CA) 签名但尚未为您的系统配置全局证书,您可以使用
curl
命令指定此证书。证书的路径可使用--cacert
标志传递给 curl 命令:$ curl https://event-delivery-default.example.com --cacert <file>
输出示例
Hello Serverless!
5.1.6. 使用 HTTP2 和 gRPC 与无服务器应用程序交互
OpenShift Serverless 只支持不安全或边缘终端路由。
不安全或边缘终端路由不支持 OpenShift Container Platform 中的 HTTP2。这些路由也不支持 gRPC,因为 gRPC 由 HTTP2 传输。
如果您在应用程序中使用这些协议,则必须使用入口(ingress)网关直接调用应用程序。要做到这一点,您必须找到 ingress 网关的公共地址以及应用程序的特定主机。
流程
- 找到应用程序主机。请参阅验证无服务器应用程序部署中的相关内容。
查找 ingress 网关的公共地址:
$ oc -n knative-serving-ingress get svc kourier
输出示例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kourier LoadBalancer 172.30.51.103 a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com 80:31380/TCP,443:31390/TCP 67m
公共地址位于
EXTERNAL-IP
字段,在本例中是a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com
。手动在 HTTP 请求的主机标头中设置应用程序的主机,但将请求定向到 ingress 网关的公共地址。
$ curl -H "Host: hello-default.example.com" a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com
输出示例
Hello Serverless!
您还可以通过将授权设置为应用程序的主机来发出 gRPC 请求,同时将请求直接定向到 ingress 网关:
grpc.Dial( "a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com:80", grpc.WithAuthority("hello-default.example.com:80"), grpc.WithInsecure(), )
注意如上例所示,请确保将对应的端口(默认为 80)附加到两个主机中。
5.1.7. 在具有限制性网络策略的集群中启用与 Knative 应用程序通信
如果您使用多个用户可访问的集群,您的集群可能会使用网络策略来控制哪些 pod、服务和命名空间可以通过网络相互通信。
如果您的集群使用限制性网络策略,Knative 系统 Pod 可能无法访问 Knative 应用程序。例如,如果您的命名空间具有以下网络策略(拒绝所有请求),Knative 系统 pod 无法访问您的 Knative 应用程序:
拒绝对命名空间的所有请求的 NetworkPolicy 对象示例
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: deny-by-default namespace: example-namespace spec: podSelector: ingress: []
要允许从 Knative 系统 pod 访问应用程序,您必须为每个 Knative 系统命名空间添加标签,然后在应用程序命名空间中创建一个 NetworkPolicy
对象,以便为具有此标签的其他命名空间访问命名空间。
拒绝对集群中非原生服务的请求的网络策略仍阻止访问这些服务。但是,通过允许从 Knative 系统命名空间访问 Knative 应用程序,您可以从集群中的所有命名空间中访问 Knative 应用程序。
如果您不想允许从集群中的所有命名空间中访问 Knative 应用程序,您可能需要为 Knative 服务使用 JSON Web Token 身份验证 (请参阅 Knative Serving 文档)。Knative 服务的 JSON Web 令牌身份验证需要 Service Mesh。
流程
将
knative.openshift.io/system-namespace=true
标签添加到需要访问应用程序的每个 Knative 系统命名空间:标记
knative-serving
命名空间:$ oc label namespace knative-serving knative.openshift.io/system-namespace=true
标记
knative-serving-ingress
命名空间:$ oc label namespace knative-serving-ingress knative.openshift.io/system-namespace=true
标记
knative-eventing
命名空间:$ oc label namespace knative-eventing knative.openshift.io/system-namespace=true
标记
knative-kafka
命名空间:$ oc label namespace knative-kafka knative.openshift.io/system-namespace=true
在应用程序命名空间中创建一个
NetworkPolicy
对象,允许从带有knative.openshift.io/system-namespace
标签的命名空间访问:NetworkPolicy
对象示例apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: <network_policy_name> 1 namespace: <namespace> 2 spec: ingress: - from: - namespaceSelector: matchLabels: knative.openshift.io/system-namespace: "true" podSelector: {} policyTypes: - Ingress
5.1.8. 每个服务的 HTTPS 重定向
您可以通过配置 networking.knative.dev/httpOption
注解来启用或禁用服务的 HTTPS 重定向,如下例所示:
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example namespace: default annotations: networking.knative.dev/httpOption: "redirected" spec: ...
5.1.9. 在离线模式中使用 kn CLI
kn CLI 的离线模式只是一个技术预览功能。技术预览功能不被红帽产品服务等级协议 (SLA) 支持,且可能在功能方面有缺陷。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。
有关红帽技术预览功能支持范围的详情,请参阅 https://access.redhat.com/support/offerings/techpreview/。
5.1.9.1. 关于离线模式
通常,在执行 kn service
命令时,更改会立即传播到集群。但作为替代方案,您可以在离线模式下执行 kn service
命令:
- 当您以离线模式创建服务时,集群不会发生任何更改。相反,唯一发生的事情是在本地计算机上创建服务描述符文件。
- 创建描述符文件后,您可以手动修改并在版本控制系统中跟踪该文件。
-
最后,您可以在描述符文件中使用
kn service create -f
、kn service apply -f
或oc apply -f
命令将更改传播到集群。
离线模式有几种用途:
- 在使用描述符文件对集群进行更改之前,您可以手动修改该文件。
- 您可以在本地跟踪版本控制系统中服务的描述符文件。这可让您在目标集群以外的位置重复使用描述符文件,例如在持续集成(CI)管道、开发环境或演示中。
-
您可以检查创建的描述符文件,以了解 Knative 服务的信息。特别是,您可以看到生成的服务如何受到传递给
kn
命令的不同参数的影响。
离线模式有其优点:速度非常快,不需要连接到集群。但是,离线模式缺少服务器端验证。因此,您无法验证服务名称是否唯一,或者是否可以拉取指定镜像。
5.1.9.2. 使用离线模式创建服务
先决条件
- 在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。
-
已安装
kn
CLI。
流程
在离线模式下,创建一个本地 Knative 服务描述符文件:
$ kn service create event-display \ --image quay.io/openshift-knative/knative-eventing-sources-event-display:latest \ --target ./ \ --namespace test
输出示例
Service 'event-display' created in namespace 'test'.
--target ./
标志启用脱机模式,并将./
指定为用于存储新目录树的目录。如果您没有指定现有目录,但使用文件名,如
--target my-service.yaml
,则不会创建目录树。相反,当前目录中只创建服务描述符my-service.yaml
文件。文件名可以具有
.yaml
、.yml
或.json
扩展名。选择.json
以 JSON 格式创建服务描述符文件。namespace test
选项将新服务放在test
命名空间中。如果不使用
--namespace
,且您登录到 OpenShift Container Platform 集群,则会在当前命名空间中创建描述符文件。否则,描述符文件会在default
命名空间中创建。
检查创建的目录结构:
$ tree ./
输出示例
./ └── test └── ksvc └── event-display.yaml 2 directories, 1 file
-
使用
--target
指定的当前./
目录包含新的test/
目录,它在指定的命名空间后命名。 -
test/
目录包含ksvc
,它在资源类型后命名。 -
ksvc
目录包含描述符文件event-display.yaml
,它根据指定的服务名称命名。
-
使用
检查生成的服务描述符文件:
$ cat test/ksvc/event-display.yaml
输出示例
apiVersion: serving.knative.dev/v1 kind: Service metadata: creationTimestamp: null name: event-display namespace: test spec: template: metadata: annotations: client.knative.dev/user-image: quay.io/openshift-knative/knative-eventing-sources-event-display:latest creationTimestamp: null spec: containers: - image: quay.io/openshift-knative/knative-eventing-sources-event-display:latest name: "" resources: {} status: {}
列出新服务的信息:
$ kn service describe event-display --target ./ --namespace test
输出示例
Name: event-display Namespace: test Age: URL: Revisions: Conditions: OK TYPE AGE REASON
--target ./
选项指定包含命名空间子目录的目录结构的根目录。另外,您可以使用
--target
选项直接指定 YAML 或 JSON 文件名。可接受的文件扩展包括.yaml
、.yml
和.json
。--namespace
选项指定命名空间,与kn
通信包含所需服务描述符文件的子目录。如果不使用
--namespace
,并且您登录到 OpenShift Container Platform 集群,kn
会在以当前命名空间命名的子目录中搜索该服务。否则,kn
在default/
子目录中搜索。
使用服务描述符文件在集群中创建服务:
$ kn service create -f test/ksvc/event-display.yaml
输出示例
Creating service 'event-display' in namespace 'test': 0.058s The Route is still working to reflect the latest desired specification. 0.098s ... 0.168s Configuration "event-display" is waiting for a Revision to become ready. 23.377s ... 23.419s Ingress has not yet been reconciled. 23.534s Waiting for load balancer to be ready 23.723s Ready to serve. Service 'event-display' created to latest revision 'event-display-00001' is available at URL: http://event-display-test.apps.example.com