Skip to content
This repository has been archived by the owner on Dec 15, 2021. It is now read-only.

Commit

Permalink
differentiate service port and target port for container (#993)
Browse files Browse the repository at this point in the history
  • Loading branch information
gimlet2 authored and andresmgot committed Jan 29, 2019
1 parent daf1814 commit 6d371ae
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 19 deletions.
11 changes: 10 additions & 1 deletion cmd/kubeless/function/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,14 @@ var deployCmd = &cobra.Command{
logrus.Fatalf("Invalid port number %d specified", port)
}

servicePort, err := cmd.Flags().GetInt32("servicePort")
if err != nil {
logrus.Fatal(err)
}
if servicePort < 0 || servicePort > 65535 {
logrus.Fatalf("Invalid servicePort number %d specified", servicePort)
}

funcDeps := ""
if deps != "" {
contentType, err := getContentType(deps)
Expand All @@ -191,7 +199,7 @@ var deployCmd = &cobra.Command{
"function": funcName,
}

f, err := getFunctionDescription(funcName, ns, handler, file, funcDeps, runtime, runtimeImage, mem, cpu, timeout, imagePullPolicy, port, headless, envs, labels, secrets, defaultFunctionSpec)
f, err := getFunctionDescription(funcName, ns, handler, file, funcDeps, runtime, runtimeImage, mem, cpu, timeout, imagePullPolicy, port, servicePort, headless, envs, labels, secrets, defaultFunctionSpec)
if err != nil {
logrus.Fatal(err)
}
Expand Down Expand Up @@ -277,4 +285,5 @@ func init() {
deployCmd.Flags().Bool("headless", false, "Deploy http-based function without a single service IP and load balancing support from Kubernetes. See: https://kubernetes.io/docs/concepts/services-networking/service/#headless-services")
deployCmd.Flags().Bool("dryrun", false, "Output JSON manifest of the function without creating it")
deployCmd.Flags().Int32("port", 8080, "Deploy http-based function with a custom port")
deployCmd.Flags().Int32("servicePort", 0, "Deploy http-based function with a custom service port. If not provided the value of 'port' will be used")
}
5 changes: 4 additions & 1 deletion cmd/kubeless/function/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ func parseContent(file, contentType string) (string, string, error) {
return content, checksum, nil
}

func getFunctionDescription(funcName, ns, handler, file, deps, runtime, runtimeImage, mem, cpu, timeout string, imagePullPolicy string, port int32, headless bool, envs, labels []string, secrets []string, defaultFunction kubelessApi.Function) (*kubelessApi.Function, error) {
func getFunctionDescription(funcName, ns, handler, file, deps, runtime, runtimeImage, mem, cpu, timeout string, imagePullPolicy string, port int32, servicePort int32, headless bool, envs, labels []string, secrets []string, defaultFunction kubelessApi.Function) (*kubelessApi.Function, error) {

function := defaultFunction
function.TypeMeta = metav1.TypeMeta{
Expand Down Expand Up @@ -329,6 +329,9 @@ func getFunctionDescription(funcName, ns, handler, file, deps, runtime, runtimeI
svcSpec.Ports[0].Port = port
svcSpec.Ports[0].TargetPort = intstr.FromInt(int(port))
}
if servicePort != 0 {
svcSpec.Ports[0].Port = servicePort
}
function.Spec.ServiceSpec = svcSpec

for _, secret := range secrets {
Expand Down
20 changes: 10 additions & 10 deletions cmd/kubeless/function/function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func TestGetFunctionDescription(t *testing.T) {
file.Close()
defer os.Remove(file.Name()) // clean up

result, err := getFunctionDescription("test", "default", "file.handler", file.Name(), "dependencies", "runtime", "test-image", "128Mi", "", "10", "Always", 8080, false, []string{"TEST=1"}, []string{"test=1"}, []string{"secretName"}, kubelessApi.Function{})
result, err := getFunctionDescription("test", "default", "file.handler", file.Name(), "dependencies", "runtime", "test-image", "128Mi", "", "10", "Always", 8080, 0, false, []string{"TEST=1"}, []string{"test=1"}, []string{"secretName"}, kubelessApi.Function{})

if err != nil {
t.Error(err)
Expand Down Expand Up @@ -189,7 +189,7 @@ func TestGetFunctionDescription(t *testing.T) {
}

// It should take the default values
result2, err := getFunctionDescription("test", "default", "", "", "", "", "", "", "", "", "Always", 8080, false, []string{}, []string{}, []string{}, expectedFunction)
result2, err := getFunctionDescription("test", "default", "", "", "", "", "", "", "", "", "Always", 8080, 0, false, []string{}, []string{}, []string{}, expectedFunction)

if err != nil {
t.Error(err)
Expand All @@ -210,7 +210,7 @@ func TestGetFunctionDescription(t *testing.T) {
file.Close()
defer os.Remove(file.Name()) // clean up

result3, err := getFunctionDescription("test", "default", "file.handler2", file.Name(), "dependencies2", "runtime2", "test-image2", "256Mi", "100m", "20", "Always", 8080, false, []string{"TEST=2"}, []string{"test=2"}, []string{"secret2"}, expectedFunction)
result3, err := getFunctionDescription("test", "default", "file.handler2", file.Name(), "dependencies2", "runtime2", "test-image2", "256Mi", "100m", "20", "Always", 8080, 0, false, []string{"TEST=2"}, []string{"test=2"}, []string{"secret2"}, expectedFunction)

if err != nil {
t.Error(err)
Expand Down Expand Up @@ -336,7 +336,7 @@ func TestGetFunctionDescription(t *testing.T) {
file.Close()
zipW.Close()

result4, err := getFunctionDescription("test", "default", "file.handler", newfile.Name(), "dependencies", "runtime", "", "", "", "", "Always", 8080, false, []string{}, []string{}, []string{}, expectedFunction)
result4, err := getFunctionDescription("test", "default", "file.handler", newfile.Name(), "dependencies", "runtime", "", "", "", "", "Always", 8080, 0, false, []string{}, []string{}, []string{}, expectedFunction)
if err != nil {
t.Error(err)
}
Expand All @@ -345,7 +345,7 @@ func TestGetFunctionDescription(t *testing.T) {
}

// It should maintain previous HPA definition
result5, err := getFunctionDescription("test", "default", "file.handler", file.Name(), "dependencies", "runtime", "test-image", "128Mi", "", "10", "Always", 8080, false, []string{"TEST=1"}, []string{"test=1"}, []string{}, kubelessApi.Function{
result5, err := getFunctionDescription("test", "default", "file.handler", file.Name(), "dependencies", "runtime", "test-image", "128Mi", "", "10", "Always", 8080, 0, false, []string{"TEST=1"}, []string{"test=1"}, []string{}, kubelessApi.Function{

Spec: kubelessApi.FunctionSpec{
HorizontalPodAutoscaler: v2beta1.HorizontalPodAutoscaler{
Expand All @@ -359,11 +359,11 @@ func TestGetFunctionDescription(t *testing.T) {
t.Error("should maintain previous HPA definition")
}

// It should set the Port and headless service properly
result6, err := getFunctionDescription("test", "default", "file.handler", file.Name(), "dependencies", "runtime", "test-image", "128Mi", "", "", "Always", 9091, true, []string{}, []string{}, []string{}, kubelessApi.Function{})
// It should set the Port, ServicePort and headless service properly
result6, err := getFunctionDescription("test", "default", "file.handler", file.Name(), "dependencies", "runtime", "test-image", "128Mi", "", "", "Always", 9091, 9092, true, []string{}, []string{}, []string{}, kubelessApi.Function{})
expectedPort := v1.ServicePort{
Name: "http-function-port",
Port: 9091,
Port: 9092,
TargetPort: intstr.FromInt(9091),
NodePort: 0,
Protocol: v1.ProtocolTCP,
Expand Down Expand Up @@ -457,7 +457,7 @@ func TestGetFunctionDescription(t *testing.T) {
},
}

result7, err := getFunctionDescription("test", "default", "file.handler", ts.URL, "dependencies", "runtime", "test-image", "128Mi", "", "10", "Always", 8080, false, []string{"TEST=1"}, []string{"test=1"}, []string{"secretName"}, kubelessApi.Function{})
result7, err := getFunctionDescription("test", "default", "file.handler", ts.URL, "dependencies", "runtime", "test-image", "128Mi", "", "10", "Always", 8080, 0, false, []string{"TEST=1"}, []string{"test=1"}, []string{"secretName"}, kubelessApi.Function{})

if err != nil {
t.Error(err)
Expand All @@ -481,7 +481,7 @@ func TestGetFunctionDescription(t *testing.T) {

expectedURLFunction.Spec.FunctionContentType = "url+zip"
expectedURLFunction.Spec.Function = ts2.URL + "/test.zip"
result8, err := getFunctionDescription("test", "default", "file.handler", ts2.URL+"/test.zip", "dependencies", "runtime", "test-image", "128Mi", "", "10", "Always", 8080, false, []string{"TEST=1"}, []string{"test=1"}, []string{"secretName"}, kubelessApi.Function{})
result8, err := getFunctionDescription("test", "default", "file.handler", ts2.URL+"/test.zip", "dependencies", "runtime", "test-image", "128Mi", "", "10", "Always", 8080, 0, false, []string{"TEST=1"}, []string{"test=1"}, []string{"secretName"}, kubelessApi.Function{})
if err != nil {
t.Error(err)
}
Expand Down
10 changes: 9 additions & 1 deletion cmd/kubeless/function/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,13 @@ var updateCmd = &cobra.Command{
if port <= 0 || port > 65535 {
logrus.Fatalf("Invalid port number %d specified", port)
}
servicePort, err := cmd.Flags().GetInt32("servicePort")
if err != nil {
logrus.Fatal(err)
}
if servicePort < 0 || servicePort > 65535 {
logrus.Fatalf("Invalid servicePort number %d specified", servicePort)
}

output, err := cmd.Flags().GetString("output")
if err != nil {
Expand All @@ -162,7 +169,7 @@ var updateCmd = &cobra.Command{
logrus.Fatal(err)
}

f, err := getFunctionDescription(funcName, ns, handler, file, funcDeps, runtime, runtimeImage, mem, cpu, timeout, imagePullPolicy, port, headless, envs, labels, secrets, previousFunction)
f, err := getFunctionDescription(funcName, ns, handler, file, funcDeps, runtime, runtimeImage, mem, cpu, timeout, imagePullPolicy, port, servicePort, headless, envs, labels, secrets, previousFunction)
if err != nil {
logrus.Fatal(err)
}
Expand Down Expand Up @@ -218,6 +225,7 @@ func init() {
updateCmd.Flags().StringP("timeout", "", "180", "Maximum timeout (in seconds) for the function to complete its execution")
updateCmd.Flags().Bool("headless", false, "Deploy http-based function without a single service IP and load balancing support from Kubernetes. See: https://kubernetes.io/docs/concepts/services-networking/service/#headless-services")
updateCmd.Flags().Int32("port", 8080, "Deploy http-based function with a custom port")
updateCmd.Flags().Int32("servicePort", 0, "Deploy http-based function with a custom service port")
updateCmd.Flags().Bool("dryrun", false, "Output JSON manifest of the function without creating it")
updateCmd.Flags().StringP("output", "o", "yaml", "Output format")

Expand Down
12 changes: 6 additions & 6 deletions pkg/utils/kubelessutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -528,11 +528,11 @@ func EnsureFuncImage(client kubernetes.Interface, funcObj *kubelessApi.Function,
return err
}

func svcPort(funcObj *kubelessApi.Function) int32 {
func svcTargetPort(funcObj *kubelessApi.Function) int32 {
if len(funcObj.Spec.ServiceSpec.Ports) == 0 {
return int32(8080)
}
return funcObj.Spec.ServiceSpec.Ports[0].Port
return int32(funcObj.Spec.ServiceSpec.Ports[0].TargetPort.IntValue())
}

func mergeMap(dst, src map[string]string) map[string]string {
Expand All @@ -558,7 +558,7 @@ func EnsureFuncDeployment(client kubernetes.Interface, funcObj *kubelessApi.Func
// "targets")
"prometheus.io/scrape": "true",
"prometheus.io/path": "/metrics",
"prometheus.io/port": strconv.Itoa(int(svcPort(funcObj))),
"prometheus.io/port": strconv.Itoa(int(svcTargetPort(funcObj))),
}
maxUnavailable := intstr.FromInt(0)

Expand Down Expand Up @@ -648,19 +648,19 @@ func EnsureFuncDeployment(client kubernetes.Interface, funcObj *kubelessApi.Func
dpm.Spec.Template.Spec.Containers[0].Env = append(dpm.Spec.Template.Spec.Containers[0].Env,
v1.EnvVar{
Name: "FUNC_PORT",
Value: strconv.Itoa(int(svcPort(funcObj))),
Value: strconv.Itoa(int(svcTargetPort(funcObj))),
},
)

dpm.Spec.Template.Spec.Containers[0].Name = funcObj.ObjectMeta.Name
dpm.Spec.Template.Spec.Containers[0].Ports = append(dpm.Spec.Template.Spec.Containers[0].Ports, v1.ContainerPort{
ContainerPort: svcPort(funcObj),
ContainerPort: svcTargetPort(funcObj),
})

// update deployment for loading dependencies
lr.UpdateDeployment(dpm, runtimeVolumeMount.MountPath, funcObj.Spec.Runtime)

livenessProbeInfo := lr.GetLivenessProbeInfo(funcObj.Spec.Runtime, int(svcPort(funcObj)))
livenessProbeInfo := lr.GetLivenessProbeInfo(funcObj.Spec.Runtime, int(svcTargetPort(funcObj)))

if dpm.Spec.Template.Spec.Containers[0].LivenessProbe == nil {
dpm.Spec.Template.Spec.Containers[0].LivenessProbe = livenessProbeInfo
Expand Down

0 comments on commit 6d371ae

Please sign in to comment.