1. 回顾
之前写过一篇 kuberntes-dashboard 的文章,介绍如何使用 nodeport 方式部署与访问。
本次介绍使用 ingress 域名方式访问 dashboard。
- 采用 tls 方式配置 ingress-nginx 访问 dashboard。
2. 下载对应的版本
访问 github 仓库:https://github.com/kubernetes/dashboard/
如何安装合适自己 kuberntes 版本的 Dashboard 的呢?官方发布 release 时,每个版本都有测试,当前版本支持哪些范围的 kubernetes 版本。还特意列出不完全兼容的版本信息。
在 https://github.com/kubernetes/dashboard/releases 找到"Compatibility"能找到完合兼容的版本信息,如图:
本次安装使用的 kubernetes 版本为:1.20
找到适合的 dashboard 版本:https://github.com/kubernetes/dashboard/releases/tag/v20
# 下载 YAML
wget -O dashboard.yaml https://raw.githubusercontent.com/kubernetes/dashboard/v20/aio/deploy/recommended.yaml
# YAML 里含有的镜像:
kubernetesui/dashboard:v20
kubernetesui/metrics-scraper:v17
3. 生成自签名的证书
如果是公网证书则跳过
- 使用自签名证书,去掉 dashboard.yaml 生成证书。
# 创建目录
mkdir certs
# 进入目录,准备生成证书
cd certs
# req 生成证书签名请求
# -newkey 生成新的私钥文件
# -keyout 生成新的私钥文件
# -out 生成的CS文件
# -days 证书有效期,3650天,即10年
# -subj 生成CSR证书的参数
openssl req -newkey rsa:2048 -nodes -keyout dash.k8s.io.key -x509 -days 3650 -out dash.k8s.io.crt -subj "/C=CN/ST=Beijing/L=Beijing/O=Kubernetes/OU=K8S/CN=dash.k8s.io"
# X.509证书包含三个文件:key,csr,crt。
### key是服务器上的私钥文件,用于对发送给客户端数据的加密,以及对从客户端接收到数据的解密
### csr是证书签名请求文件,用于提交给证书颁发机构(CA)对证书签名
### crt是由证书颁发机构(CA)签名后的证书,或者是开发者自签名的证书,包含证书持有人的信息,持有人的公钥,以及签署者的签名等信息
# 查看 crt 证书信息
openssl x509 -noout -text -in dash.k8s.io.crt
4. 生成 secret
crt 和 key 文件修改 dashboard.yaml 需要使用到:
- cert 文件名:dash.k8s.io.crt
- key 文件名:dash.k8s.io.key
# 创建命名空间
kubectl create ns kubernetes-dashboard
# 在 kubernetes-dashboard 空间下创建 secret
## secret=kubernetes-dashboard-certs 固定的名称,请勿修改。
kubectl create secret tls kubernetes-dashboard-certs --cert=dash.k8s.io.crt --key=dash.k8s.io.key -n kubernetes-dashboard
5. 修改 dashboard.yaml 文件
- 注释掉 dashboard.yaml 自动生成的证书。
- 使用自签名的证书。
vim dashboard.yaml
# 找到 Deployment name=kubernetes-dashboard
# 注释 kubernetes-dashboard-certs 名称,因为前面生成了自签名的 secret,注意名称必须与这个名称一致。
# apiVersion: v1
# kind: Secret
# metadata:
# labels:
# k8s-app: kubernetes-dashboard
# name: kubernetes-dashboard-certs # 替换成手动生成的 secret 文件
# namespace: kubernetes-dashboard
# type: Opaque
# 修改第2处
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:
containers:
- name: kubernetes-dashboard
image: kubernetesui/dashboard:v20
imagePullPolicy: Always
resources: {}
ports:
- containerPort: 8443
protocol: TCP
args:
# - --auto-generate-certificates # 去掉自动生成的证书
- --namespace=kubernetes-dashboard
- --tls-key-file=tls.key # 生成 Secret 时默认给的名称即:tls.key
- --tls-cert-file=tls.crt # 生成 Secret 时默认给的名称即:tls.crt
- --token-ttl=3600 # 设置 token 的超时时间
为什么这样填写: --tls-key-file=tls.key
, --tls-cert-file=tls.crt
- 生成 kubernetes-dashboard-certs 时,系统生成的名称即是 tls.key, tls,crt
-> # k -n kubernetes-dashboard get secret kubernetes-dashboard-certs -o yaml
apiVersion: v1
data:
tls.crt: xxx # crt 名称
tls.key: xxx # key 名称
kind: Secret
metadata:
name: kubernetes-dashboard-certs
namespace: kubernetes-dashboard
type: kubernetes.io/tls
6. 部署 Dashboard
kubectl apply -f dashboard.yaml
7. 创建 token
dashboard 不是输入用户名和密码方式登陆,而是采用 token 和 kubeconfig 两种方式登陆。
本次介绍使用 token 方式登陆,可以赋予不同权限给 Token,从而实现权限控制。
7.1. 将 cluster-admin 权限授权给 kubernetes-dashboard
将集群内的最高权限角色 cluster-admin 分配给 kubernetes-dashboard 命名空间里的 kubernetes-dashboard 服务账户
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dashboardcrbinding
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
或者使用 kubectl
kubectl create clusterrolebinding dashboardcrbinding \
--clusterrole=cluster-admin \
--serviceaccount=kubernetes-dashboard:kubernetes-dashboard
7.2. 创建 admin token
本 token 具体超级权限,可以访问整个集群,分享权限时,慎重操作。
想要控制权限范围,给新用户添加访问权限控制,需要创建普通 token。
# 创建 serviceAccount 帐号名称
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
# 将 clustrole 与 serviceAccount 进行绑定
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
查看 token 字符串:
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get serviceaccount admin-user -o jsonpath="{.secrets[0].name}")
7.3. 创建单个空间的 token
假设我们需要给某用户授权 general 命名空间下的权限:
- pods
- deployments,
- configmaps
- services
- statefulsets
- ingresses
注意:pods 没有删除权限,只有 list, get, watch 权限。
文件名: create-general.yaml
######################## 创建指定命名空间下的 token #############################
apiVersion: v1
kind: ServiceAccount
metadata:
name: general-user
namespace: general # 权限限制的操作的命名空间
annotations:
remark: "创建一个 ServiceAccount 帐号"
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: general # 权限限制的操作的命名空间
name: role-general
annotations:
remark: "创建一个角色名称,即这个角色可以做什么"
rules:
- apiGroups: [""]
resources: ["pods"] # 可以操作的对象,如 pods
verbs: ["get", "watch", "list"] # 如何操作,具有的权限
- apiGroups: ["extensions", "apps"]
resources: ["deployments", "configmaps", "services", "statefulsets", "ingresses"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: role-bind-cnych
namespace: general # 权限限制的操作的命名空间
annotations:
remark: "将 ServiceAccount 与 Role 进行绑定在一起,给用户赋予角色操作权限"
subjects:
- kind: ServiceAccount
name: general-user # serviceAccount 帐号名称
namespace: general # 权限限制的操作的命名空间
roleRef:
kind: Role
name: role-general # 绑定的角色
apiGroup: rbac.authorization.k8s.io
查看 token:
kubectl -n general describe secret $(kubectl -n general get secret | grep general-user | awk '{print $1}')
# 或
kubectl -n general describe secret $(kubectl -n general get serviceaccount admin-user -o jsonpath="{.secrets[0].name}")
7.4. 创建多个空间的 token
# 创建 serviceAccount 帐号名称
apiVersion: v1
kind: ServiceAccount
metadata:
name: view-all-service-account
namespace: namespace1
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: namespace1
name: view-all-role
rules:
- apiGroups: [""]
resources: ["pods", "pods/log", "pods/exec"] # 可以操作的对象,如 pods
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # 如何操作,具有的权限
- apiGroups: ["extensions", "apps"]
resources: ["deployments", "configmaps", "services", "statefulsets", "ingresses"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: namespace2
name: view-all-role
rules:
- apiGroups: ["*"] # "*" 表示所有 API 组
resources: ["*"] # "*" 表示所有资源
verbs: ["*"] # "*" 表示所有操作
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: view-all-binding
namespace: namespace1
subjects:
- kind: ServiceAccount
name: view-all-service-account
namespace: namespace1
roleRef:
kind: Role
name: view-all-role
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: view-all-binding
namespace: namespace2
subjects:
- kind: ServiceAccount
name: view-all-service-account
namespace: namespace1
roleRef:
kind: Role
name: view-all-role
apiGroup: rbac.authorization.k8s.io
---
# 测试用例
# k create ns namespace1
# k create ns namespace2
# kubectl -n namespace1 run test-nginx --image=nginx --restart=Always
# kubectl -n namespace2 run test-nginx --image=nginx --restart=Always
# 获取 token
# SECRET_NAME=$(kubectl get serviceaccount view-all-service-account -n namespace1 -o jsonpath="{.secrets[0].name}")
# kubectl get secret $SECRET_NAME -n namespace1 -o jsonpath="{.data.token}" | base64 --decode
# 获取 token
# kubectl -n namespace1 describe secret $(kubectl -n namespace1 get serviceaccount view-all-service-account -o jsonpath="{.secrets[0].name}")
8. 配置 ingress-nginx
需要配置自定义的域名:dash.k8s.io,使用 ingress-nginx:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: kube-ingress
namespace: kubernetes-dashboard
annotations:
kubernetes.io/ingress.class: nginx
nginx.kubernetes.io/ingress.class: "nginx" # 指定 nginx
# 默认为 true,启用 TLS 时,http请求会 308 重定向到https
nginx.ingress.kubernetes.io/ssl-redirect: "true"
# 默认为 http,开启后端服务使用 proxy_pass https://协议
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
tls:
- hosts:
- dash.k8s.io
secretName: kubernetes-dashboard-certs
rules:
- host: dash.k8s.io # 域名配置
http:
paths:
- path: /
backend:
serviceName: kubernetes-dashboard
servicePort: 443
注意:nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
默认为 HTTP
因为 ingress-nginx 代理 kubernetes-dashboard 443 端口,必须要设置 nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
,若不设置则无法访问。
区别在于 proxy_pass
如果设置 backend-protocal = http
proxy_pass http://upstream_balancer;
如果设置 backend-protocal = https
proxy_pass https://upstream_balancer;
9. dashboard 登陆使用
请求地址:https://dash.k8s.io:8884/#/login
将配置好的 token 输入到界面中,即可登陆。
10. 参考
11. 关于作者
我的博客:https://yezihack.github.io
欢迎关注我的微信公众号【空树之空】,一日不学则面目可憎也,吾学也。