kubernetes--配置与存储(ConfigMap、加密数据配置Secret、SubPath、热更新、Volumes、NFS挂载、PV与PVC)

news2024/12/23 22:18:33

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 

出自B站博主教程笔记: 

完整版Kubernetes(K8S)全套入门+微服务实战项目,带你一站式深入掌握K8S核心能力_哔哩哔哩_bilibiliicon-default.png?t=O83Ahttps://www.bilibili.com/video/BV1MT411x7GH/?spm_id_from=333.337.search-card.all.click

一、配置管理

1、ConfigMap

一般用于去存储 Pod 中应用所需的一些配置信息,或者环境变量,将配置于 Pod 分开,避免应为修改配置导致还需要重新构建镜像与容器。 例如:明文键值对

1.1、创建

 [root@master ~]# kubectl create configmap -h  # 可查看实例学习,例如
 Examples:
  # Create a new config map named my-config based on folder bar
  kubectl create configmap my-config --from-file=path/to/bar
  ...

示例1指定某个文件夹,其中存放着配置文件

 # mkdir test/
 [root@master ~]# touch db.properties
 [root@master ~]# vim db.properties
 username=root
 password=admin
 [root@master ~]# vim redis.properties
 host: 127.0.0.1
 port: 3306
 [root@master ~]# kubectl create configmap test-dir-config --from-file=test/
 [root@master ~]# kubectl get cm
 NAME                DATA        AGE
 kube-root-ca.art    1           20h
 kube-dir-config     2           7s
 [root@master ~]# kuebctl describe cm test-dir-config
 Name:           test-dir-config
 Namepspace:     default
 Labels:         <none>
 Annotations:    <none>
 ​
 Data:                   # 可以看到配置文件的信息
 ...

示例二常用的,基于指定的文件创建

 [root@master ~]# vim application.yaml
 spring:
   application:
     name: test-app
 server:
   port: 8080
 [root@master ~]# kubectl create cm spring-boot-test-yaml --from-file=/opt/k8s/config/aplication.yaml
 [root@master ~]# kubectl get cm
 NAME                    DATA        AGE
 kube-root-ca.art        1           20h
 kube-dir-config         2           7m
 spring-boot-test-yaml   2           8s
 [root@master ~]# kuebctl describe cm spring-boot-test-yaml
 Name:               spring-boot-test-yaml
 Namespace:          default
 Labels:             <none>
 Annotations:        <none>
 ​
 Data
 ====
 application.yaml:
 ----
 ...
 # 还可使用另外一种取别名的方式创建
 [root@master ~]# kubectl create cm spring-boot-test-yaml --from-file=app.yml=/opt/k8s/config/aplication.yaml
 [root@master ~]# kuebctl describe cm spring-boot-test-yaml
 Name:               spring-boot-test-yaml
 Namespace:          default
 Labels:             <none>
 Annotations:        <none>
 ​
 Data
 ====
 app.yml:        # 注意这里名称将变为自己取的别名
 ​
 # 再另一种方式;自己写配置文件的参数,在命令之中
 [root@master ~]# kubectl create cm test-key-value-config --from-literal=username=root --from-literal=password=admin

1.2、使用ConfigMap

编写一个环境变量的配置,默认挂载到环境变量之中:

 [root@master ~]# kubectl create cm test-env-config --from-literal=JAVA-OPTS-TEST='-Xmx512m -Xms=512m' --from-literal=APP_NAME=springboot-env-test
 [root@master ~]# vim env-test-pod.yaml
 apiVersion: v1
 metadata:
   name: test-env-po
 spec:
   containers:
   - name: env-test
     image: alpine
     command: ["/bin/sh"."-c","env;sleep 3600"]
     imagePullPolicy: IfNotPresent
     env: 
     - name: JAVA_VM_OPTS
       valueFrom:
         configMapKeyRef:
           name: test-env-config     # configMap 的名字
           key: JAVA_OPTS_TEST       # 表示从name的ConfigMap中获取名字为key的value,将其赋值给本地环境变量JAVA_VM_OPTS
     - name: APP
       valueFrom:
         configMapKeyRef:
           name: test-env-config
           key: APP_NAME
   restartPolicy: Never
 [root@master ~]# kubectl create -f env-test-pod.yaml 
 [root@master ~]# kubectl get po
 Name                READY   STATUS                  RESTARTS        AGE
 ...
 test-env-po         1/1     Running                 0               23s
 ​
 # 打印容器的日志信息,会发现日志输出的环境变量中包含了我们创建cm时的配置信息
 [root@master ~]# kubectl logs -f test-env-po
 ...
 JAVA_VM_OPTS=-Xms512m -Xms512m
 APP=springboot-env-test
 ...

将1中基于文件夹的配置创建方式中的配置加载到我们的容器中,实现步骤:

 [root@master ~]# vim file-test-pod.yaml
 apiVersion: v1
 metadata:
   name: test-configfile-po
 spec:
   containers:
   - name: config-test
     image: alpine
     command: ["/bin/sh"."-c","sleep 3600"]
     imagePullPolicy: IfNotPresent
     volumeMounts:       # 加载数据卷
     - name: db-config   # 加载volumes 属性中哪个数据卷
       mountPath: "/usr/local/mysql/conf"    # 想要将数据卷中的文件加载到哪个目录下
       readOnly: true    # 是否只读,默认为false
   volumes:      # 数据卷挂载 configmap、secret
     - name: db-config       # 数据卷的名字
       configMap:            # 数据卷类型为configMap
         name: test-dir-config   # configMap的名字,和想要加载的configmap相同
         items:      # 将configMap中的key进行映射,若不指定,则会将configMap中所有key全部转换为诶一个个同名的文件
         - key: "db.properties"  # configMap中的key
           path: "db.properties" # 将该configMap的值转换为文件
   restartPolicy: Never
 [root@master ~]# kubectl create -f file-test-pod.yaml
 [root@master ~]# kubectl get po
 NAME                    READY       STATUS      RESTARTS        AGE
 ...
 test-configfile-po      1/1         Running     0               4s
 [root@master ~]# kubectl exec -it test-configfile-po -- sh
 / # cd /usr/local/mysql/conf/
 /usr/local/mysql/conf # ls
 db.properties
 /usr/local/mysql/conf # cat db.properties
 username=root
 password=admin

2、加密数据配置Secret

与 ConfigMap 类似,用于存储配置信息,但是主要用于存储敏感信息、需要加密的信息,Secret 可以提供数据加密、解密功能

在创建 Secret 时,要注意如果要加密的字符中,包含了有特殊字符,需要使用转义符转移,例如 $转移后为\ $,也可以对特殊字符使用单引号描述,这样就不需要转移例如 1​$289*-! 转换为 '1$289*-!'

不常用;更多用在Docker私有镜像仓库的一个拉取;

2.1、创建

 [root@master ~]# kubectl create secret generic orig-secret --from-literal=username=admin --from-literal=password='ds@!3/'

2.2、使用

在Docker私有镜像仓库的一个拉取中使用;主要使用配置的账号密码进行私有镜像仓库的登录;

 [root@master ~]# kubectl create secret docker-registry harbor-secret --docker-username=admin --docker-password=wolfcode --docker-email=liu@wolfcode.cn --docker-server=192.168.113.122:8858
 [root@nde2 ~]# docker images
 [root@node2 ~]# docker tag nginx:1.9.1 192.168.113.122:8858/opensource/nginx:1.9.1
 [root@node2 ~]# docker login -uadmin 192.168.113.122:8858
 [root@node2 ~]# docker push 192.168.113.122:8858/opensource/nginx:1.9.1
 # 此时,我们远程docker私有仓库中就有这个nginx镜像了

我们再去另一个节点中创建一个新的pod,使用这个进行拉取

 [root@master ~]# vim private-image-pull-pod.yaml
 apiVersion: v1
 metadata:
   name: private-image-pull-pod
 spec:
   imagePullSecrets:     # 配置登录docker registry的secret
   - name: harbor-secret # 指定从这个Secret中的账号密码登录镜像中心
   containers:
   - name: nginx
     image: 192.168.113.122:8858/opensource/nginx:1.9.1
     command: ["/bin/sh"."-c","sleep 3600"]
     imagePullPolicy: IfNotPresent
     volumeMounts:       
     - name: db-config   
       mountPath: "/usr/local/mysql/conf"    
       readOnly: true    
   volumes:      
     - name: db-config       
       configMap:            
         name: test-dir-config
         items:      
         - key: "db.properties"  
           path: "db.properties"
   restartPolicy: Never
 [root@master ~]# kubectl create -f private-imag-pull-pod.yaml

