Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .ci/clusters/compute_v1alpha1_function_builtin_hpa.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
apiVersion: compute.functionmesh.io/v1alpha1
kind: Function
metadata:
name: function-builtin-hpa-sample
namespace: default
spec:
image: streamnative/pulsar-functions-java-sample:2.8.0.7
className: org.apache.pulsar.functions.api.examples.ExclamationFunction
forwardSourceMessageProperty: true
MaxPendingAsyncRequests: 1000
replicas: 1
maxReplicas: 5
logTopic: persistent://public/default/logging-function-logs
input:
topics:
- persistent://public/default/input-java-topic
typeClassName: java.lang.String
output:
topic: persistent://public/default/output-java-topic
typeClassName: java.lang.String
resources:
requests:
cpu: "0.1"
memory: 1G
limits:
cpu: "0.2"
memory: 1.1G
# each secret will be loaded ad an env variable from the `path` secret with the `key` in that secret in the name of `name`
secretsMap:
"name":
path: "test-secret"
key: "username"
"pwd":
path: "test-secret"
key: "password"
pulsar:
pulsarConfig: "test-pulsar"
#authConfig: "test-auth"
java:
jar: /pulsar/examples/api-examples.jar
# to be delete & use admission hook
clusterName: test
autoAck: true
pod:
builtinAutoscaler:
- AverageUtilizationCPUPercent20
- AverageUtilizationMemoryPercent20
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test-pulsar
data:
webServiceURL: http://sn-platform-pulsar-broker.default.svc.cluster.local:8080
brokerServiceURL: pulsar://sn-platform-pulsar-broker.default.svc.cluster.local:6650
#---
#apiVersion: v1
#kind: ConfigMap
#metadata:
# name: test-auth
#data:
# clientAuthenticationPlugin: "abc"
# clientAuthenticationParameters: "xyz"
# tlsTrustCertsFilePath: "uvw"
# useTls: "true"
# tlsAllowInsecureConnection: "false"
# tlsHostnameVerificationEnable: "true"
---
apiVersion: v1
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
kind: Secret
metadata:
name: test-secret
type: Opaque
80 changes: 80 additions & 0 deletions .ci/clusters/compute_v1alpha1_function_hpa.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
apiVersion: compute.functionmesh.io/v1alpha1
kind: Function
metadata:
name: function-hpa-sample
namespace: default
spec:
image: streamnative/pulsar-functions-java-sample:2.8.0.7
className: org.apache.pulsar.functions.api.examples.ExclamationFunction
forwardSourceMessageProperty: true
MaxPendingAsyncRequests: 1000
replicas: 1
maxReplicas: 5
logTopic: persistent://public/default/logging-function-logs
input:
topics:
- persistent://public/default/input-java-topic
typeClassName: java.lang.String
output:
topic: persistent://public/default/output-java-topic
typeClassName: java.lang.String
resources:
requests:
cpu: "0.1"
memory: 1G
limits:
cpu: "0.2"
memory: 1.1G
# each secret will be loaded ad an env variable from the `path` secret with the `key` in that secret in the name of `name`
secretsMap:
"name":
path: "test-secret"
key: "username"
"pwd":
path: "test-secret"
key: "password"
pulsar:
pulsarConfig: "test-pulsar"
#authConfig: "test-auth"
java:
jar: /pulsar/examples/api-examples.jar
# to be delete & use admission hook
clusterName: test
autoAck: true
pod:
autoScalingMetrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test-pulsar
data:
webServiceURL: http://sn-platform-pulsar-broker.default.svc.cluster.local:8080
brokerServiceURL: pulsar://sn-platform-pulsar-broker.default.svc.cluster.local:6650
#---
#apiVersion: v1
#kind: ConfigMap
#metadata:
# name: test-auth
#data:
# clientAuthenticationPlugin: "abc"
# clientAuthenticationParameters: "xyz"
# tlsTrustCertsFilePath: "uvw"
# useTls: "true"
# tlsAllowInsecureConnection: "false"
# tlsHostnameVerificationEnable: "true"
---
apiVersion: v1
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
kind: Secret
metadata:
name: test-secret
type: Opaque
3 changes: 3 additions & 0 deletions .ci/deploy_pulsar_cluster.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ fi
# install storage provisioner
ci::install_storage_provisioner

# install metrics server
ci::install_metrics_server

# install pulsar chart
ci::install_pulsar_charts "$VALUES_FILE"

Expand Down
32 changes: 32 additions & 0 deletions .ci/helm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,20 @@ function ci::install_storage_provisioner() {
echo "Successfully installed the local storage provisioner."
}

