【k8s】第三阶段实战演练(二十一)


知识回顾

要点回顾一: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 顺序编号、顺序创建,保证应用有一个确定的启动先后次序,这样就可以实现主从、主备等关系。

在使用ServiceStatefulSet 创建服务的时候,它也会为每个 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 ServerPrometheus 两个工具:

  • 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 ClassIngress 对象,为了保持名字空间的整齐,也把它放在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 的用法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值