K8s – Dashboard

这里只介绍如何部署Dashboard,至于使用方法,会在之前的文章:K8s – Core Resource Management Method GUI部分进行总结;

安装部署Dashboard

上传Dashboard的Image

root@f0-15:~# docker pull docker.io/k8scn/kubernetes-dashboard-amd64:v1.8.3
v1.8.3: Pulling from k8scn/kubernetes-dashboard-amd64
a4026007c47e: Pull complete 
Digest: sha256:ebc993303f8a42c301592639770bd1944d80c88be8036e2d4d0aa116148264ff
Status: Downloaded newer image for k8scn/kubernetes-dashboard-amd64:v1.8.3
docker.io/k8scn/kubernetes-dashboard-amd64:v1.8.3
root@f0-15:~# docker images |grep dashboard
k8scn/kubernetes-dashboard-amd64   v1.8.3                     fcac9aa03fd6   4 years ago   102MB
root@f0-15:~# docker tag fcac9aa03fd6 harbor.frank.com/public/dashboard:v1.8.3
root@f0-15:~# docker push harbor.frank.com/public/dashboard:v1.8.3

资源配置清单

配置清单可以去Github kubenetes中,根据版本查阅,如我用的是v1.15.2,那么就需要参考:https://github.com/kubernetes/kubernetes/tree/release-1.15/cluster/addons/dashboard

root@f0-13:~# kubectl version
Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.2", GitCommit:"f6278300bebbb750328ac16ee6dd3aa7d3549568", GitTreeState:"clean", BuildDate:"2019-08-05T09:23:26Z", GoVersion:"go1.12.5", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.2", GitCommit:"f6278300bebbb750328ac16ee6dd3aa7d3549568", GitTreeState:"clean", BuildDate:"2019-08-05T09:15:22Z", GoVersion:"go1.12.5", Compiler:"gc", Platform:"linux/amd64"}

RBAC

注意官网上的rbac授权的是mini权限,建议绑定”cluster-admin“,可以从下面看到这个集群角色有admin的权限:

root@f0-15:/data/k8s-yaml/dashboard# more rbac.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: kubernetes-dashboard
    addonmanager.kubernetes.io/mode: Reconcile
  name: kubernetes-dashboard-admin
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard-admin
  namespace: kube-system
  labels:
    k8s-app: kubernetes-dashboard
    addonmanager.kubernetes.io/mode: Reconcile
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard-admin
  namespace: kube-system
root@f0-13:/opt/src# kubectl get clusterrole cluster-admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  creationTimestamp: "2022-08-09T04:55:53Z"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: cluster-admin
  resourceVersion: "40"
  selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/cluster-admin
  uid: 159a8597-e5c6-4875-923e-d21beca67a70
rules:
- apiGroups:
  - '*'
  resources:
  - '*'
  verbs:
  - '*'
- nonResourceURLs:
  - '*'
  verbs:
  - '*'

Deployment

root@f0-15:/data/k8s-yaml/dashboard# more dp.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kubernetes-dashboard
  namespace: kube-system
  labels:
    k8s-app: kubernetes-dashboard
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
spec:
  selector:
    matchLabels:
      k8s-app: kubernetes-dashboard
  template:
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      annotations:
        scheduler.alpha.kubernetes.io/critical-pod: ''
    spec:
      priorityClassName: system-cluster-critical
      containers:
      - name: kubernetes-dashboard
        image: harbor.frank.com/public/dashboard:v1.8.3
        resources:
          limits:
            cpu: 100m
            memory: 300Mi
          requests:
            cpu: 50m
            memory: 100Mi
        ports:
        - containerPort: 8443
          protocol: TCP
        args:
          # PLATFORM-SPECIFIC ARGS HERE
          - --auto-generate-certificates
        volumeMounts:
        - name: tmp-volume
          mountPath: /tmp
        livenessProbe:
          httpGet:
            scheme: HTTPS
            path: /
            port: 8443
          initialDelaySeconds: 30
          timeoutSeconds: 30
      volumes:
      - name: tmp-volume
        emptyDir: {}
      serviceAccountName: kubernetes-dashboard-admin
      tolerations:
      - key: "CriticalAddonsOnly"
        operator: "Exists"

