Kubernetes集群——存储管理

目录

一.简单介绍

二.临时存储卷------emptyDir卷

2.1简单介绍

2.2创建emptyDir卷

2.3内存临时存储卷

三.本地存储卷------hostPath卷

3.1简单介绍

3.2创建hostPath卷

四.远程挂载卷------nfs卷

4.1简单介绍

4.2配置nfs服务

4.2.1配置nfs服务端

4.2.2配置nfs客户端

4.3配置nfs卷

五.持久化存储

5.1简单介绍

5.2持久卷------PV

5.2.1简单介绍

5.3静态持久卷

5.3.1创建静态持久卷PV

[5.3.2 创建静态持久卷PVC](#5.3.2 创建静态持久卷PVC)

5.3.3绑定PVC

5.3.4回收Pv

5.4动态持久卷

5.4.1简单介绍

5.4.2创建RBAC

[5.4.3创建provisioner Pod](#5.4.3创建provisioner Pod)

5.4.4创建StroageClass

5.4.5创建PVC

5.4.6回收PVC

5.4.7测试前端

5.4.8测试后端

5.5部署mysql分布式集群

5.5.1部署mysql主数据库

5.5.2回收数据库集群


一.简单介绍

产生原因 :容器内部存储的生命周期是短暂的,会随着容器环境的销毁而销毁,具有不稳定性。如果多个容器希望共享同一份存储,则仅仅依赖容器本身是很难实现的。

说明 :在Kubernetes系统中,将对容器应用所需的存储资源抽象为存储卷(Volume)概念来解决这些问题 。 **Volume是与Pod绑定的(独立于容器)与Pod具有相同生命周期的资源对象。**可以将Volume的内容理解为目录或文件,容器如需使用某个Volume,则仅需设置volumeMounts将一个或多个Volume挂载为容器中的目录或文件,即可访问Volume中的数据。Volume具体是什么类型,以及由哪个系统提供,对容器应用来说是透明的。

类型分为 :emptyDir卷,hostPath卷和nfs卷等等。

二.临时存储卷------emptyDir卷

2.1简单介绍

说明 :该类型的Volume将在Pod被调度到Node时进行创建,在初始状态下目录中是空的,所以命名为"空目录"(Empty Directory),它与Pod具有相同的生命周期,当Pod被销毁时,Node上相应的目录也会被删除 。 同一个Pod中的多个容器都可以挂载这种Volume。Pod启动时为空,存储空间来自本地的kubelet 根目录(通常是根磁盘)或内存中。

2.2创建emptyDir卷

说明 :同一个 Pod 内多个容器通过 emptyDir 共享数据,并用"触发文件"做简单同步 。两个容器并行启动,第一个容器生产文件,第二个容器等待信号后消费(列出)文件。

1.编写yaml文件

bash 复制代码
vim job-emptydir.yml

添加以下内容:

bash 复制代码
apiVersion: batch/v1
kind: Job
metadata:
  name: convert
spec:
  backoffLimit: 3    #Pod最多重试 3 次
  ttlSecondsAfterFinished: 100    # 100秒后自动回收job和pod
  template:
    spec:
      restartPolicy: OnFailure    
      containers:
      - image: reg.westos.org/library/centos:7
        name: create-files
        volumeMounts:
        - mountPath: /cache
          name: cache-volume
        command:
        - sh
        - -c
        - touch /cache/{1..30};touch /cache/trigger    #创建文件
      - image: reg.westos.org/library/centos:7
        name: generate-logs
        volumeMounts:
        - mountPath: /logs
          name: cache-volume
        command:
        - sh
        - -c
        - until test -f /logs/trigger;do sleep 1;done;find /logs/    #先轮询等待信号文件出现,再列出目录内容。
      volumes:
      - name: cache-volume    
        emptyDir: {}    #挂载临时卷

2.运行yaml文件

bash 复制代码
kubectl apply -f job-emptydir.yml
kubectl get jobs.batch
kubectl get pod
kubectl logs convert-2s5kw

2.3内存临时存储卷

1. 说明 :将 emptyDir.medium 字段设置为 "Memory" ,以告诉 Kubernetes 为您安装 tmpfs(基于内存的文件系统)。 虽然 tmpfs 速度非常快,但是要注意它与磁盘不同。 tmpfs 在节点重启时会被清除,并且您所写入的所有文件都会计入容器的内存消耗,受容器内存限制约束。

2.编写yaml文件

bash 复制代码
vim job-emptydir_nginx.yml    #使用内存临时存储

添加以下内容:

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: emptydir-tmpfs    
spec:
  containers:
  - name: webapp
    image: reg.westos.org/library/nginx
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      medium: Memory    #使用内存进行临时存储
      sizeLimit: 100Mi    #限制内存容量

3.运行yaml文件

说明:存储只有100MB,生成200MB的文件无法做到

bash 复制代码
kubectl apply -f job-emptydir_nginx.yml    #运行yaml文件
kubectl get pod emptydir-tmpfs -o wide    #查看Pod
kubectl exec -it emptydir-tmpfs -- bash
dd if=/dev/zero of=/usr/share/nginx/html/bigfile bs=1M count=200    #生成200MB的文件
bash 复制代码
du /usr/share/nginx/html/bigfile -h    #查看文件

三.本地存储卷------hostPath卷

3.1简单介绍

说明 :HostPath类型的存储卷用于将Node文件系统的目录或文件挂载到容器内部使用 。对于大多数容器应用来说,都不需要使用宿主机的文件系统。容器应用的关键数据需要被持久化到宿主机上。 只要节点存在且路径未被删除,数据就会保留。

3.2创建hostPath卷

说明 :以 apiserver-etcd-client 证书通过 TLS 认证 ,连接本机 127.0.0.1:2379,把etcd 数据保存为带时间戳的 .bak 文件到 /backup/etcd/。

1.编写yaml文件

bash 复制代码
vim etcd-backup.yml

添加以下内容:

bash 复制代码
apiVersion: batch/v1
kind: CronJob
metadata:
  name: etcd-backup
spec:
  schedule: "*/5 * * * *"    #每5分钟执行一次
  concurrencyPolicy: Forbid    #确保同一时间只有一个 Job 实例在运行。
  jobTemplate:
    spec:
      ttlSecondsAfterFinished: 100    #Job执行100秒后删除
      template:
        spec:
          nodeSelector:
            kubernetes.io/hostname: "k8s1"    #在k8s1上执行
          tolerations:    #容忍度
          - key: node-role.kubernetes.io/control-plane
            effect: NoSchedule
          hostNetwork: true
          restartPolicy: Never
          volumes:
          - name: etcd-certs
            hostPath:    #使用hostPath本地卷
              path: /etc/kubernetes/pki
          - name: etcd-data
            hostPath:    #使用hostPath本地卷
              path: /backup/etcd
              type: DirectoryOrCreate    #挂载宿主机上的一个目录;如果这个目录不存在,就自动创建它。
          containers:
          - name: etcd-client
            image: reg.westos.org/library/etcd:3.6.6-0
            args:
            - /bin/sh
            - -ec
            - ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt
              --cert=/etc/kubernetes/pki/apiserver-etcd-client.crt
              --key=/etc/kubernetes/pki/apiserver-etcd-client.key
              --endpoints https://127.0.0.1:2379
              snapshot save /backup/etcd/etcd-$(date +%s).bak    #以 apiserver-etcd-client 证书通过 TLS 认证,连接本机 127.0.0.1:2379,把 etcd 数据保存为带时间戳的 .bak 文件到 /backup/etcd/。
              #- sleep 100000
            volumeMounts:
            - name: etcd-data
              mountPath: /backup/etcd
            - name: etcd-certs
              mountPath: /etc/kubernetes/pki
              readOnly: true

2.运行yaml文件

bash 复制代码
kubectl apply -f etcd-backup.yml
kubectl get pod
kubectl logs emptydir-tmpfs    #查看Pod日志
ll /backup/etcd/    #查看 etcd 备份文件

四.远程挂载卷------nfs卷

4.1简单介绍

1.说明 :nfs 卷能将 NFS (网络文件系统) 挂载到你的 Pod 中。 不像 emptyDir 那样会在删除 Pod 的同时也会被删除,nfs 卷的内容在删除 Pod 时会被保存,卷只是被卸载。 这意味着 nfs 卷可以被预先填充数据,并且这些数据可以在 Pod 之间共享。

4.2配置nfs服务

4.2.1配置nfs服务端

说明:真正存放数据的挂载点

1.安装server端

bash 复制代码
yum install -y nfs-utils

2.编写exports文件

bash 复制代码
mkdir -p /mnt/nfs/k8s    #创建挂载目录
vim /etc/exports    #编写exports文件

添加以下内容:

bash 复制代码
/mnt/nfs        *(rw,sync,no_root_squash)

参数介绍:

*:所有外机均可挂载

rw:拥有读写权限

sync:同步写入,数据落盘后,再传入

no_root_squash:客户端 root 用户保留 root 权限,不降权

3.启动服务

bash 复制代码
systemctl enable --now nfs-server nfs-utils
showmount -e    #查看本机的可挂载列表

4.2.2配置nfs客户端

说明:用于kubernetes集群的挂载点,所有节点均安装

bash 复制代码
yum install -y nfs-utils    #安装 nfs 服务
systemctl enable --now nfs-utils
systemctl status nfs-utils

4.3配置nfs卷

1.编写yaml文件

bash 复制代码
vim sts-db-cm-secret-pvc.yml

添加以下内容:

bash 复制代码
apiVersion: "apps/v1"
kind: "Deployment"
metadata:
  name: "webserver"
spec:
  replicas: 3
  selector:
    matchLabels:
      app: "web"
  template:
    metadata:
      labels:
        app: "web"
    spec:
      containers:
      - name: "apache-frontend"
        image: "reg.westos.org/library/httpd:secure"
        ports:
        - containerPort: 80
        env:
        - name: DB_ROOT_PWD
          valueFrom:
            secretKeyRef:    #引入secret
              name: db-root-pwd
              key: dbpwd
        volumeMounts:
        - name: webenvvol
          mountPath: /etc/httpd/conf.d/env.conf
          subPath: env.conf
        - name: webdata
          mountPath: /var/www/html/    #容器内部文件
      volumes:
        - name: webenvvol    
          configMap:    #引入configmap
            name: webenv
        - name: webdata
          nfs:    #nfs远程挂载
            server: 192.168.7.161    #挂载主机
            path: /mnt/nfs/k8s    #挂载目录

2.运行yaml文件

bash 复制代码
kubectl apply -f deploy-web-secret-nfs.yml    #执行yaml文件
kubectl get deployment
kubectl get pod -o wide

3.服务端添加内容,并完成测试:

bash 复制代码
echo nfs > /mnt/nfs/k8s/index.html    #index.html文件会自动挂载到容器内部

五.持久化存储

5.1简单介绍

说明 :Kubernetes 对于有状态的容器应用或者对数据需要持久化的应用,不仅需要将容器内的目录挂载到宿主机的目录或者emptyDir临时存储卷,而且需要更加可靠的存储来保存应用产生的重要数据,以便容器应用在重建之后仍然可以使用之前的数据。

不过,存储资源和计算资源(CPU/内存)的管理方式完全不同。为了能够屏蔽底层存储实现的细节,让用户方便使用,同时让管理员方便管理,Kubernetes 引入 PersistentVolume(PV)和PersistentVolumeClaim(PVC)两个资源对象来实现对存储的管理子系统。

5.2持久卷------PV

5.2.1简单介绍

1.说明 :是集群中的一块存储,可以由管理员事先制备,或者使用存储类(Storage Class**)来动态制备**。 持久卷是集群资源,就像节点也是集群资源一样。PV持久卷和普通的Volume一样, 也是使用卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。

2.工作流程:

3.PV回收策略

1. Retain:保留,该策略允许手动回收资源, 当删除PVC时,PV仍然存在 ,PV被视为已释放,管理员可以手动回收卷。
2. Recycle:回收,如果Volume插件支持,Recycle策略会对卷执行 rm -rf清理该PV,并使其可用于下一个新的PVC,目前回收策略Recycle已被废弃。

3. Delete:删除,如果Volume插件支持,删除PVC时会同时删除PV,动态卷默认为Delete。

4.PV的访问策略

1. ReadWriteOnce :可以被单节点以读写模式挂载 ,命令行中可以被缩写为RWO。(块存储)适用于单Pod独占存储的场景(如数据库)。PV只能被调度到同一节点上的Pod挂载;同一节点上只能有一个Pod挂载该PV并写入数据。

2. ReadOnlyMany :可以被多个节点以只读模式挂载 ,命令行中可以被缩写为ROX。适用于需要多节点共享静态数据的场景(如配置文件)。

3.ReadWriteMany :可以被多个节点以读写模式挂载, 命令行中可以被缩写为RWX。(文件共享存储)

4.ReadWriteOncePod :可以被单个Pod以读写方式挂载。 如果你想确保整个集群中只有一个 Pod 可以读取或写入该 PVC, 请使用 ReadWriteOncePod 访问模式。

5.PV 生命周期的各个阶段状态

1. Available :可用,没有被PVC绑定的空闲资源。
2. Bound :已绑定,已经被PVC绑定。

3. Released :已释放,PVC被删除,但是资源还未被重新使用。

4. Failed :失败,自动回收失败

5.3静态持久卷

5.3.1创建静态持久卷PV

说明:这里我使用nfs卷来创建pv,因为nfs卷能够确保不论pod在哪个节点上都可以连接到存储资源。

域名配置如下:

|---------------|------------------------|
| 主机IP | 域名解析 |
| 192.168.7.161 | docker1 reg.westos.org |
| 192.168.7.163 | k8s1 |
| 192.168.7.164 | k8s2 |
| 192.168.7.165 | k8s3 |

2.1配置nfs输出目录

说明:进入docker1,配置nfs挂载目录。由于前面已经讲过如何配置nfs服务,这里就不再赘述。

bash 复制代码
mkdir -p /mnt/nfs/k8s1
cd /mnt/nfs/k8s1
mkdir pv1 pv2 pv3    #创建3个目录

2.2编写yaml文件

bash 复制代码
vim pv-nfs.yml

添加以下内容:

bash 复制代码
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1                # PV名称
spec:
  capacity:
    storage: 5Gi    # 容量配置,nfs不支持容量配置,配置时需要后端存储设备支持
  volumeMode: Filesystem    # 卷的模式,目前支持Filesystem(文件系统)和Block(块)
  accessModes:
    - ReadWriteOnce        # PV的访问模式
  persistentVolumeReclaimPolicy: Retain    # PV的回收策略
  storageClassName: nfs        # PV的类
  nfs:
    path: /nfsdata/pv1        # NFS上的共享目录
    server: 192.168.7.161    # NFS的IP地址

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv2
spec:
  capacity:
    storage: 10Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfsdata/pv2
    server: 192.168.7.161

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv3
spec:
  capacity:
    storage: 15Gi
  volumeMode: Filesystem
  accessModes:
    - ReadOnlyMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfsdata/pv3
    server: 192.168.7.161

2.3运行yaml文件,创建PV

bash 复制代码
kubectl apply -f pv-nfs.yml
kubectl get pv

5.3.2 创建静态持久卷PVC

1.编写yaml文件

bash 复制代码
vim pvc-nfs.yml

添加以下内容:

bash 复制代码
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc1
spec:
  storageClassName: nfs    #存储卷类型
  accessModes:    
    - ReadWriteOnce    #读写模式
  resources:
    requests:
      storage: 1Gi    #请求1G的空间

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc2
spec:
  storageClassName: nfs
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc3
spec:
  storageClassName: nfs
  accessModes:
    - ReadOnlyMany
  resources:
    requests:
      storage: 15Gi

2.运行yaml文件

说明:当你创建pvc后,如果pvc所提的资源需求刚好有对应活跃的pv存在吗,K8s 后台的控制器会自动寻找属性匹配的空闲 PV 并瞬间完成绑定。

bash 复制代码
kubectl apply -f pvc-nfs.yml
kubectl get pvc

5.3.3绑定PVC

说明:如果你想指定绑定的pv,需要我们手动帮他们绑定

1.编写yaml文件

bash 复制代码
vim deploy-web-secret-pvc.yml

添加以下内容:

bash 复制代码
apiVersion: "apps/v1"
kind: "Deployment"
metadata:
  name: "webserver"
spec:
  replicas: 3
  selector:
    matchLabels:
      app: "web"
  template:
    metadata:
      labels:
        app: "web"
    spec:
      containers:
      - name: "apache-frontend"
        image: "reg.westos.org/library/httpd:secure"
        ports:
        - containerPort: 80
        env:
        - name: DB_ROOT_PWD
          valueFrom:
            secretKeyRef:
              name: db-root-pwd
              key: dbpwd
        volumeMounts:
        - name: webenvvol
          mountPath: /etc/httpd/conf.d/env.conf
          subPath: env.conf
        - name: webdata
          mountPath: /var/www/html/
      volumes:
      - name: webenvvol
        configMap:
          name: webenv
      - name: webdata
        persistentVolumeClaim:    #挂载PVC
          claimName: pvc1    #3个pod挂载pvc1

2.运行yaml文件

bash 复制代码
kubectl apply -f deploy-web-secret-pvc.yml
kubectl describe deployment webserver | grep volume -A5    #查看是否挂载成功

3.测试挂载卷

bash 复制代码
echo pv1 > /mnt/nfs/k8s1/pv1/index.html    #输入内容
kubectl get svc -o wide
curl 192.168.7.100

使用pod测试

bash 复制代码
kubectl get pod -o wide
curl 10.244.219.60
curl 10.244.109.113
curl 10.244.109.114

5.3.4回收Pv

说明 :清理pvc后,需要手动清理PV,不然无法再次绑定

回收顺序 :先删pvc,后删pv

1.删除pvc

bash 复制代码
kubectl delete pvc pvc3
kubectl get pvc
kubectl get pv

2.删除pv

bash 复制代码
kubectl delete pv pv3
kubectl get pv

5.4动态持久卷

5.4.1简单介绍

1.说明 :动态存储就是"存储卷随用随建" :用户写一个 PVC 说"我要多大、什么类型",StorageClass 提供配方,Provisioner 当场在底层存储系统里创建出这块卷并生成 PV,自动完成绑定。它取代了"管理员提前手动创建 PV"的静态模式,实现了存储的按需供给、自助服务、弹性伸缩------这也是云原生存储体系的核心能力。

2.工作流程:

1.管理员创建 StorageClass,声明"我能提供什么"。

2.用户创建 PersistentVolumeClaim(PVC) ,声明"我需要什么",并通过 storageClassName 字段指定想要的类别。

3.Kubernetes 根据匹配的 StorageClass 定义,自动调用底层存储驱动,创建出对应的 PV 并完成绑定。

5.4.2创建RBAC

1.RBAC :Role-Based Access Control(基于角色的访问控制) ,是 Kubernetes 的授权(Authorization)机制 ,回答的问题是:"这个身份,能对哪些资源,执行哪些操作?"

2.yaml文件说明 :创建一个专用的 ServiceAccount ,并赋予它足够的权限,使其能够监听 PVC 的创建请求,自动在 NFS 服务器上创建目录 ,并生成对应的 PersistentVolume(PV),从而实现基于 NFS 的动态存储供给。

3.编辑yaml文件

bash 复制代码
vim rbac.yml    #编辑yaml文件

添加以下内容:

bash 复制代码
apiVersion: v1
kind: Namespace
metadata:
  name: nfs-client-provisioner    #创建一个namespace
---
apiVersion: v1
kind: ServiceAccount    
metadata:
  name: nfs-client-provisioner    #创建SA访问角色
  namespace: nfs-client-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["nodes"]    #节点权限
    verbs: ["get", "list", "watch"]    
  - apiGroups: [""]
    resources: ["persistentvolumes"]    #PV权限
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]    #PVC权限
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]    #存储类权限
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]    #events权限
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding    #集群权限绑定
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount    #SA账户
    name: nfs-client-provisioner
    namespace: nfs-client-provisioner
