diff --git a/docs/guide/dashboard-1.8.2.md b/docs/guide/dashboard-1.8.2.md new file mode 100644 index 000000000..21d762898 --- /dev/null +++ b/docs/guide/dashboard-1.8.2.md @@ -0,0 +1,148 @@ +## dashboard + +本文档基于 dashboard 1.8.2版本,k8s版本 1.9.x。 + +### 部署 + +如果之前已按照本项目部署dashboard1.6.3,先删除旧版本:`kubectl delete -f /etc/ansible/manifests/dashboard/` + +1.8.2配置文件参考[官方文档](https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml) + ++ 增加了通过`api-server`方式访问dashboard ++ 增加了`NodePort`方式暴露服务,这样集群外部可以使用 `https://NodeIP:NodePort` (注意是https不是http,区别于1.6.3版本) 直接访问 dashboard,生产环境建议关闭该访问途径。 + +安装部署 + +``` bash +# 部署dashboard 主yaml配置文件 +$ kubectl create -f /etc/ansible/manifests/dashboard/1.8.2/kubernetes-dashboard.yaml +# 部署基本密码认证配置[可选],密码文件位于 /etc/kubernetes/ssl/basic-auth.csv +$ kubectl create -f /etc/ansible/manifests/dashboard/ui-admin-rbac.yaml +$ kubectl create -f /etc/ansible/manifests/dashboard/ui-read-rbac.yaml +``` + +### 验证 + +``` bash +# 查看pod 运行状态 +kubectl get pod -n kube-system | grep dashboard +kubernetes-dashboard-7c74685c48-9qdpn 1/1 Running 0 22s +# 查看dashboard service +kubectl get svc -n kube-system|grep dashboard +kubernetes-dashboard NodePort 10.68.219.38 443:24108/TCP 53s +# 查看集群服务 +kubectl cluster-info|grep dashboard +kubernetes-dashboard is running at https://192.168.1.1:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy +# 查看pod 运行日志,关注有没有错误 +kubectl logs kubernetes-dashboard-7c74685c48-9qdpn -n kube-system +``` + +### 访问 + +因为dashboard 作为k8s 原生UI,能够展示各种资源信息,甚至可以有修改、增加、删除权限,所以有必要对访问进行认证和控制,本项目部署的集群有以下安全设置:详见 [apiserver配置模板](../../roles/kube-master/templates/kube-apiserver.service.j2) + ++ 启用 `TLS认证` `RBAC授权`等安全特性 ++ 关闭 apiserver非安全端口8080的外部访问`--insecure-bind-address=127.0.0.1` ++ 关闭匿名认证`--anonymous-auth=false` ++ 补充启用基本密码认证 `--basic-auth-file=/etc/kubernetes/ssl/basic-auth.csv`,[密码文件模板](../../roles/kube-master/templates/basic-auth.csv.j2)中按照每行(密码,用户名,序号)的格式,可以定义多个用户 + +新版本dashboard登陆可以分为两步,类似流行的双因子登陆系统: + ++ 第一步通过api-server本身安全认证流程,与之前1.6.3版本相同 ++ 第二步通过dashboard自带的登陆流程,使用`Kubeconfig` `Token`等方式登陆 + +#### 1. 临时访问:使用 `https://NodeIP:NodePort` 方式直接访问 dashboard,生产环境建议关闭该途径 +打开页面出现dashboard 新版本自带的登陆页面,我们选择“令牌(Token)”方式登陆,关于令牌的获取[参考](https://github.com/kubernetes/dashboard/wiki/Creating-sample-user) + +``` bash +# 创建Service Account 和 ClusterRoleBinding +$ kubectl create -f /etc/ansible/manifests/dashboard/1.8.2/admin-user-sa-rbac.yaml +# 获取 Bearer Token,找到输出中 ‘token:’ 开头那一行 +$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}') +``` + +#### 2. 用户+密码访问:安全性比证书方式差点,务必保管好密码文件`basic-auth.csv` + +- 这里演示两种权限,使用admin 登陆dashboard拥有所有权限,使用readonly 登陆后仅查看权限,首先在 master节点文件 `/etc/kubernetes/ssl/basic-auth.csv` 确认用户名和密码,如果要增加或者修改用户,修改保存该文件后记得逐个重启你的master 节点 +- 为了演示用户密码访问,如果你已经完成证书访问方式,你可以在浏览器删除证书,或者访问时候浏览器询问你证书时不选证书 +- 2.1 设置用户admin 的RBAC 权限,如下运行配置文件 `kubectl create -f ui-admin-rbac.yaml` + +``` bash +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: ui-admin +rules: +- apiGroups: + - "" + resources: + - services + - services/proxy + verbs: + - '*' + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: ui-admin-binding + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: ui-admin +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: admin +``` +- 2.2 设置用户readonly 的RBAC 权限,如下运行配置文件 `kubectl create -f ui-read-rbac.yaml` + +``` bash +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: ui-read +rules: +- apiGroups: + - "" + resources: + - services + - services/proxy + verbs: + - get + - list + - watch + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: ui-read-binding + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: ui-read +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: readonly +``` +- 2.3 访问 `https://x.x.x.x:6443/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy` 使用 admin登陆拥有所有权限,比如删除某个部署;使用 readonly登陆只有查看权限,尝试删除某个部署会提示错误 `forbidden: User \"readonly\" cannot delete services/proxy in the namespace \"kube-system\"` + +- dashboard自带的登陆流程同上 + +#### 3. 证书访问:最安全的方式,配置较复杂 +- 使用集群CA 生成客户端证书,可以根据需要生成权限不同的证书,这里为了演示直接使用 kubectl使用的证书和key(在03.kubectl.yml阶段生成),该证书拥有所有权限 +- 指定格式导出该证书,进入`/etc/kubernetes/ssl`目录,使用命令`openssl pkcs12 -export -in admin.pem -inkey admin-key.pem -out kube-admin.p12` 提示输入证书密码和确认密码,可以用密码再增加一层保护,也可以直接回车跳过,完成后目录下多了 `kube-admin.p12`文件,将它分发给授权的用户 +- 用户将 `kube-admin.p12` 双击导入证书即可,`IE` 和`Chrome` 中输入`https://x.x.x.x:6443/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy` 或者 `https://x.x.x.x:6443/ui` 即可访问。补充:最新firefox需要在浏览器中单独导入 [选项] - [隐私与安全] - [证书/查看证书] - [您的证书] 页面点击 [导入] 该证书 +- dashboard自带的登陆流程同上 + +### 小结 + ++ dashboard 访问控制实现较复杂,文档中给出的例子也有助于你理解 RBAC的灵活控制能力,当然最好去[官方文档](https://kubernetes.io/docs/admin/authorization/rbac/)学习一下,这块篇幅不长 ++ 由于还未部署 Heapster 插件,当前 dashboard 不能展示 Pod、Nodes 的 CPU、内存等 metric 图形,后续部署 heapster后自然能够看到 ++ 本文中的权限设置仅供演示用,生产环境请在此基础上修改成适合你安全需求的方式 + +[前一篇](kubedns.md) -- [目录](index.md) -- [后一篇](heapster.md) diff --git a/docs/guide/dashboard.md b/docs/guide/dashboard.md index c97fbb4ed..c25790b42 100644 --- a/docs/guide/dashboard.md +++ b/docs/guide/dashboard.md @@ -1,6 +1,6 @@ ## dashboard -本文档基于 dashboard 1.6.3版本,目前 dashboard 已出 1.8.0版本,在安全控制方面已有很大改进,后续更新新版本说明。 +本文档基于 dashboard 1.6.3版本,目前 dashboard 已出 1.8.x版本,在安全控制方面已有很大改进,升级dashboard 1.8.2请看[这里](dashboard-1.8.2.md)。 ### 部署 diff --git a/manifests/dashboard/1.8.2/admin-user-sa-rbac.yaml b/manifests/dashboard/1.8.2/admin-user-sa-rbac.yaml new file mode 100644 index 000000000..667de889c --- /dev/null +++ b/manifests/dashboard/1.8.2/admin-user-sa-rbac.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: admin-user + namespace: kube-system + +--- +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 + diff --git a/manifests/dashboard/1.8.2/kubernetes-dashboard.yaml b/manifests/dashboard/1.8.2/kubernetes-dashboard.yaml new file mode 100644 index 000000000..e1b394dff --- /dev/null +++ b/manifests/dashboard/1.8.2/kubernetes-dashboard.yaml @@ -0,0 +1,171 @@ +# 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. + +# Configuration to deploy release version of the Dashboard UI compatible with +# Kubernetes 1.8. +# +# Example usage: kubectl create -f + +# ------------------- 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: k8s.gcr.io/kubernetes-dashboard-amd64:v1.8.2 + image: mirrorgooglecontainers/kubernetes-dashboard-amd64:v1.8.2 + ports: + - containerPort: 8443 + protocol: TCP + args: + - --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 + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: Reconcile + name: kubernetes-dashboard + namespace: kube-system +spec: + ports: + - port: 443 + targetPort: 8443 + selector: + k8s-app: kubernetes-dashboard + type: NodePort