3、SubPath的使用

使用 ConfigMap 或 Secret 挂载到目录的时候,会将容器中源目录给覆盖掉,此时我们可能只想覆盖目录中的某一个文件,但是这样的操作会覆盖整个文件,因此需要使用到 SubPath

配置方式:

  1. 定义 volumes 时需要增加 items 属性配置 key 和 path且 path 的值不能从 / 开始
  2. 在容器内的 volumeMounts 中增加 subPath 属性,该值与 volumes 中 items.path 的值相同

 containers:
   ......
   volumeMounts:     
     - mountPath: /etc/nginx/nginx.conf # 挂载到哪里
       name: config-volume # 使用哪个 configmap 或 secret
       subPath: etc/nginx/nginx.conf # 与 volumes.[0].items.path 相同
 volumes:
 - configMap:
   name: nginx-conf # configMap 名字
   items: # subPath 配置
     key: nginx.conf # configMap 中的文件名
     path: etc/nginx/nginx.conf # subPath 路径

4、配置的热更新

我们通常会将项目的配置文件作为 configmap 然后挂载到 pod,那么如果更新 configmap 中的配置,会不会更新到 pod 中呢?

这得分成几种情况:

  • 默认方式会更新,更新周期是更新时间 + 缓存时间
  • subPath不会更新
  • 变量形式如果 pod 中的一个变量是从 configmap 或 secret 中得到,同样也是不会更新的

对于 subPath 的方式,我们可以取消 subPath 的使用将配置文件挂载到一个不存在的目录,避免目录的覆盖,然后再利用软连接的形式,将该文件链接到目标位置

但是如果目标位置原本就有文件,可能无法创建软链接,此时可以基于前面讲过的 postStart 操作执行删除命令,将默认的文件删除即可

4.1、通过 edit 命令直接修改 configmap

 # 在一个没有配置SubPath的Pod进行操作,直接对cm进行修改操作,等待后,会发现基于此configMap创建的pod里的配置会更新!!!
 [root@master ~]# kubectl edit cm test-dir-config 

4.2、通过 replace 替换

由于 configmap 我们创建通常都是基于文件创建,并不会编写 yaml 配置文件,因此修改时我们也是直接修改配置文件,而 replace 是没有 --from-file 参数的,因此无法实现基于源配置文件的替换,此时我们可以利用下方的命令实现

# 该命令的重点在于 --dry-run 参数,该参数的意思打印 yaml 文件,但不会将该文件发送给 apiserver,再结合 -oyaml 输出 yaml 文件就可以得到一个配置好但是没有发给 apiserver 的文件,然后再结合 replace 监听控制台输出得到 yaml 数据即可实现替换

 # 编辑一个新的配置文件
 [root@master ~]# vim /test/db.properties
 [root@master ~]# ls 
 db.properties test
 # 通过replace进行替换
 [root@master ~]# kubectl create cm test-dir-config --from-file=./test/ --dry-run -o yaml | kubectl replace -f- 

5、不可变的Secret和ConfigMap

对于一些敏感服务的配置文件,在线上有时是不允许修改的,此时在配置 configmap 时可以设置 immutable: true 来禁止修改不可逆

二、持久化存储

1、Volumes

1.1、HostPath

节点上的文件或目录挂载到 Pod 上,此时该目录会变成持久化存储目录,即使 Pod 被删除后重启,也可以重新加载到该目录,该目录下的文件不会丢失 ;

 apiVersion: v1
 kind: Pod
 metadata:
   name: test-volume-pd
 spec:
   containers:
   - image: nginx
     name: nginx-volume
     volumeMounts:
     - mountPath: /test-pd # 挂载到容器的哪个目录
       name: test-volume # 挂载哪个 volume
   volumes:
   - name: test-volume
     hostPath:       # 与主机共享目录,加载主机中指定目录到容器中
       path: /data   # 节点中的目录
       type: Directory   # 检查类型,在挂载前对挂载目录做什么检查操作,有多种选项,默认为空字符串,不做任何检查
