How to add services in load balancer through API?

Hi,

I have a use case where I want to add service1 in stack1 and service2 in stack2 to be configured to rancher load balancer through API(for L7 load balance).

I was able to create an empty stack named “lb” and I was able to launch a load balancer container named “lbcontainer” through API. But I couldn’t find enough details of adding services to the load balancer.

I saw few docs and discussions led me to addservicelink(/v1/projects/1a5/loadbalancerservices/1s104/?action=addservicelink) but this isn’t helping me.

Could you please explain how to add the services in the load balancer?.

Thanks.

To addservicelink the loadBalancerService :

{

"serviceLink": {

	"ports": [

		"string1",

		"string2",

		"...stringN"

	],

	"serviceId": "reference[service]",

	"uuid": "string"

}

}

Can anyone please explain this. Or can show me any example.

I’m confused here about the ports!. And should I give only uuid or should I also give serviceId?

Hey @Adaikal_Raj

So for my stack (project/1a5 in this case), I added the load balancer service by passing in the lb_post_me.json payload, with the following command:

mudboxR:scratch ahmad$ curl -H "Content-Type: application/json" -X POST -d @lb_post_me.json -u APIKEY:SECRETKEY http://RancherServerIP:PORT/v1/projects/1a5/loadbalancerservices?create

Contents of lb_post_me.json, with minimal configuration info to get the LB service going :

{
	"environmentId": "1e1",
	"launchConfig": {
		"ports": [
			"80:8080"
		],
		"restartPolicy": {
			"name": "always"
		},
		"tty": true
	},
	"name": "dd-lbtest",
	"scale": 3,
	"startOnCreate": true,
	"type": "loadBalancerService"
}

I find the developers tools in the chrome browser a great way of reverse engineering API commands. It’s useful for showing the exact commands, as well as sequence of execution, for creating/updating/deleting resources in Rancher.

Hope that helps…

Hi Aemneina,

Thank you for your help. I believe that you are saying about creating a Load balancer service. But, I was able to create a load balancer service. My problem is, I’m unable to add application services( like apache, wordpress) to the load balancer through API.

This is what I’m trying to achieve now How to access Advanced routing option in rancher load balancer in API?

Have you tried out this advanced load balancing in API?.

Thank you.

Right, after creating the load balancer service, make another call to /v1/projects/STACKID/loadbalancerservices/addservicelink?environmentId=ENVID&name=SOMENAME

and pass in the service link. It should look something like:

{
    "serviceLinks": [
        {
            "ports": [
                "ghost.example.com:80/blog=80"
            ],
            "serviceId": "SERVICEID"
        }
    ]
}

Let me know how that works for you.

Awesome! You saved my day. It’s working perfectly. Thanks a lot Aemneina, appreciate your help!

1 Like

Hello,

And sorry for necromancing this thread.

Is your response still relevant?

Is there a way to reliably add a new service link to a rancher load balancer?

The documentation: https://docs.rancher.com/rancher/v1.6/en/api/v2-beta/api-resources/loadBalancerService/#addservicelink shows how a service link should look like but I do not see any way you can specify some ports.

When I try to make a POST request at the specified URL: /v2-beta/projects/${PROJECT_ID}/loadBalancerServices/${ID}?action=addservicelink , it fails by saying JSON data is not valid. The type property indicates an error.

No more information about the error is given.

Thanks for your help.

For 1.2-ish+ the balancer has an “lbConfig” -> “portRules” that you directly manipulate. You can also add a single selector rule to the balancer and use it to select service containers, which bank define their own additional portRules. This way you don’t have to change the balancer when services come and go at all.

Hello,

And thank you for your support. Unfortunately I can’t seem to find how I can directly manipulate the lbConfig. Can you pinpoint me to the right documentation page or maybe show an example JSON?

