I’m writing an api to create game servers that run in kubernetes. I need to create an endpoint that creates a deployment and a service and then returns the service’s external ip.
I can create both succesfully and if I run kubectl get svc
after hiting the endpoint I see this:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d21h
minecraft-service LoadBalancer 10.96.172.60 localhost 25565:31683/TCP 5s
My problem is I can’t access the value under the column EXTERNAL-IP from javascript. I can’t use loadBalancer.ingress
because this is for a game server, so there is no ingress created. And can’t use loadBalancer.loadBalancerIP
because it’s undefined.
This is the code of my endpoint:
const express = require('express')
const k8s = require('@kubernetes/client-node')
const app = express()
const port = 3000
const kc = new k8s.KubeConfig()
kc.loadFromDefault()
const k8sApi = kc.makeApiClient(k8s.CoreV1Api)
const k8sAppsApi = kc.makeApiClient(k8s.AppsV1Api)
app.post('/api/server/', async (req, res) => {
const deploymentDefinition = {
apiVersion: 'apps/v1',
kind: 'Deployment',
metadata: {
name: 'minecraft-deployment',
},
spec: {
replicas: 1,
selector: {
matchLabels: {
app: 'game-server',
},
},
template: {
metadata: {
labels: {
app: 'game-server',
game: 'minecraft'
},
},
spec: {
containers: [
{
name: 'minecraft',
image: 'minecraft',
imagePullPolicy: 'Never'
},
],
},
},
},
}
const serviceDefinition = {
kind: "Service",
apiVersion: "v1",
metadata: {
name: "minecraft-service",
},
spec: {
selector: {
app: "game-server",
},
ports: [{
protocol: "TCP",
port: 25565,
targetPort: 25565,
}],
type: "LoadBalancer"
}
}
try {
const createService = await k8sApi.createNamespacedService('default', serviceDefinition)
const createDeployment = await k8sAppsApi.createNamespacedDeployment('default', deploymentDefinition)
sleep(5000)
const service = await k8sApi.readNamespacedService('minecraft-service', 'default')
//console.log(createService.body.status.loadBalancer)
// Por defecto, algunos kube-proxy y servicios solo llenarĂ¡n 'status.loadBalancer.ingress[0].ip', otros llenarĂ¡n 'status.loadBalancer.ingress[0].hostname'.
console.log(service.body)
//const ip = service.body.status.loadBalancer.ingress[0].ip || service.status.loadBalancer.ingress[0].hostname
//res.json({ ip })
} catch (error) {
console.error(error)
res.status(500).json({ error: error.toString() })
}
})
console.log(service.body)
prints this:
V1Service {
apiVersion: 'v1',
kind: 'Service',
metadata: V1ObjectMeta {
annotations: undefined,
creationTimestamp: 2024-04-30T19:37:24.000Z,
deletionGracePeriodSeconds: undefined,
deletionTimestamp: undefined,
finalizers: undefined,
generateName: undefined,
generation: undefined,
labels: undefined,
managedFields: [ [V1ManagedFieldsEntry] ],
name: 'minecraft-service',
namespace: 'default',
ownerReferences: undefined,
resourceVersion: '64833',
selfLink: undefined,
uid: '61a9ceed-6ed6-482e-b488-6c2da17fe4c4'
},
spec: V1ServiceSpec {
allocateLoadBalancerNodePorts: true,
clusterIP: '10.96.172.60',
clusterIPs: [ '10.96.172.60' ],
externalIPs: undefined,
externalName: undefined,
externalTrafficPolicy: 'Cluster',
healthCheckNodePort: undefined,
internalTrafficPolicy: 'Cluster',
ipFamilies: [ 'IPv4' ],
ipFamilyPolicy: 'SingleStack',
loadBalancerClass: undefined,
loadBalancerIP: undefined,
loadBalancerSourceRanges: undefined,
ports: [ [V1ServicePort] ],
publishNotReadyAddresses: undefined,
selector: { app: 'game-server' },
sessionAffinity: 'None',
sessionAffinityConfig: undefined,
type: 'LoadBalancer'
},
status: V1ServiceStatus {
conditions: undefined,
loadBalancer: V1LoadBalancerStatus { ingress: undefined }
}
}
Any idea how to do this? Thanks
By the way, I’m on Windows 11, Docker Desktop and running the Kubernetes that comes with it.
I tried sleeping after the creation of the service. Geting the service from the cluster after creating it. I tried accessing service.loadBalancer.ingress[0].ip
but resulted in an error because ingress
is undefined. Tried accessing service.loadBalancer.loadBalancerIP
and service.loadBalancer.externalIPs
but these two are undefined too. And Tried changing the version of kubernetes/client-node to 0.19 and 0.15 but all these variables remained undefined.