1 - 常见问题解答
本文档描述在使用OpenFunction时的常见问题解答。
Q: 如何在OpenFunction中使用私有镜像仓库?
A: OpenFunction在构建阶段使用Shipwright(利用Tekton与Cloud Native Buildpacks集成)将用户函数打包到应用镜像中。
用户通常选择以不安全的方式访问私有镜像仓库,这在Cloud Native Buildpacks中尚不受支持。
我们提供以下解决方法,暂时绕过这个限制:
- 使用IP地址而不是主机名作为私有镜像仓库的访问地址。
- 运行Knative-runtime函数时,应该跳过标签解析。
参考链接:
buildpacks/tekton-integration#31
Q: 如何在不引入新的入口控制器的情况下访问Knative-runtime函数?
A: OpenFunction提供了函数可访问性的统一入口点,它基于Ingress Nginx实现。然而,对于一些用户来说,这是不必要的,引入新的入口控制器可能会影响当前集群。
一般来说,可访问的地址用于同步(Knative-runtime)函数。以下是解决此问题的两种方法:
Magic DNS
您可以按照此指南配置DNS。
CoreDNS
这类似于使用Magic DNS,不同之处在于DNS解析的配置放置在CoreDNS内部。假设用户已在
knative-serving
命名空间的config-domain
ConfigMap下配置了一个名为"openfunction.dev"的域(如下所示):$ kubectl -n knative-serving get cm config-domain -o yaml apiVersion: v1 data: openfunction.dev: "" kind: ConfigMap metadata: annotations: knative.dev/example-checksum: 81552d0b labels: app.kubernetes.io/part-of: knative-serving app.kubernetes.io/version: 1.0.1 serving.knative.dev/release: v1.0.1 name: config-domain namespace: knative-serving
接下来,让我们为此域添加一个A记录。OpenFunction使用Kourier作为Knative Serving的默认网络层,该域名应该流向到Kourier。
$ kubectl -n kourier-system get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kourier LoadBalancer 10.233.7.202 <pending> 80:31655/TCP,443:30980/TCP 36m
kourier-internal ClusterIP 10.233.47.71 <none> 80/TCP 36m
然后,用户只需在CoreDNS中配置此通配符DNS解析,以解析集群中任何Knative服务的URL地址。
其中"10.233.47.71"是Service kourier-internal的地址。
$ kubectl -n kube-system get cm coredns -o yaml
apiVersion: v1
data:
Corefile: |
.:53 {
errors
health
ready
template IN A openfunction.dev {
match .*\.openfunction\.dev
answer "{{ .Name }} 60 IN A 10.233.47.71"
fallthrough
}
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
hosts /etc/coredns/NodeHosts {
ttl 60
reload 15s
fallthrough
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
...
如果用户在集群外无法解析此函数的URL地址,请配置hosts
文件如下:
其中"serving-sr5v2-ksvc-sbtgr.default.openfunction.dev"是从命令"kubectl get ksvc"中获取的URL地址。
10.233.47.71 serving-sr5v2-ksvc-sbtgr.default.openfunction.dev
配置完成后,可以使用以下命令获取函数的URL地址。然后,您可以使用curl
或浏览器触发该函数。
$ kubectl get ksvc
NAME URL
serving-sr5v
2-ksvc-sbtgr http://serving-sr5v2-ksvc-sbtgr.default.openfunction.dev
Q: 如何为函数启用和配置并发性?
A: OpenFunction将函数类型分为"同步运行时“和”异步运行时",基于正在处理的请求类型。这两种类型的函数由Knative Serving和Dapr + KEDA驱动。
因此,要启用和配置函数的并发性,您需要参考上述组件中的具体实现。
以下部分介绍了如何根据"同步运行时“和”异步运行时“部分在OpenFunction中启用和配置函数的并发性。
同步运行时
您可以首先参考Knative Serving中的此文档,了解如何启用和配置并发性功能。
软限制
您可以参考此文档中的Global(ConfigMap)
和Global(Operator)
部分,配置全局并发性功能。
而对于Per Revision
,您可以像这样进行配置此处。
apiVersion: core.openfunction.io/v1beta2
kind: Function
metadata:
name: function-sample
spec:
serving:
scaleOptions:
knative:
autoscaling.knative.dev/target: "200"
硬限制
OpenFunction目前不支持为Per Revision
配置硬限制。您可以参考此文档中的Global(ConfigMap)
和Global(Operator)
部分,配置全局并发性功能。
简而言之
简而言之,您可以为每个函数配置Knative Serving的与自动缩放相关的配置项,如下所示,只要它们可以作为注释传递,否则只能进行全局设置。
# 在Knative Serving中的配置
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld-go
namespace: default
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/<key>: "value"
# 在OpenFunction中的配置(推荐)
apiVersion: core.openfunction.io/v1beta2
kind: Function
metadata:
name: function-sample
spec:
serving:
scaleOptions:
knative:
<key>: "value"
# 替代方法
apiVersion: core.openfunction.io/v1beta2
kind: Function
metadata:
name: function-sample
spec:
serving:
annotations:
autoscaling.knative.dev/<key>: "value"
异步运行时
您可以首先参考Dapr中的此文档,了解如何启用和配置并发性功能。
与同步运行时的并发性配置相比,异步运行时的并发性配置更简单。
# 在Dapr中的配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodesubscriber
namespace: default
spec:
template:
metadata:
annotations:
dapr.io/app-max-concurrency: "value"
# 在OpenFunction中的配置(推荐)
apiVersion: core.openfunction.io/v1beta2
kind: Function
metadata:
name: function-sample
spec:
serving:
annotations:
dapr.io/app-max-concurrency: "value"
Q: 如何为函数镜像构建过程创建源代码仓库凭据?
A: 在使用spec.build.srcRepo.credentials
时,您可能会遇到类似Unsupported type of credentials provided, either SSH private key or username/password is supported (exit code 110)
的错误,这意味着您正在使用不正确的Secret资源作为源代码仓库凭据。
OpenFunction目前基于ShipWright实现函数镜像构建框架,因此我们需要参考此文档来设置正确的源代码仓库凭据。
Q: 如何在离线环境中安装OpenFunction?
A: 您可以通过以下步骤在离线环境中安装和使用OpenFunction:
拉取Helm Chart
在可以访问GitHub的环境中拉取Helm Chart:
helm repo add openfunction https://openfunction.github.io/charts/
helm repo update
helm pull openfunction/openfunction
然后使用诸如scp之类的工具将Helm包复制到离线环境,例如:
scp openfunction-v1.0.0-v0.5.0.tgz <username>@<your-machine-ip>:/home/<username>/
同步镜像
您需要将这些镜像同步到您的私有镜像仓库:
# dapr
docker.io/daprio/dashboard:0.10.0
docker.io/daprio/dapr:1.8.3
# keda
openfunction/keda:2.8.1
openfunction/keda-metrics-apiserver:2.8.1
# contour
docker.io/bitnami/contour:1.21.1-debian-11-r5
docker.io/bitnami/envoy:1.22.2-debian-11-r6
docker.io/bitnami/nginx:1.21.6-debian-11-r10
# tekton-pipelines
openfunction/tektoncd-pipeline-cmd-controller:v0.37.2
openfunction/tektoncd-pipeline-cmd-kubeconfigwriter:v0.37.2
openfunction/tektoncd-pipeline-cmd-git-init:v0.37.2
openfunction/tektoncd-pipeline-cmd-entrypoint:v0.37.2
openfunction/tektoncd-pipeline-cmd-nop:v0.37.2
openfunction/tektoncd-pipeline-cmd-imagedigestexporter:v0.37.2
openfunction/tektoncd-pipeline-cmd-pullrequest-init:v0.37.2
openfunction/tektoncd-pipeline-cmd-pullrequest-init:v0.37.2
openfunction/tektoncd-pipeline-cmd-workingdirinit:v0.37.2
openfunction/cloudsdktool-cloud-sdk@sha256:27b2c22bf259d9bc1a291e99c63791ba0c27a04d2db0a43241ba0f1f20f4067f
openfunction/distroless-base@sha256:b16b57be9160a122ef048333c68ba205ae4fe1a7b7cc6a5b289956292ebf45cc
openfunction/tektoncd-pipeline-cmd-webhook:v0.37.2
# knative-serving
openfunction/knative.dev-serving-cmd-activator:v1.3.2
openfunction/knative.dev-serving-cmd-autoscaler:v1.3.2
openfunction/knative.dev-serving-cmd-queue:v1.3.2
openfunction/knative.dev-serving-cmd-controller:v1.3.2
openfunction/knative.dev-serving-cmd-domain-mapping:v1.3.2
openfunction/knative.dev-serving-cmd-domain-mapping-webhook:v1.3.2
openfunction/knative.dev-net-contour-cmd-controller:v1.3.0
openfunction/knative.dev-serving-cmd-default-domain:v1.3.2
openfunction/knative.dev-serving-cmd-webhook:v1.3.2
# shipwright-build
openfunction/shipwright-shipwright-build-controller:v0.10.0
openfunction/shipwright-io-build-git:v0.10.0
openfunction/shipwright-mutate-image:v0.10.0
openfunction/shipwright-bundle:v0.10.0
openfunction/shipwright-waiter:v0.10.0
openfunction/buildah:v1.23.3
openfunction/buildah:v1.28.0
# openfunction
openfunction/openfunction:v1.0.0
openfunction/kube-rbac-proxy:v0.8.0
openfunction/eventsource-handler:v4
openfunction/trigger-handler:v4
openfunction/dapr-proxy:v0.1.1
openfunction/revision-controller:v1.0.0
创建自定义值
在您的离线环境中创建 custom-values.yaml
文件:
touch custom-values.yaml
编辑 custom-values.yaml
,添加以下内容:
knative-serving:
activator:
activator:
image:
repository: <您的私有镜像仓库>/knative.dev-serving-cmd-activator
autoscaler:
autoscaler:
image:
repository: <您的私有镜像仓库>/knative.dev-serving-cmd-autoscaler
configDeployment:
queueSidecarImage:
repository: <您的私有镜像仓库>/knative.dev-serving-cmd-queue
controller:
controller:
image:
repository: <您的私有镜像仓库>/knative.dev-serving-cmd-controller
domainMapping:
domainMapping:
image:
repository: <您的私有镜像仓库>/knative.dev-serving-cmd-domain-mapping
domainmappingWebhook:
domainmappingWebhook:
image:
repository: <您的私有镜像仓库>/knative.dev-serving-cmd-domain-mapping-webhook
netContourController:
controller:
image:
repository: <您的私有镜像仓库>/knative.dev-net-contour-cmd-controller
defaultDomain:
job:
image:
repository: <您的私有镜像仓库>/knative.dev-serving-cmd-default-domain
webhook:
webhook:
image:
repository: <您的私有镜像仓库>/knative.dev-serving-cmd-webhook
shipwright-build:
shipwrightBuildController:
shipwrightBuild:
image:
repository: <您的私有镜像仓库>/shipwright-shipwright-build-controller
GIT_CONTAINER_IMAGE:
repository: <您的私有镜像仓库>/shipwright-io-build-git
MUTATE_IMAGE_CONTAINER_IMAGE:
repository: <您的私有镜像仓库>/shipwright-mutate-image
BUNDLE_CONTAINER_IMAGE:
repository: <您的私有镜像仓库>/shipwright-bundle
WAITER_CONTAINER_IMAGE:
repository: <您的私有镜像仓库>/shipwright-waiter
tekton-pipelines:
controller:
tektonPipelinesController:
image:
repository: <您的私有镜像仓库>/tektoncd-pipeline-cmd-controller
kubeconfigWriterImage:
repository: <您的私有镜像仓库>/tektoncd-pipeline-cmd-kubeconfigwriter
gitImage:
repository: <您的私有镜像仓库>/tektoncd-pipeline-cmd-git-init
entrypointImage:
repository: <您的私有镜像仓库>/tektoncd-pipeline-cmd-entrypoint
nopImage:
repository: <您的私有镜像仓库>/tektoncd-pipeline-cmd-nop
imagedigestExporterImage:
repository: <您的私有镜像仓库>/tektoncd-pipeline-cmd-imagedigestexporter
prImage:
repository: <您的私有镜像仓库>/tektoncd-pipeline-cmd-pullrequest-init
workingdirinitImage:
repository: <您的私有镜像仓库>/tektoncd-pipeline-cmd-workingdirinit
gsutilImage:
repository: <您的私有镜像仓库>/cloudsdktool-cloud-sdk
digest: sha256:27b2c22bf259d9bc1a291e99c63791ba0c27a04d2db0a43241ba0f1f20f4067f
shellImage:
repository: <您的私有镜像仓库>/distroless-base
digest: sha256:b16b57be9160a122ef048333c68ba205ae4fe1a7b7cc6a5b289956292ebf45cc
webhook:
webhook:
image:
repository: <您的私有镜像仓库>/tektoncd-pipeline-cmd-webhook
keda:
image:
keda:
repository: <您的私有镜像仓库>/keda
tag: 2.8.1
metricsApiServer:
repository: <您的私有镜像仓库>/keda-metrics-apiserver
tag: 2.8.1
dapr:
global:
registry: <您的私有镜像仓库>/daprio
tag: '1.8.3'
contour:
contour:
image:
registry: <您的私有镜像仓库>
repository: <您的私有镜像仓库>/contour
tag: 1.21.1-debian-11-r5
envoy:
image:
registry: <您的私有镜像仓库>
repository: <您的私有镜像仓库>/envoy
tag: 1.22.2-debian-11-r6
defaultBackend:
image:
registry: <您的私有镜像仓库>
repository: <您的私有镜像仓库>/nginx
tag: 1.21.6-debian-11-r10
请将 <您的私有镜像仓库>
替换为您的私有镜像仓库的地址。
安装 OpenFunction
在离线环境中运行以下命令尝试安装 OpenFunction:
kubectl create namespace openfunction
helm install openfunction openfunction-v1.0.0-v0.5.0.tgz -n openfunction -f custom-values.yaml
注意
如果 helm install
命令卡住,可能是由于 job contour-contour-cergen
引起的。
运行以下命令确认 job 是否执行成功:
kubectl get job contour-contour-cergen -n projectcontour
如果 job 存在且 job 状态为完成,运行以下命令完成安装:
helm uninstall openfunction -n openfunction --no-hooks
helm install openfunction openfunction-v1.0.0-v0.5.0.tgz -n openfunction -f custom-values.yaml --no-hooks
补丁 ClusterBuildStrategy
如果您想在离线环境中构建 wasm 函数或使用 buildah
构建函数,运行以下命令补丁 ClusterBuildStrategy
:
kubectl patch clusterbuildstrategy buildah --type='json' -p='[{"op": "replace", "path": "/spec/buildSteps/0/image", "value":"openfunction/buildah:v1.28.0"}]'
kubectl patch clusterbuildstrategy wasmedge --type='json' -p='[{"op": "replace", "path": "/spec/buildSteps/0/image", "value":"openfunction/buildah:v1.28.0"}]'
Q: 如何在离线环境中构建和运行函数
A: 以 Java 函数 为例,说明如何在离线环境中构建和运行函数:
将
https://github.com/OpenFunction/samples.git
同步到您的私有代码仓库按照此 prerequisites 文档创建
push-secret
和git-repo-secret
将公共 maven 仓库更改为私有 maven 仓库:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>dev.openfunction.samples</groupId> <artifactId>samples</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <repositories> <repository> <id>snapshots</id> <name>Maven snapshots</name> <!--<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>--> <url>your private maven repository</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> <dependencies> <dependency> <groupId>dev.openfunction.functions</groupId> <artifactId>functions-framework-api</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> </dependencies> </project>
确保将更改提交到代码仓库。
将
openfunction/buildpacks-java18-run:v1
同步到您的私有镜像仓库根据您的环境修改
functions/knative/java/hello-world/function-sample.yaml
:apiVersion: core.openfunction.io/v1beta2 kind: Function metadata: name: function-http-java spec: version: "v2.0.0" image: "<your private image repository>/sample-java-func:v1" imageCredentials: name: push-secret build: builder: <your private image repository>/builder-java:v2-18 params: RUN_IMAGE: "<your private image repository>/buildpacks-java18-run:v1" env: FUNC_NAME: "dev.openfunction.samples.HttpFunctionImpl" FUNC_CLEAR_SOURCE: "true" srcRepo: url: "https://<your private code repository>/OpenFunction/samples.git" sourceSubPath: "functions/knative/java" revision: "main" credentials: name: git-repo-secret serving: template: containers: - name: function # DO NOT change this imagePullPolicy: IfNotPresent triggers: http: port: 8080
如果您的私有镜像仓库是不安全的,请参考 以不安全的方式使用私有镜像仓库
运行以下命令构建和运行函数:
kubectl apply -f functions/knative/java/hello-world/function-sample.yaml