部署kubernetes-dashboard並配置ServiceAccount和登錄鑑權

"種草" kubernetes-dashboard

Kubernetes Dashboard 是通用的用於管理 Kubernetes 集羣的 WebUI面板

image

kubernetes-dashboard 代碼庫 readme 中對自己的介紹:

Kubernetes Dashboard is a general purpose, web-based UI for Kubernetes clusters. It allows users to manage applications running in the cluster and troubleshoot them, as well as manage the cluster itself.

通過這個面板, 可以讓我們非常直觀看到pod的狀態, 創建時間, 標籤, 運行在哪個結點等元數據

image

還能看到容器中定義的環境變量, 掛載的磁盤, livenessreadiness探針等信息

image

有了這個面板, 不光是pod, 可以對幾乎 kubernetes 中的任何資源(前提是當前用戶有足夠的權限) 查看和管理

再介紹一個這個面板我自己最常用的功能: 重啓pod

image

確實通過命令kubectl rollout restart -n prod deployment mysql-8-0可以實現同樣的操作, 不過有了這個面板, 鼠標點點就能完成豈不美哉, 重啓前還會彈出確認框提示你是不是確定要重啓, 還貼心的把用於重啓命令給我們展示出來了, awesome! 再也不怕忘記命令每次都要去google一下文檔啦!

image


這個面板可以使用kubernetes的ServiceAccount來登錄鑑權, 對權限控制的粒度可以做到非常細緻, 別急, 往下看!

安裝部署dashboard

官方的deployment.yaml

這份文件中, 首先定義了個Namespace -> kubernetes-dashboard, 然後的所有資源都在這個Namespace下;

先看2個Deployment的定義, 分別是kubernetes-dashboarddashboard-metrics-scraper

點擊展開 -> Deployment: kubernetes-dashboard
kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
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:v2.7.0
          imagePullPolicy: Always
          ports:
            - containerPort: 8443
              protocol: TCP
          args:
            - --auto-generate-certificates
            - --namespace=kubernetes-dashboard
            # 通過nginx-ingress暴露出去, 這裏不需要ssl了, 沒有這個標誌位會導致無法正常登錄
            - --enable-insecure-login=true
          volumeMounts:
            - name: kubernetes-dashboard-certs
              mountPath: /certs
              # Create on-disk volume to store exec logs
            - mountPath: /tmp
              name: tmp-volume
          livenessProbe:
            httpGet:
              scheme: HTTPS
              path: /
              port: 8443
            initialDelaySeconds: 30
            timeoutSeconds: 30
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            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
      # Comment the following tolerations if Dashboard must not be deployed on master
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule
點擊展開 -> Deployment: dashboard-metrics-scraper
kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    k8s-app: dashboard-metrics-scraper
  name: dashboard-metrics-scraper
  namespace: kubernetes-dashboard
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:v1.0.8
          ports:
            - containerPort: 8000
              protocol: TCP
          livenessProbe:
            httpGet:
              scheme: HTTP
              path: /
              port: 8000
            initialDelaySeconds: 30
            timeoutSeconds: 30
          volumeMounts:
          - mountPath: /tmp
            name: tmp-volume
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            runAsUser: 1001
            runAsGroup: 2001
      serviceAccountName: kubernetes-dashboard
      nodeSelector:
        "kubernetes.io/os": linux
      # Comment the following tolerations if Dashboard must not be deployed on master
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule
      volumes:
        - name: tmp-volume
          emptyDir: {}

再看ServiceAccount: kubernetes-dashboard; 上面兩個Deployment kubernetes-dashboarddashboard-metrics-scraper 中的容器都綁定到了這個ServiceAccount

點擊展開 ServiceAccount: kubernetes-dashboard
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard

deployment.yaml中還定義了ClusterRole: kubernetes-dashboardRole: kubernetes-dashboard, ClusterRole Role中定義了面板所需的權限

ClusterRole和Role的定義
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
rules:
  # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
  - apiGroups: [""]
    resources: ["secrets"]
    resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
    verbs: ["get", "update", "delete"]
    # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
  - apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["kubernetes-dashboard-settings"]
    verbs: ["get", "update"]
    # Allow Dashboard to get metrics.
  - apiGroups: [""]
    resources: ["services"]
    resourceNames: ["heapster", "dashboard-metrics-scraper"]
    verbs: ["proxy"]
  - apiGroups: [""]
    resources: ["services/proxy"]
    resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
    verbs: ["get"]

