apiVersion: apps/v1 kind: Deployment metadata: name: tmobile-exporter namespace: monitoring labels: app.kubernetes.io/name: tmobile-exporter spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: tmobile-exporter template: metadata: labels: app.kubernetes.io/name: tmobile-exporter spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault containers: # json_exporter scrapes the gateway JSON on demand and exposes /probe. # The nginx sidecar below rewrites the public /metrics URL onto it. - name: json-exporter image: quay.io/prometheuscommunity/json-exporter:v0.7.0 args: - --config.file=/etc/json_exporter/json-exporter.yml ports: - name: probe containerPort: 7979 protocol: TCP resources: requests: cpu: 10m memory: 24Mi limits: memory: 96Mi securityContext: runAsUser: 65534 runAsGroup: 65534 allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: ["ALL"] volumeMounts: - name: config mountPath: /etc/json_exporter readOnly: true # nginx rewrites GET /metrics → GET /probe?module=tmhi&target=. # nginxinc/nginx-unprivileged runs as UID 101 (non-root) without file caps, # so it survives no_new_privs + readOnlyRootFilesystem cleanly. - name: nginx image: nginxinc/nginx-unprivileged:1.27-alpine-slim ports: - name: metrics containerPort: 9099 protocol: TCP resources: requests: cpu: 10m memory: 16Mi limits: memory: 64Mi securityContext: runAsUser: 101 runAsGroup: 101 allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: ["ALL"] volumeMounts: - name: config mountPath: /etc/nginx/nginx.conf subPath: nginx.conf readOnly: true - name: nginx-tmp mountPath: /tmp readinessProbe: httpGet: path: /healthz port: metrics periodSeconds: 10 livenessProbe: httpGet: path: /healthz port: metrics periodSeconds: 30 volumes: - name: config configMap: name: tmobile-exporter-config - name: nginx-tmp emptyDir: {}