部署dashboard
创建yaml文件
vi kubernetes-dashboard.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ------------------- Dashboard Secret ------------------- #
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-certs
namespace: kube-system
type: Opaque
---
# ------------------- Dashboard Service Account ------------------- #
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
---
# ------------------- Dashboard Role & Role Binding ------------------- #
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
rules:
# Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create"]
# Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["create"]
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
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 from heapster.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard-minimal
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system
---
# ------------------- Dashboard Deployment ------------------- #
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
containers:
- name: kubernetes-dashboard
image: kubernets/kubernetes-dashboard-amd64:v1.8.3
ports:
- containerPort: 8443
protocol: TCP
args:
- --authentication-mode=basic
- --auto-generate-certificates
# Uncomment the following line to manually specify Kubernetes API server Host
# If not specified, Dashboard will attempt to auto discover the API server and connect
# to it. Uncomment only if the default does not work.
# - --apiserver-host=http://my-address:port
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
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
---
# ------------------- Dashboard Service ------------------- #
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
ports:
- port: 443
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
kubectl create secret generic kubernetes-dashboard-certs --from-file=/certs -n kube-system
kubectl apply -f kubernetes-dashboard.yaml
访问地址
https://10.167.130.205:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login
system:anonymous问题
访问dashboard网页时,可能出现下面这种报错:
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "services \"https:kubernetes-dashboard:\" is forbidden: User \"system:anonymous\" cannot get services/proxy in the namespace \"kube-system\"",
"reason": "Forbidden",
"details": {
"name": "https:kubernetes-dashboard:",
"kind": "services"
},
"code": 403
}
Kubernetes API Server新增了–anonymous-auth选项,允许匿名请求访问secure port。没有被其他authentication方法拒绝的请求即Anonymous requests, 这样的匿名请求的username为system:anonymous, 归属的组为system:unauthenticated。并且该选项是默认的。这样一来,当采用chrome浏览器访问dashboard UI时很可能无法弹出用户名、密码输入对话框,导致后续authorization失败。为了保证用户名、密码输入对话框的弹出,需要将–anonymous-auth设置为false。
解决方法:在api-server配置文件中添加–anonymous-auth=false
KUBE_APISERVER_OPTS="--logtostderr=true \
--v=4 \
--etcd-servers=https://10.167.130.205:2379,https://10.167.130.206:2379,https://10.167.130.210:2379 \
--bind-address=10.167.130.205 \
--secure-port=6443 \
--advertise-address=10.167.130.205 \
--allow-privileged=true \
--service-cluster-ip-range=10.0.0.0/24 \
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota,NodeRestriction \
--authorization-mode=RBAC,Node \
--anonymous-auth=false \ # 不接受匿名访问,若为true,则表示接受,此处设置为false,便于dashboard访问
--basic-auth-file=/opt/kubernetes/cfg/basic_auth_file \
--enable-bootstrap-token-auth \
--token-auth-file=/opt/kubernetes/cfg/token.csv \
--service-node-port-range=30000-50000 \
--tls-cert-file=/opt/kubernetes/ssl/server.pem \
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \
--etcd-cafile=/opt/etcd/ssl/ca.pem \
--etcd-certfile=/opt/etcd/ssl/server.pem \
--etcd-keyfile=/opt/etcd/ssl/server-key.pem"
Unauthorized问题
解决了上面那个问题之后,再度访问dashboard页面,发现还是有问题,出现下面这个问题:
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "Unauthorized",
"reason": "Unauthorized",
"code": 401
}
解决方法:
新建/etc/kubernetes/basic_auth_file文件,并在其中添加:
admin,admin,1002
文件内容格式:password,username,uid
然后在api-server配置文件(即上面的配置文件)中添加
–basic-auth-file=/opt/kubernetes/cfg/basic_auth_file \
保存重启kube-apiserver:
systemctl daemon-reload
systemctl enable kube-apiserver
systemctl start kube-apiserver
systemctl status kube-apiserver
最后在kubernetes上执行下面这条命令:
kubectl create clusterrolebinding login-dashboard-admin --clusterrole=cluster-admin --user=admin
将访问账号名admin与kubernetes中指定的cluster-admin关联,获得访问权限。
再次访问即可
https://10.167.130.205:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login
参考文章
Kubernetes dashboard1.8.0 WebUI安装与配置
dashboard登录
默认只有两种方式 kubeconfig和token登录
kubeconfig方式不考虑
token登录
新建admin-user用户
vi admin-user
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
给admin-user绑定到集群管理员组
vi admin-role
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: kube-system
查看秘钥可以看到admin-user-token这个秘钥文件
kubectl get secret --all-namespaces
NAMESPACE NAME TYPE DATA AGE
default default-token-s5l89 kubernetes.io/service-account-token 3 5d16h
kube-public default-token-zmfvj kubernetes.io/service-account-token 3 5d16h
kube-system admin-user-token-brfdq kubernetes.io/service-account-token 3 11s
kube-system default-token-tk8vd kubernetes.io/service-account-token 3 15h
kube-system kubernetes-dashboard-certs Opaque 0 15h
kube-system kubernetes-dashboard-key-holder Opaque 2 15h
kube-system kubernetes-dashboard-token-j5q8g kubernetes.io/service-account-token 3 15h
查看秘钥的详细信息
kubectl describe secrets -n kube-system admin-user-token-brfdq
可以看到有token直接复制这一长串到dashboard里的登录即可需要注意token前边有空格经测试有的需要粘贴空格可以base64加密一下也行
basic登录
除了token还可以开启basic基本身份验证就是用户名密码登录dashboard
修改kubernetes-dashboard.yaml文件,添加args:
args:
- --authentication-mode=basic #修改身份验证为basic
- --auto-generate-certificates
# Uncomment the following line to manually specify Kubernetes API server Host
# If not specified, Dashboard will attempt to auto discover the API server and connect
# to it. Uncomment only if the default does not work.
# - --apiserver-host=http://my-address:port
volumeMounts:
- name: kubernetes-dashboard-certs
由于之前apiserver加过认证文件了用户名admin密码admin
访问dashboard
https://10.167.130.205:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login
需要输入两次用户名密码,由于之前解决访问403的问题,与api建立连接需要带授权的用户过去,这里需要输入一次用户名密码,才可以跳转到dashboard页面。
参考文章
addon-dashboard
k8s rbac 多租户控制权限实现
kubernetes API Server 权限管理实践
kubectl logs exec 等报403
root@master:~# kubectl logs nginx-7cdbd8cdc9-9572f
Error from server (Forbidden): Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) ( pods/log nginx-7cdbd8cdc9-
9572f)
这个官方有解释是因为
默认情况下,未被其他已配置的身份验证方法拒绝的对kubelet的HTTPS端点的请求将被视为匿名请求,并且会给出用户名system:anonymous 和组system:unauthenticated。禁用匿名访问401 Unauthorized并向未经身份验证的请求发送响应
kubectl logs去请求kubelet带过去的用户是system:anonymous但并没有这个role也没有任何权限会返回403
我们需要做的的操作修改kubelet的验证参数,禁用anonymous
node节点操作
[root@node1 cfg]# pwd
/opt/kubernetes/cfg
[root@node1 cfg]# cat kubelet.config
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 10.167.130.206
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS: ["10.0.0.2"]
clusterDomain: cluster.local.
failSwapOn: false
authentication:
anonymous:
enabled: false #之前是true改为false禁用anonymous
————————————————————————————————————
[root@node1 cfg]# pwd
/opt/kubernetes/cfg
[root@node1 cfg]# vi kubelet
KUBELET_OPTS="--logtostderr=true \
--v=4 \
--hostname-override=10.167.130.206 \
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \
--bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \
--config=/opt/kubernetes/cfg/kubelet.config \
--cert-dir=/opt/kubernetes/ssl \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \ #添加这一行ca是master上生成的根证书
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"
systemctl restart kubelet
systemctl status kubelet
再次尝试查看logs
kubectl logs nginx-7cdbd8cdc9-9572f
error: You must be logged in to the server (the server has asked for the client to provide credentials
服务器要求提供凭证这对我们来说是这个好消息
我们修改master的apiserver配置文件带上证书去访问node的kubelet
[root@node cfg]# pwd
/opt/kubernetes/cfg
[root@node cfg]# vi kube-apiserver
KUBE_APISERVER_OPTS="--logtostderr=true \
--v=4 \
--etcd-servers=https://10.167.130.205:2379,https://10.167.130.206:2379,https://10.167.130.210:2379 \
--bind-address=10.167.130.205 \
--secure-port=6443 \
--advertise-address=10.167.130.205 \
--allow-privileged=true \
--service-cluster-ip-range=10.0.0.0/24 \
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota,NodeRestriction \
--authorization-mode=RBAC,Node \
--anonymous-auth=false \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \
--basic-auth-file=/opt/kubernetes/cfg/basic_auth_file \
--enable-bootstrap-token-auth \
--token-auth-file=/opt/kubernetes/cfg/token.csv \
--service-node-port-range=30000-50000 \
--kubelet-client-certificate=/opt/kubernetes/ssl/server.pem \#添加访问node kubelet的证书公钥
--kubelet-client-key=/opt/kubernetes/ssl/server-key.pem \#添加访问node kubelet的证书私钥
--tls-cert-file=/opt/kubernetes/ssl/server.pem \
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \
--etcd-cafile=/opt/etcd/ssl/ca.pem \
--etcd-certfile=/opt/etcd/ssl/server.pem \
--etcd-keyfile=/opt/etcd/ssl/server-key.pem"
systemctl restart kube-apiserver
systemctl status kube-apiserver
再次尝试查看logs
kubectl logs nginx-7cdbd8cdc9-9572f
Error from server (Forbidden): Forbidden (user=kubernetes, verb=get, resource=nodes, subresource=proxy) ( pods/log nginx-7cdbd8cdc9-9572f)
提示我们user kubernetes是没有权限的
我们通过创建yaml文件来进行权限授权
vi apiserver-to-kubelet-rbac.yml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:kube-apiserver-to-kubelet
rules:
- apiGroups:
- ""
resources:
- nodes/proxy
- nodes/stats
- nodes/log
- nodes/spec
- nodes/metrics
verbs:
- "*"
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: kube-apiserve
namespace: ""
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-apiserver-to-kubelet
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: kubernetes #这个kubernetes是我们server.pem和server-key.pem CN里的用户
脑补了一下验证k8s会把证书里的CN内容当做用户O当做用户组
再次尝试查看logs
kubectl logs nginx-7cdbd8cdc9-9572f
[root@node home]# kubectl logs -n kube-system heapster-c679b85f9-kn4vv | head -n 3
I0110 02:48:13.027198 1 heapster.go:71] /heapster --source=kubernetes:https://kubernetes.default --sink=influxdb:http://monitoring-i
nfluxdb.kube-system.svc:8086I0110 02:48:13.027290 1 heapster.go:72] Heapster version v1.3.0-beta.1
I0110 02:48:13.027636 1 configs.go:61] Using Kubernetes client with master "https://kubernetes.default" and version v1
已成功返回了log内容exec可以去dashboard里查看