-
Notifications
You must be signed in to change notification settings - Fork 357
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
Support dotnet trace
running in a sidecar container
#810
Comments
This is something we are actively working on lighting up, but is unsupported right now. There are some PRs in flight that will enable this scenario in the 5.0 timeframe. dotnet/runtime#1600 and #770 when merged will make this easy to configure. We are thinking of changing the names of the configuration variables from what was merged in the runtime PR, but the functionality should be the same. Documentation on how we recommend setting this scenario up will come before release. It will involve a shared volume mount inside the pod. CC @shirhatti |
Our use case: When encountering a low memory situation in a container (e.g. host = 16 GB, each containers = 2GB), the tools within that same container cannot do a memory dump because the tool doesn't have enough memory either. But if there was another container, this would be much simpler. |
.NET Core app on linux creates domain socket files in /tmp catalog. You can establish IPC session with this file. Pid in this case in nothing more than abstraction. Internally Microsoft.Diagnostics.NETCore.Client.IpcClient uses pid just to find socket file name and start an IPC session:
I've configured intercontainer IPC in my monitoring app so it collects counters just by socket file names from two other containers. You even don't need target pid in this scenario. |
@MichaelSimons is this still the primary issue for this? I saw in #1737 that you are using this for tracking? Following the steps in the issue above still has issues with the PIDs being inaccurate between |
@glitch100 - as far as I am aware, this is the primary issue. @shirhatti - can you help @glitch100? |
@glitch100 As noted in an earlier comment, access to the PID namespace isn't really required. You just need access to the diagnostic server created by the runtime. As it stands today (3.0/3.1), this socket is always created in the Tooling and runtime changes are incoming for 5.0 that allow you customize how the diagnostics server is created and how the tools attach. @bss-git's suggestion of sharing the temp directory across both containers should suffice. FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS tools
RUN dotnet tool install --tool-path /tools dotnet-trace
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS runtime
COPY --from=tools /tools /tools
ENV PATH="/tools:${PATH}"
ENV COMPlus_EnableDiagnostics="0"
WORKDIR /tools docker run -d -p 8000:80 -v /container:/tmp mcr.microsoft.com/dotnet/core/samples:aspnetapp
docker run --rm -u root -it -v /container:/tmp trace /bin/sh
# Inside the trace container
dotnet-trace collect -p 1 |
@shirhatti
In the dockerfile or we hit that issue around CoreClr starting (Due to /tmp directory.) Once running, and having another container with the Dockerfile you provided I still hit an issue:
I have confirmed that both have volumes for Could you provide a working example? Also is this documented anywhere? |
That's not going to work. If you disable the diagnostics server, you can't trace the application. If creation of pipes fails, do you mind creating a new issue for that? Let's work through that first.
I'll publish a gist later today. |
@shirhatti Any luck on that gist? |
Worth noting that I have tried what you posted with a vanilla ASPNET app with docker support (As per Visual Studio), as well as the trace container. I have tried in both Docker Compose and via the CLI with the commands above. Docker Compose gives me that
I look forward to seeing the gist as I am hoping I have done something silly rather than this being an issue on the dotnet side. |
EDIT: I made a small change to my earlier comment to include
As I mentioned earlier, please create a separate issue for that. |
I will give it a try. Where would you recommend I raise that issue? |
|
@shirhatti I appreciate you making the edit however the timeline of this conversation does now seem a bit strange. That said the edits you made did get it working which is good 🎉, so thanks. I might be wrong on this one but it seems like the default Dockerfile in a new ASPNETAPP (template) was not compatible with that flow, however the differences are quite minor so I am really unsure if it's down to the way I am running the container or if I made some changes along the way. I validated this by running the sample image as you did, seeing success, running mine, seeing failure, and then updating my Dockerfile to match. Is is the I will make a ticket on the CORECLR repo. Final question - is this documented somewhere? |
Hey folks! After reading this issue among many others I was able to make it work. The YAML would look something like this: apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
shareProcessNamespace: true
volumes:
- name: data
emptyDir: {}
- name: tmp
emptyDir: {}
containers:
- name: sampleapp
image: sampleapp:latest
imagePullPolicy: Never
volumeMounts:
- name: data
mountPath: /app/data
- name: tmp
mountPath: /tmp
ports:
- containerPort: 8080
- name: profiler
image: profiler:latest
imagePullPolicy: Never
stdin: true
tty: true
env:
- name: PROFILER_TARGET_PROCESS
value: "SampleApp"
- name: PROFILER_BLOB_CONTAINER
value: "dumps"
- name: PROFILER_DATA_PATH
value: /profiler/data
volumeMounts:
- name: data
mountPath: /profiler/data
- name: tmp
mountPath: /tmp The important pieces there are:
The rest of the options are totally optional as they are only meant to simplify and make the profiler container more generic. On my example, I'm also mapping the So yes, it is somehow an involved process but it works just fine. I hope it helps! |
You can ofc use the injection hooks on the admission controller to add that profiler pod spec using a label rather than having it hardcoded on the pod/deployment definition. I just meant to give an example and what are the requirements to get it working. |
Thanks a bunch - I was having trouble with |
You can also try our kubectl plugin that was created for gathering trace/gcdump results from dotnet apps running in k8s |
Sort of. That issue is tracking shipping a container that comes pre-installed with our tools. This issue is tracking an experience where you can configure your multi-container Pod to have the tools in one container and your app in another. We have added the necessary features to the tools/runtime for 5.0 to do this but haven't documented the functionality fully yet. There is a PR open on the docs repo that documents the flags for the tools, but not the end-to-end experience: dotnet/docs#21666 |
docker run -it -p 8000:80 --name aspnetapp mcr.microsoft.com/dotnet/core/samples:aspnetapp
dotnet trace
tooldocker build -t dotnet/trace .
docker run -it --net=container:aspnetapp --pid=container:aspnetapp --cap-add ALL --privileged dotnet/trace
Expected Results:
I should be able to collect a dotnet trace. It is a common technique to utilize sidecar containers to profile applications running in another container. This allows you to profile existing application images without having to modify them. You can package all of your tools into a completely separate tools image.
An example of running perfcollect with this pattern is documented in this blog post
Actual Results
dotnet trace ps
does not matchps -aux
dotnet trace
cannot be found when runningcollect
ps
is not a valid .NET app when runningcollect
Notes:
dotnet trace
version3.1.57502+6767a9ac24bde3a58d7b51bdaff7c7d75aab9a65
dotnet trace
worked as expected if I added it within my application container. This required me to install to .NET SDK since it is a global tool.The text was updated successfully, but these errors were encountered: