Co-authored-by: rlander@microsoft.com <Rich Lander>
Co-authored-by: Logan Bussell <loganbussell@microsoft.com>
Co-authored-by: Matt Thalman <mthalman@microsoft.com>
This commit is contained in:
Rich Lander 2024-01-22 14:28:11 -08:00 коммит произвёл GitHub
Родитель 7bca20cb06
Коммит 27ed26e141
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
10 изменённых файлов: 31 добавлений и 49 удалений

Просмотреть файл

@ -82,28 +82,6 @@ microsoftaspnetcorehosting_failed_requests 0 1681509076290
Port `52325` is special since it limits access to just the `metrics` endpoint, making it safe to expose to external systems. The other endpoints -- only accessible on port `52323` -- may provide access to privileged data, like dumps. This is why port `52323` is configured for the loopback interface, making it only accessible to the pod.
## Generate load
You may want to generate more traffic to demonstrate that `dotnet-monitor` can work well in production.
Apply the [`load-test.yaml`](load-test.yaml) manifest. Start collecting `livemetrics` just before doing (in another terminal).
```bash
% curl "http://localhost:52323/livemetrics?pid=1"
{"timestamp":"2023-04-11T02:16:37.4180174+00:00","provider":"Microsoft.AspNetCore.Hosting","name":"requests-per-second","displayName":"Request Rate","unit":"count","counterType":"Rate","tags":"","value":31937}
{"timestamp":"2023-04-11T02:16:37.4180254+00:00","provider":"Microsoft.AspNetCore.Hosting","name":"total-requests","displayName":"Total Requests","unit":"","counterType":"Metric","tags":"","value":409508}
{"timestamp":"2023-04-11T02:16:37.418029+00:00","provider":"Microsoft.AspNetCore.Hosting","name":"current-requests","displayName":"Current Requests","unit":"","counterType":"Metric","tags":"","value":9}
{"timestamp":"2023-04-11T02:16:37.4180323+00:00","provider":"Microsoft.AspNetCore.Hosting","name":"failed-requests","displayName":"Failed Requests","unit":"","counterType":"Metric","tags":"","value":0}
```
Delete the job.
```bash
kubectl delete -f load-test.yaml
```
Note: The job must be deleted and then re-applied to be run again.
## Monitor with Prometheus
[Prometheus](https://prometheus.io/) is a popular monitoring solution. `dotnet-monitor` exports metrics data in [Prometheus exposition format](https://prometheus.io/docs/instrumenting/exposition_formats/) via its `metrics` endpoint. That makes it straightforward to connect the two systems.

Просмотреть файл

@ -17,6 +17,10 @@ spec:
image: mcr.microsoft.com/dotnet/samples:aspnetapp
ports:
- containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1654
env:
- name: DOTNET_DiagnosticPorts
value: /diag/dotnet-monitor.sock
@ -76,7 +80,6 @@ spec:
- name: aspnetapp
protocol: TCP
port: 8080
targetPort: 80
- name: monitor
protocol: TCP
port: 52323

Просмотреть файл

@ -1,12 +0,0 @@
apiVersion: batch/v1
kind: Job
metadata:
name: load-test
spec:
template:
spec:
containers:
- name: bombardier
image: dotnetnonroot.azurecr.io/bombardier
args: ["--duration=60s", "http://aspnetapp.default.svc.cluster.local/Environment"]
restartPolicy: Never

Просмотреть файл

@ -21,7 +21,7 @@ spec:
spec:
containers:
- name: aspnetapp
image: dotnetnonroot.azurecr.io/aspnetapp
image: mcr.microsoft.com/dotnet/samples:aspnetapp
ports:
- containerPort: 8080
env:
@ -44,8 +44,9 @@ spec:
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1654
- name: monitor
image: mcr.microsoft.com/dotnet/monitor:8.0.0-preview.3
image: mcr.microsoft.com/dotnet/monitor:8.0
ports:
- containerPort: 52325
# DO NOT use the --no-auth argument for deployments in production; this argument is used for demonstration

Просмотреть файл

@ -15,9 +15,13 @@ spec:
app: aspnetapp
containers:
- name: aspnetapp
image: dotnetnonroot.azurecr.io/aspnetapp
image: mcr.microsoft.com/dotnet/samples:aspnetapp
ports:
- containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1654
env:
- name: DOTNET_DiagnosticPorts
value: /diag/dotnet-monitor.sock
@ -38,8 +42,9 @@ spec:
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1654
- name: monitor
image: mcr.microsoft.com/dotnet/monitor:8.0.0-preview.3
image: mcr.microsoft.com/dotnet/monitor:8.0
ports:
- containerPort: 52325
# DO NOT use the --no-auth argument for deployments in production; this argument is used for demonstration

Просмотреть файл

@ -27,6 +27,13 @@ kubectl port-forward service/dotnet-app 8080:8080
View the sample app at http://localhost:8080/ or call `curl http://localhost:8080/Environment`.
Should look like:
```bash
$ curl http://localhost:8080/Environment
{"runtimeVersion":".NET 8.0.1","osVersion":"Alpine Linux v3.18","osArchitecture":"X64","user":"root","processorCount":8,"totalAvailableMemoryBytes":67373219840,"memoryLimit":0,"memoryUsage":30572544,"hostName":"dotnet-app-547757d7f4-xqmsk"}
```
Delete the resources.
```bash

Просмотреть файл

@ -36,7 +36,7 @@ View the sample app at http://localhost:8080/ or call `curl http://localhost:808
```bash
% curl http://localhost:8080/Environment
{"runtimeVersion":".NET 8.0.0-preview.3.23174.8","osVersion":"Linux 5.15.49-linuxkit #1 SMP PREEMPT Tue Sep 13 07:51:32 UTC 2022","osArchitecture":"Arm64","user":"app","processorCount":4,"totalAvailableMemoryBytes":4124512256,"memoryLimit":0,"memoryUsage":29655040}
{"runtimeVersion":".NET 8.0.1","osVersion":"Alpine Linux v3.18","osArchitecture":"X64","user":"app","processorCount":8,"totalAvailableMemoryBytes":67373219840,"memoryLimit":0,"memoryUsage":30576640,"hostName":"dotnet-non-root-7bdbc96b8-bcp6c"}
```
`user` is displayed as `app`, as expected.
@ -57,16 +57,18 @@ This `securityContext` object enforces non-root hosting:
spec:
containers:
- name: aspnetapp
image: dotnetnonroot.azurecr.io/aspnetapp
image: mcr.microsoft.com/dotnet/samples:aspnetapp
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1654
```
- [allowPrivilegeEscalation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) -- Prevents (if `false`) a process from gaining greater privileges than its parent process. This is a good setting, but not directly related to users.
- `runAsNonRoot` -- Tests that the user (via uid) is a non-root user, otherwise fail.
- `runAsUser` -- Sets the user; only needed if not set in the container image.
The `USER` Dockerfile instruction must be set via `UID` for the the `runAsNonRoot` setting to work correctly, as demonstrated by [Dockerfile.alpine-non-root](https://github.com/dotnet/dotnet-docker/blob/f4786b8c0b4469f7eb18f891fd6c090561e50006/samples/aspnetapp/Dockerfile.alpine-non-root#L27) and the following example.
The `USER` Dockerfile instruction must be set via `UID` for the the `runAsNonRoot` setting to work correctly, as demonstrated by [Dockerfile](https://github.com/dotnet/dotnet-docker/blob/7bca20cb06e1f912fc2e7fa8ce04dda606277537/samples/aspnetapp/Dockerfile#L21) and the following example.
```dockerfile
USER $APP_UID

Просмотреть файл

@ -14,12 +14,13 @@ spec:
spec:
containers:
- name: aspnetapp
image: dotnetnonroot.azurecr.io/aspnetapp
image: mcr.microsoft.com/dotnet/samples:aspnetapp
ports:
- containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1654
---
apiVersion: v1
kind: Service

Просмотреть файл

@ -16,7 +16,7 @@ spec:
- name: aspnetapp
image: mcr.microsoft.com/dotnet/samples:aspnetapp
ports:
- containerPort: 80
- containerPort: 8080
resources:
requests:
memory: "80Mi"
@ -26,7 +26,7 @@ spec:
livenessProbe:
httpGet:
path: /healthz
port: 80
port: 8080
---
apiVersion: v1
kind: Service
@ -40,4 +40,3 @@ spec:
- name: aspnetapp
protocol: TCP
port: 8080
targetPort: 80

Просмотреть файл

@ -16,7 +16,7 @@ spec:
- name: aspnetapp
image: mcr.microsoft.com/dotnet/samples:aspnetapp
ports:
- containerPort: 80
- containerPort: 8080
resources:
requests:
memory: "60Mi"
@ -37,5 +37,3 @@ spec:
- name: aspnetapp
protocol: TCP
port: 8080
targetPort: 80