Bug 1431781 - “oc expose svc” should use service targetPort number not port number
Summary: “oc expose svc” should use service targetPort number not port number
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: OpenShift Container Platform
Classification: Red Hat
Component: Networking
Version: 3.5.0
Hardware: Unspecified
OS: Unspecified
medium
medium
Target Milestone: ---
: ---
Assignee: Phil Cameron
QA Contact: Meng Bo
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2017-03-13 18:02 UTC by Weibin Liang
Modified: 2017-08-16 19:51 UTC (History)
4 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Cause: expose was picking up the service port instead of the target port Consequence: route didn't work Fix: bug fix now grabs target port. Doc should discuss this behavior. Result:
Clone Of:
Environment:
Last Closed: 2017-08-10 05:18:47 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Origin (Github) 13609 0 None None None 2017-04-04 18:42:04 UTC
Red Hat Product Errata RHEA-2017:1716 0 normal SHIPPED_LIVE Red Hat OpenShift Container Platform 3.6 RPM Release Advisory 2017-08-10 09:02:50 UTC

Description Weibin Liang 2017-03-13 18:02:49 UTC
Description of problem:
Using “ oc expose svc” to create a route,  the port number for route is configured from svc port number not targetPort number, then curl the route will fail.


Version-Release number of selected component (if applicable):
oc v3.5.0.50
kubernetes v1.5.2+43a9be4


How reproducible:
Every time.

Steps to Reproduce:
[root@ip-172-18-0-243 ~]# oc create -f pod.json 
pod "endpoint-1" created
[root@ip-172-18-0-243 ~]# oc create -f svc.json 
service "endpoints" created
[root@ip-172-18-0-243 ~]# cat svc.json 
{
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
        "name": "endpoints",
        "labels": {
            "test": "router"
        }
    },
    "spec": {
        "ports": [
            {
                "protocol": "TCP",
                "port": 8888,
                "targetPort": 8080
            }
        ],
        "selector": {
            "endpoints": "router",
            "test": "router"
        }
    }
}
[root@ip-172-18-0-243 ~]# 
[root@ip-172-18-0-243 ~]# oc get svc
NAME        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
endpoints   172.30.152.36   <none>        8888/TCP   24s
[root@ip-172-18-0-243 ~]# curl 172.30.152.36:8888
Hello OpenShift!
[root@ip-172-18-0-243 ~]# oc get ep
NAME        ENDPOINTS          AGE
endpoints   10.128.0.36:8080   36s
[root@ip-172-18-0-243 ~]# curl 10.128.0.36:8080
Hello OpenShift!
[root@ip-172-18-0-243 ~]# 

[root@ip-172-18-0-243 ~]# oc expose svc endpoints
route "endpoints" exposed
[root@ip-172-18-0-243 ~]# oc get route
NAME        HOST/PORT                              PATH      SERVICES    PORT      TERMINATION   WILDCARD
endpoints   endpoints-p1.0313-i0q.qe.rhcloud.com             endpoints   8888                    None
[root@ip-172-18-0-243 ~]# 

[root@ip-172-18-0-243 ~]# curl --resolve endpoints-p1.0313-i0q.qe.rhcloud.com:80:172.18.8.92  

[root@ip-172-18-0-243 ~]# oc edit route endpoints 
route "endpoints" edited
[root@ip-172-18-0-243 ~]# oc get route endpoints -o json | grep targetPort
            "targetPort": 8080
[root@ip-172-18-0-243 ~]# 

[root@ip-172-18-0-243 ~]# oc get route
NAME        HOST/PORT                              PATH      SERVICES    PORT      TERMINATION   WILDCARD
endpoints   endpoints-p1.0313-i0q.qe.rhcloud.com             endpoints   8080                    None
[root@ip-172-18-0-243 ~]# curl --resolve endpoints-p1.0313-i0q.qe.rhcloud.com:80:172.18.8.92  http://endpoints-p1.0313-i0q.qe.rhcloud.com
Hello OpenShift!
[root@ip-172-18-0-243 ~]# 