检查类型作用
空字符串默认类型,不做任何检查
DirectoryOrCreate如果给定的 path 不存在,就创建一个 755 的空目录
Directory这个目录必须存
FileOrCreate如果给定的文件不存在,则创建一个空文件,权限为 644
File这个文件必须存在
Socket:UNIX套接字,必须存在
CharDevice字符设备,必须存在
BlockDevice块设备,必须存在

1.2、EmptyDir

EmptyDir 主要用于一个 Pod 中不同的 Container 共享数据使用的,由于只是在 Pod 内部使用,因此与其他 volume 比较大的区别是,当 Pod 如果被删除了,那么 emptyDir 也会被删除

存储介质可以是任意类型,如 SSD、磁盘或网络存储。可以将 emptyDir.medium 设置为 Memory 让 k8s 使用 tmpfs(内存支持文件系统),速度比较快,但是重启 tmpfs 节点时,数据会被清除,且设置的大小会计入到 Container 的内存限制中。

 # vim empty-dir-dp.yaml
 apiVersion: v1
 kind: Pod
 metadata:
   name: empty-dir-pd
 spec:
   containers:
   - image: alpine
     name: nginx-emptydir1
     cammand: ["/bin/sh","-c","sleep 3600;"] # 让容器保持运行
     volumeMounts:
     - mountPath: /cache
       name: cache-volume
   - image: alpine
     name: nginx-emptydir2
     cammand: ["/bin/sh","-c","sleep 3600;"] 
     volumeMounts:
     - mountPath: /opt
       name: cache-volume
   volumes:
   - name: cache-volume
     emptyDir: {}    # 起共享作用
# kubectl create -f empty-dir-pd.yaml
# kubectl get po
分别进入nginx-emptydir1和nginx-emptydir2中,发现实现了pod中的两个容器之间的数据共享
# kubectl exec -it empty-dir-pd -c nginx-emptydir1 -- sh
/ # cd  /cache
/cache # touch a.txt

# kubectl exec -it empty-dir-pd -c nginx-emptydir2 -- sh
/ # cd /opt
/opt # ls
a.txt

2、NFS挂载

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

2.1、安装NFS

 # 安装 nfs
 yum install nfs-utils -y
 # 启动 nfs
 systemctl start nfs-server
 # 查看 nfs 版本
 cat /proc/fs/nfsd/versions
 ​
 # 在磁盘较大的节点中创建共享目录
 mkdir -p /data/nfs
 cd /data/nfs
 mkdir rw
 mkdir ro
 ​
 # 设置共享目录 export
 vim /etc/exports
 /data/nfs/rw 192.168.113.0/24(rw,sync,no_subtree_check,no_root_squash)
 /data/nfs/ro 192.168.113.0/24(ro,sync,no_subtree_check,no_root_squash)
 ​
 # 重新加载
 exportfs -f
 systemctl reload nfs-server
 ​
 # 到其他测试节点安装 nfs-utils 并加载测试
 mkdir -p /mnt/nfs/rw
 # 加载作为共享目录的节点中的目录文件,填写共享目录主机IP
 mount -t nfs 192.168.113.121:/data/nfs/rw /mnt/nfs/rw

2.2、配置文件

 # vim nfs-test-pd.yaml
 apiVersion: v1
 kind: Pod
 metadata:
   name: nfs-test-pd
 spec:
   containers:
   - image: nginx
     name: test-container
     volumeMounts:
     - mountPath: /my-nfs-data
       name: test-volume
   volumes:
   - name: test-volume
     nfs:
       server: my-nfs-server.example.com # 网络存储服务地址
       path: /my-nfs-volume      # 网络存储路径
       readOnly: true            # 是否只读

3、PV与PVC

持久卷(PersistentVolume,PV)是集群中的一块存储,可由管理员事先制备,或用存储类(Storage Class)来动态制备。持久卷是集群资源,就像节点也是集群资源一样。PV与普通Volume不同之处在于它拥有独立于任何使用PV的Pod的生命周期

