kubernetes-PV与PVC、存储卷

一、PV和PVC详解

        当前,存储的方式和种类有很多,并且各种存储的参数也需要非常专业的技术人员才能够了解。在Kubernetes集群中,放了方便我们的使用和管理,Kubernetes提出了PV和PVC的概念,这样Kubernetes集群的管理人员就可以将注意力集中到Kubernetes集群中来,而无需操心后端的存储设备。

pv : 相当于磁盘分区
 
pvc: 相当于磁盘请求

PersistentVolumeClaim(PVC)是用户存储的请求

PVC的使用逻辑:在pod中定义一个存储卷(该存储卷类型为PVC),
定义的时候直接指定大小,pvc必须与对应的pv建立关系,
pvc会根据定义去pv申请,而pv是由存储空间创建出来的。
pv和pvc是kubernetes抽象出来的一种存储资源。

  • PV : 持久化卷的意思,是对底层的共享存储的一种抽象
  • PVC(Persistent Volume Claim)是持久卷请求于存储需求的一种声明(PVC其实就是用户向kubernetes系统发出的一种资源需求申请。)

        从上图可以看出,底层的存储可以使各种类型,包括NFS、Ceph、CIFS等等,而Kubernetes会把这些存储统一抽象为PV。PV,即Persistent Volume,是集群中配置的存储资源。PVC,即Persistent Volume Claim,是用户存储的请求,通常我们在一个Pod中定义一个存储卷,定义的时候会指定该存储卷的相关信息,比如空间大小、可读可写等属性。但是PVC并不是真正的存储空间,Pod的PVC和PV之间必须建立某种联系,这样才能使得Pod可以调用实际存储空间。

apiVersion: v1  
kind: PersistentVolume
metadata:
  name: pv2
spec:
  nfs: # 存储类型,与底层真正存储对应
  capacity:  # 存储能力,目前只支持存储空间的设置
    storage: 2Gi
  accessModes:  # 访问模式
  storageClassName: # 存储类别
  persistentVolumeReclaimPolicy: # 回收策略

使用了PV和PVC之后,工作可以得到进一步的细分:

存储:存储工程师维护
PV: kubernetes管理员维护
PVC:kubernetes用户维护

二、PV和PVC生命周期

实际上,不管是PV,还是PVC,都遵循以下生命周期:

Provisioning(配置)---> Binding(绑定)---> Using(使用)---> Releasing(释放) ---> Recycling(回收)

2.1 Provisioning  配置

        Provisioning,即配置阶段。一般而言,PV的提供方式有两种——静态和动态。
        所谓静态提供,就是Kubernetes管理员创建多个PV,这些PV的存储空间等属性已经确定,并且已经和真实的存储设备进行了关联。Pod中的PVC可以根据需要请求这些PV。
        所谓动态提供,需要依托与StorageClass的支持,这时Kubernetes会尝试为PVC来动态的创建PV。这样做的好处是避免出现这种情况:部分PVC被分配给了远远超出其资源需求的PV、或者说系统存在很多资源较少的PV,但是一个资源需求很高的PVC缺无法被满足的情况。

2.2 Binding 结合

        在动态配置的情况下,用户创建或者已经创建了具有特定数量的PVC后,PVC与PV绑定的过程。
        如果没有满足PVC请求需求的PV,那么PVC将无法被创建,因此造成的结果就是相应的Pod也不会被创建。

2.3 Using 使用

        即PVC与PC绑定后,Pod对存储空间的使用过程。

2.4 Releasing 释放

        当Pod被删除或者对该PV的资源使用结束后,Kubernetes就会删除该PVC对象,相应的也会回收PV资源,这时的PV就会处于这种状态。但是此时的PV还需要处理完毕之前的Pod在该存储卷上存储信息后才能够被使用。

2.5 Reclaiming 处理中

        PV的回收策略对被释放的PV的处理过程。

2.6 Recycling 循环

        根据配置,有时PV会被执行擦除操作,删除掉该存储空间上的所有信息,并且该存储资源也可以被再次使用。