Actual results:
[root@ip-172-18-0-243 ~]# oc get route
NAME        HOST/PORT                              PATH      SERVICES    PORT      TERMINATION   WILDCARD
endpoints   endpoints-p1.0313-i0q.qe.rhcloud.com             endpoints   8888                    None
[root@ip-172-18-0-243 ~]# curl --resolve endpoints-p1.0313-i0q.qe.rhcloud.com:80:172.18.8.92  

Expected results:
[root@ip-172-18-0-243 ~]# oc get route
NAME        HOST/PORT                              PATH      SERVICES    PORT      TERMINATION   WILDCARD
endpoints   endpoints-p1.0313-i0q.qe.rhcloud.com             endpoints   8080                    None
[root@ip-172-18-0-243 ~]# curl --resolve endpoints-p1.0313-i0q.qe.rhcloud.com:80:172.18.8.92  http://endpoints-p1.0313-i0q.qe.rhcloud.com
Hello OpenShift!


Additional info:

Comment 1 Meng Bo 2017-03-14 05:31:16 UTC
I think this is working as expected. 
https://github.com/openshift/origin/commit/56fd35e1681b2bf63b1d23a9582abae36f193f4d

User can use option --target-port when exposing service.

Comment 2 Weibin Liang 2017-03-14 15:07:10 UTC
[root@ip-172-18-7-62 ~]# oc expose svc hello-service --port 8080
route "hello-service" exposed
[root@ip-172-18-7-62 ~]# oc get route
NAME            HOST/PORT                                     PATH      SERVICES        PORT      TERMINATION   WILDCARD
hello-service   hello-service-https.0313-udf.qe.rhcloud.com             hello-service   8080                    None
[root@ip-172-18-7-62 ~]# oc delete route hello-service
[root@ip-172-18-7-62 ~]# oc expose svc hello-service --port 8080
route "hello-service" exposed
[root@ip-172-18-7-62 ~]# oc get route
NAME            HOST/PORT                                     PATH      SERVICES        PORT      TERMINATION   WILDCARD
hello-service   hello-service-https.0313-udf.qe.rhcloud.com             hello-service   8888                    None

oc expose svc with --port will use correct port.

But, this bug is about without --port option the default behavior for oc expose svc is to use the target-port defined in svc.json file.

Comment 3 Phil Cameron 2017-03-30 22:22:14 UTC
Two errors: expose pod and expose service both take the port, not the containerPort or targetPort.

========================
Experiment: Expose a pod:

# oc get po hello-openshift  -o yaml | grep containerPort
    - containerPort: 8080

# oc expose po hello-openshift
service "hello-openshift" exposed
# oc get svc
NAME              CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
hello-openshift   172.30.63.66   <none>        8080/TCP   8s
# curl 172.30.63.66:8080
Hello OpenShift!
# oc get svc -o yaml
    ports:
    - port: 8080
      protocol: TCP
      targetPort: 8080

========
# oc delete svc hello-openshift
service "hello-openshift" deleted
# oc expose po hello-openshift --port=9999
service "hello-openshift" exposed
# oc get svc hello-openshift
NAME              CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
hello-openshift   172.30.137.134   <none>        9999/TCP   36s
# curl 172.30.137.134:9999
curl: (7) Failed connect to 172.30.137.134:9999; Connection refused
# oc get svc hello-openshift -o yaml
  ports:
  - port: 9999
    protocol: TCP
    targetPort: 9999    <<< expected this to be 8080 (pod containerPort)


=========
# oc edit svc hello-openshift
   change targetPort: 8080
===========
# curl 172.30.137.134:9999
Hello OpenShift!
====================
====================

Experiment: Expose a service

# oc get svc hello-openshift -o yaml
  clusterIP: 172.30.137.134
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
# oc expose svc hello-openshift
route "hello-openshift" exposed
# oc get route
NAME              HOST/PORT                                             PATH      SERVICES          PORT      TERMINATION   WILDCARD
hello-openshift   hello-openshift-bb.router.default.svc.cluster.local             hello-openshift   8080                    None
# curl -H 'Host: hello-openshift-bb.router.default.svc.cluster.local' 10.254.254.28
Hello OpenShift!

