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.
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)