三、访问模式

3.1 PV的访问模式(accessmodes)

模式翻译

ReadWriteOnce

(RWO)

可读可写,但只支持被单个节点挂载。

ReadOnlyMany

(ROX)

只读,可以被多个节点挂载。

ReadWriteMany

(RWX)

多路可读可写。这种存储可以以读写的方式被多个节点共享。不是每一种存储都支持这三种方式,像共享方式,目前支持的还比较少,比较常用的是 NFS。在PVC绑定PV时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。

3.2 PV的回收策略(persistentVolumeReclaimPolicy)

策略解释
retain不清理,保留Volume (需要手动清理)
Recycle删除数据,即rm -rf /thevolumel*(只有NFS和HostPath支持)
Delete删除存储资源,比如删除AWS EBS卷(只有AWS EBS,GCE PD,Azure Disk和Cinder支持)

3.3 pv的状态

状态解释
Available可用
Bound已经分配给PVC
ReleasedPVC解绑但还未执行回收策略
Failed发生错误

四、实验验证

4.1 安装nfs

# 1、创建目录
[root@k8s ~]# mkdir /root/data/{pv1,pv2,pv3} -pv
 chmod 777 /data/volumes


# 2、暴露服务
[root@k8s ~]# vim /etc/exports
/root/data/pv1  192.168.223.0/24(rw,sync,no_root_squash)
/root/data/pv2  192.168.223.0/24(rw,sync,no_root_squash)
/root/data/pv3  192.168.223.0/24(rw,sync,no_root_squash)
 
# 3、重启服务
[root@k8s ~]#  systemctl restart nfs

//master节点操作

vim pod-nfs-vol.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-nfs
  namespace: default
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
    - name: html
      nfs:
        path: /data/volumes
        server: stor01(主机名)

4.2 验证nfs持久化存储

//在nfs服务器上创建index.html
cd /data/volumes
vim index.html
<h1> nfs stor01</h1>

//master节点操作
curl 10.244.2.38
<h1> nfs stor01</h1>

kubectl delete -f pod-nfs-vol.yaml   #删除nfs相关pod,再重新创建,可以得到数据的持久化存储

kubectl apply -f pod-nfs-vol.yaml


nas gfs  ceph san
 

可以实现持久化存储,使用nfs将存储设别空间挂载到容器中,pod可以跨node节点共享数据

4.3 NFS使用PV和PVC 

PVC是资源的申请,用来声明对存储空间、访问模式、存储类别需求信息。下面是资源清单文件

4.3.1、配置nfs存储
 

//NFS使用PV和PVC  
1、配置nfs存储
mkdir v{1,2,3,4,5}

vim /etc/exports
/data/volumes/v1 192.168.10.0/24(rw,no_root_squash)
/data/volumes/v2 192.168.10.0/24(rw,no_root_squash)
/data/volumes/v3 192.168.10.0/24(rw,no_root_squash)
/data/volumes/v4 192.168.10.0/24(rw,no_root_squash)
/data/volumes/v5 192.168.10.0/24(rw,no_root_squash)

exportfs -arv

showmount -e
 

4.3.2 定义PV

