背景
前面文章介绍了ingress-nginx相关内容
这就是k8s系列之五 (使用ingress-nginx暴露服务)
埋头过坎,公众号:埋头过坎这就是k8s系列之五(使用ingress-nginx暴露服务)
以及介绍了TLS证书相关内容
这就是TLS系列之二 (证书)
埋头过坎,公众号:埋头过坎这就是TLS系列之二(证书)
本文就利用ingress-nginx-controller及自制的TLS证书签名来实现kubernetes dashboard的服务暴露。最后的效果如下:
操作步骤
安装kubernetes dashboard的过程主要包括以下几部分:
1. 下载kubernetes-dashboard的资源描述文件
2. 修改deployment部分的容器参数, 添加使用自定义证书文件的相关参数。(具体见下面具体实施记录)
3. 注释掉创建kubernetes-dashboard-certs Secret部分的内容。
4. 创建自签名的证书, 注意主题部分的域名设置。创建好证书后,放置到$HOME/certs目录下。
5. 基于上面创建的证书创建kubernetes-dashboard-certs Secret,注意要放到kubernets-dashboard命名空间。
6. 创建ingress文件, 指定对应的hosts、tls及路由规则配置。(具体见下面具体实施记录)
7. 应用kubernetes-dashboard的资源描述文件, 创建相关service、demployment、pod等资源。
8. 创建dashboard对应的ingress, 创建ingress服务。
9. 创建服务账号及集群角色绑定资源,并应用。
10. 获取用于登录的token。
11. 通过浏览器, 使用token登录服务, 验证服务的正确性。
具体实施
step 1: 下载kubernetes-dashboard的资源描述文件, 使用的是v2.0.5版本
[root@host01 dashboard]# cd 2.0.5
[root@host01 2.0.5]# wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.5/aio/deploy/recommended.yaml
step 2: 修改deployment部分的容器参数, 添加使用自定义证书文件的相关参数
spec:
containers:
- name: kubernetes-dashboard
image: kubernetesui/dashboard:v2.0.5
imagePullPolicy: Always
ports:
- containerPort: 8443
protocol: TCP
args:
- --tls-cert-file=/tls.crt # 证书
- --tls-key-file=/tls.key # 私钥
- --auto-generate-certificates # 保留备用
--token-ttl=7200 # 设置token超时时间
- --namespace=kubernetes-dashboard
step 3: 注释掉创建kubernetes-dashboard-certs Secret部分的内容
#apiVersion: v1
#kind: Secret
#metadata:
# labels:
# k8s-app: kubernetes-dashboard
# name: kubernetes-dashboard-certs
# namespace: kubernetes-dashboard
#type: Opaque
step 4: 创建自签名的证书
openssl genrsa -des3 -out ca.key 2048
openssl req -new -key ca.key -out ca.csr
openssl x509 -req -days 3650 -in ca.csr -signkey ca.key -out ca.crt
[root@host01 xx]# ls
ca.crt ca.csr ca.key privateKey.txt
[root@host01 xx]# cp ca.key ca.crt ~/certs/ #复制到$HOME/certs
step 5: 基于上面创建的证书创建kubernetes-dashboard-certs Secret
kubectl create secret generic kubernetes-dashboard-certs --from-file=$HOME/certs -n kubernetes-dashboard
step 6: 创建ingress文件, 指定对应的hosts、tls及路由规则配置
[root@host01 2.0.5]# cat dashboard-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: k8s-dashboard
namespace: kubernetes-dashboard
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/secure-backends: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
tls:
- hosts:
- host01
- host02
secretName: kubernetes-dashboard-certs
rules:
- host: host01
http:
paths:
- path:
pathType: Prefix
backend:
service:
name: kubernetes-dashboard
port:
number: 443
- host: host02
http:
paths:
- path:
pathType: Prefix
backend:
service:
name: kubernetes-dashboard
port:
number: 443
step 7: 应用kubernetes-dashboard的资源描述文件
[root@host01 2.0.5]# kubectl apply -f recommended.yaml
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
namespace/kubernetes-dashboard configured
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created
step 8: 创建dashboard对应的ingress
[root@host01 2.0.5]# kubectl apply -f dashboard-ingress.yaml
ingress.networking.k8s.io/k8s-dashboard created
step 9: 创建服务账号及集群角色绑定资源
[root@host01 2.0.5]# cat <<EOF | kubectl apply -f -
> apiVersion: v1
> kind: ServiceAccount
> metadata:
> name: admin-user
> namespace: kubernetes-dashboard
> EOF
serviceaccount/admin-user created
[root@host01 2.0.5]# cat <<EOF | kubectl apply -f -
> 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
> EOF
clusterrolebinding.rbac.authorization.k8s.io/admin-user created
step 10: 获取用于登录的token
[root@host01 2.0.5]# kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
step 11: 通过浏览器, 使用token登录服务, 验证服务的正确性
输入 step 10中的token即可登录成功, 说明服务安装成功了。
排错记录
Error 1: 创建ingress时失败,错误大概内容如下:
[root@host01 2.0.5]# kubectl apply -f dashboard-ingress.yaml
Error from server (InternalError): error when creating "dashboard-ingress.yaml": Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": Post "https://ingress-nginx-controller-admission.ingress-nginx.svc:443/networking/v1beta1/ingresses?timeout=10s": x509: certificate is valid for kubernetes, kubernetes.default, kubernetes.default.svc, kubernetes.default.svc.cluster.local, lb-apiserver.kubernetes.local, localhost, host01, host01.cluster.local, host01, host02, host02.cluster.local, host02, not ingress-nginx-controller-admission.ingress-nginx.svc
解决办法是删除掉老的ingress-nginx-controller-admission服务, 重新安装,如下:
[root@host01 2.0.5]# kubectl delete -n ingress-nginx service/ingress-nginx-controller-admission
[root@host01 ~]# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.41.2/deploy/static/provider/baremetal/deploy.yaml
再安装ingress即可。
Error 2: 使用letsencrypt clusterissuers颁发证书失败,如下:
# 创建的Ingress中的annotation带上cert-manager
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: k8s-dashboard
namespace: kubernetes-dashboard
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/rewrite-target:
nginx.ingress.kubernetes.io/secure-backends: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
cert-manager.io/cluster-issuer: "letsencrypt-staging"
安装时失败了,错误信息如下:
Message: The certificate request has failed to complete and will be retried: Failed to wait for order resource "kubernetes-dashboard-certs-2dm4v-441423537" to become ready: order is in "errored" state: Failed to create Order: 400 urn:ietf:params:acme:error:rejectedIdentifier: Error creating new order :: Cannot issue for "host01": The ACME server refuses to issue a certificate for this domain name, because it is forbidden by policy (and 1 more problems. Refer to sub-problems for more information.)
原因是笔者使用的域名是内部的域名,而且后缀是受政策保护的, 需要走一定流程才可以使用Letsencrypt的服务。解决方案是切换为上面自签名证书。
总结
有了前面基于ingress-nginx暴露服务及TLS证书还有letsencrypt的文章的介绍, 在类似安装kubernetes dashboard这样的应用场景下, 一切就显得不那么困难了。 日拱一卒, 厚积薄发。
参考资料
1. kubernetes dashboard官方安装文档
kubernetes dashboard官方安装文档
https://github.com/kubernetes/dashboard/blob/master/docs/user/installation.md
2. nginx ingress controller安装官方文档
nginx ingress controller安装官方文档
https://kubernetes.github.io/ingress-nginx/deploy/
3. cnblog dashboard v2.0安装文章
dashboard v2.0安装
https://www.cnblogs.com/tianleblog/p/12157499.html