roleRef:
  kind: ClusterRole        #集群权限
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  namespace: nfs-client-provisioner
rules:
  - apiGroups: [""]
    resources: ["endpoints"]    #后端节点权限,多个后端Pod会竞争成为"Leader",只有 Leader 才执行实际的 PV 创建操作,避免重复供给
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner  
  namespace: nfs-client-provisioner
subjects:
  - kind: ServiceAccount    #SA账户
    name: nfs-client-provisioner
    namespace: nfs-client-provisioner
roleRef:
  kind: Role    #绑定Role权限
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

4.运行yaml文件

bash 复制代码
kubectl apply -f rbac.yml

5.4.3创建provisioner Pod

1.编写deployment控制器

说明:在集群里运行一个 Provisioner Pod,让它监听 PVC 事件,在 NFS 共享目录下创建子目录并生成 PV,实现 NFS 的动态存储供给。

bash 复制代码
vim deployment.yml    

添加以下内容:

bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  namespace: nfs-client-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: reg.westos.org/sig-storage/nfs-subdir-external-provisioner:v4.0.2    #镜像需要科学上网下载
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 192.168.7.161
            - name: NFS_PATH
              value: /mnt/nfs/k8s
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.7.161
            path: /mnt/nfs/k8s

运行yaml文件

