Kubernetes 系统化学习之 持久存储篇(五)

news2024/11/15 16:22:13

1. ConfigMap

ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。使用时,Pods 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。ConfigMap 的主要作用就是为了让镜像和配置文件解耦,以便实现镜像的可移植性和可复用性。

ConfigMap 并不提供保密或者加密功能。 如果你想存储的数据是机密的,请使用 Secret, 或者使用其他第三方工具来保证你的数据的私密性,而不是用 ConfigMap。

  • ConfigMap 的名字必须是一个合法的 DNS 子域名。

ConfigMap 创建的4种方式

注意:此处我们用到的例子中的 cm1, cm2, cm3, cm4 后续例子中也会引用到。

这里先给出几个查看 configmap 的命令:

# 查看 configmap 列表
kubectl get cm
# 查看某个 configmap 内容
kubectl describe cm cm1
复制代码
  1. 通过直接在命令行中指定configmap参数创建,即(--from-literal=key=value):
kubectl create configmap cm1 --from-literal=host=127.0.0.1 --from-literal=port=3306
复制代码
  1. 通过指定文件创建,即(--from-file=file):
echo -n 127.0.0.1 > host
echo -n 3306 > port
复制代码
kubectl create configmap cm2 --from-file=./host --from-file=./port
复制代码
  1. 通过一个文件内多个键值对,即(--from-env-file=file):
vim env.txt
复制代码
host=127.0.0.1
port=3306
复制代码
kubectl create configmap cm3 --from-env-file=env.txt
复制代码
  1. 通过 YMAL 文件创建(推荐使用):
vim cm4.yml
复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm4
data:
  host: 127.0.0.1
  port: "3306"
复制代码
kubectl apply -f cm4.yml
复制代码

ConfigMap 的2种使用方式

  1. 通过环境变量的方式传递给 pod
vim pod-cm1.yml
复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-cm1
spec:
  containers:
  - name: mysql-pod
    image: mysql:5.7
    args: [ "/bin/sh", "-c", "sleep 10000" ]
    envFrom:							# env方式
    - configMapRef:
        name: cm1						# configmap名称
复制代码
kubectl apply -f pod-cm1.yml
kubectl exec pod-cm1 --env
复制代码
  1. 通过 volume 的方式挂载到 pod 内
vim pod-cm2.yml
复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-cm2
spec:
  containers:
  - name: mysql-pod
    image: mysql:5.7
    args: [ "/bin/sh", "-c", "sleep 10000" ]
    volumeMounts:                               # 用volume挂载方式
    - name: vol-cm                              # 对应下面的volume名
      mountPath: "/etc/mysql"                   # 挂载到容器内部的路径
      readOnly: true                            # 只读

  volumes:
  - name: vol-cm                                # 卷名称
    configMap:
      name: cm2                                 # configmap的名称
复制代码
kubectl apply -f pod-cm2.yml
kubectl exec pod-cm2 – cat /etc/mysql/host
kubectl exec pod-cm2 – cat /etc/mysql/port
复制代码

使用 subpath 参数覆盖文件

cat index.html(内容是 ABCDEFG)
复制代码
kubectl create configmap nginx-index --from-file=index.html
复制代码
vim subpath-cm.yaml
复制代码
apiVersion: v1
kind: Pod
metadata:
  name: subpath-cm
spec:
  containers:
  - name: c1
    image: nginx:1.17.1-alpine
    volumeMounts:
    - name: nginx-config
      mountPath: /usr/share/nginx/html/index.html	# configmap要挂载并覆盖的绝对路径
      subPath: index.html				# 这里要写相对路径

  volumes:
  - name: nginx-config
    configMap:
      name: nginx-index					# 对应上面创建的configmap
复制代码
kubectl apply -f subpath-cm.yaml
复制代码

此时 nginx 的首页内容就已经被覆盖成了“ABCDEFG”。

ConfigMap 的热更新

  • 通过环境变量的方式传递给 pod,这种方式不会热更新。
  • 通过 volume 的方式挂载到 pod 内。这种方式会热更新, 大概需要半分钟左右
  • 但是使用 subpath 挂载文件,这种方式也不能热更新。

我们现在就来验证这种方式:

kubectl edit cm cm2
复制代码
apiVersion: v1
data:
  host: 127.0.0.1
  port: "3308"							 		 修改成3308