===============
Edit svc with different port:
  clusterIP: 172.30.137.134
  ports:
  - port: 9999          <<<< different port here
    protocol: TCP
    targetPort: 8080
# oc delete route hello-openshift
route "hello-openshift" deleted
# oc expose svc hello-openshift
route "hello-openshift" exposed
# oc get route
NAME              HOST/PORT                                             PATH      SERVICES          PORT      TERMINATION   WILDCARD
hello-openshift   hello-openshift-bb.router.default.svc.cluster.local             hello-openshift   9999                    None
# oc get route -o yaml
    port:
      targetPort: 9999     <<<< this should be 8080 (svc targetPort)

# curl -H 'Host: hello-openshift-bb.router.default.svc.cluster.local' 10.254.254.28
      <h1>Application is not available</h1>
      <p>The application is currently not serving requests at this endpoint. It may not have been started or is still starting.</p>

================
Experiment: expose svc and specify the port

# oc delete route hello-openshift
route "hello-openshift" deleted

Using svc above 9999:8080

# oc expose svc hello-openshift --port=8080
route "hello-openshift" exposed
# oc get route hello-openshift
NAME              HOST/PORT                                             PATH      SERVICES          PORT      TERMINATION   WILDCARD
hello-openshift   hello-openshift-bb.router.default.svc.cluster.local             hello-openshift   8080                    None
# oc get route -o yaml
    port:
      targetPort: 8080
# curl -H 'Host: hello-openshift-bb.router.default.svc.cluster.local' 10.254.254.28
Hello OpenShift!

==========================
Conclusions: --port sets the route target:port
or the service port and targetPort

Comment 4 Ben Bennett 2017-05-12 13:22:46 UTC
Flagged upcoming release since this is not a regression.

Comment 5 Phil Cameron 2017-05-24 13:11:09 UTC
Out for review:
https://github.com/openshift/origin/pull/13609

Comment 6 Ben Bennett 2017-05-31 20:17:12 UTC
Will merge on Monday since it's not a blocker.

Comment 7 openshift-github-bot 2017-06-06 09:34:11 UTC
Commit pushed to master at https://github.com/openshift/origin

https://github.com/openshift/origin/commit/51581f2228f567a7f6eaabd2dd0e0107f70094af
“oc expose svc” should use service targetPort number

The upstream generator in 'oc expose' creates the route.TargetPort
when no port is set. It incorrectly selects the service.Port instead
of the needed service TargetPort. This change forces a port to be
set before invoking the upstream generator.

bug 1431781
https://bugzilla.redhat.com/show_bug.cgi?id=1431781

Signed-off-by: Phil Cameron <pcameron>

Comment 9 Weibin Liang 2017-06-27 14:58:43 UTC
Above advisory image does not fix the problem, the port number for route is still configured from svc port number not targetPort number,re open this bug.

[root@host-8-174-71 ~]# oc create -f svc.json 
service "endpoints" created
[root@host-8-174-71 ~]# oc get svc
NAME               CLUSTER-IP       EXTERNAL-IP   PORT(S)                            AGE
docker-registry    172.30.242.185   <none>        5000/TCP                           51m
endpoints          172.30.149.254   <none>        8888/TCP                           3s
hello-openshift    172.30.239.242   <none>        8080/TCP,8888/TCP                  36m
hello-pod          172.30.148.229   <none>        8080/TCP,8888/TCP                  36m
kubernetes         172.30.0.1       <none>        443/TCP,53/UDP,53/TCP              58m
registry-console   172.30.200.68    <none>        9000/TCP                           51m
router             172.30.50.170    <none>        80/TCP,443/TCP,1935/TCP,1936/TCP   52m
[root@host-8-174-71 ~]# oc expose svc endpoints
route "endpoints" exposed
[root@host-8-174-71 ~]# oc get route
NAME               HOST/PORT                                          PATH      SERVICES           PORT      TERMINATION   WILDCARD
docker-registry    docker-registry-default.0627-m46.qe.rhcloud.com              docker-registry    <all>     passthrough   None
endpoints          endpoints-default.0627-m46.qe.rhcloud.com                    endpoints          8888                    None
registry-console   registry-console-default.0627-m46.qe.rhcloud.com             registry-console   <all>     passthrough   None
[root@host-8-174-71 ~]# oc version
oc v3.6.96
kubernetes v1.6.1+5115d708d7
features: Basic-Auth GSSAPI Kerberos SPNEGO

