-
Notifications
You must be signed in to change notification settings - Fork 543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Container telemetry not shown in AppHost dashboard #4131
Comments
Which container runtime are you using? |
Rancher Desktop: https://rancherdesktop.io/ |
Could it be https? |
I think I tried every possibility. Always works with the external dashboard, but never with the host dashboard. |
Provide a minimal repro that we can run. That’ll help us diagnosis the problem. |
I was able to reproduce with the Aspire starter demo on Rancher Desktop.
var builder = DistributedApplication.CreateBuilder(args);
//var apiService = builder.AddProject<Projects.ApiService>("apiservice")
var apiService = builder.AddContainer("apiservice", "apiservice")
.WithHttpEndpoint(targetPort: 8080, name: "apiservice")
.WithOtlpExporter()
;
builder.AddProject<Projects.Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(apiService.GetEndpoint("apiservice"))
;
builder.Build().Run();
You can check that all OTEL environment variables are set for the container, but no telemetry is captured by the Aspire host. |
I'm guessing it's to do with https. |
Were you able to repro? It used to work. |
Can you turn up logging for the app in the container and look at the logs? |
I omitted, for brevity, but I'm setting these environment variables: .WithEnvironment("Logging__LogLevel__Default", "Debug")
.WithEnvironment("Logging__LogLevel__Microsoft.AspNetCore", "Debug") @davidfowl might be on something here:
But it works fine with a containerized dashboard (mcr.microsoft.com/dotnet/aspire-dashboard:8.0-preview). That's what I'm using now: var aspireDashboard = builder.AddContainer(
"hub-aspire-dashboard",
"mcr.microsoft.com/dotnet/aspire-dashboard",
"8.0-preview")
.WithEndpoint(targetPort: 18888, name: "dash", scheme: "http", isProxied: true)
.WithEndpoint(targetPort: 18889, name: "otel", scheme: "http", isProxied: true)
.WithEnvironment("DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS", "true")
.WithEnvironment("ASPIRE_ALLOW_UNSECURED_TRANSPORT", "true")
.WithEnvironment("DASHBOARD__OTLP__AUTHMODE", "ApiKey")
.WithEnvironment("DASHBOARD__OTLP__PRIMARYAPIKEY", builder.Configuration["AppHost:OtlpApiKey"])
.WithHealthCheck(
endpointName: "otel",
path: string.Empty,
httpClientFactory: () => new HttpClient
{
DefaultRequestVersion = HttpVersion.Version20,
DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher,
})
;
...
var mongoDB = builder.AddMongoDB("mongodb")
.WithImageTag("5.0")
.WithHealthCheck()
;
var hubIdp = builder.AddProject<Projects.Project1>(name: "hub-identity", launchProfileName: null)
.WithEndpoint(scheme: "http")
.WithEnvironment(ctx => ctx.EnvironmentVariables["OTEL_EXPORTER_OTLP_ENDPOINT"] = new HostUrl(aspireDashboard.GetEndpoint("otel").Url))
;
var hubContainer = builder.AddContainer("container", "Image" "Tag")
.WithEndpoint(targetPort: 8080, name: "http", scheme: "http")
.WithReference(mongoDB, connectionName: "MongoDB")
.WithOtlpExporter()
.WithEnvironment(ctx => ctx.EnvironmentVariables["OTEL_EXPORTER_OTLP_ENDPOINT"] = new
;
... |
OTEL logs don't show up in normal logs - you have to do a bit of extra magic to get them by creating an |
It's likely HTTPS as the HTTPS certificate being used to secure the dashboard endpoints when it's run from the host is the ASP.NET Core Development Certificate which will not be trusted by default from inside a container. This will cause the OTLP exporter to fail. This change was introduced in preview 6 as part of security work. In the example you provided of running the dashboard itself in a container, you're explicitly disabling the HTTPS transport via the Having composed containers be automatically configured to trust the ASP.NET Core Development Certificate is something we want to investigate enabling in the future. |
Thanks. I have a demo working with this launch profile: "http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:15190",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS": "true",
"ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19164",
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20178"
}
}
For images that are being pulled, wouldn't forcing the container to trust a certificate that shouldn't be trusted defeat the whole purpose of the security added to Aspire? It would probably be better to use HTTP endpoints for OTEL. Or both HTTP and HTTPS. |
I don't think so. Configuring a container to trust a self-signed certificate that is already trusted by the host for development purposes (and only at development time) seems no different to what we do today WRT to trusting the ASP.NET Core Development Certificate for the purposes of localhost HTTPS testing. The trust would only happen when running during local development as the certificate is only for localhost anyway. Using an unencrypted transport for OTEL means processes running as other accounts on the same machine during local development can potentially observe sensitive information being passed from apps to the dashboard's OTLP endpoint so we decided that behavior must be opt-in. |
For the standalone dashboard though it is unsecured and there's a warning in the dashboard for it. |
@JamesNK should we consider adding some new docs about this scenario? |
I had a similar setup... but moving from aspire 8.0.2 to 8.2.0 the dashboard will again show untrusted exception and an empty resources list, even with this configuration. ( forcing HTTP and allow unsure true ) |
@afscrome awesome, I missed that listed issue. Thx for the heads up and indeed now everything works fine agan. |
Did we confirm that this was an https issue? |
I tried HTTP and it has the same issue. |
If you can make a minimal repro that we can run with instructions that would be great. |
@davidfowl, I've provided instructions more than once in this issue. Unless someone tells me what's wrong with those instructions, I don't know what other instructions I can provide. |
@davidfowl, you can add the OpenTelemetry collector to test this: var otel = builder.AddContainer("otel", "otel/opentelemetry-collector-contrib", "0.117.0")
.WithHttpEndpoint(targetPort: 4317, name: "grpc")
.WithHttpEndpoint(targetPort: 4318, name: "http")
.WithBindMount("Configuration/otel/config.yaml", "/etc/otelcol-contrib/config.yaml")
.WithOtlpExporter()
;
var webservice = builder.AddProject<Projects.MyWebService>("webservice", launchProfileName: null)
.WithHttpEndpoint()
.WithServerAccessTokenHandler(idp)
.WithLoggingDefaults()
.WithEnvironment("OTEL_EXPORTER_OTLP_ENDPOINT", otel.GetEndpoint("grpc")).WaitFor(otel)
; Where config.yaml is: receivers:
otlp:
protocols:
grpc:
http:
exporters:
otlp:
endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT}
service:
pipelines:
traces:
receivers: [otlp]
exporters: [otlp] If you look at the logs from the OTEL collector, you'll see something like this:
|
I can't repro this in Docker Desktop on Windows. I get a connection error but it's due to HTTPS which is expected:
@paulomorgado you're getting a timeout which suggests it's actually a networking issue. Does container->host networking just work with Rancher on macOS? |
@paulomorgado This works of me - see https://github.com/afscrome/AspireOtelExample/tree/main/AspireApp1.AppHost. Can't explain the no connection issue - If you're still using Rancher make sure you've on 1.17.0. In terms of your config file, there are a few things that mean the config file is never likely to work
See https://github.com/afscrome/AspireOtelExample/blob/main/AspireApp1.AppHost/otel-config.yaml for a working example. That successfully forwards telemetry from projects on the host into the otel collector in a container and then back out to the dashboard. You can verify this by looking for the ![]() |
@DamianEdwards, I'm using podman now and with OpenTelemetry coming from a container. |
So 2 issues:
|
@afscrome, you don't need the API key if your Aspire host has |
@davidfowl, I'm using I don't have issues having one container validating JWTs against a Keycloak container - all HTTP. Could this be a GRPC issue, because it's HTTPS? |
Perhaps - I've never tried that.
The |
@davidfowl - I don't think container to host networking is borked after the tests I did late last year. I think Aspires built in proxy isn't working correctly. See this comment: #6846 (comment) |
I'm working on a project where I'm having this issue. @DamianEdwards pointed me towards https://github.com/dotnet/aspire-samples/blob/main/samples/AspireWithNode/AspireWithNode.AppHost/NodeHostingExtensions.cs and https://github.com/dotnet/aspire-samples/blob/main/samples/Metrics/MetricsApp.AppHost/OpenTelemetryCollector/OpenTelemetryCollectorResourceBuilderExtensions.cs as possible workarounds until this works one day! |
And it worked? |
I ran into this issue this week and am proposing a feature to BYO certificates for aspire (just like we can for other kestrel certs via kestrel config). See issue #7627 for details. |
We're working on a broader solution for this @DamianEdwards can add color. |
OK so the issue here is that when containers want to talk to services running on the host machine (rather than other containers) they do so via a special host name, So to make this work we need two things:
For 1, we're planning on updating For 2, we'll productize the capability from our samples repo that facilitates injecting the dev cert into Aspire resources (containers or executables) by exporting it from the host (using We'd like to be able to get all this done in an Aspire 9.x update. Soonest would be 9.2 but that's optimistic. |
Thank you for the detailed response on your planned solution. Regarding container injection, can you provide a bit more detail on how that would work and what level of configuration one has to modify default behavior? I am concerned with the potential for bind mount clashes, or non typical workloads or custom dockerfile images that may not play well with steps to inject the certificate into the container. If the bind mount is customizable we could more easily incorporate it into our cert bootstrapping processes already present in our docker builds. What about the ability to simply set the certificate used by aspire (request #7627 above)? Depending on how simple that is, it gives the development team the ability to take ownership over authentication, and those with a mature approach already in place could simply use our existing generated certificates and immediately solve the problem. (we include all necessary subject alternative names in our short lived self signed developer certs already in play). |
RE how flexible the cert injection will be, you'll be able to customize the environment variables and bind mount path. If you want to take over completely, you can simply call an API to request the dev cert file path (Pem or Pfx format) and then take full control of how you want to inject it into the container. RE custom certificates, seems like a nice complimentary feature. For ASP.NET Core apps you can already specify the path to a cert on disk to use (via Kestrel configuration) so that shouldn't be a problem. Making that first class is something I could see us doing. |
Awesome, thank you for the updates! Looking forward to this seeing this feature released. |
In preview 5, adding
.WithOtlpExporter()
to.AddContainer(...)
would show OpenTelemetry logs, traces and metrics in the dashboard.Since preview 6 this doesn't happen.
But if I had a dashboard container (mcr.microsoft.com/dotnet/aspire-dashboard or mcr.microsoft.com/dotnet/nightly/aspire-dashboard:8.0-preview):
the dashboard from the
aspireDashboard
container show telemetry from theservice
container.service
container is referenced from other resources and references other resources without any issues.The text was updated successfully, but these errors were encountered: