--- - name: Deploy Kubernetes Dashboard to k3s cluster hosts: master become: yes vars: dashboard_namespace: "kubernetes-dashboard" dashboard_version: "v2.7.0" metrics_scraper_version: "v1.0.8" tasks: - name: Create kubernetes dashboard namespace shell: | kubectl create namespace {{ dashboard_namespace }} --dry-run=client -o yaml | kubectl apply -f - register: namespace_result failed_when: false - name: Apply Kubernetes Dashboard manifests shell: | kubectl apply -f - << 'EOF' apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: {{ dashboard_namespace }} --- apiVersion: v1 kind: Service metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: {{ dashboard_namespace }} spec: ports: - port: 443 targetPort: 8443 selector: k8s-app: kubernetes-dashboard type: ClusterIP --- apiVersion: v1 kind: Secret metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard-certs namespace: {{ dashboard_namespace }} type: Opaque --- apiVersion: v1 kind: Secret metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard-csrf namespace: {{ dashboard_namespace }} type: Opaque data: csrf: "" --- apiVersion: v1 kind: Secret metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard-key-holder namespace: {{ dashboard_namespace }} type: Opaque --- apiVersion: v1 kind: ConfigMap metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard-settings namespace: {{ dashboard_namespace }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: {{ dashboard_namespace }} rules: - apiGroups: [""] resources: ["secrets"] resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"] verbs: ["get", "update", "delete"] - apiGroups: [""] resources: ["configmaps"] resourceNames: ["kubernetes-dashboard-settings"] verbs: ["get", "update"] - apiGroups: [""] resources: ["services"] resourceNames: ["heapster", "dashboard-metrics-scraper"] verbs: ["proxy"] - apiGroups: [""] resources: ["services/proxy"] resourceNames: ["heapster", "http:heapster:", "https:heapster:"] verbs: ["get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard rules: - apiGroups: ["metrics.k8s.io"] resources: ["pods", "nodes"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: {{ dashboard_namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: kubernetes-dashboard subjects: - kind: ServiceAccount name: kubernetes-dashboard namespace: {{ dashboard_namespace }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kubernetes-dashboard roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: kubernetes-dashboard subjects: - kind: ServiceAccount name: kubernetes-dashboard namespace: {{ dashboard_namespace }} --- apiVersion: apps/v1 kind: Deployment metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: {{ dashboard_namespace }} spec: replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: k8s-app: kubernetes-dashboard template: metadata: labels: k8s-app: kubernetes-dashboard spec: securityContext: seccompProfile: type: RuntimeDefault containers: - name: kubernetes-dashboard image: kubernetesui/dashboard:{{ dashboard_version }} imagePullPolicy: Always ports: - containerPort: 8443 protocol: TCP args: - --auto-generate-certificates - --namespace={{ dashboard_namespace }} - --enable-skip-login - --enable-insecure-login volumeMounts: - name: kubernetes-dashboard-certs mountPath: /certs - mountPath: /tmp name: tmp-volume livenessProbe: httpGet: scheme: HTTPS path: / port: 8443 initialDelaySeconds: 30 timeoutSeconds: 30 periodSeconds: 10 failureThreshold: 3 securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: false runAsUser: 1001 runAsGroup: 2001 volumes: - name: kubernetes-dashboard-certs secret: secretName: kubernetes-dashboard-certs - name: tmp-volume emptyDir: {} serviceAccountName: kubernetes-dashboard nodeSelector: "kubernetes.io/os": linux tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule - key: node-role.kubernetes.io/control-plane effect: NoSchedule --- apiVersion: v1 kind: Service metadata: labels: k8s-app: dashboard-metrics-scraper name: dashboard-metrics-scraper namespace: {{ dashboard_namespace }} spec: ports: - port: 8000 targetPort: 8000 selector: k8s-app: dashboard-metrics-scraper --- apiVersion: apps/v1 kind: Deployment metadata: labels: k8s-app: dashboard-metrics-scraper name: dashboard-metrics-scraper namespace: {{ dashboard_namespace }} spec: replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: k8s-app: dashboard-metrics-scraper template: metadata: labels: k8s-app: dashboard-metrics-scraper spec: securityContext: seccompProfile: type: RuntimeDefault containers: - name: dashboard-metrics-scraper image: kubernetesui/metrics-scraper:{{ metrics_scraper_version }} ports: - containerPort: 8000 protocol: TCP livenessProbe: httpGet: scheme: HTTP path: / port: 8000 initialDelaySeconds: 30 timeoutSeconds: 30 periodSeconds: 10 failureThreshold: 3 volumeMounts: - mountPath: /tmp name: tmp-volume securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: false runAsUser: 1001 runAsGroup: 2001 volumes: - name: tmp-volume emptyDir: {} serviceAccountName: kubernetes-dashboard nodeSelector: "kubernetes.io/os": linux tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule - key: node-role.kubernetes.io/control-plane effect: NoSchedule EOF register: dashboard_result - name: Create admin user for dashboard shell: | kubectl apply -f - << 'EOF' apiVersion: v1 kind: ServiceAccount metadata: name: admin-user namespace: {{ dashboard_namespace }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: admin-user namespace: {{ dashboard_namespace }} EOF register: admin_user_result - name: Wait for dashboard pods to be ready shell: | kubectl wait --for=condition=ready pod -l k8s-app=kubernetes-dashboard -n {{ dashboard_namespace }} --timeout=120s register: wait_result failed_when: false - name: Get dashboard service info shell: | kubectl get svc kubernetes-dashboard -n {{ dashboard_namespace }} register: svc_info - name: Display dashboard service info debug: msg: "{{ svc_info.stdout_lines }}" - name: Display deployment status debug: msg: "Kubernetes Dashboard deployed successfully in namespace {{ dashboard_namespace }}"