Kubernetes Dashboard v2.0.4 通过 Ingress 暴露访问

Kubernetes dashboard v2.0.4 exposed access through ingress

Posted by alovn on November 28, 2020

使用Kubernetes过程中,如果总是觉它少点什么,那一定是可以通过鼠标点点点进行操作的UI界面了。K8S官方提供了 kubernetes Dashboard。

安装 Kubernetes Dashboard

安装 Kubernetes Dashboard 非常简单, 只需要执行以下命令就可以了,:

1
2
3
4
5
//https 方式暴露
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/recommended.yaml

// 或者 http方式暴露
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/alternative.yaml

我这里是用的 Dashboard v2.0.4 版本,上面recommended.yaml 是https方式访问的,alternative.yaml是http方式的,安装起来是比较简单的,可是安装完成后,相信许多人多多少少会遇到一些问题,比如:我改怎么访问安装完成的 Dashboard 呢?

如何访问 Kubernetes Dashboard

Dashboard 的访问有一些限制, 要求浏览器必须使用 HTTPS 的方式访问,如果想要通过 HTTP 的方式访问,则访问地址必须是本机 localhost 或 127.0.0.1。如果临时访问可以通过下面 kubectl proxy 和 port-forward 两种方式来访问。

API Server

可以直接通过 API Server 访问:

1
https://<master-ip>:<apiserver-port>/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

kubectl proxy

在集群集群上运行 kubectl proxy 后,为你创建 API Server的代理:

1
2
kubectl proxy --address=0.0.0.0
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

kubectl port-forward

port-forward 可以通过端口转发映射本地端口到指定的pod、svc端口, 比 kubectl proxy 的访问方式要好一些,它的使用方式如下

1
2
3
4
//pod
kubectl --namespace ${NAMESPACE} port-forward $POD_NAME {local_port}:{pod_port} --address 0.0.0.0
//svc
kubectl --namespace ${NAMESPACE} port-forward svc/$SERVICE_NAME {local_port}:{svc_port} --address 0.0.0.0

比如我们映射的dashboard svc:

1
kubectl --namespace kubernetes-dashboard port-forward svc/kubernetes-dashboard 8443:443 --address 0.0.0.0

运行过之后直接访问映射到的端口就可以了。

需要注意的是 Kubernetes Dashbaord 的自动证书 在新版本的 Chrome 下是打不开的,最好使用自签证书。

NodePort

只需要将yaml声明中的 type: ClusterIP 修改为 NodePort 即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
...
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
  - port: 443
    protocol: TCP
    targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard
  sessionAffinity: None
  type: NodePort # 修改为NodePort
status:
  loadBalancer: {}

然后查看 nodeport的端口:

1
kubectl -n kubernetes-dashboard get service kubernetes-dashboard

ingress

既然 K8S 已经提供了 ingress, 那为什么不用 ingress 将 kubernetes dashboard 暴露出来呢, 我使用的是以下方式:

1
ingress-nginx (HTTPS)--->svc--->Dashbard Pod (HTTP) 

接下来操作,先安装http方式的dashbard:

1
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/alternative.yaml

接下来为ingress创建证书,如果有注册域名的话可以用 Let’s Encrypt 签发的证书,我们这里使用自签证书:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//创建目录
mkdir certs

//创建证书

//创建证书私钥
openssl genrsa -out certs/tls.key 2048
//创建证书签发请求文件
openssl req -new -key certs/tls.key -out certs/tls.csr -subj "/CN=k8s.lab.org/C=CN/ST=/L=/O=HomeLab/OU=HomeLabDev"
//创建证书
openssl x509 -req -sha256 -days 3650 -in certs/tls.csr -signkey certs/tls.key -out certs/tls.crt

//或者
openssl req -nodes -newkey rsa:2048 -keyout certs/tls.key -out certs/tls.csr -subj "/CN=k8s.lab.org/C=CN/ST=/L=/O=HomeLab/OU=HomeLabDev" -days 3650
openssl x509 -req -sha256 -days 3650 -in certs/tls.csr -signkey certs/tls.key -out certs/tls.crt

-req 是证书请求的子命令 -newkey rsa:2048 -keyout private_key.pem 表示生成私钥(PKCS8格式) -nodes 表示私钥不加密 -x509 表示输出证书 -days 3650 为有效期

创建 k8s secreet:

1
kubectl -n kubernetes-dashboard create secret tls kubernetes-dashboard-certs1 --cert=certs/tls.crt --key=certs/tls.key

创建 ingress-dashboard.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-dashboard
  namespace: kubernetes-dashboard
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/enable-access-log: "true"
    nginx.ingress.kubernetes.io/configuration-snippet: |
       access_log /var/log/nginx/dashboard-access.log upstreaminfo if=$loggable;
       error_log  /var/log/nginx/dashboard-error.log;
spec:
  tls:
  - hosts:
    - 'k8s.lab.org'
    secretName: kubernetes-dashboard-certs1
  rules:
  - host: "k8s.lab.org"
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: kubernetes-dashboard
            port:
              number: 80

执行 kubectl apply -f ingress-dashboard.yaml 后,就可以用 https 的方式访问 dashboard 了。

我经过实验,发现只要你的浏览器是通过 https 的方式访问 dashboard的就可以了。 如果你在 ingress 前面还有一层nginx, 那么也可以 ingress 暴露 http, 在 nginx 上启用 HTTPS 证书访问:

1
Nginx (HTTPS) ---> ingress-nginx (HTTP) ---> svc ---> Dashbard Pod (HTTP) 

获取Token

创建 dashboard-account.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
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: kubernetes-dashboard

执行

1
kubectl apply -f dashboard-account.yaml

查看token:

1
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')  

接下来就可以直接使用token登录 kubernetes dashboard 了。

参考文档

Kubernetes-Dashboard

Kubernetes-Dashboard Accessing

Kubernetes-Dashboard creating-sample-user