Server https://host-8-174-71.host.centralci.eng.rdu2.redhat.com:8443
openshift v3.6.96
kubernetes v1.6.1+5115d708d7
[root@host-8-174-71 ~]# rpm -qa | grep 3.6.96
atomic-openshift-excluder-3.6.96-1.git.0.381dd63.el7.noarch
atomic-openshift-clients-3.6.96-1.git.0.381dd63.el7.x86_64
atomic-openshift-sdn-ovs-3.6.96-1.git.0.381dd63.el7.x86_64
atomic-openshift-docker-excluder-3.6.96-1.git.0.381dd63.el7.noarch
atomic-openshift-3.6.96-1.git.0.381dd63.el7.x86_64
tuned-profiles-atomic-openshift-node-3.6.96-1.git.0.381dd63.el7.x86_64
atomic-openshift-node-3.6.96-1.git.0.381dd63.el7.x86_64
atomic-openshift-master-3.6.96-1.git.0.381dd63.el7.x86_64
[root@host-8-174-71 ~]# cat svc.json 
{
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
        "name": "endpoints",
        "labels": {
            "test": "router"
        }
    },
    "spec": {
        "ports": [
            {
                "protocol": "TCP",
                "port": 8888,
                "targetPort": 8080
            }
        ],
        "selector": {
            "endpoints": "router",
            "test": "router"
        }
    }
}
[root@host-8-174-71 ~]#

Comment 10 Phil Cameron 2017-06-27 15:37:37 UTC
Tested on 3.6.96
 3.6.96 was made at 2017/06/06 4:37am, commit for this change was 2017-06-06 05:34:11 EDT

Comment 11 Weibin Liang 2017-06-27 15:47:20 UTC
Failed on errata 28089 which ask using 3.9.96, but passed on 3.9.121

[root@ip-172-18-8-94 ~]# oc version
oc v3.6.121
kubernetes v1.6.1+5115d708d7
features: Basic-Auth GSSAPI Kerberos SPNEGO

Server https://ip-172-18-8-94.ec2.internal:8443
openshift v3.6.121
kubernetes v1.6.1+5115d708d7
[root@ip-172-18-8-94 ~]# vi svc.json
[root@ip-172-18-8-94 ~]# oc create -f svc.json 
service "endpoints" created
[root@ip-172-18-8-94 ~]# oc get svc
NAME               CLUSTER-IP       EXTERNAL-IP   PORT(S)                            AGE
docker-registry    172.30.9.110     <none>        5000/TCP                           18h
endpoints          172.30.183.101   <none>        8888/TCP                           13s
kubernetes         172.30.0.1       <none>        443/TCP,53/UDP,53/TCP              18h
registry-console   172.30.180.65    <none>        9000/TCP                           18h
router             172.30.22.253    <none>        80/TCP,443/TCP,1935/TCP,1936/TCP   18h
[root@ip-172-18-8-94 ~]# oc expose svc endpoints
route "endpoints" exposed
[root@ip-172-18-8-94 ~]# oc get route
NAME               HOST/PORT                                          PATH      SERVICES           PORT      TERMINATION   WILDCARD
docker-registry    docker-registry-default.0626-2-q.qe.rhcloud.com              docker-registry    <all>     passthrough   None
endpoints          endpoints-default.0626-2-q.qe.rhcloud.com                    endpoints          8080                    None
registry-console   registry-console-default.0626-2-q.qe.rhcloud.com             registry-console   <all>     passthrough   None
[root@ip-172-18-8-94 ~]#

Comment 13 errata-xmlrpc 2017-08-10 05:18:47 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHEA-2017:1716


Note You need to log in before you can comment on or make changes to this bug.