Service

root@f0-15:/data/k8s-yaml/dashboard# more svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: kubernetes-dashboard
  namespace: kube-system
  labels:
    k8s-app: kubernetes-dashboard
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
spec:
  selector:
    k8s-app: kubernetes-dashboard
  ports:
  - port: 443
    targetPort: 8443

Ingress

root@f0-15:/data/k8s-yaml/dashboard# more ingress.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: dashboard.frank.com
    http:
      paths:
      - path: /
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 443

部署Dashboard

root@f0-13:~# kubectl apply -f http://k8s-yaml.frank.com/dashboard/rbac.yaml
role.rbac.authorization.k8s.io/kubernetes-dashboard-minimal created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard-minimal created
root@f0-13:~# kubectl apply -f http://k8s-yaml.frank.com/dashboard/dp.yaml
deployment.apps/kubernetes-dashboard created
root@f0-13:~# kubectl apply -f http://k8s-yaml.frank.com/dashboard/svc.yaml
service/kubernetes-dashboard created
root@f0-13:~# kubectl apply -f http://k8s-yaml.frank.com/dashboard/ingress.yaml
ingress.extensions/kubernetes-dashboard created

如果设置错了,直接利用配置清单删掉资源即可:

root@f0-13:~# kubectl delete -f http://k8s-yaml.frank.com/dashboard/rbac.yaml

添加业务域名解析

root@f0-11:~# more /etc/bind/db.frank.com |grep dashboard -C 1
traefik         A       172.20.0.18
dashboard       A       172.20.0.18
root@f0-11:~# systemctl restart bind9
root@f0-11:~# dig -t A dashboard.frank.com @172.20.0.11 +short
172.20.0.18
root@f0-13:~# dig -t A dashboard.frank.com @172.1.13.4 +short
172.20.0.18

验证Dashboard

root@f0-13:~# kubectl get pods -n kube-system
NAME                                    READY   STATUS    RESTARTS   AGE
coredns-684d79cc-55sst                  1/1     Running   1          2d19h
kubernetes-dashboard-6d9757fc4d-ktktt   1/1     Running   0          3m11s
traefik-ingress-7zhbq                   1/1     Running   1          2d17h
traefik-ingress-x9g92                   1/1     Running   1          2d17h
root@f0-13:~# 
root@f0-13:~# kubectl get svc -n kube-system
NAME                      TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
coredns                   ClusterIP   10.254.0.2       <none>        53/UDP,53/TCP,9153/TCP   2d19h
kubernetes-dashboard      ClusterIP   10.254.243.192   <none>        443/TCP                  7m24s
traefik-ingress-service   ClusterIP   10.254.176.139   <none>        80/TCP,8080/TCP          2d17h
root@f0-13:~# 
root@f0-13:~# kubectl get ingress -n kube-system
NAME                   HOSTS                 ADDRESS   PORTS   AGE
kubernetes-dashboard   dashboard.frank.com             80      7m33s
traefik-web-ui         traefik.frank.com               80      2d17h

打开web界面后,可以通过3种方式进入dashboard,3种方式可以给访问者不同的权限,进而控制k8s的各种资源。其中“SKIP”是使用默认权限令牌(新版本中会移除这个skip),对于Token,每个service account都会有一个默认的default token;

但需要注意的是,目前没法直接用token登录,因为目前网站没有证书(web的标题栏显示“Not Secure”);

root@f0-13:/opt/src# kubectl get secret 
NAME                  TYPE                                  DATA   AGE
default-token-7s2vl   kubernetes.io/service-account-token   3      9d
root@f0-13:/opt/src# kubectl describe secret default-token-7s2vl
Name:         default-token-7s2vl
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: default
              kubernetes.io/service-account.uid: 9fd7c248-e30f-458a-b0ee-660382a9a178

