文章目录
知识回顾
要点回顾一:API 对象
第三阶段:可以分成三个部分,第一部分讲的是 PersistentVolume、StatefulSet 等 API 对象。
【k8s】PersistentVolume解决数据持久化问题(十三) PersistentVolume 简称 PV,是 Kubernetes 对持久化存储的抽象,代表了 LocalDisk、NFS、Ceph 等存储设备,和 CPU、内存一样,属于集群的公共资源。
因为不同存储设备之间的差异很大,为了更好地描述 PV 特征,就出现了 StorageClass,它的作用是分类存储设备,让我们更容易去选择 PV 对象。
PV 一般由系统管理员来创建,我们如果要使用 PV 就要用 PVC(PersistentVolumeClaim)去申请,说清楚需求的容量、访问模式等参数,然后 Kubernetes 就会查找最合适的 PV 分配给我们使用。
【k8s】PersistentVolume 使用网络共享存储-NFS(十四) 手动创建 PV 的工作量很大,麻烦而且容易出错,所以就有了“动态存储卷”的概念,需要在 StorageClass 里绑定一个 Provisioner 对象,由它来代替人工,根据 PVC 自动创建出符合要求的 PV。
有了 PV 和 PVC,我们就可以在 Pod 里用persistentVolumeClaim
来引用 PVC,创建出可供容器使用的 Volume,然后在容器里用volumeMounts
把它挂载到某个路径上,这样容器就可以读写 PV,实现数据的持久化存储了。
【k8s】StatefulSet管理有状态的应用(十五) 持久化存储的一个重要应用领域就是保存应用的状态数据,管理有状态的应用,就要使用新的对象 StatefulSet,可以认为它是管理无状态应用对象 Deployment 的一个特例。
StatefulSet
对象的 YAML 描述和 Deployment 非常像,spec
里只是多了一个serviceName
字段,但它部署应用的方式却与 Deployment 差距很大。
Deployment
创建的 Pod 是随机的名字,而 StatefulSet
会对 Pod 顺序编号、顺序创建,保证应用有一个确定的启动先后次序,这样就可以实现主从、主备等关系。
在使用Service
为 StatefulSet
创建服务的时候,它也会为每个 Pod 单独创建域名,同样也是顺序编号,保证 Pod 有稳定的网络标识,外部用户就可以用这个域名来准确地访问到某个具体的 Pod。
StatefulSet 还使用volumeClaimTemplates
字段来定义持久化存储,里面其实就是一个 PVC,每个 Pod 可以用这个模板来生成自己的 PVC 去申请 PV,实现存储卷与 Pod 的独立绑定。
通过启动顺序、稳定域名和存储模板这三个关键能力,StatefulSet
就可以很好地处理 Redis、MySQL
等有状态应用了。
要点回顾二:应用管理
第二部分讲的是应用管理,包括滚动更新、资源配额和健康检查等内容。
【k8s】Deployment滚动更新(十六) 在 Kubernetes 里部署好应用后,我们还需要对它做持续的运维管理,其中一项任务是版本的更新和回退。
版本更新很简单,只要编写一个新的 YAML(Deployment、DaemonSet、StatefulSet
),再用 kubectl apply
应用就可以了。Kubernetes 采用的是滚动更新
策略,实际上是两个同步进行的扩容
和缩容
动作,这样在更新的过程中始终会有 Pod 处于可用状态,能够平稳地对外提供服务。
应用的更新历史可以用命令 kubectl rollout history
查看,如果有什么意外,就可以用 kubectl rollout undo
来回退。这两个命令相当于给我们的更新流程上了一个保险,可以放心大胆操作,失败就用S/L 大法
。
【k8s】Resources/探针-使pod稳定运行(十七) 为了让 Pod 里的容器能够稳定运行,我们可以采用资源配额
和检查探针
这两种手段。
资源配额能够限制容器申请的 CPU 和内存数量,不至于过多或者过少,保持在一个合理的程度,更有利于 Kubernetes 调度。
检查探针是 Kubernetes 内置的应用监控工具,有 Startup、Liveness、Readiness
三种,分别探测启动、存活、就绪状态,探测的方式也有 exec、tcpSocket、httpGet 三种。组合运用这些就可以灵活地检查容器的状态,Kubernetes 发现不可用就会重启容器,让应用在总体上处于健康水平。
要点回顾三:集群管理
第三部分讲的是集群管理,有名字空间、系统监控和网络通信等知识点。
【k8s】利用namespace分隔系统资源(十八) Kubernetes 的集群里虽然有很多计算资源,但毕竟是有限的,除了要给 Pod 加上资源配额,我们也要为集群加上资源配额,方法就是用名字空间,把整体的资源池切分成多个小块,按需分配给不同的用户使用。
名字空间的资源配额使用的是“ResourceQuota”,除了基本的 CPU 和内存,它还能够限制存储容量和各种 API 对象的数量,这样就可以避免多用户互相挤占,更高效地利用集群资源。
【k8s】使用Metrics Server和Prometheus(十九) 系统监控是集群管理的另一个重要方面,Kubernetes 提供了 Metrics Server
和 Prometheus
两个工具:
Metrics Server
专门用来收集 Kubernetes 核心资源指标,可以用 kubectl top 来查看集群的状态,它也是水平自动伸缩对象HorizontalPodAutoscaler
的前提条件。Prometheus
,继 Kubernetes 之后的第二个 CNCF 毕业项目,是云原生监控领域的“事实标准”,在集群里部署之后就可以用 Grafana 可视化监控各种指标,还可以集成自动报警等功能。
【k8s】网络插件(二十) 对于底层的基础网络设施,Kubernetes 定义了平坦的网络模型IP-per-pod
,实现它就要符合 CNI 标准。常用的网络插件有 Flannel、Calico、Cilium
等,Flannel
使用Overlay
模式,性能较低,Calico
使用 Route
模式,性能较高。
一、搭建 WordPress 网站
接下来我们就来在【k8s】二阶段实战演练(十二) 的基础上继续优化 WordPress 网站,其中的关键是让数据库 MariaDB 实现数据持久化。
网站的整体架构图变化不大,前面的 Nginx、WordPress 还是原样,只需要修改 MariaDB:
因为 MariaDB 由 Deployment 改成了 StatefulSet,所以我们要修改 YAML,添加serviceName``volumeClaimTemplates
这两个字段,定义网络标识和 NFS 动态存储卷,然后在容器部分用volumeMounts
挂载到容器里的数据目录/var/lib/mysql
。
修改后的 YAML 就是这个样子:
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: maria-sts
name: maria-sts
spec:
# headless svc
serviceName: maria-svc
# pvc
volumeClaimTemplates:
- metadata:
name: maria-100m-pvc
spec:
storageClassName: nfs-client
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100Mi
replicas: 1
selector:
matchLabels:
app: maria-sts
template:
metadata:
labels:
app: maria-sts
spec:
containers:
- image: mariadb:10
name: mariadb
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
envFrom:
- prefix: 'MARIADB_'
configMapRef:
name: maria-cm
volumeMounts:
- name: maria-100m-pvc
mountPath: /var/lib/mysql
改完 MariaDB,我们还要再对 WordPress 做一点小修改。
StatefulSet
管理的每个 Pod 都有自己的域名
,所以要把 WordPress 的环境变量改成 MariaDB 的新名字,也就是maria-sts-0.maria-svc
:
apiVersion: v1
kind: ConfigMap
metadata:
name: wp-cm
data:
HOST: 'maria-sts-0.maria-svc' #注意这里
USER: 'wp'
PASSWORD: '123'
NAME: 'db'
改完这两个 YAML,我们就可以逐个创建 MariaDB、WordPress、Ingress
等对象了。
和之前一样,访问 NodePort 的30088
端口,或者是用 Ingress Controller 的wp.test
域名,都可以进入 WordPress 网站:
StatefulSet 的持久化存储是否生效了呢?
你可以把这些对象都删除后重新创建,再进入网站,看看是否原来的数据依然存在。或者更简单一点,直接查看 NFS 的存储目录,应该可以看到 MariaDB 生成的一些数据库文件:
这两种方式都能够证明,我们的 MariaDB 使用 StatefulSet 部署后数据已经保存在了磁盘上,不会因为对象的销毁而丢失。
二、部署 Dashboard
在【k8s】第一阶段实战演练(六), 我简单介绍了 Kubernetes 的图形管理界面,也就是 Dashboard, 当时 Dashboard 是直接内置在 minikube 里的,不需要安装,一个命令启动,就能在浏览器里直观地管理 Kubernetes 集群了,非常方便。
那现在我们用 kubeadm 部署了实际的多节点集群,从零开始安装 Dashboard。
首先,可以先去 Dashboard 的项目网站(https://github.com/kubernetes/dashboard),看一下它的说明文档,了解一下它的基本情况。
它的安装很简单,只需要一个 YAML 文件,可以直接下载:
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.6.0/aio/deploy/recommended.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.
apiVersion: v1
kind: Namespace
metadata:
name: kubernetes-dashboard
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- port: 443
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-certs
namespace: kubernetes-dashboard
type: Opaque
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-csrf
namespace: kubernetes-dashboard
type: Opaque
data:
csrf: ""
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-key-holder
namespace: kubernetes-dashboard
type: Opaque
---
kind: ConfigMap
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-settings
namespace: kubernetes-dashboard
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
rules:
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
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.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster", "dashboard-metrics-scraper"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
verbs: ["get"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
rules:
# Allow Metrics Scraper to get metrics from the Metrics server
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
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:
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: kubernetes-dashboard
image: kubernetesui/dashboard:v2.6.0
imagePullPolicy: Always
ports:
- containerPort: 8443
protocol: TCP
args:
- --auto-generate-certificates
- --namespace=kubernetes-dashboard
# 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
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1001
runAsGroup: 2001
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
nodeSelector:
"kubernetes.io/os": linux
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
name: dashboard-metrics-scraper
namespace: kubernetes-dashboard
spec:
ports:
- port: 8000
targetPort: 8000
selector:
k8s-app: dashboard-metrics-scraper
---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
name: dashboard-metrics-scraper
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: dashboard-metrics-scraper
template:
metadata:
labels:
k8s-app: dashboard-metrics-scraper
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: dashboard-metrics-scraper
image: kubernetesui/metrics-scraper:v1.0.8
ports:
- containerPort: 8000
protocol: TCP
livenessProbe:
httpGet:
scheme: HTTP
path: /
port: 8000
initialDelaySeconds: 30
timeoutSeconds: 30
volumeMounts:
- mountPath: /tmp
name: tmp-volume
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1001
runAsGroup: 2001
serviceAccountName: kubernetes-dashboard
nodeSelector:
"kubernetes.io/os": linux
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
volumes:
- name: tmp-volume
emptyDir: {}
这个 YAML 里包含了很多对象,虽然文件比较大,但现在的你应该基本都能够看懂了,要点有这么几个:
- 所有的对象都属于“kubernetes-dashboard”名字空间。
- Dashboard 使用 Deployment 部署了一个实例,端口号是 8443。
- 容器启用了 Liveness 探针,使用 HTTPS 方式检查存活状态。
- Service 对象使用的是 443 端口,它映射了 Dashboard 的 8443 端口。
- 使用命令 kubectl apply 就可以轻松部署 Dashboard 了:
kubectl apply -f recommended.yaml
1.部署 Ingress/Ingress Controller
由于 Dashboard 默认使用的是加密的 HTTPS
协议,拒绝明文 HTTP
访问,所以我们要先生成证书,让 Ingress
也走 HTTPS 协议。
简单起见,我直接用 Linux 里的命令行工具“openssl”来生成一个自签名的证书(如果你有条件,也可以考虑找 CA 网站申请免费证书):
openssl req -x509 -days 365 -out k8s.test.crt -keyout k8s.test.key \
-newkey rsa:2048 -nodes -sha256 \
-subj '/CN=k8s.test' -extensions EXT -config <( \
printf "[dn]\nCN=k8s.test\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:k8s.test\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
openssl 的命令比较长,我简单解释一下:它生成的是一个 X509 格式的证书,有效期 365 天,私钥是 RSA2048 位,摘要算法是 SHA256,签发的网站是“k8s.test”。
运行命令行后会生成两个文件,一个是证书k8s.test.crt
,另一个是私钥k8s.test.key
,我们需要把这两个文件存入 Kubernetes 里供 Ingress 使用。
因为这两个文件属于机密信息,存储的方式当然就是用 Secret 了。你仍然可以用命令 kubectl create secret 来自动创建 YAML,不过类型不是generic
,而是tls
,同时还要用 -n 指定名字空间,用 --cert、–key 指定文件:
export out="--dry-run=client -o yaml"
kubectl create secret tls dash-tls -n kubernetes-dashboard --cert=k8s.test.crt --key=k8s.test.key $out > cert.yml
出来的 YAML 大概是这个样子:
apiVersion: v1
kind: Secret
metadata:
name: dash-tls
namespace: kubernetes-dashboard
type: kubernetes.io/tls
data:
tls.crt: LS0tLS1CRUdJTiBDRVJU...
tls.key: LS0tLS1CRUdJTiBQUklW...
创建这个 Secret
对象之后,你可以再用 kubectl describe
来检查它的状态:
接下来我们就来编写 Ingress Class
和 Ingress
对象,为了保持名字空间的整齐,也把它放在kubernetes-dashboard
名字空间里。
Ingress Class 对象很简单,名字是dash-ink
,指定 Controller 还是我们之前用的 Nginx 官方的 Ingress Controller:
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: dash-ink
namespace: kubernetes-dashboard
spec:
controller: nginx.org/ingress-controller
Ingress 对象可以用 kubectl create 命令自动生成,如果你有点忘记的话,可以回头参考一下【k8s】Ingress 集群进出流量总管(十一):
kubectl create ing dash-ing --rule="k8s.test/=kubernetes-dashboard:443" --class=dash-ink -n kubernetes-dashboard $out
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dash-ing
namespace: kubernetes-dashboard
annotations:
nginx.org/ssl-services: "kubernetes-dashboard"
spec:
ingressClassName: dash-ink
tls:
- hosts:
- k8s.test
secretName: dash-tls
rules:
- host: k8s.test
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kubernetes-dashboard
port:
number: 443
最后一个对象,就是 Ingress Controller 了,还是拿现成的模板修改,记得要把args
里的 Ingress Class 改成我们自己的“dash-ink”:
apiVersion: apps/v1
kind: Deployment
metadata:
name: dash-kic-dep
namespace: nginx-ingress
spec:
replicas: 1
selector:
matchLabels:
app: dash-kic-dep
template:
metadata:
labels:
app: dash-kic-dep
spec:
serviceAccountName: nginx-ingress
automountServiceAccountToken: true
#hostNetwork: true
containers:
- image: nginx/nginx-ingress:2.2-alpine
imagePullPolicy: IfNotPresent
name: nginx-ingress
ports:
- name: http
containerPort: 80
#hostPort: 2080
- name: https
containerPort: 443
#hostPort: 20443
securityContext:
allowPrivilegeEscalation: true
runAsUser: 101 #nginx
runAsNonRoot: true
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
args:
- -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
- -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret
- -ingress-class=dash-ink
要让我们在外面能够访问 Ingress Controller,还要为它再定义一个 Service,类型是NodePort
,端口指定是30443
:
apiVersion: v1
kind: Service
metadata:
name: dash-kic-svc
namespace: nginx-ingress
spec:
ports:
- port: 443
protocol: TCP
targetPort: 443
nodePort: 30443
selector:
app: dash-kic-dep
type: NodePort
把上面的 Secret、Ingress Class、Ingress、Ingress Controller、Service 都创建好之后,我们再来确认一下它们的运行状态:
[root@k8s-console k8s-gjp-sz]# kubectl get svc -n nginx-ingress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dash-kic-svc NodePort 10.97.53.191 <none> 443:30443/TCP 85s
[root@k8s-console k8s-gjp-sz]#
[root@k8s-console k8s-gjp-sz]# kubectl get ingressclasses.networking.k8s.io -n kubernetes-dashboard
NAME CONTROLLER PARAMETERS AGE
dash-ink nginx.org/ingress-controller <none> 85s
[root@k8s-console k8s-gjp-sz]# kubectl get ingress -n kubernetes-dashboard
NAME CLASS HOSTS ADDRESS PORTS AGE
dash-ing dash-ink k8s.test 80, 443 12d
[root@k8s-console k8s-gjp-sz]# kubectl get pod,svc -n nginx-ingress
NAME READY STATUS RESTARTS AGE
pod/dash-kic-dep-78c7d759bc-tg4rl 1/1 Running 6 (7h42m ago) 111s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/dash-kic-svc NodePort 10.97.53.191 <none> 443:30443/TCP 111s
因为这些对象比较多,处于不同的名字空间,关联有点复杂,我画了一个简单的示意图,你可以看一下:
访问 Dashboard到这里,Dashboard 的部署工作就基本完成了。为了能正常访问,我们还要为它创建一个用户,才能登录进 Dashboard。
Dashboard 的网站上有一个简单示例(https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md),我们直接拿来用就行:
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
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
这个 YAML 创建了一个 Dashboard 的管理员账号,名字叫admin-user
,使用的是 Kubernetes 的 RBAC
机制。
这个账号不能用简单的“用户名 + 密码”的方式登录,需要用到一个 Token,可以用kubectl get secret、kubectl describe secret
查到:
kubectl get secret -n kubernetes-dashboard
kubectl describe secrets -n kubernetes-dashboard admin-user-token-xxxx
Token 是一个很长的字符串,把它拷贝存好,再为它的测试域名k8s.test
加上域名解析(修改 /etc/hosts),然后我们就可以在浏览器里输入网址https://k8s.test:30443
访问 Dashboard 了:
下面的两张截图就是我查看集群里“kube-system”名字空间的情况,由于我们之前安装了 Metrics Server,所以 Dashboard 也能够以图形的方式显示 CPU 和内存状态,有那么一点 Prometheus + Grafana 的意思:
总结
今天有两个实战项目。首先是 WordPress,把后端的存储服务 MariaDB 改造成了 StatefulSet,挂载了 NFS 网盘,这样就实现了一个功能比较完善的网站,达到了基本可用的程度。
接着我们在 Kubernetes 里安装了 Dashboard,主要部署在名字空间“kubernetes-dashboard”。Dashboard 自身的安装很简单,但我们又为它在前面搭建了一个反向代理,配上了安全证书,进一步实践了 Ingress 的用法。