//这里定义5个PV,并且定义挂载的路径以及访问模式,还有PV划分的大小。
vim pv-demo.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    name: pv001
spec:
  nfs:
    path: /data/volumes/v1  

    server: stor01                                                                                                                                                                                        
    
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
    path: /data/volumes/v2
    server: stor01
  accessModes: ["ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
    path: /data/volumes/v3
    server: stor01
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv004
  labels:
    name: pv004
spec:
  nfs:
    path: /data/volumes/v4
    server: stor01
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 4Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv005
  labels:
    name: pv005
spec:
  nfs:
    path: /data/volumes/v5
    server: stor01
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 5Gi

kubectl apply -f pv-demo.yaml

kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM     STORAGECLASS   REASON    AGE
pv001     1Gi        RWO,RWX        Retain           Available                                      7s
pv002     2Gi        RWO            Retain           Available                                      7s
pv003     2Gi        RWO,RWX        Retain           Available                                      7s
pv004     4Gi        RWO,RWX        Retain           Available                                      7s
pv005     5Gi        RWO,RWX        Retain           Available                                       7s
 

4.3.3 定义PVC

//这里定义了pvc的访问模式为多路读写,该访问模式必须在前面pv定义的访问模式之中。定义PVC申请的大小为2Gi,此时PVC会自动去匹配多路读写且大小为2Gi的PV,匹配成功获取PVC的状态即为Bound
vim pod-vol-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
  namespace: default
spec:
  accessModes: ["ReadWriteMany"]
  resources:
    requests:
      storage: 2Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-pvc
  namespace: default
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1   
  volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
    - name: html
      persistentVolumeClaim:
        claimName: mypvc


kubectl apply -f pod-vol-pvc.yaml

kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON    AGE
pv001     1Gi        RWO,RWX        Retain           Available                                            19m
pv002     2Gi        RWO            Retain           Available                                            19m
pv003     2Gi        RWO,RWX        Retain           Bound       default/mypvc                            19m
pv004     4Gi        RWO,RWX        Retain           Available                                            19m
pv005     5Gi        RWO,RWX        Retain           Available                                            19m

kubectl get pvc
NAME      STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc     Bound     pv003     2Gi        RWO,RWX                       22s

4.3.4 测试访问

//在存储服务器上创建index.html,并写入数据,通过访问Pod进行查看,可以获取到相应的页面。
cd /data/volumes/v3/
echo "welcome to use pv3" > index.html

kubectl get pods -o wide
pod-vol-pvc             1/1       Running   0          3m        10.244.2.39   k8s-node02

curl  10.244.2.39
welcome to use pv3

4.4 搭建 StorageClass + NFS,实现 NFS 的动态 PV 创建

4.4.1 在stor01节点上安装nfs,并配置nfs服务

关闭防火墙

mkdir /opt/k8s
chmod 777 /opt/k8s/

vim /etc/exports
/opt/k8s 192.168.10.0/24(rw,no_root_squash,sync)

systemctl restart nfs

4.4.2 创建 Service Account,用来管理 NFS Provisioner 在 k8s 集群中运行的权限,设置 nfs-client 对 PV,PVC,StorageClass 等的规则

vim nfs-client-rbac.yaml
#创建 Service Account 账户,用来管理 NFS Provisioner 在 k8s 集群中运行的权限
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
---
#创建集群角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: nfs-client-provisioner-clusterrole
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: ["list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
---
#集群角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: nfs-client-provisioner-clusterrolebinding
subjects:
- kind: ServiceAccount
  name: nfs-client-provisioner
  namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-clusterrole
  apiGroup: rbac.authorization.k8s.io


kubectl apply -f nfs-client-rbac.yaml
 

4.4.3 3、使用 Deployment 来创建 NFS Provisioner
NFS Provisione(即 nfs-client),有两个功能:一个是在 NFS 共享目录下创建挂载点(volume),另一个则是将 PV 与 NFS 的挂载点建立关联。

#由于 1.20 版本启用了 selfLink,所以 k8s 1.20+ 版本通过 nfs provisioner 动态生成pv会报错,解决方法如下:
vim /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
  containers:
  - command:
    - kube-apiserver
    - --feature-gates=RemoveSelfLink=false       #添加这一行
    - --advertise-address=192.168.10.19
......

kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
kubectl delete pods kube-apiserver -n kube-system 
kubectl get pods -n kube-system | grep apiserver

#创建 NFS Provisioner
vim nfs-client-provisioner.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs-client-provisioner
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner         #指定Service Account账户
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: nfs-storage       #配置provisioner的Name,确保该名称与StorageClass资源中的provisioner名称保持一致
            - name: NFS_SERVER
              value: stor01           #配置绑定的nfs服务器
            - name: NFS_PATH
              value: /opt/k8s          #配置绑定的nfs服务器目录
      volumes:              #申明nfs数据卷
        - name: nfs-client-root
          nfs:
            server: stor01
            path: /opt/k8s
    
    
kubectl apply -f nfs-client-provisioner.yaml 

kubectl get pod
NAME                                   READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-cd6ff67-sp8qd   1/1     Running   0          14s

4.4.4 创建 StorageClass,负责建立 PVC 并调用 NFS provisioner 进行预定的工作,并让 PV 与 PVC 建立关联

vim nfs-client-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client-storageclass
provisioner: nfs-storage     #这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致
parameters:
  archiveOnDelete: "false"   #false表示在删除PVC时不会对数据进行存档,即删除数据
  
  
kubectl apply -f nfs-client-storageclass.yaml

kubectl get storageclass
NAME                      PROVISIONER   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-client-storageclass   nfs-storage   Delete          Immediate           false                  43s

4.4.5 创建 PVC 和 Pod 测试

vim test-pvc-pod.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-nfs-pvc-1
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs-client-storageclass    #关联StorageClass对象
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: test-storageclass-pod
spec:
  containers:
  - name: busybox
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    command:
    - "/bin/sh"
    - "-c"
    args:
    - "sleep 3600"
    volumeMounts:
    - name: nfs-pvc
      mountPath: /mnt
  restartPolicy: Never
  volumes:
  - name: nfs-pvc
    persistentVolumeClaim:
      claimName: test-nfs-pvc-1      #与PVC名称保持一致  

4.4.6 验证结果

kubectl get pod -owide
NAME                                     READY   STATUS    RESTARTS   AGE    IP           NODE     NOMINATED NODE   
myapp01                                  1/1     Running   0          24h    10.244.1.6   node01   <none>           
myapp04                                  1/1     Running   0          24h    10.244.2.4   node02   <none>           
nfs-client-provisioner-d9dcdf4c4-f57d4   1/1     Running   0          144m   10.244.2.6   node02   <none>           
nginx-6799fc88d8-9vhpk                   1/1     Running   0          24h    10.244.1.7   node01   <none>           
pod-vol-nfs                              1/1     Running   0          19h    10.244.2.5   node02   <none>           
pod-vol-pvc                              1/1     Running   1          18h    10.244.1.8   node01   <none>           
test-storageclass-pod                    1/1     Running   0          78s    10.244.1.9   node01   <none> 

kubectl exec -it test-storageclass-pod sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.

/ # 
/ # cd /mnt/
/mnt # ls
/mnt # 
/mnt # echo "wang shi kang sb" > index.html
/mnt # 
 

五、总结

5.1 Volume

①emptyDir:可以实现Pod中的容器之间共享数据,但是存储卷不能持久化数据,且会随着Pod生命周期结束而一起删除

②hostpath:可以实现持久化存储,使用node节点的目录或文件挂载到容器,但是存储空间会收到node节点单机限制,node节点故障数据会丢失,Pod会跨节点不能共享数据

③NFS:可以实现持久化存储,使用NFS将存储设备空间挂载到容器中,Pod可以跨Node节点共享数据

5.2 PV和PVC

①PV 持久卷(Persistent Volumes)是集群中的一块存储资源,由管理员事先创建或由动态供应机制(如StorageClass)自动创建。

②PVC持久卷声明(Persistent Volume Claims)是用户对存储的请求或声明,Pod通过挂载PVC来使用PV。这种方式提供了存储的抽象和解耦,使得应用无需关心具体的存储细节。

③当Pod销毁或重建时,与之关联的PVC仍然保留,保证了数据的持久性。

5.3 StorageClass——动态存储

①存储类定义了存储的“类”,用于动态供应PV。管理员可以根据不同的需求(如性能、成本)定义多个存储类。

②用户在创建PVC时可以选择一个存储类,Kubernetes会自动匹配并创建合适的PV。

③对于存储资源,虽然不像CPU和内存那样频繁地设置请求和限制,但在使用PV/PVC时,可以通过设置存储容量的大小来间接限制使用量。

④在Pod的YAML定义中,可以通过volumeMounts来指定容器如何挂载卷,以及是否需要设置读写权限等。

⑤Pod中的存储卷可以配置访问模式(如只读、读写)来确保数据的安全性。
对于敏感数据,推荐使用Secrets或ConfigMaps,并注意权限控制。

六、存储卷

        容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失——容器以干净的状态(镜像最初的状态)重新启动。其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes 中的Volume抽象就很好的解决了这些问题。Pod中的容器通过Pause容器共享Volume。

6.1 emptyDir存储卷

        当Pod被分配给节点时,首先创建emptyDir卷,并且只要该Pod在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod 中的容器可以读取和写入emptyDir卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时,emptyDir中的数据将被永久删除。

mkdir /opt/volumes
cd /opt/volumes
 
vim pod-emptydir.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-emptydir
  namespace: default
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    #定义容器挂载内容
    volumeMounts:
    #使用的存储卷名称,如果跟下面volume字段name值相同,则表示使用volume的这个存储卷
    - name: html
      #挂载至容器中哪个目录
      mountPath: /usr/share/nginx/html/
  - name: busybox
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: html
      #在容器内定义挂载存储名称和挂载路径
      mountPath: /data/
    command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done']
  #定义存储卷
  volumes:
  #定义存储卷名称  
  - name: html
    #定义存储卷类型
    emptyDir: {}
 
[root@master01 volumes]]#kubectl get pods -owide
NAME                                READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx-deployment-797d747cf6-6mkc9   1/1     Running   0          12d   10.244.1.12   node02   <none>           <none>
nginx-deployment-797d747cf6-hzn8m   1/1     Running   0          12d   10.244.2.13   node01   <none>           <none>
nginx-deployment-797d747cf6-rk8hr   1/1     Running   0          12d   10.244.2.12   node01   <none>           <none>
pod-emptydir                        2/2     Running   0          96s   10.244.2.14   node01   <none>           <none>

        在上面定义了2个容器,其中一个容器是输入日期到index.html中,然后验证访问nginx的html是否可以获取日期。以验证两个容器之间挂载的emptyDir实现共享。

6.2 hastPath存储卷

hostPath卷将 node 节点的文件系统中的文件或目录挂载到集群中。
hostPath可以实现持久存储,但是在node节点故障时,也会导致数据的丢失。

//在 node01 节点上创建挂载目录
mkdir -p /data/pod/volume1
echo 'node01.kgc.com' > /data/pod/volume1/index.html
 
//在 node02 节点上创建挂载目录
mkdir -p /data/pod/volume1
echo 'node02.kgc.com' > /data/pod/volume1/index.html
 
//创建 Pod 资源
vim pod-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-hostpath
  namespace: default
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
    #定义容器挂载内容
    volumeMounts:
    #使用的存储卷名称,如果跟下面volume字段name值相同,则表示使用volume的这个存储卷
    - name: html
      #挂载至容器中哪个目录
      mountPath: /usr/share/nginx/html
      #读写挂载方式,默认为读写模式false
      readOnly: false
  #volumes字段定义了paues容器关联的宿主机或分布式文件系统存储卷
  volumes:
    #存储卷名称
    - name: html
      #路径,为宿主机存储路径
      hostPath:
        #在宿主机上目录的路径
        path: /data/pod/volume1
        #定义类型,这表示如果宿主机没有此目录则会自动创建
        type: DirectoryOrCreate
 
 
kubectl apply -f pod-hostpath.yaml
NAME                                READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
nginx-deployment-797d747cf6-6mkc9   1/1     Running   0          12d    10.244.1.12   node02   <none>           <none>
nginx-deployment-797d747cf6-hzn8m   1/1     Running   0          12d    10.244.2.13   node01   <none>           <none>
nginx-deployment-797d747cf6-rk8hr   1/1     Running   0          12d    10.244.2.12   node01   <none>           <none>
pod-emptydir                        2/2     Running   0          30m    10.244.2.14   node01   <none>           <none>
pod-hostpath                        1/1     Running   0          2m3s   10.244.1.13   node02   <none>           <none>
[root@master01 volumes]]#curl 10.244.1.13
node02.rmh.com
 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenAI 文生图模型演进:DDPM、IDDPM、ADM、GLIDE、DALL-E 2、DALL-E 3

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学。 针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 合集&#x…

