dashboard 1.8
新版的dashboard在安全方面下了不少功夫,也提供了多种认证方式。以下就踩过的坑来进行一下介绍。dashboard官方文档:https://github.com/kubernetes/dashboard/wikiInstallationRecommended setup访问dashboard为用户授权Installationdashboard有两个...
新版的dashboard在安全方面下了不少功夫,也提供了多种认证方式。以下就踩过的坑来进行一下介绍。
dashboard官方文档:
https://github.com/kubernetes/dashboard/wiki
Installation
dashboard有两个发行版本,offical和deployment. 这里使用offical版本。
dashboard的安装文档中提到了3中方式:
1. quick setup
快速安装,但是只能通过kubectl proxy
的方式使用本机地址(localhost,127.0.0.1)来进行登录。
2. recommended setup
常规安装,可以通过NodePort
和ingress
的方式访问。
3. alternative setup
采用http协议访问,出于安全性考虑,就没使用这个了。
快速安装和常规安装几乎一模一样,唯一不同的是采用常规安装的时候,需要先生成dashboard的服务器端证书,然后通过configMap
挂载到dashboard容器中。
Recommended setup
第一步,生成证书:
mkdir certs && cd certs
openssl genrsa -out dashboard.key 2048
openssl req -new -key dashboard.key -out dashboard.csr -config dashboard-csr.conf
openssl x509 -req -in dashboard.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out dashboard.crt -days 1000 -extensions v3_ext -extfile dashboard-csr.conf
dashboard-csr.conf
文件内容如下:
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[ dn ]
C = CN
L = SZ
O = Fonsview
CN = 172.16.6.79
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = kubernetes-dashboard
DNS.2 = kubernetes-dashboard.kube-system
DNS.3 = kubernetes-dashboard.kube-system.svc
DNS.4 = kubernetes-dashboard.kube-system.svc.cluster
DNS.5 = kubernetes-dashboard.kube-system.svc.cluster.local
DNS.6 = dashboard.k8s.fonsview.com
IP.1 = 172.16.6.79
IP.2 = 172.16.6.47
IP.3 = 172.16.6.249
[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names
这里我直接使用了kubernetes 里面的ca证书,用浏览器访问的时候会提示该网站证书不可靠
. 官方推荐是去Let’s Encrypt 网站中生成自己的证书。
将创建好的证书,添加到Secret
中.
kubectl create secret generic kubernetes-dashboard-certs --from-file=./certs -n kube-system
修改kubernetes-dashboard的yaml文件:
kind: Deployment
apiVersion: apps/v1beta2
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: gcr.io/google_containers/kubernetes-dashboard-amd64:v1.8.0
ports:
- containerPort: 8443
protocol: TCP
args:
# - --auto-generate-certificates
- --tls-key-file=dashboard.key
- --tls-cert-file=dashboard.crt
- --authentication-mode=basic
# 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
添加--tls-key-file
和--tls-cert-file
.
如果要采用用户名和密码的认证形式,需要加上--authentication-mode=basic
。 默认是使用token认证。
Note: 这里要注意证书的路径
然后执行
kubectl apply -f kubernetes-dashboard.yaml
不出意外的话,可以用命令看到pod能正常启动:
[root@walker-1 kubernetes]# kubectl get po -o wide --namespace=kube-system | grep dashboard
kubernetes-dashboard-68b6699b8-mrvfl 1/1 Running 0 5s 192.168.187.202 walker-1.novalocal
访问dashboard
修改dashboard的service, 改为NodePort
的访问形式
[root@walker-1 kubernetes]# kubectl describe svc kubernetes-dashboard -n kube-system
Name: kubernetes-dashboard
Namespace: kube-system
Labels: k8s-app=kubernetes-dashboard
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"k8s-app":"kubernetes-dashboard"},"name":"kubernetes-dashboard","namespace":...
Selector: k8s-app=kubernetes-dashboard
Type: NodePort
IP: 10.103.175.251
Port: <unset> 443/TCP
TargetPort: 8443/TCP
NodePort: <unset> 32723/TCP
Endpoints: 192.168.187.202:8443
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
至此就可以通过 https://<nodeip>:<nodeport>
的方式来访问dashboard了
官网上还提及了通过apiserver和kubectl proxy
的方式来访问页面。据个人实际使用,kubectl proxy
默认监听127.0.0.1。只能通过本地地址去访问。当然可以绑定到其他地址,但是页面无法进行登录操作。这在文档中有描述:
NOTE: Dashboard should not be exposed publicly using kubectl proxy command as it only allows HTTP connection. For domains other than localhost and 127.0.0.1 it will not be possible to sign in. Nothing will happen after clicking Sign in button on login page.
通过apiserver端口来访问时,会出现403权限问题。提示是以匿名用户身份访问的,权限拒绝。但是要让浏览器支持提供身份请求显然不现实,所以也放弃了。
为用户授权
如果使用token的认证方式来登录,也是可行的。不过需要为service account添加合适的权限。如果想直接跳过认证,那么默认是以kubernetes-dashboard
的service account账户来访问。如果不做配置,kubernetes-dashboard
只能访问很少一部分资源。官方文档中提供了将所有权限赋予kubernetes-dashboard
的配置。
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard
labels:
k8s-app: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system
将用户绑定到 cluster-admin权限组。这样一来kubernetes-dashboard就能访问平台所有资源。这样做很方便,但有安全风险,不建议。
token认证方案已经很好了,但是大佬们显然更倾向使用账户+密码的方式认证。具体配置步骤如下:
- 在dashboard的deployment配置中,添加
--authentication-mode=basic
修改
apiserver
的配置,在启动参数中添加密码文件、ABAC
认证以及指定ABAC策略文件。- 编辑密码文件
密码文件的格式如下:
- 编辑密码文件
password,user,uid,"group1, group2..."
详情可参考:https://kubernetes.io/docs/admin/authentication/#static-password-file
为了方便起见,我创建了/etc/kubernetes/dashboard 文件夹
[root@walker-1 ~]# cd /etc/kubernetes/dashboard/
[root@walker-1 dashboard]# cat dashboard.basic
password,walker,123123,system:authenticated
Note: 一定要为用户添加
system:authenticated
组,否则默认为system:unauthenticated
组,用户被视为匿名用户,丧失访问权限。
- 编辑ABAC策略文件
[root@walker-1 dashboard]# cat dashboard-abac.json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "walker", "namespace": "*", "resource": "*", "apiGroup": "*"}}
这里把所有权限放开给walker用户。
有关ABAC认证参考:https://kubernetes.io/docs/admin/authorization/abac/
Note: 策略文件中的用户名要和密码文件对应。
- 修改apiserver配置
apiVersion: v1
kind: Pod
metadata:
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ""
creationTimestamp: null
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
- kube-apiserver
- --service-cluster-ip-range=10.96.0.0/12
- --service-account-key-file=/etc/kubernetes/pki/sa.pub
- --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
- --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
- --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
- --enable-bootstrap-token-auth=true
- --admission-control=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota
- --advertise-address=172.16.6.47
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
- --insecure-port=0
- --requestheader-username-headers=X-Remote-User
- --requestheader-extra-headers-prefix=X-Remote-Extra-
- --requestheader-allowed-names=front-proxy-client
- --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
- --allow-privileged=true
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
- --secure-port=6443
- --requestheader-group-headers=X-Remote-Group
- --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
- --authorization-mode=Node,RBAC,ABAC
- --authorization-policy-file=/etc/kubernetes/dashboard/dashboard-abac.json
- --basic-auth-file=/etc/kubernetes/dashboard/dashboard.basic
- --etcd-servers=http://walker-1:2379,http://walker-2:2379,http://walker-4:2379
image: gcr.io/google_containers/kube-apiserver-amd64:v1.8.1
livenessProbe:
failureThreshold: 8
httpGet:
host: 127.0.0.1
path: /healthz
port: 6443
scheme: HTTPS
initialDelaySeconds: 15
timeoutSeconds: 15
name: kube-apiserver
resources:
requests:
cpu: 250m
volumeMounts:
- mountPath: /etc/kubernetes/pki
name: k8s-certs
readOnly: true
- mountPath: /etc/kubernetes/dashboard
name: k8s-dashboard
readOnly: true
- mountPath: /etc/ssl/certs
name: ca-certs
readOnly: true
- mountPath: /etc/pki
name: ca-certs-etc-pki
readOnly: true
hostNetwork: true
volumes:
- hostPath:
path: /etc/kubernetes/pki
type: DirectoryOrCreate
name: k8s-certs
- hostPath:
path: /etc/kubernetes/dashboard
type: DirectoryOrCreate
name: k8s-dashboard
- hostPath:
path: /etc/ssl/certs
type: DirectoryOrCreate
name: ca-certs
- hostPath:
path: /etc/pki
type: DirectoryOrCreate
name: ca-certs-etc-pki
status: {}
添加了ABAC
认证方式,--authorization-policy-file
以及--basic-auth-file
。将/etc/kubernetes/dashboard 挂载到容器中。
- 重启apiserver, 使用添加的用户进行访问。
先使用一个错误的密码试试认证有没有生效:
在使用正确密码登录:
至此密码认证方式配置完毕。
更多推荐
所有评论(0)