bash 复制代码
kubectl apply -f deployment.yml
kubectl get deployments.apps -n nfs-client-provisioner
kubectl get pod -n nfs-client-provisioner -o wide

5.4.4创建StroageClass

1.说明 :StorageClass (存储类)是 Kubernetes 中用于描述和抽象存储"服务等级"的集群级资源 。你可以把它理解为集群管理员提供给用户的一份"存储菜单",用户通过它来声明自己需要"哪种类型、什么性能"的存储,而不必关心底层究竟用的是 AWS EBS、GCE PD 还是 Ceph。

2.编写yaml文件

说明:声明一个名为 nfs-client 的存储类,指定由 k8s-sigs.io/nfs-subdir-external-provisioner 来动态创建 PV,并把它设为集群默认存储类。

bash 复制代码
vim class.yml    #编写yaml文件

添加以下内容:

bash 复制代码
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"    
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner    
parameters:
  archiveOnDelete: "false"    #删除 PVC 时目录直接删

3.运行yaml文件

bash 复制代码
kubectl apply -f class.yml
kubectl get sc

5.4.5创建PVC

1.说明 :根据nfs-client的存储类创建PVC,PVC创建完成后,会使用Provisioner Pod自动创建对应PV

2.编写yaml文件

bash 复制代码
vim test-claim.yaml