Or maybe I got it all wrong and this operation requires an entire update of the load balancer with a full load balancer json config (https://docs.rancher.com/rancher/v1.6/en/api/v2-beta/api-resources/loadBalancerService/#upgrade) (however that is upgrade) ?

I am searching on this page: https://docs.rancher.com/rancher/v1.6/en/api/v2-beta/api-resources/loadBalancerService/

Thank you.

You need to send the entire lbConfig but not the entire service object, you can PUT to the self link with just the field you want to change. e.g.:

{
  "portRules":[
    {
      "priority":1,
      "protocol":"http",
      "serviceId":"1s6",
      "sourcePort":1234,
      "targetPort":80
    }
  ]
}

Upgrade is not needed to change portRules.

Hi Vincent,

Thank you for your posts. I am trying to do the same thing as Stefan - I’d like to add a new service rule to our load balancer. I’ve gone over the documentation but I can’t find this mentioned. So, as you recommended, I have attempted to post the lbConfig to the self end point with the new rule under portRules but it’s not adding the rule to my load balancer.
Would you mind taking a look at my example and telling me where I am going wrong? The call returns the full json for the self URL so it seems to be completing successfully but the new rule is not appearing in the UI or in the returned json.

Thank you for your help.

NEW_LBCONFIG_JSON='
{
   "type":"lbConfig",
   "config":null,
   "portRules":[
      {
         "type":"portRule",
         "priority":1,
         "protocol":"http",
         "serviceId":"1s30",
         "sourcePort":15672,
         "targetPort":15672
      },
      {
         "type":"portRule",
         "hostname":"myhost.com",
         "path":"/",
         "priority":2,
         "protocol":"http",
         "serviceId":"1s22",
         "sourcePort":8088,
         "targetPort":80
      }
   ],
   "certificateIds":[

   ],
   "defaultCertificateId":null,
   "stickinessPolicy":null
}'

curl -s -u "${RANCHER_ACCESS_KEY}:${RANCHER_SECRET_KEY}" \
-X PUT \
-H 'Content-Type: application/json' \
-d "${NEW_LBCONFIG_JSON}" \
"http://${RANCHER_URL}:8080/v2-beta/projects/${PROJECT_ID}/loadbalancerservices/${RANCHER_LOADBALANCER_ID}"

@craig_mylifedigital Your body needs an extra layer wrapped around it, {lbConfig: <what you have>}. You’re putting to a load balancer service, which has a field called lbConfig, which contains all that stuff.

Hi Vincent,
That has worked a treat! Thanks very much. Full example below for anyone else that needs to do this in future.
Cheers

{
   "lbConfig":{
      "portRules":[
         {
            "type":"portRule",
            "hostname":"host1.com",
            "path":"/",
            "priority":1,
            "protocol":"http",
            "serviceId":"1s108",
            "sourcePort":8088,
            "targetPort":80
         },
         {
            "type":"portRule",
            "hostname":"host2.com",
            "path":"/",
            "priority":2,
            "protocol":"http",
            "serviceId":"1s275",
            "sourcePort":8088,
            "targetPort":80
         }
      ]
   }
}
curl -s -u "${RANCHER_ACCESS_KEY}:${RANCHER_SECRET_KEY}" \
-X PUT \
-H 'Content-Type: application/json' \
-d "${NEW_LBCONFIG_JSON}" \
"http://${RANCHER_URL}:8080/v2-beta/projects/${PROJECT_ID}/loadbalancerservices/${RANCHER_LOADBALANCER_ID}"

Hai :blush:

I’m using Rancher over Kubernetes to manage my environement.

I’m trying to update portRules of my load-balancer, it replace all the existing ones each time I’m doing a PUT query. Moreover, I can’t set the related service with “serviceId”. It leave it blank and only specify the ports, path, hostname, etc…

Do you know if it’s possible to just “add” some rules and why serviceId does not link the services to my rules ?

Here is the JSON object I’m sending :

{
	"lbConfig": {
		"portRules": [
			{
				"hostname": "",
				"access": "public",
				"protocol": "http",
				"serviceId": "1s260",
				"port": "80",
				"targetPort": "4200",
				"path": "/"
			},{
				"hostname": "",
				"access": "public",
				"protocol": "http",
				"serviceId": "1s277",
				"port": "80",
				"targetPort": "4200",
				"path": "/frontend"
			}
		]
	}
}

Also, I almost forgot, all the rules are create with “Internal” access. Is it also possible to specify “Public” access at creation ?

I didn’t see these points covered into the documentation : http://docs.rancher.com/rancher/v1.5/en/api/v2-beta/api-resources/service/

Thanks a lot :wink:

I was sending my query to the wrong URL !

Insteand of : http://rancherserver:8080/v2-beta/projects/1a21/services/1s286
I used : http://rancherserver:8080/v2-beta/projects/1a21/loadbalancerservices/1s286

And then, I could modify all the fields I wanted ! Pretty cooll !

I was dumb enough to use the wrong API, here, there is a specific API to manage loadbalancers : http://docs.rancher.com/rancher/v1.5/en/api/v2-beta/api-resources/loadBalancerService/#update

Still ,the only detail I can’t seems to be able to specify is the access choice between [Internal/Public]

Public-ness is based on the listening ports, not the target rules. launchConfig -> ports for public, expose for internal.

1 Like

hi @vincent, thanks for your reply.

I had some time to test it this afternoon, but whether I’m using it wrong, whether it doesn’t work as I expect. I’m sending this JSON body :

{
	"lbConfig": {
		"name": "loadbalancer-test",
		"description": "Test Loadbalancer",
		"launchConfig": {
			"ports": [
				"4201",
				"4202"
			],
			"expose": [
				"9001",
				"9002"
			]
		},
		"portRules": [
			{
				"hostname": "",
				"protocol": "http",
				"serviceId": "1s292",
				"sourcePort": "4201",
				"targetPort": "4201",
				"path": "/"
			},
			{
				"hostname": "",
				"protocol": "http",
				"serviceId": "1s294",
				"sourcePort": "9001",
				"targetPort": "9001",
				"path": "/purchase"
			},
			{
				"hostname": "",
				"protocol": "http",
				"serviceId": "1s291",
				"sourcePort": "9002",
				"targetPort": "9002",
				"path": "/products"
			}
		]
	}
}

Rules are correctly added, but I still see all ports with the "Internal’ access from the UI. I tried to put all ports into “expose” or “ports” it’s still the same. Anyway I still have an issue when I try to Dockerize my frontend so I can’t even test network routes, so take your time to answer :smiley:

Thanks again,

launchConfig goes at the same level as lbConfig, not inside of it.

My god I was so unfocused this afternoon that I missed that. Anyway, thanks for taking time to reply Vincent.

I know this is a really old thread. But when I try to do this it wipes our all existing entries and the custom config and replaces it with the new entry.