function ci::install_metrics_server() {
echo "install metrics-server"
${KUBECTL} apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.3.7/components.yaml
${KUBECTL} patch deployment metrics-server -n kube-system -p '{"spec":{"template":{"spec":{"containers":[{"name":"metrics-server","args":["--cert-dir=/tmp", "--secure-port=4443", "--kubelet-insecure-tls","--kubelet-preferred-address-types=InternalIP"]}]}}}}'
echo "Successfully installed the metrics-server."
WC=$(${KUBECTL} get pods -n kube-system --field-selector=status.phase=Running | grep metrics-server | wc -l)
while [[ ${WC} -lt 1 ]]; do
echo ${WC};
sleep 20
${KUBECTL} get pods -n kube-system
WC=$(${KUBECTL} get pods -n kube-system --field-selector=status.phase=Running | grep metrics-server | wc -l)
done
}

function ci::install_pulsar_charts() {
echo "Installing the pulsar charts ..."
values=${1:-".ci/clusters/values.yaml"}
Expand Down Expand Up @@ -126,6 +140,24 @@ function ci::verify_function_mesh() {
${KUBECTL} describe pod -lname=${FUNCTION_NAME}
}

function ci::verify_hpa() {
FUNCTION_NAME=$1
${KUBECTL} get function
${KUBECTL} get function ${FUNCTION_NAME} -o yaml
${KUBECTL} get hpa.v2beta2.autoscaling
${KUBECTL} get hpa.v2beta2.autoscaling ${FUNCTION_NAME}-function -o yaml
${KUBECTL} describe hpa.v2beta2.autoscaling ${FUNCTION_NAME}-function
WC=$(${KUBECTL} get hpa.v2beta2.autoscaling ${FUNCTION_NAME}-function -o jsonpath='{.status.conditions[?(@.type=="AbleToScale")].status}' | grep False | wc -l)
while [[ ${WC} -lt 0 ]]; do
echo ${WC};
sleep 20
${KUBECTL} get hpa.v2beta2.autoscaling ${FUNCTION_NAME}-function -o yaml
${KUBECTL} describe hpa.v2beta2.autoscaling ${FUNCTION_NAME}-function
${KUBECTL} get hpa.v2beta2.autoscaling ${FUNCTION_NAME}-function -o jsonpath='{.status.conditions[?(@.type=="AbleToScale")].status}'
WC=$(${KUBECTL} get hpa.v2beta2.autoscaling ${FUNCTION_NAME}-function -o jsonpath='{.status.conditions[?(@.type=="AbleToScale")].status}' | grep False | wc -l)
done
}

function ci::test_function_runners() {
${KUBECTL} exec -n ${NAMESPACE} ${CLUSTER}-pulsar-broker-0 -- bin/pulsar-admin functions create --tenant public --namespace default --name test-java --className org.apache.pulsar.functions.api.examples.ExclamationFunction --inputs persistent://public/default/test-java-input --jar /pulsar/examples/api-examples.jar --cpu 0.1
sleep 15
Expand Down
16 changes: 16 additions & 0 deletions .ci/verify_function_mesh.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,20 @@ case ${1} in
ci::print_function_log functionmesh-sample-python-function
ci::verify_mesh_function
;;
compute_v1alpha1_function_hpa)
ci::verify_function_mesh function-hpa-sample
ci::verify_hpa function-hpa-sample
sleep 60
ci::print_function_log function-hpa-sample
ci::verify_java_function function-hpa-sample
ci::verify_hpa function-hpa-sample
;;
compute_v1alpha1_function_builtin_hpa)
ci::verify_function_mesh function-builtin-hpa-sample
ci::verify_hpa function-builtin-hpa-sample
sleep 60
ci::print_function_log function-builtin-hpa-sample
ci::verify_java_function function-builtin-hpa-sample
ci::verify_hpa function-builtin-hpa-sample
;;
esac
2 changes: 1 addition & 1 deletion .github/workflows/test-helm-charts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
if: steps.list-changed.outputs.changed == 'true'

- name: Create kind cluster
uses: helm/kind-action@v1.2.0
run: hack/kind-cluster-build.sh --name chart-testing -c 3 -v 10
if: steps.list-changed.outputs.changed == 'true'
with:
node_image: kindest/node:v1.15.12
Expand Down
24 changes: 24 additions & 0 deletions .github/workflows/test-integration-kind-samples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ jobs:
- name: Verify Function kind - Java Function
run: |
.ci/verify_function_mesh.sh compute_v1alpha1_function
kubectl delete -f .ci/clusters/compute_v1alpha1_function.yaml

- name: Test Function kind - Python Function
run: |
Expand All @@ -72,6 +73,7 @@ jobs:
- name: Verify Function kind - Python Function
run: |
.ci/verify_function_mesh.sh compute_v1alpha1_py_function
kubectl delete -f .ci/clusters/compute_v1alpha1_py_function.yaml

- name: Test Function kind - Go Function
run: |
Expand All @@ -81,6 +83,7 @@ jobs:
- name: Verify Function kind - Go Function
run: |
.ci/verify_function_mesh.sh compute_v1alpha1_go_function
kubectl delete -f .ci/clusters/compute_v1alpha1_go_function.yaml