持久卷申领(PersistentVolumeClain,PVC)表达的是用户对存储的请求。Pod会耗用节点资源,而PVC申领会耗用PV资源。Pod可以请求特定数量的资源(CPU和内存);同样PVC申领也可以请求特定大小和访问模式

3.1、生命周期

(1)构建

静态构建

集群管理员创建若干 PV 卷。这些卷对象带有真实存储的细节信息, 并且对集群用户可用(可见)。PV 卷对象存在于 Kubernetes API 中,可供用户消费(使用)。

动态构建

如果集群中已经有的 PV 无法满足 PVC 的需求,那么集群会根据 PVC 自动构建一个 PV,该操作是通过 StorageClass 实现的。

想要实现这个操作,前提是 PVC 必须设置 StorageClass,否则会无法动态构建该 PV,可以通过启用 DefaultStorageClass 来实现 PV 的构建

(2)绑定

当用户创建一个 PVC 对象后,主节点会监测新的 PVC 对象,并且寻找与之匹配的 PV 卷,找到 PV 卷后将二者定在一起。

如果找不到对应的 PV,则需要看 PVC 是否设置 StorageClass 来决定是否动态创建 PV,若没有配置,PVC 就会一致处于未绑定状态,直到有与之匹配的 PV 后才会申领绑定关系。

(3)使用

Pod 将 PVC 当作存储卷来使用,集群会通过 PVC 找到绑定的 PV,并为 Pod 挂载该卷。

Pod 一旦使用 PVC 绑定 PV 后,为了保护数据,避免数据丢失问题,PV 对象会受到保护,在系统中无法被删除

(4)回收策略
保留(Retain):

回收策略 Retain 使得用户可以手动回收资源。当 PersistentVolumeClaim 对象被删除时,PersistentVolume 卷仍然存在,对应的数据卷被视为"已释放(released)"。 由于卷上仍然存在这前一申领人的数据,该卷还不能用于其他申领。 管理员可以通过下面的步骤来手动回收该卷:

  1. 删除 PersistentVolume 对象。与之相关的、位于外部基础设施中的存储资产 (例如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)在 PV 删除之后仍然存在。
  2. 根据情况,手动清除所关联的存储资产上的数据
  3. 手动删除所关联的存储资产

如果你希望重用该存储资产,可以基于存储资产的定义创建新的 PersistentVolume 卷对象。

删除(delete):

对于支持 Delete 回收策略的卷插件,删除动作会将 PersistentVolume 对象从 Kubernetes 中移除同时也会从外部基础设施(如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)中移除所关联的存储资产。 动态制备的卷会继承其 StorageClass 中设置的回收策略, 该策略默认为 Delete。管理员需要根据用户的期望来配置 StorageClass; 否则 PV 卷被创建之后必须要被编辑或者修补。

回收(Recycle):

警告: 回收策略 Recycle 已被废弃。取而代之的建议方案是使用动态制备

如果下层的卷插件支持,回收策略 Recycle 会在卷上执行一些基本的擦除 (rm -rf /thevolume/*)操作,之后允许该卷用于新的 PVC 申领。

3.2、PV

(1)状态
  • Available:空闲,未被绑定
  • Bound:已经被 PVC 绑定
  • Released:PVC 被删除,资源已回收,但是 PV 未被重新使用
  • Failed:自动回收失败
(2)配置文件
 apiVersion: v1
 kind: PersistentVolume      # 描述资源对象为 PV 类型
 metadata:
   name: pv0001              # PV名
 spec:
   capacity:         # 容量配置
     storage: 5Gi    # pv 的容量
   volumeMode: Filesystem    # 存储类型为文件系统
   accessModes: # 访问模式:ReadWriteOnce、ReadWriteMany、ReadOnlyMany
     - ReadWriteOnce # 可被单节点独写
   persistentVolumeReclaimPolicy: Recycle # 回收策略
   storageClassName: slow # 创建 PV 的存储类名,需要与 pvc 的相同
   mountOptions: # 加载配置
     - hard
     - nfsvers=4.1
   nfs: # 连接到 nfs
     path: /data/nfs/rw/test-pv # 存储路径
     server: 192.168.113.121 # nfs 服务地址

3.3、PVC

(1)Pod绑定PVC

在 pod 的挂载容器配置中,增加 pvc 挂载

 containers:
   ......
   volumeMounts:
     - mountPath: /tmp/pvc
       name: nfs-pvc-test
 volumes:
   - name: nfs-pvc-test
     persistentVolumeClaim:
       claimName: nfs-pvc    # pvc 的名称 
(2)配置文件
apiVersion: v1
kind: PersistentVolumeClaim		# 资源类型为PVC
metadata:
  name: nfs-pvc
spec:
  accessModes:
    - ReadWriteOnce 	# 权限需要与对应的 pv 相同
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi # 资源可以小于 pv 的,但是不能大于,如果大于就会匹配不到 pv
  storageClassName: slow # 名字需要与对应的 pv 相同
#  selector: # 使用选择器选择对应的 pv
#    matchLabels:
#      release: "stable"
#    matchExpressions:
#      - {key: environment, operator: In, values: [dev]}

3.4、StorageClass

(1)制备器(Provisioner)
  • 每个 StorageClass 都有一个制备器(Provisioner),用来决定使用哪个卷插件制备 PV

(2)NFS 动态制备案例
nfs-provisioner:
 apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: nfs-client-provisioner
   namespace: kube-system
   labels:
     app: 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: quay.io/external_storage/nfs-client-provisioner:latest
           volumeMounts:
             - name: nfs-client-root
               mountPath: /persistentvolumes
           env:
             - name: PROVISIONER_NAME
               value: fuseim.pri/ifs
             - name: NFS_SERVER
               value: 192.168.113.121
             - name: NFS_PATH
               value: /data/nfs/rw
       volumes:
         - name: nfs-client-root
           nfs:
             server: 192.168.113.121
             path: /data/nfs/rw
StorageClass 配置
 apiVersion: storage.k8s.io/v1   
 kind: StorageClass      # 资源类型 CS
 metadata:
   name: managed-nfs-storage 
   namespace: kube-system
 provisioner: fuseim.pri/ifs     # 外部制备器提供者,编写为提供者的名称
 parameters:
   archiveOnDelete: "false" # 是否存档,false 表示不存档,会删除 oldPath 下面的数据,true 表示存档,会重命名路径
 reclaimPolicy: Retain # 回收策略,默认为 Delete 可以配置为 Retain
 volumeBindingMode: Immediate # 默认为 Immediate,表示创建 PVC 立即进行绑定,只有 azuredisk 和 AWSelasticblockstore 支持其他值
RBAC 配置
 apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: nfs-client-provisioner
   namespace: kube-system
 ---
 kind: ClusterRole
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
   name: nfs-client-provisioner-runner
   namespace: kube-system
 rules:
   - apiGroups: [""]
     resources: ["persistentvolumes"]
     verbs: ["get", "list", "watch", "create", "delete"]
   - apiGroups: [""]
     resources: ["persistentvolumeclaims"]
     verbs: ["get", "list", "watch", "update"]
   - apiGroups: ["storage.k8s.io"]
     resources: ["storageclasses"]
     verbs: ["get", "list", "watch"]
   - apiGroups: [""]
     resources: ["events"]
     verbs: ["create", "update", "patch"]
 ---
 kind: ClusterRoleBinding
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
   name: run-nfs-client-provisioner
   namespace: kube-system
 subjects:
   - kind: ServiceAccount
     name: nfs-client-provisioner
     namespace: default
 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: kube-system
 rules:
   - apiGroups: [""]
     resources: ["endpoints"]
     verbs: ["get", "list", "watch", "create", "update", "patch"]
 ---
 kind: RoleBinding
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
   name: leader-locking-nfs-client-provisioner
   namespace: kube-system
 subjects:
   - kind: ServiceAccount
     name: nfs-client-provisioner
 roleRef:
   kind: Role
   name: leader-locking-nfs-client-provisioner
   apiGroup: rbac.authorization.k8s.io
PVC 处于 Pending 状态

在 k8s 1.20 之后,出于对性能和统一 apiserver 调用方式的初衷,移除了对 SelfLink 的支持,而默认上面指定的 provisioner 版本需要 SelfLink 功能,因此 PVC 无法进行自动制备。

(1)配置 SelfLink
 修改 apiserver 配置文件
 vim /etc/kubernetes/manifests/kube-apiserver.yaml
 ​
 spec:
   containers:
   - command:
     - kube-apiserver
     - --feature-gates=RemoveSelfLink=false # 新增该行
     ......
 ​
 修改后重新应用该配置
 kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
(2)不需要 SelfLink 的 provisioner

将 provisioner 修改为如下镜像之一即可:  ​  

gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.0  ​  

registry.cn-beijing.aliyuncs.com/pylixm/nfs-subdir-external-provisioner:v4.0.0

PVC测试配置
 apiVersion: v1
 kind: PersistentVolumeClaim
 metadata:
   name: auto-pv-test-pvc
 spec:
   accessModes:
   - ReadWriteOnce
   resources:
     requests:
       storage: 300Mi
   storageClassName: managed-nfs-storage

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

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

相关文章

Tranformer分布式特辑

随着大模型的发展&#xff0c;如何进行分布式训练也成了每位开发者必备的技能。 单机训练 CPU OffloadingGradient Checkpointing 正向传播时&#xff0c;不存储当前节点的中间结果&#xff0c;在反向传播时重新计算&#xff0c;从而起到降低显存占用的作用 Low Precision Da…

HarmonyOS 是如何实现一次开发多端部署 -- HarmonyOS自学1

一次开发多端部署遇到的几个关键问题 为了实现“一多”的目标&#xff0c;需要解决如下三个基础问题&#xff1a; 问题1&#xff1a;页面如何适配 不同设备间的屏幕尺寸、色彩风格等存在差异&#xff0c;页面如何适配。 问题2&#xff1a;功能如何兼容 不同设备的系统能力…

身份证实名认证接口如何用C#实现

一、什么是身份证实名认证&#xff1f; 身份证实名认证又叫身份证实名核验、身份证二要素、身份实名核验、身份证验证&#xff0c;输入姓名、身份证号&#xff0c;校验此两项是否匹配&#xff0c;同时返回生日、性别、籍贯等信息&#xff0c;同时支持港澳台证件核验。 二、身…

【Three.js】实现护罩(防御罩、金钟罩、护盾)效果

前言&#xff1a; 在这篇博客中&#xff0c;我们将使用 Three.js 从零开始生成一个护罩效果。护罩将使用自定义的 Shader 材质&#xff0c;带有动画效果&#xff0c;最终呈现一个视觉上酷炫的护罩。此篇文章的重点将放在如何生成一个3D护罩&#xff0c;其它功能将在之后的博客…

SprinBoot+Vue旅游网站的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质…

AI和新基建赋能智慧工地超融合管理平台解决方案

1. 项目背景与需求 电力行业的工程管理正朝着智慧化发展&#xff0c;但目前仍处于起步阶段。为满足数字化、网络化、智能化的发展需求&#xff0c;需要构建一个高效综合监控平台&#xff0c;实现对电力项目全过程的精益化管控。 2. 综合管理平台的构建 该平台集成了超融合实…

【Visual Studio 报错】未加载 wntdll.pdb(一种可行的解决办法)

调试程序时&#xff0c;会出现下面这个报错 分析原因&#xff1a; 出现未加载 wntdll.pdb 报错大概率是你的指针使用错误 &#xff0c;比如使用野指针、越界访问、或者堆区空间释放方式错误等。 这里以 堆区空间释放方式错误 为例子 1、堆区开辟的数组空间使用 delete 释放 …

Java 日志

日志就是为了将程序的运行状况保存到文件中去。 命名的一个小细节&#xff1a; 比如把信息保存到文件中这个方法的名字可以写为infoToFile&#xff0c;有个人为了偷懒&#xff0c;写成info2File&#xff0c;发现效果还挺好&#xff0c;一下就能分清两个单词&#xff0c;所以后…

windows版本mysql8.2忘记密码

忙了一年的项目终于有点空闲时间了&#xff08;996累成狗&#xff09;&#xff0c;想折腾点开源项目&#xff0c; 结果发现忘了本地mysql密码&#xff0c;查了一些资料&#xff0c;记录如下&#xff1a; --windows mysql8.2忘记密码&#xff08;思路整理&#xff1a;先无密码…

【信创建设】信息系统信创建设整体技方案(word原件完整版)

信创&#xff0c;即“信息技术应用创新”。我国自主信息产业聚焦信息技术应用创新&#xff0c;旨在通过对IT硬件、软件等各个环节的重构&#xff0c;基于我国自有IT底层架构和标准&#xff0c;形成自有开放生态&#xff0c;从根本上解决本质安全问题&#xff0c;实现信息技术可…

Superset二次开发之新增复选框Checkbox筛选器

一. 背景 Superset目前支持的筛选类型:值、数值范围、时间列、时间粒度、时间范围 5种类型,显然无法满足业务需求。根据产品需要,需要支持复选框、单选框、级联选择等类型的筛选器。本文探讨复选框、单选框的技术实现方式。 二. 效果预览 三. 实现思路 复用 值 筛选器模块,…

计算蛋白质结构中氨基酸之间的方向和方位

在蛋白质结构分析中,方向(direction)和方位(orientation)是描述相邻氨基酸(残基)之间相对空间关系的重要几何参数。可以通过原子坐标来计算相邻氨基酸之间的方向向量和方位关系。以下是这些概念的详细解释以及如何通过 PyTorch 来计算它们。 1. 方向 (Direction) 方向…

二、Maven工程的创建--JavaSEJavaEE

1、idea创建Maven JavaSE工程&#xff1a; 2、idea创建Maven JavaEE工程&#xff1a; &#xff08;1&#xff09;手动创建 &#xff08;2&#xff09;插件方式创建 在idea里安装插件JBLJavaToWeb&#xff1b; 选择需要生成的项目文件后&#xff0c;右击&#xff1a; 项目…

拉普拉斯分布-简要介绍

拉普拉斯分布&#xff0c;又称双指数分布&#xff0c;是概率论中的一种连续概率分布。拉普拉斯分布是由法国数学家皮埃尔-西蒙拉普拉斯在研究误差理论时提出的&#xff0c;在数据集中经常用于描述具有尖峰和长尾特征的分布。 拉普拉斯分布的定义 拉普拉斯分布的概率密度函数&…

HOT 100(七)栈、堆、贪心算法

一、栈 1、每日温度 使用单调递减栈来解决。主要思路是遍历temperatures数组&#xff0c;利用栈来存储还没有找到比当前温度高的天数的索引。当遇到比栈顶索引所对应温度更高的温度时&#xff0c;就可以确定当前这一天的温度比之前那一天高。索引的差值就是等待的天数。 求一…

前端 Vue3 项目开发—— ESLint prettier 配置代码风格

ESLint & prettier 介绍 如果你用的是 pnpm create vue 来创建项目&#xff0c;那么创建项目时就会让你选择是否添加 ESLint 和 prettier 我们在上一篇博客中详细介绍过 ESLint&#xff0c;可以说上一篇博客是这篇博客的先修知识&#xff0c;所以各位小伙伴们请先去看看我…

微信小程序页面制作——个人信息

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

Docker | 虚拟机 是一个东西吗

文章目录 虚拟机与Docker如果要在linux环境下运行程序&#xff0c;那么docker会给我下载整个linux操作系统吗&#xff1f;Docker的一些名词 虚拟机与Docker 虚拟机就相当于买了一台新电脑&#xff0c;有了完整的独立的一个操作系统Docker 不需要创建完整的虚拟操作系统&#xf…

el-table行编辑

需求&#xff1a;单点行编辑并且请求接口更新数据&#xff0c;表格中某几个字段是下拉框取值的&#xff0c;剩下的是文本域&#xff1b;展示的时候 需要区分下拉框编码还是中文 故障模式这个展示的是fault_mode编码,但要显示的文字fault_mode_chn 这点需要注意 <el-tablere…

【H2O2|全栈】关于Photoshop | PS(4)

PS的一些杂谈&#xff08;亖&#xff09; 目录 PS的一些杂谈&#xff08;亖&#xff09; 前言 准备工作 图形工具 基本属性 混合选项 形状图层 文字工具 基本属性 进一步变化文字 组和图层 UI设计案例 预告和回顾 后话 前言 这一篇博客我将会写一下图形工具和…