Skip to content
This repository has been archived by the owner on Nov 20, 2023. It is now read-only.

[Dapr Extension] Allow defining custom placement container address #767

Merged

Conversation

dasiths
Copy link
Member

@dasiths dasiths commented Nov 9, 2020

As referenced in #763

When running Dapr in Windows (with WSL2 backend) the Dapr placement container runs on 6050 port on the host. So it requires we do something like this in Tye.yaml (Example https://github.com/dotnet/tye/blob/master/samples/dapr/tye.yaml)

# To ensure that your are running a dapr placement container with the right binding port.
# (50005 as HostPort)
- name: placement
  image: daprio/dapr
  args: ./placement
  bindings:
    - port: 50005

Edit: With @jkotalik suggestions the PR now does the following

  • Creates a Dapr placement container automatically and uses it if one is not defined by you.
  • Allows you to instruct Tye to use a particular host port for the above.
  • Allows you to instruct Tye to reuse an existing Dapr placement container that's already running.
extensions:
- name: dapr

  # If you want to use a different tag or container port
  # placement-image: daprio/dapr
  # placement-container-port: 50005

  # You can instruct Tye to not create the Dapr placement container on your behalf. This is required if you have Dapr running and want to use that container.
  # Doing a `docker ps` can show if its already running. If it's running then you can set 'exclude-placement-container: true' with `placement-port: xxxx` set to the host port of that container.
  # (i.e. In Windows + WSL2, Dapr uses 6050 as the host port)

  exclude-placement-container: true
  placement-port: 6050

@dnfadmin
Copy link

dnfadmin commented Nov 9, 2020

CLA assistant check
All CLA requirements met.

@jkotalik
Copy link
Contributor

jkotalik commented Nov 9, 2020

Is the placement container something we always need to be running with dapr now? If so, I think always creating the placement service and allowing someone to specify the service to override settings may be better, rather than having placement-address.

@davidfowl thoughts?

@dasiths
Copy link
Member Author

dasiths commented Nov 9, 2020

Is the placement container something we always need to be running with dapr now? If so, I think always creating the placement service and allowing someone to specify the service to override settings may be better, rather than having placement-address.

@davidfowl thoughts?

I'm not sure which side of the boundary the placement container instantiation ownership should sit. I feel like if it's already there created and running by Dapr we should just use it. Now that I think about it, some sort of auto detection would be a lot smarter.

@jkotalik
Copy link
Contributor

To sum up our thoughts:

  • If there isn't a placement container in the tye.yaml, we should create one to be used in the dapr extension. This matches what we have for the dapr proxies.
  • If there is a placement container, just use it.

The only question now is auto detection of the placement container. Probably just checking for the image name daprio/dapr ./placement. Also we could add an argument to the extension called excludePlacementContainer to avoid adding it.

@dasiths
Copy link
Member Author

dasiths commented Nov 13, 2020

  • If there isn't a placement container in the tye.yaml

We can then have more fine grained control by using exclude-placement-container or placement-port to reuse something running on a different port perhaps. I've updated the PR, have a look and let me know.

@dasiths dasiths changed the title [Dapr Extension] Allow defining custom placement container address [WIP][Dapr Extension] Allow defining custom placement container address Nov 13, 2020
@dasiths
Copy link
Member Author

dasiths commented Nov 13, 2020

@jkotalik Let's consider these scenarios

  • Dapr placement not running at all. So we create it and point to port 50005 (or pick port dynamically) and use it.
  • Dapr placement is defined in Tye.yaml. So we use it.
  • Dapr is already running placement container on 50005 or 6050. We need to either auto detect that and use it or allow the user to specify that in Tye.yaml (My original idea with placement-address).

If you can verify my assumptions are correct I can try and make the necessary changes.

@dasiths dasiths changed the title [WIP][Dapr Extension] Allow defining custom placement container address [Dapr Extension] Allow defining custom placement container address Nov 15, 2020
@dasiths
Copy link
Member Author

dasiths commented Nov 17, 2020

@jkotalik @davidfowl I've updated the PR to cover the scenarios captured in the discussion and also included a sample app to demonstrate it.

I can move the sample app to a separate PR if required. The magic in this PR happens in the src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs

The build was successful till my last commit but it's broken now due to something else in the pipeline not related to this PR. Once that is fixed the PR will pass the build and tests.

Please let me know if there are any more changes required. :)

@jkotalik
Copy link
Contributor

@dasiths yes I think you assumptions were correct! Apologies for not confirming earlier.

@jkotalik
Copy link
Contributor

@dasiths yes I think you assumptions were correct! Apologies for not confirming earlier.

Looks like potentially our format checker is affected by the set_env issue in github actions. I'll look into that.

var isCustomPlacementPort = false;

var existingDaprPlacementDefinition = context.Application.Services.FirstOrDefault(s =>
s is ContainerServiceBuilder serviceBuilder && serviceBuilder.Image == "daprio/dapr");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case of using ImageName + Tag, placement definition cannot be found.
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The more I think about this, the more I don't like sniffing to determine if the placement port is already defined or not.