添加以下内容:

bash 复制代码
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim
spec:
  storageClassName: nfs-client    #定义存储类
  accessModes:
    - ReadWriteMany    
  resources:    #资源
    requests:    #需求
      storage: 1Gi

3.运行yaml文件

bash 复制代码
kubectl apply -f test-claim.yaml
kubectl get pv pvc-ca9cdbfc-8ddc-4677-8a62-e1eb9b467d7c    #pvc-ca这个是自动创建的
ll /mnt/nfs/k8s | grep default-test-claim-pvc-ca9cdbfc-8ddc-4677-8a62-e1eb9b467d7c

5.4.6回收PVC

说明 :动态创建的PVC,删除PVC后,会自动删除对应的PV

bash 复制代码
kubectl delete pvc test-claim    #删除PVC
kubectl get pv

5.4.7测试前端

1.创建前端PVC

1.1编写yaml文件

bash 复制代码
vim pvc-webclaim.yml

添加以下内容:

bash 复制代码
kubectl apply -f pvc-webclaim.yml
kubectl get pvc webclaim

2.创建前端Web

bash 复制代码
vim deploy-web-secret-pvc-update.yml

添加以下内容:

bash 复制代码
apiVersion: "apps/v1"
kind: "Deployment"
metadata:
  name: "webserver"