Type:  kubernetes.io/service-account-token

Data
====
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tN3MydmwiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjlmZDdjMjQ4LWUzMGYtNDU4YS1iMGVlLTY2MDM4MmE5YTE3OCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.EXWFzPUEDYC8tgk240IU624K3DRysPS5W_NlSsdg6_F9JtV1_kk6rCLz5WJIAhiv17ImygRj7aDMXf6zV9wPnCNS6MO_uUr4gBD-RiZAVnQeAr5AMAlhRgIWkxrTnn8Zr--VjM0VQ_1MJBATMSqBBKkSNmRz1-pMNyDh_Z3p5rI8nDq0cGJ71aeimp1qjByX830HGV-2R1d2IRCQwx4MphcOFvIukTjDC4QwMBIWMW8I6zLM8iGqPvTeeW0rf-fr7i6omI8SPhgYJoHWMx2kXwtUbh6hgZEF4aL0Lf-cZGpEZrf6LT_Wlty3IIkpD70r9ZAyBStSldhWnsliCcmgjQ
ca.crt:     1127 bytes
namespace:  7 bytes

Token登录方式(openssl签发证书)

如上所述,如果需要用token登录,那么dashboard.frank.com就需要证书。之前用的是cfssl签发的证书,这次用openssl签发证书,方法如下:

生成RSA私钥

root@f0-15:/opt/certs# openssl genrsa -out dashboard.frank.com.key 2048
root@f0-15:/opt/certs# chmod 644 dashboard.frank.com.key 
root@f0-15:/opt/certs# ll |grep dashboard
-rw-r--r-- 1 root root 1675 Aug 19 09:49 dashboard.frank.com.key

生成CSR证书签发请求

利用上面生成的私钥,以及“-subj”信息生成证书签发请求文件:

root@f0-15:/opt/certs# openssl req -new -key dashboard.frank.com.key -out dashboard.frank.com.csr -subj "/CN=dashboard.frank.com/C=CN/ST=ShangHai/L=ShangHai/O=FZ/OU=arch"
root@f0-15:/opt/certs# ll |grep dashboard
-rw-r--r-- 1 root root 1013 Aug 19 09:57 dashboard.frank.com.csr
-rw-r--r-- 1 root root 1675 Aug 19 09:49 dashboard.frank.com.key

生成服务端证书

根据CSR文件和根证书(根证书是在搭建k8s时签的,具体看这里),生成服务端证书,由于是自签证书,所以天数直接给了10年:

root@f0-15:/opt/certs# openssl x509 -req -in dashboard.frank.com.csr -CA ca.pem -CAkey ca-key.pem -out dashboard.frank.com.pem -CAcreateserial -days 3650
Signature ok
subject=CN = dashboard.frank.com, C = CN, ST = ShangHai, L = ShangHai, O = FZ, OU = arch
Getting CA Private Key
root@f0-15:/opt/certs# ll |grep dashboard
-rw-r--r-- 1 root root 1013 Aug 19 09:57 dashboard.frank.com.csr
-rw-r--r-- 1 root root 1675 Aug 19 09:49 dashboard.frank.com.key
-rw-r--r-- 1 root root 1107 Aug 19 10:01 dashboard.frank.com.pem

拷贝并应用证书

注意,拷贝证书和更改nginx的配置需要在f0-11和f0-12上同时做,这里只展示f0-11;

root@f0-11:/etc/nginx/certs# ll
total 16
drwxr-xr-x 2 root root 4096 Aug 19 11:13 ./
drwxr-xr-x 9 root root 4096 Aug 19 11:26 ../
-rw-r--r-- 1 root root 1675 Aug 19 11:12 dashboard.frank.com.key
-rw-r--r-- 1 root root 1107 Aug 19 11:12 dashboard.frank.com.pem