- name: Test Mesh kind
run: |
Expand All @@ -90,3 +93,24 @@ jobs:
- name: Verify Mesh kind
run: |
.ci/verify_function_mesh.sh compute_v1alpha1_functionmesh
kubectl delete -f .ci/clusters/compute_v1alpha1_functionmesh.yaml

- name: Test Function HPA
run: |
kubectl apply -f .ci/clusters/compute_v1alpha1_function_hpa.yaml
kubectl get all

- name: Verify Function HPA
run: |
.ci/verify_function_mesh.sh compute_v1alpha1_function_hpa
kubectl delete -f .ci/clusters/compute_v1alpha1_function_hpa.yaml

- name: Test Function Builtin HPA
run: |
kubectl apply -f .ci/clusters/compute_v1alpha1_function_builtin_hpa.yaml
kubectl get all

- name: Verify Function Builtin HPA
run: |
.ci/verify_function_mesh.sh compute_v1alpha1_function_builtin_hpa
kubectl delete -f .ci/clusters/compute_v1alpha1_function_builtin_hpa.yaml
21 changes: 21 additions & 0 deletions api/v1alpha1/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package v1alpha1
import (
"encoding/json"

autov2beta2 "k8s.io/api/autoscaling/v2beta2"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -93,6 +94,26 @@ type PodPolicy struct {
// ServiceAccountName is the name of the ServiceAccount to use to run this pod.
// +optional
ServiceAccountName string `json:"serviceAccountName,omitempty"`

// BuiltinAutoscaler refers to the built-in autoscaling rules
// Available values: AverageUtilizationCPUPercent80, AverageUtilizationCPUPercent50, AverageUtilizationCPUPercent20
// AverageUtilizationMemoryPercent80, AverageUtilizationMemoryPercent50, AverageUtilizationMemoryPercent20
// +optional
// TODO: validate the rules, user may provide duplicate rules, should check with webhook
BuiltinAutoscaler []BuiltinHPARule `json:"builtinAutoscaler,omitempty"`

// AutoScalingMetrics contains the specifications for which to use to calculate the
// desired replica count (the maximum replica count across all metrics will
// be used).
// More info: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#metricspec-v2beta2-autoscaling
// +optional
AutoScalingMetrics []autov2beta2.MetricSpec `json:"autoScalingMetrics,omitempty"`

// AutoScalingBehavior configures the scaling behavior of the target
// in both Up and Down directions (scaleUp and scaleDown fields respectively).
// If not set, the default HPAScalingRules for scale up and scale down are used.
// +optional
AutoScalingBehavior *autov2beta2.HorizontalPodAutoscalerBehavior `json:"autoScalingBehavior,omitempty"`
}

type Runtime struct {
Expand Down
14 changes: 9 additions & 5 deletions api/v1alpha1/function_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,15 @@ import (
type FunctionSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
Name string `json:"name,omitempty"`
ClassName string `json:"className,omitempty"`
Tenant string `json:"tenant,omitempty"`
ClusterName string `json:"clusterName,omitempty"`
Replicas *int32 `json:"replicas,omitempty"`
Name string `json:"name,omitempty"`
ClassName string `json:"className,omitempty"`
Tenant string `json:"tenant,omitempty"`
ClusterName string `json:"clusterName,omitempty"`
Replicas *int32 `json:"replicas,omitempty"`

// MaxReplicas indicates the maximum number of replicas and enables the HorizontalPodAutoscaler
// If provided, a default HPA with CPU at average of 80% will be used.
// For complex HPA strategies, please refer to Pod.HPAutoscaler.
MaxReplicas *int32 `json:"maxReplicas,omitempty"` // if provided, turn on autoscaling
Input InputConf `json:"input,omitempty"`
Output OutputConf `json:"output,omitempty"`
Expand Down
33 changes: 33 additions & 0 deletions api/v1alpha1/hpa.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

// Package v1alpha1 contains API Schema definitions for the cloud v1alpha1 API group
// +kubebuilder:object:generate=true
// +groupName=compute.functionmesh.io
package v1alpha1

type BuiltinHPARule string

const (
AverageUtilizationCPUPercent80 BuiltinHPARule = "AverageUtilizationCPUPercent80"
AverageUtilizationCPUPercent50 BuiltinHPARule = "AverageUtilizationCPUPercent50"
AverageUtilizationCPUPercent20 BuiltinHPARule = "AverageUtilizationCPUPercent20"

AverageUtilizationMemoryPercent80 BuiltinHPARule = "AverageUtilizationMemoryPercent80"
AverageUtilizationMemoryPercent50 BuiltinHPARule = "AverageUtilizationMemoryPercent50"
AverageUtilizationMemoryPercent20 BuiltinHPARule = "AverageUtilizationMemoryPercent20"
)
Loading