spec:
  replicas: 3
  selector:
    matchLabels:
      app: "web"
  template:
    metadata:
      labels:
        app: "web"
    spec:
      containers:
      - name: "apache-frontend"
        image: "reg.westos.org/library/httpd:secure"
        ports:
        - containerPort: 80
        env:
        - name: DB_ROOT_PWD
          valueFrom:
            secretKeyRef:
              name: db-root-pwd
              key: dbpwd
        volumeMounts:
        - name: webenvvol
          mountPath: /etc/httpd/conf.d/env.conf
          subPath: env.conf
        - name: webdata
          mountPath: /var/www/html/
      volumes:
      - name: webenvvol
        configMap:
          name: webenv
      - name: webdata
        persistentVolumeClaim:
          claimName: webclaim    #配置webclaim

3.运行yaml文件

bash 复制代码
kubectl apply -f deploy-web-secret-pvc-update.yml
kubectl get pod -o wide

4.配置访问页面

1.配置访问页

bash 复制代码
kubectl get pvc webclaim
cd /mnt/nfs/k8s/default-webclaim-pvc-db0cf668-43e5-4fc3-864e-9a93f5aee7f6/
echo webclaim > index.html    #配置访问页面

2.访问web页面

bash 复制代码
kubectl get pod -o wide
curl 10.244.219.15
curl 10.244.109.94
curl 10.244.109.124