前端实习记录——git篇(一些问题与相关命令)

1、版本控制 &#xff08;1&#xff09;版本回滚 git log // 查看版本git reset --mixed HEAD^ // 回滚到修改状态&#xff0c;文件内容没有变化git reset --soft HEAD^ // 回滚暂存区&#xff0c;^的个数代表几个版本git reset --hard HEAD^ // 回滚到修改状态&#xff…

Reids高频面试题汇总总结

一、Redis基础 Redis是什么? Redis是一个开源的内存数据存储系统,它可以用作数据库、缓存和消息中间件。Redis支持多种数据结构,如字符串、哈希表、列表、集合、有序集合等,并提供了丰富的操作命令来操作这些数据结构。Redis的主要特点是什么? 高性能:Redis将数据存储在内…

Linux —— 动静态库

一、基本认识 1.什么是库&#xff1f; 在编译C或C时&#xff0c;在使用一些函数时&#xff0c;我们都需要先声明头文件&#xff0c;头文件中一般存放着这些函数的声明&#xff0c;而具体的实现方法&#xff0c;一般就被放在库中&#xff0c;库文件在编译链接的阶段会被链接到…

PADS做CAM文件时,提示填充宽度对于精确的焊盘填充过大

1、开发环境&#xff1a; PADS VX1.2 2、问题复现&#xff1a; 同一个PCB文件&#xff0c;设计验证没有错误。但是输出CAM光辉文件时&#xff0c;总是弹出“填充宽度对于精确的焊盘填充过大&#xff0c;填充宽度……”&#xff0c;如下图&#xff1a; 3、错误的方法&#xff1…