---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
rules:
  # Allow Metrics Scraper to get metrics from the Metrics server
  - apiGroups: ["metrics.k8s.io"]
    resources: ["pods", "nodes"]
    verbs: ["get", "list", "watch"]

ClusterRole, Role與 前面提到的 ServiceAccount:kubernetes-dashboard 通過 ClusterRoleBindingRoleBinding 綁定到了一起, 就是給 ServiceAccount:kubernetes-dashboard 授權, 讓它可以訪問集羣裏的資源

ClusterRoleBinding, RoleBinding 綁定 ServiceAccount 與 ClusterRole, Role
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: kubernetes-dashboard
subjects:
  - kind: ServiceAccount
    name: kubernetes-dashboard
    namespace: kubernetes-dashboard

---

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: kubernetes-dashboard

最後就是 Service, ConfigMap, 和幾個ssl相關的 Secret, 幾個 Secret 的定義對我來說是不重要的, 因爲上面Deployment容器的啓動命令裏, 我加上了 --enable-insecure-login=true, 我在外部通過nginx-ingress暴露服務, 配置好了ingress的部分配置ssl, 所裏這裏就無所謂了

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard

---

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: dashboard-metrics-scraper
  name: dashboard-metrics-scraper
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 8000
      targetPort: 8000
  selector:
    k8s-app: dashboard-metrics-scraper

---

kind: ConfigMap
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-settings
  namespace: kubernetes-dashboard

---

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-certs
  namespace: kubernetes-dashboard
type: Opaque

---

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-csrf
  namespace: kubernetes-dashboard
type: Opaque
data:
  csrf: ""

---

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-key-holder
  namespace: kubernetes-dashboard
type: Opaque

配置Ingress, 向外暴露服務

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: kubernetes-dashboard
  name: kubernetes-dashboard-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/backend-protocol: http
spec:
  ingressClassName: 
  tls:
    - hosts:
        - <這裏填域名>
      secretName: <這裏填集羣內配置好的Secret證書>
  rules:
    - host: <這裏填域名>
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: kubernetes-dashboard
              port:
                number: 80

創建用於登錄面板的ServiceAccount

新建account.yaml中定義ServiceAccount並綁定到內置的ClusterRole

定義兩個 ServiceAccount 分別是 rootreadonly

  • root 綁定到內置的 ClusterRole cluster-admin
  • readonly 綁定到內置的 ClusterRole view
  • kubectl get clusterrole 可以列表當前集羣中已存在的角色
apiVersion: v1
kind: ServiceAccount
metadata:
  name: root
  namespace: kubernetes-dashboard

---

apiVersion: v1
kind: ServiceAccount
metadata:
  name: readonly
  namespace: kubernetes-dashboard

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: root
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: root
  namespace: kubernetes-dashboard

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: readonly
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view
subjects:
- kind: ServiceAccount
  name: readonly
  namespace: kubernetes-dashboard

kubectl apply -f account.yaml 應用後, rootreadonly 就創建好了, 然後我們去生成 Token 輸入到面板的登錄界面中就可以登錄了

root 生成有效期30天 Token 的命令 kubectl create token --namespace kubernetes-dashboard --duration 2592000s root

Token 登錄

image

權限控制

root 賬戶綁定的角色是內置的 cluster-admin, 可以對集羣內的一切資源進行查看或修改, 刪除等操作

readonly 賬戶綁定的角色是內置的 view, 擁有對集羣內大部分資源的只讀權限

也可以自己新建一個角色, 授予這個新角色某些指定權限, 例如下面的示例, 創建了一個名爲 testClusterRole, 對pods有隻讀權限, 然後將這個角色與 ServiceAccount 綁定

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: test
rules:
  - apiGroups: [""] 
    resources: ["pods"]
    verbs: ["get", "watch", "list"]

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: root-to-test
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: test
subjects:
- kind: ServiceAccount
  name: root
  namespace: kubernetes-dashboard
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章