5.4.8测试后端

1.编写yaml文件

bash 复制代码
vim sts-db-cm-secret-pvc.yml

添加以下内容:

bash 复制代码
apiVersion: "apps/v1"
kind: "StatefulSet"
metadata:
  name: "dbserver"
spec:
  replicas: 3
  selector:
    matchLabels:
      app: "db"
  serviceName: "database"
  template:
    metadata:
      labels:
        app: "db"
    spec:
      containers:
      - name: "db-backend"
        image: "reg.westos.org/library/mysql:v2"
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-root-pwd
              key: dbpwd
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: configvol
          mountPath: /docker-entrypoint-initdb.d/
        - name: database    
          mountPath: /var/lib/mysql    #挂载数据目录
        resources:
          limits:
            cpu: 500m
            memory: 512Mi
      volumes:
        - name: configvol
          configMap:
            name: dbinit
  volumeClaimTemplates:
  - metadata:
      name: database
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1G

2.运行yaml文件

bash 复制代码
kubectl apply -f sts-db-cm-secret-pvc.yml
kubectl get pod -l app=db -o wide
kubectl get pvc

3.更新后端数据库

3.1创建新用户

bash 复制代码
kubectl port-forward dbserver-2 33060:3306 &    #完成端口映射
mysql -h 127.0.0.1 -P 33060 -u root -pmysql -e 'create user philip;'    #只修改dbserver-2的数据库
curl 192.168.7.100/cgi-bin/action    #由于存在三个后端,多个后端轮询访问,有一个能够看到

3.2删除后重建Pod

bash 复制代码
kubectl delete pod dbserver-2
kubectl get pod dbserver-2
curl 192.168.7.100/cgi-bin/action

5.5部署mysql分布式集群

5.5.1部署mysql主数据库

1.创建Service
适用场景: 该配置通常用于 需要提前发现节点 / Pod,或依赖未就绪状态下的网络通信的场景,

1.分布式集群初始化:某些分布式系统(如 ZooKeeper、Kafka)在启动过程中,即使节点未完全就绪(Ready),也需要互相发现并通信以完成集群初始化。

2.健康检查与故障恢复:允许监控系统或管理工具在 Pod 未就绪时仍能访问,以便诊断问题

**3.滚动更新过渡:**在滚动更新过程中,新 Pod 可能需要与旧 Pod 通信以同步数据,即使新 Pod 尚未完全就绪。

bash 复制代码
vim service-galera.yml

添加以下内容:

bash 复制代码
apiVersion: "v1"
kind: "Service"
metadata:
  name: "galera"
spec:
  publishNotReadyAddresses: true    #当设置 publishNotReadyAddresses: true 时,Service 会将 所有 Pod(无论是否就绪)的地址都发布到 DNS,客户端可以通过 DNS 解析到未就绪的 Pod IP。
  clusterIP: None
  ports:
  - protocol: "TCP"
    port: 3306
  selector:
    app: "mysql"

2.运行yaml文件

bash 复制代码
kubectl apply -f service-galera.yml
kubectl get svc galera

2.创建statefulset

2.1编写yaml文件

bash 复制代码
vim statefulset-galera.yml

添加以下内容:

bash 复制代码
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: "galera"
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      initContainers:
      - name: install
        image: reg.westos.org/library/galera-install:0.1
        args:
        - "--work-dir=/work-dir"
        volumeMounts:
        - name: workdir
          mountPath: "/work-dir"
        - name: config
          mountPath: "/etc/mysql"
      - name: bootstrap
        image: reg.westos.org/library/debian:jessie
        command:
        - "/work-dir/peer-finder"
        args:
        - -on-start="/work-dir/on-start.sh"
        - "-service=galera"
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        volumeMounts:
        - name: workdir
          mountPath: "/work-dir"
        - name: config
          mountPath: "/etc/mysql"
      containers:
      - name: mysql
        image: reg.westos.org/library/mysql-galera:e2e
        ports:
        - containerPort: 3306
          name: mysql
        - containerPort: 4444
          name: sst
        - containerPort: 4567
          name: replication
        - containerPort: 4568
          name: ist
        args:
        - --defaults-file=/etc/mysql/my-galera.cnf
        - --user=root
        readinessProbe:
          # TODO: If docker exec is buggy just use k8s.gcr.io/mysql-healthz:1.0
          exec:
            command:
            - sh
            - -c
            - "mysql -u root -e 'show databases;'"
          initialDelaySeconds: 15
          timeoutSeconds: 5
          successThreshold: 2
        volumeMounts:
        - name: datadir
          mountPath: /var/lib/
        - name: config
          mountPath: /etc/mysql
      volumes:
      - name: config
        emptyDir: {}
      - name: workdir
        emptyDir: {}
  volumeClaimTemplates:
  - metadata:
      name: datadir
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

2.2运行yaml文件

bash 复制代码
kubectl apply -f statefulset-galera.yml
kubectl get pod -l app=mysql -o wide

2.3运行镜像

bash 复制代码
kubectl run -it dbtest --rm --image=reg.westos.org/library/mysql -- bash
mysql -h galera -e "show status like 'wsrep_incoming_addresses'"
mysql -h galera -e "create database hadb;"
mysql -h mysql-0.galera -e "show databases;"
mysql -h mysql-1.galera -e "show databases;"
mysql -h mysql-2.galera -e "show databases;"

5.5.2回收数据库集群

bash 复制代码
kubectl scale --replicas=0 statefulset mysql
kubectl delete -f statefulset-galera.yml
相关推荐
孔令飞18 分钟前
企业智能化升级:智能体平台设计和实现
云原生·go·ai编程
分布式存储与RustFS17 小时前
镜像仓库的层别堆本地盘:用 RustFS 给 Docker Registry 当 S3 后端
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
闲云自留地1 天前
K8s 的记忆大脑!ETCD 集群部署、etcdctl 命令与备份恢复全通关
容器·kubernetes·etcd
weirong1 天前
Operator 上生产前补的 6 件事,和 5 件我明确不做的
kubernetes
孙克旭_1 天前
k8s基础组件与创建资源
运维·docker·容器·kubernetes
孙克旭_1 天前
云原生基础之Containerd容器运行时
运维·云原生
分布式存储与RustFS1 天前
RustFS 自建对象存储实战目录:110 篇按场景分类(持续更新)
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
java_logo2 天前
Docker 部署 EmulatorJS:轻松搭建浏览器复古游戏平台
游戏·docker·容器·复古游戏·轩辕镜像·emulatorjs·红白机
吴声子夜歌2 天前
Kubernetes权威指南——网络原理(一)
网络·容器·kubernetes