kind: ConfigMap
metadata:
  creationTimestamp: "2020-11-07T12:09:15Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:host: {}
        f:port: {}
    manager: kubectl
    operation: Update
    time: "2020-11-07T12:09:15Z"
  name: cm2
  namespace: default
  resourceVersion: "169707"
  selfLink: /api/v1/namespaces/default/configmaps/cm2
复制代码

验证对应的 pod 里的变化,一段时间后会改变:

kubectl exec pod-cm2 – cat /etc/mysql/port
复制代码

2. Secret

Secret 与 ConfigMap 类似, 主要区别是 Secret 存储的是密文, 而 ConfigMap 存储的是明文。

所以 ConfigMap 可以用配置文件管理, 而 Secret 可用于密码, 密钥, token 等敏感数据的配置管理。

Secret 的4种类型

  • Opaque: base64 编码格式的 Secret,用来存储密码、密钥、信息、证书等,类型标识符为 generic;
  • Service Account: 用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod的/run/secrets/kubernetes.io/serviceaccount目录中;
  • kubernetes.io/dockerconfigjson: 用来存储私有 docker registry 的认证信息,类型标识为docker-registry。
  • kubernetes.io/tls: 用于为 SSL 通信模式存储证书和私钥文件,命令式创建类型标识为 tls。

使用 Opaque 类型来创建 mysql 密码 Secret:

将明文密码进行base64编码

echo -n 123456 |base64
复制代码
MTIzNDU2
复制代码

编写创建secret的YAML文件

vim secret-mysql.yml
复制代码
apiVersion: v1
kind: Secret
metadata:
 name: secret-mysql
data:
 password: MTIzNDU2
复制代码

创建secret并确认

kubectl apply -f secret-mysql.yml
kubectl get secret |grep secret-mysql
复制代码

Secret 的2种使用方式

Secret结构与ConfigMap类似,均是键/值对的映射。Secret的使用方法也与ConfigMap相同。

  1. 通过环境变量的方式传递给 pod
vim pod-mysql-secret.yml
复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-mysql-secret1
spec:
  containers:
  - name: mysql-pod
    image: mysql:5.7
    env:
      - name: MYSQL_ROOT_PASSWORD
        valueFrom:
          secretKeyRef:
            name: secret-mysql				# 对应创建的secret名字
            key: password
复制代码
kubectl apply -f pod-mysql-secret.yml
复制代码
  1. 通过 volume 的方式挂载到 pod 内
vim pod-mysql-secret2.yml
复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-mysql-secret2
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 100000
    volumeMounts:
    - name: vol-secret                  # 定义挂载的卷,对应下面定义的卷名
      mountPath: "/opt/passwd"          # 挂载目录(支持热更新),也可以使用subPath挂载文件(但不支持热更新)
      readOnly: true                    # 只读
  volumes:
  - name: vol-secret                    # 定义卷名
    secret:                             # 使用secret
      secretName: secret-mysql          # 对应创建好的secret名
复制代码
kubectl apply -f pod-mysql-secret2.yml
复制代码

3. Volume

Pod 本身具有生命周期,这就带了一系列的问题,第一,当一个容器损坏之后,kubelet 会重启这个容器,但是文件会丢失-这个容器会是一个全新的状态;第二,当很多容器在同一 Pod 中运行的时候,很多时候需要数据文件的共享。Docker 支持配置容器使用存储卷将数据持久存储于容器自身文件系统之外的存储空间之中,它们可以是节点文件系统或网络文件系统之上的存储空间。相应的,Kubernetes 也支持类似的存储卷功能,不过,其存储卷是与 Pod 资源绑定而非容器。

Kubernetes 中的卷有明确的寿命 —— 与封装它的 Pod 相同。所以,卷的生命比 Pod 中的所有容器都长,当这个容器重启时数据仍然得以保存。当然,当 Pod 不再存在时,卷也将不复存在。也许更重要的是,Kubernetes 支持多种类型的卷,Pod 可以同时使用任意数量的卷。

Kubernetes 支持非常丰富的存储卷类型,包括本地存储(节点)和网络存储系统中的诸多存储机制,还支持 ConfigMapSecret 这样的特殊存储资源。 通过命令kubectl explain pod.spec可以查看当前 kubernetes 版本支持的存储卷类型。常用类型如下:

  • 非持久性存储
  • emptyDir
  • hostPath
  • 网络连接性存储
  • SAN:iscsi
  • NFS:nfs、cfs
  • 分布式存储
  • glusterfs、cephfs、rbd
  • 云端存储
  • awsElasticBlockStore、azureDisk、gitRepo