I think including an option called excludePlacementService, which default to false, is enough to have people either include or exclude it as required.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed sniffing. It will now use an auto assigned port and be agnostic about the user defined services. The only way to control the port is via the placement-port property.

@@ -20,12 +20,67 @@ public override Task ProcessAsync(ExtensionContext context, ExtensionConfigurati

if (context.Operation == ExtensionContext.OperationKind.LocalRun)
{
// default placement port number
var placementPort = 50005;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be a random port instead of a specific port?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will now use the next available port, same as the other parts of the system.

Bindings = {
new BindingBuilder() {
Port = placementPort,
ContainerPort = 50005,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the container port always supposted to be 50005 for the placement?

Copy link
Member Author

@dasiths dasiths Nov 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it's defined by Dapr. I did however introduce a new property called placement-container-port to allow the developer to set it if required. (i.e. If Dapr releases a new image with a new port). Similarly I now have a placement-image which allows the developers to define a custom image name if required. (i.e. daprio/dapr:edge)

else
{
// use the port defined in the custom service definition is possible
var definedPlacementPort = existingDaprPlacementDefinition.Bindings.FirstOrDefault(b => b.Port.HasValue);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on my suggestion earlier, I think if someone sets excludePlacementService, they must define placement-port so we know what that is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I added this check now. It will ignore exclude-placement-service if not placement-port has been defined.

@jkotalik
Copy link
Contributor

Sample looks great FYI.

@@ -51,12 +106,12 @@ public override Task ProcessAsync(ExtensionContext context, ExtensionConfigurati

// These environment variables are replaced with environment variables
// defined for this service.
Args = $"-app-id {project.Name} -app-port %APP_PORT% -dapr-grpc-port %DAPR_GRPC_PORT% --dapr-http-port %DAPR_HTTP_PORT% --metrics-port %METRICS_PORT% --placement-address localhost:50005",
Args = $"-app-id {project.Name} -app-port %APP_PORT% -dapr-grpc-port %DAPR_GRPC_PORT% --dapr-http-port %DAPR_HTTP_PORT% --metrics-port %METRICS_PORT% --placement-address localhost:{placementPort}",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be great this issue #802 also could be addressed here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be --placement-host-address, instead of --placement-address

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mtaghavi2005 @thangchung I incorporated this change here. Should now support Dapr rc1. :)

@dasiths
Copy link
Member Author

dasiths commented Nov 18, 2020

@jkotalik I have addressed all of the comments. Please let me know if you're happy with this revision. Cheers.

Edit: There is something fishy happening with the build agents while running tests. The OSX one passed, Windows one is now hanging for 30 mins and Ubuntu one failed. There aren't any tests that are affected by my change. Weird.

https://dev.azure.com/dnceng/public/_build/results?buildId=890711&view=ms.vss-test-web.build-test-results-tab&runId=28487644&resultId=100015&paneView=debug

@dasiths
Copy link
Member Author

dasiths commented Nov 26, 2020

@jkotalik any feedback about this?

@jkotalik
Copy link
Contributor

jkotalik commented Dec 1, 2020

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

foreach (var binding in service.Description.Bindings)
{
// Auto assign a port
if (binding.Port == null)
{
binding.Port = GetNextPort();
binding.Port = NextPortFinder.Instance.GetNextPort();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have NextPortFinder as an instance rather than just a static method?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I followed the pattern from the GitDetector class but more than happy to make it static as it doesn't have any dependencies or logic in the constructor.

Copy link
Contributor

@jkotalik jkotalik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM besides a few nits.

@@ -0,0 +1,26 @@
using System.Net;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit copyright

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@jkotalik
Copy link
Contributor

jkotalik commented Dec 1, 2020

@dasiths apologies, holidays in the states 😄

@dasiths dasiths force-pushed the feature/allow-custom-placement-address branch from c1f45cc to ac1e237 Compare December 2, 2020 00:13
@dasiths
Copy link
Member Author

dasiths commented Dec 2, 2020

@dasiths apologies, holidays in the states 😄

No worries. Hope you had a good break Justin. Looking forward to holidays myself. It's another sweltering 40c December awaiting us in downunder. 😉

I've updated the PR with the changes now.

@dasiths
Copy link
Member Author

dasiths commented Dec 11, 2020

@jkotalik Anything else required here?

@thangchung
Copy link
Contributor

How was it going on, guys? Look like tye wasn't upgrade accordingly with dapr rc right away so that it makes it hard to use dapr with tie respectively :(

@jkotalik jkotalik merged commit 45bf552 into dotnet:master Jan 5, 2021
@jkotalik
Copy link
Contributor

jkotalik commented Jan 5, 2021

Thanks @dasiths!

@dasiths dasiths deleted the feature/allow-custom-placement-address branch January 6, 2021 03:29
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants