microsoft / mindaro

Bridge to Kubernetes - for Visual Studio and Visual Studio Code
MIT License
307 stars 106 forks source link

Migration from Azure Dev Space failed #84

Open ciacco85 opened 3 years ago

ciacco85 commented 3 years ago

Describe the bug I've just switched the profile / launch of all my microservices inside my solution according to the docs from dev spaces to bridge to kubernetes I've used the same urls and namespace of my dev space With "multiple startup project" function of VS2019, I've selected all my 4 microservices projects I get this error "A Service is already connected"

Expected behavior 4 console up and app running in my local pc listening for requests

Environment Details VS2019 latest version supporting net core 5.0

daniv-msft commented 3 years ago

Thanks @ciacco85 for logging this bug. As of today, unfortunately, solutions are not supported in Visual Studio. However, I believe that you can still debug multiple services by launching multiple instances of Visual Studio. @danegsta > If you have any more details on how to do this or any known limitations, could you please provide them?

@ciacco85 > So that I better understand your scenario, could you please confirm that you have to run these 4 microservices locally at the same time? I imagine that you are developing all of them in parallel, and thus cannot redirect only a subset of them. Is this correct?

ciacco85 commented 3 years ago

Yeah, i've 4 microservices and I often have to start at least 2 of them (they talk to each other trough Azure Service Bus) What I honestly can't understand is if there any walkaround: I don't know like running a command using Visual Studio / Visual Studio Code

daniv-msft commented 3 years ago

Thanks for your reply. In your case, it is possible to start two separate instances of Visual Studio with each one opening its own project. There are two limitations however:

We're working on adding the support for solutions right into Visual Studio, but this is not available as of today.

Alternatively, as you're mentioning VS Code, using multi-root workspaces is possible there and would allow you to run Bridge to Kubernetes for your two projects in the same instance. You will need to configure (run the Bridge to Kubernetes: Configure command) for both projects and, if you want to use isolation, you would need to make sure that both projects use the same isolateAs header value in your tasks.json files.

Please don't hesitate to let us know if you need any other information.

ciacco85 commented 3 years ago

Unfotunately this setup is not optimal for standardized approach for the teams. Instead, is there any plan to support Bridge to Kubernetes for visual studio solution?

daniv-msft commented 3 years ago

@ciacco85 Yes, adding support for solutions in Visual Studio is something we plan to add in the coming months. In the meantime, would using VS Code be a workaround for you?

ciacco85 commented 3 years ago

I've managed to run one microservice with bridge to kubernetes in VS code Any advice, official doc or whatever in order to run multiple services in VS code?

daniv-msft commented 3 years ago

@ciacco85 You can use a multi-root workspace to open your multiple services in VS Code (similar as a solution in Visual Studio). Then, you just need to configure each of them for Bridge to Kubernetes, and debug them one by one. Please let me know if you need anything else.

ciacco85 commented 3 years ago

We've managed to run multiple service with compound We've set launch.json/task.json in .vscode folder in the root of the repo Running the compound, we've managed hitting 2 breakpoint in 2 different controller in 2 different microservices.

"tasks": [
        {
            "label": "build",
            "command": "dotnet",
            "type": "process",
            "args": [
                "build",
                "${workspaceFolder}\\src\\Services\\Identity\\Identity.API\\Identity.API.csproj"
            ],
            "problemMatcher": "$msCompile"
        },
        {
            "label": "publish",
            "command": "dotnet",
            "type": "process",
            "args": [
                "publish",
                "${workspaceFolder}\\src\\Services\\Identity\\Identity.API\\Identity.API.csproj",
                "/property:GenerateFullPaths=true",
                "/consoleloggerparameters:NoSummary"
            ],
            "problemMatcher": "$msCompile"
        },
        {
            "label": "watch",
            "command": "dotnet",
            "type": "process",
            "args": [
                "watch",
                "run",
                "${workspaceFolder}\\src\\Services\\Resource\\Resource.API\\Resource.API.csproj",
                "/property:GenerateFullPaths=true",
                "/consoleloggerparameters:NoSummary"
            ],
            "problemMatcher": "$msCompile"
        },
        {
            "label": "build",
            "command": "dotnet",
            "type": "process",
            "args": [
                "build",
                "${workspaceFolder}\\src\\Services\\Resource\\Resource.API\\Resource.API.csproj"
            ],
            "problemMatcher": "$msCompile"
        },
        {
            "label": "publish",
            "command": "dotnet",
            "type": "process",
            "args": [
                "publish",
                "${workspaceFolder}\\src\\Services\\Resource\\Resource.API\\Resource.API.csproj",
                "/property:GenerateFullPaths=true",
                "/consoleloggerparameters:NoSummary"
            ],
            "problemMatcher": "$msCompile"
        },
        {
            "label": "watch",
            "command": "dotnet",
            "type": "process",
            "args": [
                "watch",
                "run",
                "${workspaceFolder}\\src\\Services\\Identity\\Identity.API\\Identity.API.csproj",
                "/property:GenerateFullPaths=true",
                "/consoleloggerparameters:NoSummary"
            ],
            "problemMatcher": "$msCompile"
        },
        {
            "label": "bridge-to-kubernetes.service.identity",
            "type": "bridge-to-kubernetes.service",
            "service": "identity",
            "ports": [
                50000
            ],
            "targetCluster": "pga-aks-dev",
            "targetNamespace": "fventurini"
        },
        {
            "label": "bridge-to-kubernetes.compound.identity",
            "dependsOn": [
                "bridge-to-kubernetes.service.identity",
                "build"
            ],
            "dependsOrder": "sequence"
        },
        {
            "label": "bridge-to-kubernetes.service.resource",
            "type": "bridge-to-kubernetes.service",
            "service": "resource",
            "ports": [
                50002
            ],
            "targetCluster": "pga-aks-dev",
            "targetNamespace": "fventurini"
        },
        {
            "label": "bridge-to-kubernetes.compound.resource",
            "dependsOn": [
                "bridge-to-kubernetes.service.resource",
                "build"
            ],
            "dependsOrder": "sequence"
        }
]```

```json
"configurations": [
        {
            "name": "Identity Local with Kubernetes",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "bridge-to-kubernetes.compound.identity",
            "program": "${workspaceFolder}/src/Services/Identity/Identity.API/bin/Debug/net5.0/Identity.API.dll",
            "args": [],
            "cwd": "${workspaceFolder}/src/Services/Identity/Identity.API",
            "stopAtEntry": false,
            "env": {
                "ASPNETCORE_ENVIRONMENT": "Development",
                "ASPNETCORE_URLS": "http://+:50000"
            },
            "sourceFileMap": {
                "/Views": "${workspaceFolder}/src/Views"
            }
        },
        {
            "name": "Resource Local with Kubernetes",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "bridge-to-kubernetes.compound.resource",
            "program": "${workspaceFolder}/src/Services/Resource/Resource.API/bin/Debug/net5.0/Resource.API.dll",
            "args": [],
            "cwd": "${workspaceFolder}/src/Services/Resource/Resource.API",
            "stopAtEntry": false,
            "env": {
                "ASPNETCORE_ENVIRONMENT": "Development",
                "ASPNETCORE_URLS": "http://+:50002"
            },
            "sourceFileMap": {
                "/Views": "${workspaceFolder}/src/Views"
            }
        }
]
"compounds": [
        {
            "name": "PGA all uservices",
            "configurations": ["Identity Local with Kubernetes", "Resource Local with Kubernetes"]
        }
    ]

But...I repeat BUT

We aren't getting all the real advantages of bridge to kubernetes like dev spaces because we aren't using isolation: each developer has its own namespace on aks cluster

We have worked in order to let things works because our development was blocked, I hope this approach is still valid with isolation, since obviously we want to improve it according to best practices. So, what do you think about it? Is multi-root workspace better for, I don't know, less setup time, less configuration, better maintenance of whatever?

daniv-msft commented 3 years ago

Thanks for your reply. Is there a reason not to use isolation in your case? You can select whether you want to work isolated when configuring Bridge (command Bridge to Kubernetes: Configure) or by adding manually the isolateAs field to your project's tasks.json, for example:

{
    "label": "bridge-to-kubernetes.service.identity",
    "type": "bridge-to-kubernetes.service",
    "service": "identity",
    "ports": [
        50000
    ],
    "targetCluster": "pga-aks-dev",
    "targetNamespace": "fventurini",
    "isolateAs": "fventurini"
}

Please note that in the example above, I used fventurini as it is the name of your namespace, but that you can put whatever value you want here. Also, you will need all your services to use the same isolateAs value so that they can call each others even when isolated.

Once you added this isolateAs header to your tasks.json files and that you start debugging, you will see the new entrypoints in the status bar menu (click the Kubernetes item in VS Code's status bar, or run the Bridge to Kubernetes: Open Menu command): image

Regarding using compound vs. multi-root workspace, it seems to me that multi-root workspace is more often used to replicate opening together a group of projects. Also, compound might need manual setup (to update the paths of projects for example) whereas a multi-root workspace will usually be better handled by extensions. However, VS Code is quite open about what developers can do so if the current solution works for you, that's what's important.

ciacco85 commented 3 years ago

Sorry I haven't explained my self. We aim to use isolation, but the easiest solution to start working with bridge to kubernetes is without it, especially if the development of the whole team was blocked due to Azure Dev Space issue. So let's see if everything is working fine, then we'll add complexity. Don't forget that, without isolation and with one namespace per developer, we're aware that we're wasting lot of resources of the cluster, but with isolation (tell me if I'm wrong) only one "dev" namespaces is needed and each developer work with his needed isolated pod inside the dev namespace Little by little :) Thank you for the compound vs multi-root workspace! I'll evaluate your precious feedback and follow our best options: as you said, in this comparison there's no silver bullet, but I always investigate the best solution, especially if the suggestion comes for the official team of a tool at the root of our development process

daniv-msft commented 3 years ago

Thank you @ciacco85! Yes, makes sense, I understand that unblocking yourself and your team was the first priority. Please don't hesitate to contact us if we can help you more!

ciacco85 commented 3 years ago

A question. Since microservice 2 microservice communication is achieved by azure service bus and Mass Transit, we've managed to isolate each developer work by adding a prefix to the queue/topic binded to developer azure dev space name obtained from the Helm's Release structure. Since bridge to kubernetes encourage the use of a single namespace, are there an best practice around this topic or suggestion?

daniv-msft commented 3 years ago

We still need to spend more time understanding how we work with Azure Service Bus, but are you dependent on having a single namespace for each user for this to work?

If not, could you reuse the logic you put in place for Dev Spaces for Bridge to Kubernetes? Isn't it possible to bind your queue with the isolated service Bridge creates?

Apologies if I'm missing something: we still need to investigate Azure Service Bus and how it works with Bridge.