未来已来:Facebook的数字革命与社交转型

在当今数字化时代&#xff0c;Facebook作为全球最大的社交网络之一&#xff0c;不仅扮演着连接人们的桥梁&#xff0c;更是引领着社交行业的数字革命与转型。本文将深入探讨Facebook如何通过创新技术、改变用户体验以及应对挑战&#xff0c;塑造了未来社交的面貌&#xff0c;以…

Python数据处理,使用 tkinter 模块点击获取文件目录

Python数据处理&#xff0c;使用 tkinter 模块点击获取文件目录 正文 正文 当我们进行数据处理读取文件内数据的时候&#xff0c;通常&#xff0c;我们需要设定好一个存放当前文件所在目录的变量。比如如下目录&#xff1a; file_path rC:\Users\xxx\Desktop\DataSet\Data.c…

使用DataGrip连接跳板机后再连接远程服务器的mysql数据库

相比配置本地数据库就是多了一步SSH/SSL配置。 添加新的mysql连接&#xff0c;选择SSH/SSL&#xff0c;勾选Use SSH tunnel&#xff1a; 点击右边的…配置跳板机连接&#xff0c;输入账号密码&#xff0c;然后保存&#xff1a; 接着配置General&#xff0c;里面填上要连接的数…

了解运维基础