EmptyDir 存储卷

emptyDir 存储卷是 Pod 对象生命周期中的一个临时目录,类似于 Docker 上的 “docker 挂载卷”,在 Pod 对象启动时即被创建,而在 Pod 对象被移除时会被一并删除(永久删除)。Pod 中的容器都可以读写这个目录,这个目录可以被挂载到各个容器相同或者不相同的路径下。注意:一个容器崩溃了不会导致数据的丢失,因为容器的崩溃并不移除 Pod

emptyDir 的作用

  • 普通空间,基于磁盘的数据存储
  • 作为从崩溃中恢复的备份点
  • 存储那些需要长久保存的数据,例如 web 服务中的数据

emptyDir 的示例

这里定义了一个 Pod资源对象(vol-emptydir-pod),在其内部定义了两个容器,其中一个容器是辅助容器 sidecar,每隔10秒生成一行信息追加到 index.html 文件中;另一个是 nginx 容器,将存储卷挂载到站点家目录。然后访问 nginx 的 html 页面验证两个容器之间挂载的 emptyDir 实现共享。

vim vol-emptydir.yaml
复制代码
apiVersion: v1
kind: Pod
metadata:
  name: vol-emptydir-pod
spec:
  volumes:    #定义存储卷
  - name: html    #定义存储卷的名称
    emptyDir: {}    #定义存储卷的类型
  containers:
  - name: nginx
    image: nginx:1.12
    volumeMounts:    #在容器中定义挂载存储卷的名和路径
    - name: html
      mountPath: /usr/share/nginx/html
  - name: sidecar
    image: alpine
    volumeMounts:    #在容器中定义挂载存储卷的名和路径
    - name: html
      mountPath: /html
    command: ["/bin/sh", "-c"]
    args:
    - while true; do
        echo $(hostname) $(date) >> /html/index.html;
      sleep 10;
      done
复制代码
kubectl apply -f vol-emptydir.yaml 
复制代码

HostPath 存储卷

hostPath 类型的存储卷是指将工作节点上的某文件系统的目录或文件挂载于 Pod 中的一种存储卷,独立于 Pod 资源的生命周期,具有持久性。在 Pod 删除时,数据不会丢失。

hostPath 存储卷的 type 类型

type说明
DirectoryOrCreate指定的路径不存在时自动创建其权限为0755的空目录,属主和属组为kubelet
Directory必须存在的目录路径
FileOrCreate指定的路径不存在时自动创建其权限为0644的空文件,属主和属组为kubelet
File必须存在的文件路径
Socket必须存在的Socket文件路径
CharDevice必须存在的字符设备文件路径
BlockDevice必须存在的块设备文件路径

hostPath 的示例

vim vol-hostpath.yaml
复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-hostpath
  namespace: default
spec:
  containers:
  - name: myapp
    image: nginx:1.17.1
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html
    hostPath:
      path: /data/pod/volume1
      type: DirectoryOrCreate
复制代码
kubectl apply -f vol-hostpath.yaml
复制代码

NFS 存储卷

NFS 是 Network FileSystem 的缩写,顾名思义就是网络文件存储系统, 分为服务端(Server)和客户端(Client)。最早由 sun 公司开发,是类 unix 系统间实现磁盘共享的一种方法。 它允许网络中的计算机之间通过 TCP/IP 网络共享资源。通过 NFS,我们本地 NFS 的客户端应用可以透明地读写位于服务端 NFS 服务器上的文件,就像访问本地文件一样方便。简单的理解,NFS 就是可以透过网络,让不同的主机、不同的操作系统可以共享存储的服务。

NFS 在文件传送或信息传送过程中依赖于 RPC(Remote Procedure Call) 协议,即远程过程调用,NFS 的各项功能都必须要向 RPC 来注册,如此一来 RPC 才能了解 NFS 这个服务的各项功能 Port、PID、NFS 在服务器所监听的 IP 等,而客户端才能够透过 RPC 的询问找到正确对应的端口,所以,NFS必须要有 RPC 存在时才能成功的提供服务,简单的理解二者关系:NFS是 一个文件存储系统,而 RPC是负责信息的传输。

宿主机搭建 NFS

(1) 通过 yum 安装

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

(2) 建立网上邻居共享目录

mkdir /mnt/share
复制代码

(3) 配置这个共享目录

vim /etc/exports
复制代码

写入下边的内容:

/mnt/share	192.168.138.0/24(rw,no_root_squash,async,fsid=0)
复制代码

(4) 使配置内容生效

exportfs -r 
复制代码

(5) 启动 rpcbind、nfs 服务及开机自启动

systemctl start rpcbind
systemctl start nfs
systemctl enable rpcbind
systemctl enable nfs
复制代码

4. PV 和 PVC

前面提到 Kubernetes 提供那么多存储接口,但是首先 Kubernetes 的各个 Node 节点能管理这些存储,但是各种存储参数也需要专业的存储工程师才能了解,由此我们的 Kubernetes 管理变的更加复杂。由此 kubernetes 提出了 PV 和 PVC 的概念,这样开发人员和使用者就不需要关注后端存储是什么,使用什么参数等问题。

PV

PersistentVolume(PV)是集群中已由管理员配置的一段网络存储。集群中的资源就像一个节点是一个集群资源。PV 是诸如卷之类的卷插件,但是具有独立于使用 PV 的任何单个 Pod 的生命周期。该 API 对象捕获存储的实现细节,即 NFS,ISCSI或云提供商特定的存储系统。

PVC

PersistentVolumeClaim(PVC)是用户存储的请求。它类似于 Pod。Pod 消耗节点资源,PVC 消耗存储资源。Pod 可以请求特定级别的资源(CPU 和内存)。权限要求可以请求特定的大小和访问模式。

虽然 PersistentVolumeClaims 允许用户使用抽象存储资源,但是常见的是,用户需要具有不同属性(如性能)的 PersistentVolumes ,用于不同的问题。集群管理员需要能够提供多种不同于 PersistentVolumes 的 PersistentVolumes ,而不仅仅是大小和访问模式,而不会使用户了解这些卷的实现细节。对于这些需求,存在 StorageClass 资源。

StorageClass 为管理员提供了一种描述他们提供的存储的“类”的方法。不同的类可能映射到服务质量级别,或备份策略,或者由集群管理员确定的任意策略。Kubernetes 本身对于什么类别代表是不言而喻的。这个概念有时在其它存储系统中称为“配置文件”。

生命周期

PV 是集群中的资源。PVC 是对这些资源的请求,也是对资源的索赔检查。PV 和 PVC 之间的相互作用遵循这个生命周期:

Provisioning —> Binding —> Using —> Releasing —> Recycling
复制代码
  1. 供应准备(Provisioning)

PV 有两种提供方式:静态或者动态

  • Static:集群管理员创建多个 PV 。它们携带可供集群用户使用的真实存储的详细信息。它们存在于 Kubernetes API 中,可用于消费。
  • Dynamic:当管理员创建的静态 PV 都不匹配用户的 PersistentVolumesClaim 时,集群可能会尝试为 PVC 动态配置卷。此配置基于 StorageClasses:PVC 必须请求一个类,并且管理员必须已经创建并配置该类才能进行动态配置。要求该类的声明有效地为自己禁用动态配置。
  1. 绑定(Binding)

用户创建 PVC 并指定需要的资源和访问模式。在找到可用 PV 之前,PVC 会保持未绑定状态。

  1. 使用(Using)

用户可在 Pod 中像 volume 一样使用 PVC。

  1. 释放(Releasing)

用户删除 PVC 来回收存储资源,PV 将变成 “released” 状态。由于还保留着之前的数据,这些数据要根据不同的策略来处理,否则这些存储资源无法被其它 PVC 使用。

  1. 回收(Recycling)

PV 可以设置三种回收策略:保留(Retain)、回收(Recycle)和删除(Delete)。

PV 字段说明

PersistentVolume Spec 主要支持以下几个通用字段,用于定义 PV 的容量、访问模式、和回收策略:

字段说明
capacity当前PV的容量;目前,capacity仅支持空间设定,将来应该还可以指定IOPS和throughput。
accessModes访问模式;尽管在PV层看起来并无差异,但存储设备支持及启用的功能特性却可能不尽相同。例如NFS存储支持多客户端同时挂载及读写操作,但也可能是在共享时仅启用了只读操作,其他存储系统也存在类似的可配置特性。因此,PV底层的设备或许存在其特有的访问模式,用户使用时必须在其特性范围内设定其功能。
- ReadWribeOnce:仅可被单个节点读写挂载;命令行中简写为RWO。
- ReadOnlyMany:可被多个节点同时只读挂载;命令行中简写为ROX。
- ReadWriteMany:可被多个节点同时读写挂载;命令行中简写为RWX。
persistentVolumeReclaimPolicyPV空间被释放时的处理机制;可用类型仅为Retain(默认)、Recycle或Delete,具体说明如下。
- Retain:保持不动,由管理员随后手动回收。
- Recycle:空间回收,即删除存储卷目录下的所有文件(包括子目录和隐藏文件),目前仅NFS和hostPath支持此操作。
- Delete:删除存储卷,仅部分云端存储系统支持,如AWS EBS、GCE PD、Azure Disk和Cinder。
volumeMode卷模型,用于指定此卷可被用作文件系统还是裸格式的块设备;默认为Filesystem。
storageClassName当前PV所属的StorageClass的名称;默认为空值,即不属于任何StorageClass。
mountOptions挂载选项组成的列表,如ro、soft和hard等。

PVC 字段说明

PersistentVolumeClaim 是存储卷类型的资源,它通过申请占用某个 PersistentVolume 而创建,它与 PV 是一对一的关系,用户无须关系其底层实现细节。申请时,用户只需要指定目标空间的大小、访问模式、PV标签选择器和 StorageClass 等相关信息即可。PVC 的 Spec 字段的可嵌套字段具体如下:

字段说明
accessModes当前PVC的访问模式,其可用模式与PV相同
resources当前PVC存储卷需要占用的资源量最小值;目前,PVC的资源限定仅指其空间大小
selector绑定时对PV应用的标签选择器(matchLabels)或匹配条件表达式(matchEx-pressions),用于挑选要绑定的PV;如果同时指定了两种挑选机制,则必须同时满足两种选择机制的PV才能被选出
storageClassName所依赖的存储卷的名称
volumeMode卷模型,用于指定此卷可被用作于文件系统还是裸格式的块设备;默认为“Filesystem”
volumeName用于直接指定要绑定的PV的卷名

示例使用 PV 和 PVC

准备了一台 NFS Server 创建了几个共享目录提供给 Kubernetes 作为 PV 使用。在创建 PV 的同时指定了不同的大小和不同的访问权限,然后在创建 PVC 时候指定了大小为 6Gi ,故满足条件的 PV 只有 pv003~pv005 ,这里通过标签选择器选择了 pv003 。Pod中的容器使用了 MySQL,并将 MySQL 的数据目录挂载到 PV 上。示例图如下:

  1. 准备 NFS 服务
(1)创建存储卷对应的目录
[root@storage ~]# mkdir /data/volumes/v{1..5} -p

(2)修改nfs的配置文件
[root@storage ~]# vim /etc/exports
/data/volumes/v1  192.168.1.0/24(rw,no_root_squash)
/data/volumes/v2  192.168.1.0/24(rw,no_root_squash)
/data/volumes/v3  192.168.1.0/24(rw,no_root_squash)
/data/volumes/v4  192.168.1.0/24(rw,no_root_squash)
/data/volumes/v5  192.168.1.0/24(rw,no_root_squash)

(3)查看nfs的配置
[root@storage ~]# exportfs -arv
exporting 192.168.1.0/24:/data/volumes/v5
exporting 192.168.1.0/24:/data/volumes/v4
exporting 192.168.1.0/24:/data/volumes/v3
exporting 192.168.1.0/24:/data/volumes/v2
exporting 192.168.1.0/24:/data/volumes/v1

(4)使配置生效
[root@storage ~]# showmount -e
Export list for storage:
/data/volumes/v5 192.168.1.0/24
/data/volumes/v4 192.168.1.0/24
/data/volumes/v3 192.168.1.0/24
/data/volumes/v2 192.168.1.0/24
/data/volumes/v1 192.168.1.0/24
复制代码
  1. 创建 PV;这里创建 5 个 PV ,存储大小各不相等,是否可读也不相同
vim pv-nfs-demo.yaml
复制代码
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs-001
  labels:
    name: pv001
spec:
  nfs:
    path: /data/volumes/v1
    server: 192.168.1.34
    readOnly: false 
  accessModes: ["ReadWriteOnce","ReadWriteMany"]
  capacity:
    storage: 2Gi
  persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs-002
  labels:
    name: pv002
spec:
  nfs:
    path: /data/volumes/v2
    server: 192.168.1.34
    readOnly: false 
  accessModes: ["ReadWriteOnce"]
  capacity:
    storage: 5Gi
  persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs-003
  labels:
    name: pv003
spec:
  nfs:
    path: /data/volumes/v3
    server: 192.168.1.34
    readOnly: false 
  accessModes: ["ReadWriteOnce","ReadWriteMany"]
  capacity:
    storage: 10Gi
  persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs-004
  labels:
    name: pv004
spec:
  nfs:
    path: /data/volumes/v4
    server: 192.168.1.34
    readOnly: false 
  accessModes: ["ReadWriteOnce","ReadWriteMany"]
  capacity:
    storage: 15Gi
  persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs-005
  labels:
    name: pv005
spec:
  nfs:
    path: /data/volumes/v5
    server: 192.168.1.34
    readOnly: false 
  accessModes: ["ReadWriteOnce","ReadWriteMany"]
  capacity:
    storage: 20Gi
  persistentVolumeReclaimPolicy: Retain
复制代码
kubectl apply -f pv-nfs-demo.yaml 
复制代码
  1. 创建 PVC ,绑定 PV
vim vol-nfs-pvc.yaml
复制代码
#创建PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  accessModes: ["ReadWriteMany"]
  resources:
    requests:
      storage: 6Gi    #指定PVC大小为6Gi
  selector:    #这里通过标签选择器指定了所使用的pv卷为key为name,value为pv003的pv资源
    matchLabels:
      name: pv003
---
#创建Pod
apiVersion: v1
kind: Pod
metadata:
  name: pvc-mysql
  labels:
    app: mysql
spec:
  containers:
  - name: pvc-mysql-pod
    image: mysql:latest
    imagePullPolicy: IfNotPresent
    ports:
    - name: mysqlport
      containerPort: 3306
    volumeMounts: 
    - name: mysqldata
      mountPath: /var/lib/mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "mysql"
  volumes:
  - name: mysqldata
    persistentVolumeClaim:  #通过该字段定义使用pvc
      claimName: nfs-pvc    #指定pvc的名称
      readOnly: false       #关闭只读

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/12448.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

day07 Elasticsearch搜索引擎3

day07 Elasticsearch搜索引擎3 1、数据聚合 聚合(aggregations)可以让我们极其方便的实现对文档数据的统计、分析、运算。例如: 什么品牌的手机最受欢迎?这些手机的平均价格、最高价格、最低价格?这些手机每月的销售…

java设计模式之观察者模式