下面nginx的配置就是打开对dashboard.frank.com的80和443监控,80访问重定向到https,并卸载证书,443访问直接卸载,下面是一些注意事项:

  • ^(.*)$:^ 代表以什么开头, $代表以什么结尾, . 指代除换行符以外的所有字符, * 代表0个或者任意多个, 整体代表匹配任何请求;
  • $1: 匹配第一个括号的内容, $2匹配第二个括号内容,这里只有一个括号,就是匹配括号的任意请求都转发
root@f0-11:/etc/nginx/conf.d# more dashboard.frank.com.conf 
server {
        listen  80;
        server_name     dashboard.frank.com;

        rewrite ^(.*)$ https://${server_name}$1 permanent;
}
server {
        listen  443 ssl;
        server_name     dashboard.frank.com;

        ssl_certificate "certs/dashboard.frank.com.pem";
        ssl_certificate_key     "certs/dashboard.frank.com.key";

        ssl_session_cache       shared:SSL:1m;
        ssl_session_timeout     10m;

        ssl_ciphers     HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers       on;

        location / {
                proxy_pass http://default_backend_traefik;
                proxy_set_header Host   $http_host;
                proxy_set_header        x-forwarded-for $proxy_add_x_forwarded_for;
        }
}
root@f0-11:/etc/nginx/conf.d# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
root@f0-11:/etc/nginx/conf.d# systemctl restart nginx

用web验证http重定向

用curl验证http重定向

root@f0-11:/etc/nginx/conf.d# curl -I dashboard.frank.com
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0 (Ubuntu)
Date: Tue, 23 Aug 2022 02:55:50 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Location: https://dashboard.frank.com/

用curl验证https网站

根据下面信息,nginx卸载证书已经生效了。

root@f0-11:/etc/nginx/conf.d# curl -k --cert /etc/nginx/certs/dashboard.frank.com.pem --key /etc/nginx/certs/dashboard.frank.com.key https://dashboard.frank.com
 <!doctype html> <html ng-app="kubernetesDashboard"> <head> <meta charset="utf-8"> <title ng-controller="kdTitle as $ctrl" ng-bind="$ctrl.title()"></title> <link rel="icon" type="image/png" href="assets/images/kubernetes-logo.png"> <meta name="viewport" content="width=device-width"> <link rel="stylesheet" href="static/vendor.93db0a0d.css"> <link rel="stylesheet" href="static/app.93e259f7.css"> </head> <body ng-controller="kdMain as $ctrl"> <!--[if lt IE 10]>
      <p class="browsehappy">You are using an <strong>outdated</strong> browser.
      Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your
      experience.</p>
    <![endif]--> <kd-login layout="column" layout-fill ng-if="$ctrl.isLoginState()"> </kd-login> <kd-chrome layout="column" layout-fill ng-if="!$ctrl.isLoginState()"> </kd-chrome> <script src="static/vendor.bd425c26.js"></script> <script src="api/appConfig.json"></script> <script src="static/app.b5ad51ac.js"></script> </body> </html> 

此时通过web再次访问,可以看到标题栏已经有小锁了:

点进去查看,可以看到证书的详细信息:

用token登录

此时用admin或default的token,就可以顺利进去了:

