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

Commit 6d371ae

Browse files
gimlet2andresmgot
authored andcommitted
differentiate service port and target port for container (#993)
1 parent daf1814 commit 6d371ae

File tree

5 files changed

+39
-19
lines changed

5 files changed

+39
-19
lines changed

cmd/kubeless/function/deploy.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,14 @@ var deployCmd = &cobra.Command{
165165
logrus.Fatalf("Invalid port number %d specified", port)
166166
}
167167

168+
servicePort, err := cmd.Flags().GetInt32("servicePort")
169+
if err != nil {
170+
logrus.Fatal(err)
171+
}
172+
if servicePort < 0 || servicePort > 65535 {
173+
logrus.Fatalf("Invalid servicePort number %d specified", servicePort)
174+
}
175+
168176
funcDeps := ""
169177
if deps != "" {
170178
contentType, err := getContentType(deps)
@@ -191,7 +199,7 @@ var deployCmd = &cobra.Command{
191199
"function": funcName,
192200
}
193201

194-
f, err := getFunctionDescription(funcName, ns, handler, file, funcDeps, runtime, runtimeImage, mem, cpu, timeout, imagePullPolicy, port, headless, envs, labels, secrets, defaultFunctionSpec)
202+
f, err := getFunctionDescription(funcName, ns, handler, file, funcDeps, runtime, runtimeImage, mem, cpu, timeout, imagePullPolicy, port, servicePort, headless, envs, labels, secrets, defaultFunctionSpec)
195203
if err != nil {
196204
logrus.Fatal(err)
197205
}
@@ -277,4 +285,5 @@ func init() {
277285
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")
278286
deployCmd.Flags().Bool("dryrun", false, "Output JSON manifest of the function without creating it")
279287
deployCmd.Flags().Int32("port", 8080, "Deploy http-based function with a custom port")
288+
deployCmd.Flags().Int32("servicePort", 0, "Deploy http-based function with a custom service port. If not provided the value of 'port' will be used")
280289
}

cmd/kubeless/function/function.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ func parseContent(file, contentType string) (string, string, error) {
205205
return content, checksum, nil
206206
}
207207

208-
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) {
208+
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) {
209209

210210
function := defaultFunction
211211
function.TypeMeta = metav1.TypeMeta{
@@ -329,6 +329,9 @@ func getFunctionDescription(funcName, ns, handler, file, deps, runtime, runtimeI
329329
svcSpec.Ports[0].Port = port
330330
svcSpec.Ports[0].TargetPort = intstr.FromInt(int(port))
331331
}
332+
if servicePort != 0 {
333+
svcSpec.Ports[0].Port = servicePort
334+
}
332335
function.Spec.ServiceSpec = svcSpec
333336

334337
for _, secret := range secrets {

cmd/kubeless/function/function_test.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func TestGetFunctionDescription(t *testing.T) {
102102
file.Close()
103103
defer os.Remove(file.Name()) // clean up
104104

105-
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{})
105+
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{})
106106

107107
if err != nil {
108108
t.Error(err)
@@ -189,7 +189,7 @@ func TestGetFunctionDescription(t *testing.T) {
189189
}
190190

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

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

213-
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)
213+
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)
214214

215215
if err != nil {
216216
t.Error(err)
@@ -336,7 +336,7 @@ func TestGetFunctionDescription(t *testing.T) {
336336
file.Close()
337337
zipW.Close()
338338

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

347347
// It should maintain previous HPA definition
348-
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{
348+
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{
349349

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

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

460-
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{})
460+
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{})
461461

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

482482
expectedURLFunction.Spec.FunctionContentType = "url+zip"
483483
expectedURLFunction.Spec.Function = ts2.URL + "/test.zip"
484-
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{})
484+
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{})
485485
if err != nil {
486486
t.Error(err)
487487
}

cmd/kubeless/function/update.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,13 @@ var updateCmd = &cobra.Command{
146146
if port <= 0 || port > 65535 {
147147
logrus.Fatalf("Invalid port number %d specified", port)
148148
}
149+
servicePort, err := cmd.Flags().GetInt32("servicePort")
150+
if err != nil {
151+
logrus.Fatal(err)
152+
}
153+
if servicePort < 0 || servicePort > 65535 {
154+
logrus.Fatalf("Invalid servicePort number %d specified", servicePort)
155+
}
149156

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

165-
f, err := getFunctionDescription(funcName, ns, handler, file, funcDeps, runtime, runtimeImage, mem, cpu, timeout, imagePullPolicy, port, headless, envs, labels, secrets, previousFunction)
172+
f, err := getFunctionDescription(funcName, ns, handler, file, funcDeps, runtime, runtimeImage, mem, cpu, timeout, imagePullPolicy, port, servicePort, headless, envs, labels, secrets, previousFunction)
166173
if err != nil {
167174
logrus.Fatal(err)
168175
}
@@ -218,6 +225,7 @@ func init() {
218225
updateCmd.Flags().StringP("timeout", "", "180", "Maximum timeout (in seconds) for the function to complete its execution")
219226
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")
220227
updateCmd.Flags().Int32("port", 8080, "Deploy http-based function with a custom port")
228+
updateCmd.Flags().Int32("servicePort", 0, "Deploy http-based function with a custom service port")
221229
updateCmd.Flags().Bool("dryrun", false, "Output JSON manifest of the function without creating it")
222230
updateCmd.Flags().StringP("output", "o", "yaml", "Output format")
223231

pkg/utils/kubelessutil.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -528,11 +528,11 @@ func EnsureFuncImage(client kubernetes.Interface, funcObj *kubelessApi.Function,
528528
return err
529529
}
530530

531-
func svcPort(funcObj *kubelessApi.Function) int32 {
531+
func svcTargetPort(funcObj *kubelessApi.Function) int32 {
532532
if len(funcObj.Spec.ServiceSpec.Ports) == 0 {
533533
return int32(8080)
534534
}
535-
return funcObj.Spec.ServiceSpec.Ports[0].Port
535+
return int32(funcObj.Spec.ServiceSpec.Ports[0].TargetPort.IntValue())
536536
}
537537

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

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

655655
dpm.Spec.Template.Spec.Containers[0].Name = funcObj.ObjectMeta.Name
656656
dpm.Spec.Template.Spec.Containers[0].Ports = append(dpm.Spec.Template.Spec.Containers[0].Ports, v1.ContainerPort{
657-
ContainerPort: svcPort(funcObj),
657+
ContainerPort: svcTargetPort(funcObj),
658658
})
659659

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

663-
livenessProbeInfo := lr.GetLivenessProbeInfo(funcObj.Spec.Runtime, int(svcPort(funcObj)))
663+
livenessProbeInfo := lr.GetLivenessProbeInfo(funcObj.Spec.Runtime, int(svcTargetPort(funcObj)))
664664

665665
if dpm.Spec.Template.Spec.Containers[0].LivenessProbe == nil {
666666
dpm.Spec.Template.Spec.Containers[0].LivenessProbe = livenessProbeInfo

0 commit comments

Comments
 (0)