一:观察者模式 1.什么是观察者模式? 观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。 观察者模式的基本介绍 又被称为发布-订阅(Publish/Subscribe&#xff09…

从阿里云容器攻防矩阵API安全生命周期,看如何构建金融安全云原生平台

【编者按】云原生技术正在助力银行通过差异化业务进行创新,却也带来了由于研发/运维人员对新架构不熟悉所导致的基础设施风险、业务风险及数据暴露风险。如何在飞速更迭的技术环境下保持业务持续发展,同时保证业务整体的安全性,满足不断增强的…

设计模式-装饰器模式

装饰器模式也称为包装模式是指在不改变原有对象的基础上,将功能附加到对象上,提供比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式 装饰器模式的核心是功能扩展,使用装饰器模式可以透明且动态的扩展类的功能 装饰器模式通用UML类图 主要角…

培训学校管理系统之家校管理

近年来,伴随着信息技术的进步。除了不少学校开展了数字化校园的建设,一些培训机构也在使用数字化系统进行管理。同时,由于招生数量的不断增长,如何解决学生、教师、家长三者之间的联系沟通问题,促进教学管理任务的有效…

排序(详解)

排序排序的概念常见的排序算法直接插入排序希尔排序(缩小增量排序)选择排序堆排序冒泡排序快排(递归)霍尔版本挖坑法前后指针法快排(非递归)归并排序(递归)归并排序(非递…

区块链动态化监管方案

前言 监控运维模块是区块链BaaS的核心模块之一,我们针对联盟链、主机和系统等多个监控对象提供丰富的监控指标。通过BaaS提供的综合监控大屏,用户可直观洞悉区块链业务全局,实现7*24小时监控全覆盖。 但随着BaaS业务的扩展,对监…

jsp教师教学信息管理系统Myeclipse开发sqlserver数据库web结构java编程计算机网页项目

一、源码特点 JSP 教师教学信息管理系统 是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库文,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为sqlserver2008…

微服务拆分总结(一)

微服务要解决的问题: 1、可以快速迭代; 2、解决三高问题(高并发,高可用,高性能) 什么时候拆分微服务,拆分的时机是什么? 提交频繁代码冲突; 模块之间耦合严重&#…

RocketMQ 重试机制详解及最佳实践

作者:斜阳 引言 本文主要介绍在使用 RocketMQ 时为什么需要重试与兜底机制,生产者与消费者触发重试的条件和具体行为,如何在 RocketMQ 中合理使用重试机制,帮助构建弹性,高可用系统的最佳实践。 RocketMQ 的重试机制…

[附源码]java毕业设计静谧空间自习室预订系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

服务器部署Vue2脚手架的PIXI游戏项目-知识点注意

文章目录安装PIXI框架方式一(安装)方式二(引入)javaScript代码位置initPixi方法组件挂载完毕后调用注意文件导入使用import一个个导入并命名使用setTimeout()方法使用一般方法调用表达式使用安装PIXI框架 方式一(安装…

高通量筛选检测方法-分子篇

分子水平的筛选更多的是检测酶/受体功能的改变或探针/蛋白质结合的抑制,或是检测蛋白质-配体结合的结构、动力学和亲和度。 下面将介绍了荧光偏振、荧光共振能量转移、酶联免疫吸附、表面等离子共振和核磁共振技术几种方法。 ■ 荧光偏振 荧光偏振是一项在高通量筛…

2-STM32GPIO输入之按键

文章目录1-硬件设计1.1 按键消斗1.1.1 RS触发器1.1.2 电容滤波2 按键电路设计2.1 软件消斗2.2 硬件消斗2.3 检测原理2-软件设计2.1 软件消斗2.1.1原理2.1.2 编程要点2.1.3 步骤2.2 代码编写2.2.1 主程序2.2.2 按键初始化2.2.2 按键扫描本章讲述GPIO输入的应用,使用独…

第03章_用户与权限管理

第03章_用户与权限管理1 用户管理1.1 登录MySQL服务器1.2 创建用户1.3 修改用户1.4 删除用户1.5 设置当前用户密码1.6 修改其它用户密码1.7 MySQL8密码管理(了解)2. 权限管理2.1 权限列表2.2 授予权限的原则2.3 授予权限2.4 查看权限2.5 收回权限3. 权限表3.1 user表3.2 db表3.…

【springboot】18、内置 Tomcat 配置和切换

文章目录基本介绍Tomcat配置切换其他Web服务总结基本介绍 SpringBoot 支持的 webServer有: Tomcat, Jetty, or Undertow,我们使用spring-boot-starter-web进行web开发时,默认使用的就是Tomcat,下面来说明一下tomcat的配置以及切换其他的Web服…

小啊呜产品读书笔记001:《邱岳的产品手记-05》第9讲 产品案例分析:Hopper的“人工智能” 第10讲 产品被抄袭了怎么办?

小啊呜产品读书笔记001:《邱岳的产品手记-05》第9讲 产品案例分析:Hopper的“人工智能” & 第10讲 产品被抄袭了怎么办?一、今日阅读计划二、泛读&知识摘录1、09 讲 产品案例分析:Hopper的“人工智能”2、10 讲 产品被抄袭…

《机器学习实战》8.预测数值型数据:回归

目录 预测数值型数据:回归 1 利用线性回归找到最佳拟合直线 2 局部加权线性回归 3 示例:预测鲍鱼的年龄 4 缩减系数来“理解”数据 4.1 岭回归 4.2 lasso 4.3 前向逐步回归 5 权衡偏差与方差 6 示例:预测乐高玩具套装的价格 6.1 收…

数字化转型指南发布,官方明确这样做!

上周,工信部《中小企业数字化转型指南》(以下简称《指南》)一经发布,便获得了大量官方媒体的转发,成为了几乎所有制造人的关注所在。制造企业数字化转型的标准路径首次被标准化,并传递给了更多的中国制造企…

python可以考的资格认证有哪些?

前言 可以考虑用Python做一个博客,或者仿制一个微博,或者仿制一个视频网站,或者仿制一个购物网站。界面简单一些,但是基础功能好用就行。(文末送读者福利) 2.或者学习用Python在网上爬一些数据&#xff0…