apiVersion: v1 kind: ConfigMap metadata: name: kubernetes-dashboard-auth-proxy namespace: kubernetes-dashboard data: nginx.conf.template: | pid /tmp/nginx.pid; error_log /dev/stderr warn; events {} http { access_log /dev/stdout; client_body_temp_path /tmp/client-body; proxy_temp_path /tmp/proxy; fastcgi_temp_path /tmp/fastcgi; uwsgi_temp_path /tmp/uwsgi; scgi_temp_path /tmp/scgi; map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 8080; server_name _; location = /healthz { access_log off; default_type text/plain; return 200 'ok\n'; } location / { proxy_http_version 1.1; proxy_pass https://kubernetes-dashboard-kong-proxy.kubernetes-dashboard.svc.cluster.local:443; proxy_ssl_name kubernetes-dashboard-kong-proxy.kubernetes-dashboard.svc.cluster.local; proxy_ssl_server_name on; # Kong uses its chart-generated internal certificate. proxy_ssl_verify off; proxy_set_header Authorization "Bearer @@DASHBOARD_TOKEN@@"; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-Proto https; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_read_timeout 3600s; proxy_send_timeout 3600s; } } } run.sh: | #!/bin/sh set -eu token_file=/var/run/secrets/dashboard/token template=/config/nginx.conf.template rendered=/tmp/nginx.conf render_config() { dashboard_token=$(tr -d '\n' < "$token_file") test -n "$dashboard_token" sed "s|@@DASHBOARD_TOKEN@@|$dashboard_token|g" "$template" > "$rendered.new" chmod 0600 "$rendered.new" mv "$rendered.new" "$rendered" unset dashboard_token } stop() { nginx -c "$rendered" -s quit 2>/dev/null || true exit 0 } trap stop INT TERM render_config token_digest=$(sha256sum "$token_file" | awk '{print $1}') nginx -t -c "$rendered" nginx -c "$rendered" while :; do sleep 60 next_digest=$(sha256sum "$token_file" | awk '{print $1}') if [ "$next_digest" != "$token_digest" ]; then render_config nginx -t -c "$rendered" nginx -c "$rendered" -s reload token_digest=$next_digest fi done --- apiVersion: v1 kind: Service metadata: name: kubernetes-dashboard-auth-proxy namespace: kubernetes-dashboard spec: selector: app.kubernetes.io/name: kubernetes-dashboard-auth-proxy ports: - name: http port: 8080 targetPort: http --- apiVersion: apps/v1 kind: Deployment metadata: name: kubernetes-dashboard-auth-proxy namespace: kubernetes-dashboard spec: replicas: 2 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app.kubernetes.io/name: kubernetes-dashboard-auth-proxy template: metadata: labels: app.kubernetes.io/name: kubernetes-dashboard-auth-proxy app.kubernetes.io/part-of: kubernetes-dashboard spec: serviceAccountName: admin-user automountServiceAccountToken: false securityContext: runAsNonRoot: true runAsUser: 101 runAsGroup: 101 fsGroup: 101 seccompProfile: type: RuntimeDefault containers: - name: proxy image: docker.io/nginxinc/nginx-unprivileged:1.29.1-alpine@sha256:6742337773a7ca839e7a76f489cc684cc410e3de46c0c83be8bb2bb9944360ef imagePullPolicy: IfNotPresent command: [/bin/sh, /config/run.sh] ports: - name: http containerPort: 8080 securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: [ALL] resources: requests: cpu: 25m memory: 32Mi limits: cpu: 200m memory: 128Mi readinessProbe: httpGet: path: /healthz port: http periodSeconds: 10 livenessProbe: httpGet: path: /healthz port: http periodSeconds: 20 volumeMounts: - name: config mountPath: /config readOnly: true - name: token mountPath: /var/run/secrets/dashboard readOnly: true - name: temporary mountPath: /tmp volumes: - name: config configMap: name: kubernetes-dashboard-auth-proxy defaultMode: 0555 - name: token projected: defaultMode: 0440 sources: - serviceAccountToken: path: token audience: https://kubernetes.default.svc.cluster.local expirationSeconds: 3600 - name: temporary emptyDir: sizeLimit: 64Mi --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: kubernetes-dashboard-auth-proxy namespace: kubernetes-dashboard spec: maxUnavailable: 1 selector: matchLabels: app.kubernetes.io/name: kubernetes-dashboard-auth-proxy --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: kubernetes-dashboard-auth-proxy namespace: kubernetes-dashboard spec: podSelector: matchLabels: app.kubernetes.io/name: kubernetes-dashboard-auth-proxy policyTypes: [Ingress, Egress] ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: default podSelector: matchLabels: app.kubernetes.io/name: traefik ports: - protocol: TCP port: 8080 egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: k8s-app: kube-dns ports: - protocol: UDP port: 53 - protocol: TCP port: 53 - to: - podSelector: matchLabels: app.kubernetes.io/instance: kubernetes-dashboard app.kubernetes.io/name: kong ports: - protocol: TCP port: 443 - protocol: TCP port: 8443