1

I am trying to create a new service for one of my deployments named node-js-deployment in GCE hostes Kubernetes Cluster

I followed the Documentation to create_namespaced_service

This is the service data:

{
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
        "name": "node-js-service"
    },
    "spec": {
        "selector": {
            "app": "node-js"
        },
        "ports": [
            {
                "protocol": "TCP",
                "port": 80,
                "targetPort": 8000
            }
        ]
    }
}

This is the Python function to create the service

api_instance = kubernetes.client.CoreV1Api()
namespace = 'default'  

body = kubernetes.client.V1Service()  # V1Serice

# Creating Meta Data
metadata = kubernetes.client.V1ObjectMeta()
metadata.name = "node-js-service"

# Creating spec 
spec = kubernetes.client.V1ServiceSpec()

# Creating Port object
ports = kubernetes.client.V1ServicePort()
ports.protocol = 'TCP'
ports.target_port = 8000
ports.port = 80

spec.ports = ports
spec.selector = {"app": "node-js"}

body.spec = spec


try:
    api_response = api_instance.create_namespaced_service(namespace, body, pretty=pretty)
    pprint(api_response)
except ApiException as e:
    print("Exception when calling CoreV1Api->create_namespaced_service: %s\n" % e)

Error:

Reason: Bad Request
HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json', 'Date': 'Tue, 21 Feb 2017 03:54:55 GMT', 'Content-Length': '227'})
HTTP response body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Service in version \"v1\" cannot be handled as a Service: only encoded map or array can be decoded into a struct","reason":"BadRequest","code":400}

But the service is being created if I am passing JSON. Not sure what I am doing wrong.

Any help is greatly appreciated, thank you.

2
  • Never used client-python and thus can't help 100%. But I'd guess you at least forgot to assign the metadata object to body.metadata. Also, ports should have been an array with 1 element. Commented Feb 22, 2017 at 20:47
  • I missed to include the metadata in the question. In my code I actually did. May be it was about how I was trying to attach the ports. But finally ended up using dictionaries for deployment and services. It was simple and easy. Commented Feb 24, 2017 at 12:25

1 Answer 1

7

From reading your code, it seems that you miss assigning the metadata to body.metadata. And you missed that the ports field of the V1ServiceSpec is supposed to be a list, but you used a single V1ServicePort so without testing I assume this should works:

api_instance = kubernetes.client.CoreV1Api()
namespace = 'default'

body = kubernetes.client.V1Service()  # V1Serice

# Creating Meta Data
metadata = kubernetes.client.V1ObjectMeta()
metadata.name = "node-js-service"

body.metadata = metadata

# Creating spec
spec = kubernetes.client.V1ServiceSpec()

# Creating Port object
port = kubernetes.client.V1ServicePort()
port.protocol = 'TCP'
port.target_port = 8000
port.port = 80

spec.ports = [ port ]
spec.selector = {"app": "node-js"}

body.spec = spec

The definition could also be loaded from json / yaml directly as shown in two of the examples within the offical repo - see exec.py create_deployment.py.

Your solution could then look like:

api_instance = kubernetes.client.CoreV1Api()
namespace = 'default'

manifest = {
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
        "name": "node-js-service"
    },
    "spec": {
        "selector": {
            "app": "node-js"
        },
        "ports": [
            {
                "protocol": "TCP",
                "port": 80,
                "targetPort": 8000
            }
        ]
    }
}

try:
    api_response = api_instance.create_namespaced_service(namespace, manifest, pretty='true')
    pprint(api_response)
except ApiException as e:
    print("Exception when calling CoreV1Api->create_namespaced_endpoints: %s\n" % e)
Sign up to request clarification or add additional context in comments.

1 Comment

passing the yaml as dictionary works perfectly, I have added the metadata to the body in my code bu failed to update it in the question. But like you said the problem might be on how I am passing the Ports not as a list.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.