root@f0-13:~# kubectl get secret -n kube-system
NAME                                     TYPE                                  DATA   AGE
coredns-token-kr6x4                      kubernetes.io/service-account-token   3      8d
default-token-cvpbz                      kubernetes.io/service-account-token   3      13d
kubernetes-dashboard-admin-token-2kdb2   kubernetes.io/service-account-token   3      6d1h
kubernetes-dashboard-key-holder          Opaque                                2      6d1h
traefik-ingress-controller-token-nbwdx   kubernetes.io/service-account-token   3      8d
root@f0-13:~# kubectl describe secret kubernetes-dashboard-admin-token-2kdb2 -n kube-system
Name:         kubernetes-dashboard-admin-token-2kdb2
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: kubernetes-dashboard-admin
              kubernetes.io/service-account.uid: f9faf8e4-1e63-4f59-abcb-3ada5a1f77a6

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1127 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZC1hZG1pbi10b2tlbi0ya2RiMiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZC1hZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImY5ZmFmOGU0LTFlNjMtNGY1OS1hYmNiLTNhZGE1YTFmNzdhNiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTprdWJlcm5ldGVzLWRhc2hib2FyZC1hZG1pbiJ9.CTtfJmKnA7_NW3ohnzFR56MNaj3Zo1d7cnJJ0yhVQtupdOfFlD4DZwa7_mOq2X_zO-h-bj7yUoJRPzUeya2Nyy1pwkG3ewgj5SinkTiQQfDj7nkoE2Ha0KaZGO2NB01wawsbYysKHHXNat5USN7Iio1YCC3SOIP2kmE34rlA2BPX4Nt_96LBXCe3Ep5r_KY2frfi9jdVY7KmRUm8Kr28A3qi4QtDorcOQyQkteRQOgBYoxQa5wePsQ4GVXVzGg5xjJviNpjhXu1y7gwj8jAzlQ8Zmqm7VQn-oz9meIjrJPskIYdKDmBfsDlc2Z31VCwy47ftKywa1E3wRtmva_gqUw
root@f0-13:~# 

安装heapster

按照github k8s里的描述,这个插件已经“Retire”了,这里只是简单部署下,比较容易查看资源的使用情况,现在主要由Prometheus来确认各种资源的占用。

root@f0-15:~# docker pull bitnami/heapster:1.5.4
root@f0-15:~# docker tag c359b95ad38b harbor.frank.com/public/heapster:v1.5.4
root@f0-15:~# docker push harbor.frank.com/public/heapster:v1.5.4

资源配置文件:

root@f0-15:/data/k8s-yaml/dashboard/heapster# more rbac.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: heapster
  namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: heapster
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:heapster
subjects:
- kind: ServiceAccount
  name: heapster
  namespace: kube-system
root@f0-15:/data/k8s-yaml/dashboard/heapster# more dp.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: heapster
  namespace: kube-system
spec:
  replicas: 1
  template:
    metadata:
      labels:
        task: monitoring
        k8s-app: heapster
    spec:
      serviceAccountName: heapster
      containers:
      - name: heapster
        image: harbor.frank.com/public/heapster:v1.5.4
        imagePullPolicy: IfNotPresent
        command:
        - /opt/bitnami/heapster/bin/heapster
        - --source=kubernetes:https://kubernetes.default
root@f0-15:/data/k8s-yaml/dashboard/heapster# more svc.yaml 
apiVersion: v1
kind: Service
metadata:
  labels:
    task: monitoring
    kubernetes.io/cluster-service: 'true'
    kubernetes.io/name: Heapster
  name: heapster
  namespace: kube-system
spec:
  ports:
  - port: 80
    targetPort: 8082
  selector:
    k8s-app: heapster
root@f0-13:~# kubectl apply -f http://k8s-yaml.frank.com/dashboard/heapster/rbac.yaml
serviceaccount/heapster created
clusterrolebinding.rbac.authorization.k8s.io/heapster created
root@f0-13:~# kubectl apply -f http://k8s-yaml.frank.com/dashboard/heapster/dp.yaml
deployment.extensions/heapster created
root@f0-13:~# kubectl apply -f http://k8s-yaml.frank.com/dashboard/heapster/svc.yaml
service/heapster created
本文出自 Frank's Blog

版权声明:


本文链接:K8s – Dashboard
版权声明:本文为原创文章,仅代表个人观点,版权归 Frank Zhao 所有,转载时请注明本文出处及文章链接
你可以留言,或者trackback 从你的网站

留言哦

blonde teen swallows load.xxx videos