一、运维概述 1、运维岗位的收入情况 2、运维的职位定义 什么是运维&#xff1f; 在技术人员之间&#xff0c;一致对运维有一个开玩笑的认知&#xff1a;运维就是修电脑的、装网线的、背锅的岗位。 其实不然&#xff0c;运维是一个非常广泛的定义&#xff0c;在不同的公司不同…

洗地机有哪些牌子比较好?洗地机排行榜十大品牌

随着洗地机市场竞争的日益激烈&#xff0c;市场上涌现出数百个品牌的产品&#xff0c;涵盖了从入门级到高端的各类价位和功能。这种多样化的选择一方面极大地满足了用户的不同需求&#xff0c;但另一方面也让消费者在挑选时面临一定的困扰。在众多种类的洗地机中&#xff0c;如…

Redis之内存管理过期、淘汰机制

1.Redis内存管理 我们的redis是一个内存型数据库&#xff0c;我们的数据也都是放在内存中的&#xff0c;内存是有限的空间&#xff0c;当数据满了之后&#xff0c;我们要怎么样继续保证redis的可用性呢?我们就需要采取点管理措施和机制来保证我们redis的可用性。 在redis.co…

人脸检测--FaceNet(四)

FaceNet 是一个由 Google 研究团队开发的人脸识别系统&#xff0c;它基于深度学习技术&#xff0c;可以实现高精度的人脸识别、验证和聚类任务。FaceNet 通过学习直接从图像像素到人脸嵌入的映射&#xff0c;使得它在各种人脸识别任务中表现出色。下面是对 FaceNet 的详细介绍&…

Mac 安装 Adobe 软件报错 “The installation cannot continue as the installer file may be damaged. “

文章目录 1. 引言2. 解决方法2.1 打开“任何来源”2.2 安装应用2.3 关闭“任何来源” 3. 学习用途&#xff0c;下载 Adobe 软件4. 参考 1. 引言 Mac 用户再安装 Adobe 的产品&#xff0c;如 After Effects 时&#xff0c;报错: "The installation cannot continue as th…

如何恢复被盗的加密货币?

本世纪&#xff0c;网络犯罪的首要目标是加密货币。 这要归功于加密货币的日益普及和价值&#xff0c;网络犯罪分子已经认识到经济收益的潜力&#xff0c;并将重点转向利用这种数字资产中的漏洞。 在今天的文章中&#xff0c;我们将讨论加密货币恢复和被盗加密货币恢复。 我们…

【图论】最短路(一)

发现之前做的题很乱&#xff0c;用小笔记把看过的博客和题目分类记录一下&#xff0c; 代码参考了很多佬&#xff0c;是标注出来的链接&#xff0c;若不同意我就删掉&#xff08;鞠躬&#xff09; 找了几张好点的&#xff0c;图来源图中的id和acwing 1.dijkstra 依次找到距…

Android设备获取OAID调研和实现

什么是OAID、AAID、VAID OAID OAID是"Android ID"&#xff08;安卓ID&#xff09;的一种替代方案&#xff0c;其全称为"Open Anonymous Identifier"&#xff08;开放匿名标识符&#xff09;。 因传统的移动终端设备标识如国际移动设备识别码&#xff08;…

免费,Python蓝桥杯等级考试真题--第17级(含答案解析和代码)

Python蓝桥杯等级考试真题–第17级 一、 选择题 答案&#xff1a;B 解析&#xff1a;&#xff08;x-y&#xff09;%25%21&#xff0c;故答案为B。 答案&#xff1a;B 解析&#xff1a;x16&#xff0c;所以i的值为range&#xff08;1,16&#xff09;&#xff0c;取值为1-15&…

Dinky MySQLCDC 整库同步到 MySQL jar包冲突问题解决

资源&#xff1a;flink 1.17.0、dinky 1.0.2 问题&#xff1a;对于kafka相关的包内类找不到的情况 解决&#xff1a;使用 flink-sql-connector- 胖包即可&#xff0c;去掉 flink-connector- 相关瘦包&#xff0c;解决胖瘦包冲突 source使用 flink-sql-connector- 胖包&#…

【数据库】通过一个实例来认识数据流图DFD

导读&#xff1a;通过一个实例&#xff08;数据中台&#xff09;说明数据流图DFD的作用、介绍了常见的数据流图元素及其标准符号以及如何画数据流图。数据流图主要被分析师、系统设计师、流程优化专家、系统管理员以及与系统开发和维护相关的人员查看和使用。对于刚考完2024年5…

Altium Designer软件下载安装「专业PCB设计软件」Altium Designer安装包获取!

Altium Designer&#xff0c;这款软件凭借其全面的设计流程覆盖&#xff0c;从概念到实现&#xff0c;都能为电子工程师提供强大的支持。 在硬件设计方面&#xff0c;Altium Designer提供了丰富的元件库和灵活的布局选项&#xff0c;使得工程师能够轻松地进行电路设计&#xff…