秒懂k8s中资源的介绍和用法

news2025/1/16 17:43:52

service介绍

解决什么问题

Pod的生命是有限的,死亡过后不会复活了,尽管每个Pod都有自己的IP地址,但是如果Pod重新启动了的话那么他的IP很有可能也就变化了。这就会带来一个问题:比如我们有一些后端的Pod的集合为集群中的其他前端的Pod集合提供API服务,如果我们在前端的Pod中把所有的这些后端的Pod的地址都写死,然后去某种方式去访问其中一个Pod的服务,这样看上去是可以工作的,对吧?但是如果这个Pod挂掉了,然后重新启动起来了,是不是IP地址非常有可能就变了,这个时候前端就极大可能访问不到后端的服务了。

在部署 WEB 服务时,通常会使用 Nginx 作为服务的入口,Nginx 后面会挂载大量的后端服务。以前,我们可能需要手动更改 Nginx 配置中的 upstream 选项来动态改变提供服务的数量,但随着服务发现工具的出现,如 Consul、ZooKeeper 和 etcd 等,我们现在只需要将服务注册到这些服务发现中心,然后让工具动态地更新 Nginx 的配置就可以了,完全不需要手工操作,非常方便。

同样的,如果我们要解决前端 Pod 如何连接到后端 Pod 集合的问题,也可以使用类似的方式。当后端 Pod 被销毁或新建时,我们可以将这些 Pod 的地址注册到服务发现中心。然后,前端 Pod 可以连接到这个服务发现中心,从中获取后端 Pod 的地址信息,实现动态的服务发现和连接。这样,我们就可以将服务发现的逻辑从应用中解耦出来,让前端 Pod 只需要连接到一个能够做服务发现的中间件上面,而不需要直接与后端 Pod 集合交互。

三种IP

学习Service之前,我们需要先弄明白Kubernetes系统中的三种IP这个问题

  1. Node IP:Node IP 是 Kubernetes 集群中节点(物理机器)的 IP 地址,通常是节点的物理网卡 IP 地址(内网 IP)。Node IP 允许集群内的节点之间进行直接通信。如果要从 Kubernetes 集群外部访问集群内的节点或服务,通常需要通过节点的 Node IP 进行通信。

  2. Pod IP:Pod IP 是每个 Pod 的 IP 地址,由 Docker Engine 根据 docker0 网桥的 IP 地址段进行分配。Pod IP 用于在 Kubernetes 集群内部实现 Pod 之间的通信。通常情况下,Pod IP 由网络插件(如 Flannel、Calico 等)负责管理和分配,确保在整个集群中不会发生 IP 地址冲突。

  3. Cluster IP:Cluster IP 是 Kubernetes 中 Service 对象的虚拟 IP 地址,仅作用于 Kubernetes Service。Cluster IP 由 Kubernetes 自己管理和分配,用于提供抽象的服务访问接口。通过 Service 的 Cluster IP 和端口,其他 Pod 或外部客户端可以访问 Service 提供的服务。需要注意的是,Cluster IP 没有实际的物理实体对象来响应,它只是一个虚拟的地址,用于标识 Service。

定义service

定义一个名为 myservice 的 Kubernetes Service,假定我们有一组Pod服务,它们对外暴露了 8080 端口,同时都被打上了app=myapp这样的标签,那么我们就可以像下面这样来定义一个Service对象:

apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
    name: myapp-http
  • apiVersion: v1:指定了 Kubernetes API 的版本,这里使用的是 v1 版本。
  • kind: Service:指定了要创建的 Kubernetes 资源类型,这里是一个 Service。
  • metadata: name: myservice:指定了 Service 的元数据,其中 name 字段为 myservice,表示该 Service 的名称。
  • spec: selector: app: myapp:这里定义了 Service 的选择器,指定了哪些 Pod 将会被该 Service 匹配到。这个 Service 会将流量转发给具有标签 app: myapp 的 Pod。
  • ports: - protocol: TCP port: 80 targetPort: 8080 name: myapp-http:这个部分定义了 Service 暴露的端口。具体解释如下:
    • protocol: TCP:指定了端口使用的协议,这里是 TCP 协议。
    • port: 80:指定了 Service 暴露给其他 Pod 或外部客户端的端口号,这里是 80 端口。
    • targetPort: 8080:指定了后端 Pod 上实际运行服务的端口号,这里是 8080 端口。当请求到达 Service 时,Service 会将流量转发到具有标签 app: myapp 的 Pod 上的 8080 端口。
    • name: myapp-http:指定了该端口的名称,用于标识这个端口。

运行命令

kubectl create -f myservice.yaml

就可以创建一个名为myserviceService对象,这个Service会被系统分配一个我们上面说的Cluster IP,它会将请求代理到使用 TCP 端口为 8080,具有标签app=myappPod上,这个过程需要负载均衡。

怎么实现负载均衡

Kubernetes集群中,每个Node会运行一个kube-proxy进程, 负责为Service实现一种 VIP(虚拟 IP,就是我们上面说的clusterIP)的代理形式,现在的Kubernetes中默认是使用的iptables这种模式来代理。

kube-proxy 是 Kubernetes 中的一个重要组件,负责为 Service 实现负载均衡和服务发现。它可以工作在多种模式下,其中最常见的是 iptables 模式。在 iptables 模式下,kube-proxy 监视 Kubernetes master 上的 Service 和 Endpoints 对象的变化,并根据这些信息为每个 Service 和对应的 Pod 部署 iptables 规则。

在 iptables 模式下,kube-proxy 会做以下工作:

  • 为 Service 创建负载均衡规则:当创建一个 Service 时,kube-proxy 会为该 Service 创建 iptables 规则,用于将访问 Service 的请求转发到后端 Pod。这些规则会捕获到达 Service 的请求,并将其重定向到 Service 后端的一组 Pod 中的某一个。
  • 为 Endpoints 创建负载均衡规则:kube-proxy 也会为每个 Endpoints 对象创建 iptables 规则,用于选择一个后端 Pod。这些规则允许 kube-proxy 在每个请求中选择一个后端 Pod,以实现负载均衡。
  • 实现会话亲和性:kube-proxy 支持会话亲和性,可以根据客户端 IP 来路由请求到同一个后端 Pod,以保持会话的一致性。这可以通过将 Service 的 sessionAffinity 属性设置为 "ClientIP" 来实现。
  • 自动重试后端 Pod:如果最初选择的后端 Pod 没有响应,kube-proxy 可以自动重试另一个后端 Pod。为了实现这一点,后端 Pod 必须具有 readiness probes,以确保它们能够接收流量。

kube-proxy 通常在 Kubernetes 集群中的每个物理机节点上都运行一个实例。kube-proxy 是 Kubernetes 中的一个核心组件,负责实现 Service 的负载均衡和服务发现功能。为了保证集群中的每个节点都能够访问到 Service,并实现负载均衡,kube-proxy 需要在每个节点上运行。

每个 kube-proxy 实例都会监听集群中的 Service 和 Endpoints 对象的变化,并根据这些变化来更新本地的负载均衡规则。通过在每个节点上运行 kube-proxy 实例,可以确保集群中的所有节点都能够正确地处理流量,并将请求转发到相应的后端 Pod。

Service 类型

定义Service的时候可以指定一个自己需要的类型的Service,如果不指定的话默认是ClusterIP类型。可以使用的服务类型如下:

  • ClusterIP:通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的ServiceType。

  • NodePort:通过每个 Node 节点上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 :,可以从集群的外部访问一个 NodePort 服务。

  • LoadBalancer:使用云提供商的负载局衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务,这个需要结合具体的云厂商进行操作。
  • ExternalName:通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)。没有任何类型代理被创建,这只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持。
NodePort 类型

如果设置 type 的值为 "NodePort",Kubernetes master 将从给定的配置范围内(默认:30000-32767)分配端口,每个 Node 将从该端口(每个 Node 上的同一端口)代理到 Service。该端口将通过 Service 的 spec.ports[*].nodePort 字段被指定,如果不指定的话会自动生成一个端口。

创建了一个 NodePort 类型的服务,名为 myservice。这意味着该服务将会在每个节点上绑定一个端口,并将流量转发到后端 Pod 的 80 端口。

myservice:这是你创建的 Service 的名称。

NodePort:这是 Service 的类型,表示这是一个 NodePort 类型的服务。

10.104.57.198:这是 Service 的 ClusterIP,即 Service 在集群内部的虚拟 IP 地址。

<none>:这表示该服务没有关联的外部负载均衡器 IP 地址。

80:32560/TCP:这是 Service 的端口映射规则。其中,80 是 Service 的端口,32560 是每个节点上绑定的 NodePort 端口,用于从节点外部访问该服务。它告诉 Kubernetes 在每个节点上将来自此端口的流量转发到 Service 的端口。

因此,当你访问任何物理节点的 32560 端口时,Kubernetes 将会将请求转发到集群内部的service的 80 端口,然后进一步将请求转发到具有标签 app: myapp 的 Pod 上的 80 端口,而定义Pod的时候设置了Pod里的容器会把它的服务监听的端口映射到Pod的80端口,从而实现了对后端 Pod 中的web服务的访问。

实际应用

假设我们需要让一个Wordpress来访问mysql数据库,使用Deployment来管理Pod,首先创建mysql的Deployment对象,指明容器监听的端口为3306,端口的名称是"dbport" 。

---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: mysql-deploy
  namespace: blog
  labels:
    app: mysql
spec:
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 3306
          name: dbport
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: rootPassW0rd
        - name: MYSQL_DATABASE
          value: wordpress
        - name: MYSQL_USER
          value: wordpress
        - name: MYSQL_PASSWORD
          value: wordpress
        volumeMounts:
        - name: db
          mountPath: /var/lib/mysql
      volumes:
      - name: db
        hostPath:
          path: /var/lib/mysql

然后需要让Wordpress来访问,由于它们不在同一个Pod中,需要访问就可以用到service。

所以在yaml文件中添加service信息

---
apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: blog
spec:
  selector:
    app: mysql
  ports:
  - name: mysqlport
    protocol: TCP
    port: 3306
    targetPort: dbport

运行

$ kubectl create -f wordpress-db.yaml
service "mysql" created
deployment.apps "mysql-deploy" created

然后查看Service的详细情况:

$ kubectl describe svc mysql -n blog
Name:              mysql
Namespace:         blog
Labels:            <none>
Annotations:       <none>
Selector:          app=mysql
Type:              ClusterIP
IP:                10.98.27.19
Port:              mysqlport  3306/TCP
TargetPort:        dbport/TCP
Endpoints:         10.244.2.213:3306
Session Affinity:  None
Events:            <none>

可以看到Endpoints部分匹配到了一个Pod,生成了一个clusterIP10.98.27.19,现在我们就可以通过这个clusterIP加上定义的3306端口就可以正常访问我们这个mysql服务了。(clusterIP是service提供给其他Pod访问的虚拟IP,Endpoints是service代理的Pod的实际IP和端口,其他Pod访问service使用的是clusterIP)。

接下来创建Wordpress服务,环境变量WORDPRESS_DB_HOST的值为上面mysql服务的clusterIP地址,这就是clusterIP类型service的使用。

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: wordpress-deploy
  namespace: blog
  labels:
    app: wordpress
spec:
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      containers:
      - name: wordpress
        image: wordpress
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: wdport
        env:
        - name: WORDPRESS_DB_HOST
          value: 10.98.27.19:3306
        - name: WORDPRESS_DB_USER
          value: wordpress
        - name: WORDPRESS_DB_PASSWORD
          value: wordpress

接下来需要让外网访问开启的wordpress服务,就需要建立一个能让外网用户访问的Service,这里就需要NodePort类型的Service。

---
apiVersion: v1
kind: Service
metadata:
  name: wordpress
  namespace: blog
spec:
  type: NodePort
  selector:
    app: wordpress
  ports:
  - name: wordpressport
    protocol: TCP
    port: 80
    targetPort: wdport

创建并查看信息

$ kubectl apply -f wordpress.yaml
service "wordpress" created
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
deployment.apps "wordpress-deploy" configured

$ kubectl get svc -n blog
NAME        TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
mysql       ClusterIP   10.98.27.19   <none>        3306/TCP       25m
wordpress   NodePort    10.101.7.69   <none>        80:32255/TCP   1m

可以看到wordpress服务产生了一个32255的端口,现在可以通过任意节点的NodeIP(公网IP)加上32255端口,就可以访问我们的wordpress应用了。

架构图解

NodePort模式的service绑定在每个k8s物理节点的32057端口,访问它就可以访问到service,然后service又会通过endpoint找到对应的Pod(因为它记录了这些Pod的内部 IP 地址),并访问它们的80端口。如果想让内部Pod访问service的时候,能访问到集群外部的服务,那么可以单独配置endpoint,这样service通过endpoint找的就是外部的ip地址。一般情况下不用NodePort模式的service来对外暴露服务,因为效率低,并且不支持http/https的通信,仅用于集群内部的通信,对外暴露服务需要使用ingress。

Ingress介绍

解决什么问题

把集群内部的Service暴露给外网访问,实现南北流量的互通。Service仅支持通过IP地址和端口来进行路由,不能进行HTTP请求的路径或主机头的路由。Ingress的功能和Nginx类似。

定义Ingress

路径匹配和虚拟主机匹配是两种常见的路由规则,它们根据请求的路径或主机头来路由流量到不同的后端服务。

路径匹配

路径匹配是根据请求的URL路径来进行路由的,将请求路由到不同的后端服务。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /app1
        pathType: Prefix
        backend:
          service:
            name: app1-service
            port:
              number: 80
      - path: /app2
        pathType: Prefix
        backend:
          service:
            name: app2-service
            port:
              number: 80

在上面的示例中,当请求的路径是 /app1 时,流量将被路由到 app1-service;当请求的路径是 /app2 时,流量将被路由到 app2-service

虚拟主机匹配

虚拟主机匹配是根据请求的主机头(即域名)来进行路由的。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
  - host: app1.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app1-service
            port:
              number: 80
  - host: app2.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app2-service
            port:
              number: 80

在上面的示例中,当请求的主机头是 app1.example.com 时,流量将被路由到 app1-service;当请求的主机头是 app2.example.com 时,流量将被路由到 app2-service

路径匹配适用于将不同的路径映射到不同的服务,通常用于在同一个域名下托管多个应用的情况。

虚拟主机匹配适用于将不同的主机头(域名)映射到不同的服务,通常用于在同一个集群中托管多个域名的情况。

ConfigMap介绍

解决什么问题

  • 将应用程序的配置信息(如数据库连接字符串、日志级别、端口号等)存储在ConfigMap中,然后在应用程序中通过环境变量或文件挂载的方式引用这些配置信息。
  • 对于需要加载静态文件的应用程序(如网页服务器、静态资源服务器等),可以将静态文件的路径、URL映射等配置信息存储在ConfigMap中,然后在应用程序中读取这些配置信息来加载静态文件。

定义ConfigMap

一个简单的Web应用程序,它连接到一个数据库,并且需要以下配置信息:

  • 数据库主机地址
  • 数据库端口号
  • 数据库用户名
  • 数据库密码

首先,创建一个ConfigMap来存储这些配置信息:

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-app-config
data:
  DB_HOST: "db.example.com"
  DB_PORT: "3306"
  DB_USERNAME: "admin"
  DB_PASSWORD: "password123"

然后,在部署应用程序的Deployment或Pod配置中,将这些配置信息注入到应用程序的环境变量中:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: my-app-image:latest
        ports:
        - containerPort: 8080
        envFrom:
        - configMapRef:
            name: my-app-config

我们通过envFrom字段将ConfigMap中的配置信息注入到了应用程序的环境变量中。这样,在应用程序启动时,就可以通过环境变量来访问数据库的配置信息。

Volumes介绍

解决什么问题

用于持久化存储数据。

Volume 类型

HostPath

和docker中的挂载主机目录类似。用例:一个基于 MySQL 数据库的应用程序,并且希望将数据库文件存储在宿主机上的特定目录中。

apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod
spec:
  containers:
  - name: mysql
    image: mysql:latest
    volumeMounts:
    - name: mysql-data
      mountPath: /var/lib/mysql
  volumes:
  - name: mysql-data
    hostPath:
      path: /data/mysql

创建了一个 Pod,其中包含一个名为 mysql 的容器,它使用 MySQL 镜像。我们定义了一个 HostPath Volume,它将宿主机上的 /data/mysql 目录挂载到容器内的 /var/lib/mysql 目录。简单来说相当于volumeMounts指定了用volumes作为磁盘加载到容器中。

EmptyDir

EmptyDir 是一个临时目录,它的生命周期与 Pod 的生命周期相同。当 Pod 被删除时,EmptyDir 中的数据也会被清除。常见使用场景是一个Pod中的不同容器共享数据。

用例:一个 Web 服务器应用程序,它由两个容器组成:一个容器负责生成静态网页文件,另一个容器负责提供这些网页文件。你希望生成的网页文件能够在提供容器中进行访问。在这种情况下,你可以使用 EmptyDir 来共享生成的网页文件。

apiVersion: v1
kind: Pod
metadata:
  name: web-server-pod
spec:
  containers:
  - name: webpage-generator
    image: webpage-generator:latest
    volumeMounts:
    - name: shared-data
      mountPath: /data
  - name: web-server
    image: nginx:latest
    volumeMounts:
    - name: shared-data
      mountPath: /usr/share/nginx/html
  volumes:
  - name: shared-data
    emptyDir: {}

 创建了一个 Pod,其中包含两个容器:一个是 webpage-generator,负责生成网页文件;另一个是 web-server,负责提供网页文件。我们创建了一个 EmptyDir Volume,并将其挂载到两个容器中。webpage-generator 容器可以将生成的网页文件写入 EmptyDir,而 web-server 容器可以读取并提供这些网页文件。在这个例子中,EmptyDir 提供了一个临时的共享存储介质,使得两个容器可以轻松地共享数据。

NFS介绍

解决什么问题

NFS 卷是一种用于挂载远程 NFS 服务器上的目录的卷类型,可以将远程存储中的文件或目录挂载到 Kubernetes Pod 中的容器中,相当于把 HostPath和EmpytDir结合起来,既可以实现数据共享,又可以持久化。

使用场景

有一个Web 应用程序,需要在多个 Pod 中共享静态文件,比如图片、视频或者其他资源文件。

  • 设置一个 NFS 服务器。假设 NFS 服务器的 IP 地址为 192.168.1.100,共享的目录为 /nfs/shared
  • 在Kubernetes 中创建一个 NFS 卷,以便 Pod 可以挂载这个共享目录。
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-volume
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /nfs/shared
    server: 192.168.1.100
  • 在应用程序的 Pod 配置中引用这个 NFS 卷。
apiVersion: v1
kind: Pod
metadata:
  name: webapp-pod
spec:
  containers:
  - name: webapp-container
    image: your-webapp-image
    volumeMounts:
    - name: nfs-volume
      mountPath: /app/static
  volumes:
  - name: nfs-volume
    persistentVolumeClaim:
      claimName: nfs-pvc
  • 在 Kubernetes 集群中创建一个持久卷声明,以便动态地分配 NFS 卷给 Pod。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

通过这个示例,Web 应用程序的所有 Pod 都可以共享 NFS 服务器上的/nfs/shared目录中的静态文件,无论 Pod 在 Kubernetes 集群中的哪个节点上运行,它们都可以访问相同的文件。

PV和PVC介绍

PV是Kubernetes中的存储资源的抽象,独立于任何单个Pod,PVC则是Pod对PV的请求。

解决什么问题

在没有pv的情况,每个节点使用的远程存储的方案不规范,各用各的,每个服务器都要管理自己的配置和依赖,没有统一的标准。pv对这些资源进行了抽象,关联了这些存储卷,通过在Pod上绑定PVC,就可以让Pod通过PVC去请求PV。



使用场景

下面是一个包含标签选择器的 PV 的 YAML 示例:
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /data/my-pv
  persistentVolumeReclaimPolicy: Retain
  labels:
    app: my-app
  • apiVersion: v1 指定了 Kubernetes API 的版本。
  • kind: PersistentVolume 表示这是一个 PersistentVolume 对象。
  • metadata.name 指定了 PV 的名称。
  • spec.capacity.storage 指定了 PV 的容量。
  • spec.accessModes 指定了 PV 的访问模式,这里设置为 ReadWriteOnce,表示可以被单个节点挂载为读写模式。
  • spec.nfs.path 指定了 PV 的路径,这里使用 NFS 协议。
  • spec.nfs.server 指定了 NFS 服务器的地址。
  • spec.persistentVolumeReclaimPolicy 指定了 PV 回收策略,这里设置为 Recycle,表示删除 PV 时会清空其中的数据。

创建一个 PVC 的 YAML 文件,如下所示:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      app: my-app

创建一个 Pod 的 YAML 文件,如下所示:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx
    volumeMounts:
    - name: my-volume
      mountPath: /usr/share/nginx/html
  volumes:
  - name: my-volume
    persistentVolumeClaim:
      claimName: my-pvc

这样就创建了一个 PV、一个 PVC 和一个 Pod,并将它们关联起来。Pod 将使用 PVC 中的存储资源,并将其挂载到容器中的指定路径。 
 

PV的回收策略

有不同的回收策略,用于确定当 PV 不再被使用时应如何处理其资源。

  1. Retain:在 PV 被释放后,保留 PV 的数据,不对其进行任何处理。这意味着 PV 的数据将保留在存储中,需要手动清理。这种策略适用于需要手动处理 PV 数据的情况。

  2. Delete:在 PV 被释放后,删除 PV 中的数据。这意味着 PV 的存储资源将被释放,并且 PV 中的数据将被永久删除。这种策略适用于不需要保留 PV 数据的情况,或者希望在释放 PV 时自动清理数据的情况。

PV的访问模式 

指定了如何将存储资源挂载到 Pod 中。

  1. ReadWriteOnce (RWO):该模式表示卷可以挂载到单个节点上的一个 Pod,并且可以被该 Pod 以读写的方式使用。这意味着卷不能同时被多个节点上的 Pod 挂载,但可以被同一节点上的多个 Pod 挂载。

  2. ReadOnlyMany (ROX):该模式表示卷可以同时被多个节点上的多个 Pod 以只读的方式挂载。这意味着多个 Pod 可以同时读取卷的内容,但不能对其进行写操作。

  3. ReadWriteMany (RWX):该模式表示卷可以同时被多个节点上的多个 Pod 以读写的方式挂载。这意味着多个 Pod 可以同时读取和写入卷的内容。

要选择正确的访问模式,需要根据你的应用程序和场景来确定。例如,如果你的应用程序需要多个 Pod 同时读写存储资源,那么就需要选择 RWX 访问模式。如果只需要一个 Pod 读写存储资源,那么就可以选择 RWO 访问模式。

PVC的访问模式

PV 和 PVC 的访问模式并不需要设置为完全相同。但是,PV 的访问模式必须满足 PVC 的访问需求。换句话说,PVC 可以请求比 PV 更灵活的访问模式,但不能请求更严格的访问模式。

例如:

  • 如果一个 PV 的访问模式是 ReadWriteOnce(RWO),那么它只能被单个 Pod 以读写模式挂载。其他 Pod 只能以只读模式挂载该 PV。
  • 如果一个 PVC 请求的访问模式是 ReadOnlyMany(ROX),那么它可以绑定到支持 ReadOnlyMany 或 ReadWriteMany(RWX)访问模式的 PV 上。

因此,PV 和 PVC 的访问模式可以不完全一样,但必须满足 PVC 的访问需求。

Storageclass介绍

以上构建PV的方式为静态构建,即提前手动创建好PV,等待PVC来绑定。利用storageclass可以实现动态构建,storageclass关联PVC后,可以根据PVC的需求自动创建PV。

使用场景

  1. 定义 StorageClass 的 YAML 文件:在 YAML 文件中指定 StorageClass 的名称、存储提供者、存储类型、卷大小等参数。

  2. 为 PVC 指定 StorageClass:在创建 PVC 的 YAML 文件中,通过 storageClassName 属性指定所需的 StorageClass。

  3. 使用 PVC:创建 Pod 时,将 PVC 指定为 Volume, Pod 将使用动态创建的 PV。

下面是一个 StorageClass 的简单示例:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
  zone: us-west-1

这个示例中的 StorageClass 名称为 "fast",使用 AWS EBS 作为存储提供者,并指定了一些参数,如存储类型为 gp2、区域为 us-west-1 等。创建 PVC 时,可以通过 storageClassName: fast 来使用这个 StorageClass,然后 Kubernetes 将会根据定义的策略动态地创建 PV。

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

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

相关文章

shell脚本之函数和数组

目录 一.函数 1.函数的简介 2.函数具有的几个要素 3.定义函数 4.调用函数 5.传递参数 6.函数返回值 7.函数的变量作用范围 8.函数递归 9.查看函数 二.数组 1.数组简介 2.定义数组 3.数组索引 4.数组替换 一.函数 1.函数的简介 在Shell脚本中&#xff0c;函数是…

网络传输,请每次都开启 TCP_NODELAY

原文&#xff1a;Marc Brooker - 2024.05.09 &#xff08;注&#xff1a;不必过于担心这个问题&#xff0c;大部分现代库&#xff0c;语言&#xff08;如 Go&#xff09;&#xff0c;代理&#xff08;如 Envoy&#xff09;&#xff0c;都默认设置了 TCP_NODELAY。如果遇到网络…

ubuntu编译pcl时报错

报错如下 cc1plus: warning: -Wabi wont warn about anything [-Wabi] cc1plus: note: -Wabi warns about differences from the most up-to-date ABI, which is also used by default cc1plus: note: use e.g. -Wabi11 to warn about changes from GCC 7 在网上找到了一封邮件…

深度剖析进程概念与进程状态

文章目录 1. 前言2. 什么是进程2.1 进程概念2.2 进程描述——PCB 3. 进程的一些基本操作3.1 查看进程3.2 结束进程3.3 通过系统调用获取进程标示符3.4 通过系统调用创建子进程 4. 进程状态4.1 普适的操作系统层面4.2 具体Linux操作系统层面 5. 两种特殊的进程5.1 僵尸进程5.2 孤…

2024第二届区块链、物联网与金融管理国际会议(ICBITFM2024)

2024第二届区块链、物联网与金融管理国际会议(ICBITFM2024) 会议简介 2024第二届区块链、物联网与金融管理国际会议(ICBITFM 2024)是一个重要的学术会议&#xff0c;旨在促进区块链、物联网和金融管理领域的交流和合作&#xff0c;对于推动这些领域的发展和创新具有重要意义。…

云商店如何让更多企业摘到技术普惠的“果实”?

文 | 智能相对论 作者 | 沈浪 现阶段&#xff0c;越是工业体系发达的地区&#xff0c;越需要加速技术普惠的步伐。比如&#xff0c;在苏州&#xff0c;华为云就在联合当地政府、企业伙伴打造以华为云云商店为重要链接的智能化商业增长底座。 华为云云商店以“电商式”的购物…

vue自定义权限指令

定义v-hasPermi指令 /*** v-hasPermi 操作权限处理*/import useUserStore from /store/modules/userexport default {mounted(el, binding, vnode) {const { value } bindingconst all_permission "*:*:*";const permissions useUserStore().permissions&#xff…

[IMX6ULL驱动开发]-GPIO子系统和Pinctrl子系统

目录 Pinctrl子系统的概念 GPIO子系统的概念 定义自己的GPIO节点 GPIO子系统的函数 引脚号的确定 基于GPIO子系统的驱动程序 驱动程序 设备树修改 之前我们进行驱动开发的时候&#xff0c;对于硬件的操作是依赖于ioremap对寄存器的物理地址进行映射&#xff0c;以此来达…

VRRP协议-负载分担配置【分别在路由器与交换机上配置】

VRRP在路由器与交换机上的不同配置 一、使用路由器实现负载分担二、使用交换机实现负载分担一、使用路由器实现负载分担 使用R1与R2两台设备分别进行VRRP备份组 VRRP备份组1,虚拟pc1的网关地址10.1.1.254 VRRP备份组2,虚拟pc2的网关地址10.1.1.253 ①备份组1的vrid=1,vrip=…

图片压缩工具,这三款软件简单好用!

在数字化时代&#xff0c;图片已成为我们生活和工作中不可或缺的一部分。无论是社交媒体上的分享&#xff0c;还是工作中的文件传输&#xff0c;图片都扮演着重要的角色。然而&#xff0c;随着图片质量的提高&#xff0c;其占用的存储空间也越来越大&#xff0c;这给我们的存储…

ChatGPT官网5月14日凌晨1点发布会推出最新GPT4o大模型,贾维斯时刻要来了?

就在今天北京时间2024年5月14日凌晨1点中&#xff0c;OpenAI进行了发布会&#xff0c;这次发布会的内容炸裂&#xff0c;一起来看下吧&#xff01; GPT4o多模态大模型发布 首先公开的是GPT4o多模态大模型的发布&#xff0c;相较于GPT-4turbo速度更快&#xff0c;更便宜。我刚开…

OIDC 与 OAuth2.0学习

OpenID Connect (OIDC) 和 OAuth 2.0 是两种不同的协议&#xff0c;它们通常一起使用&#xff0c;但服务于不同的目的。下面是它们的 主要区别和联系&#xff1a; OAuth 2.0 OAuth 2.0 是一个授权框架&#xff0c;它允许第三方应用代表用户获取对服务器资源的有限访问权限。…

深度践行“IaaS on DPU”理念,中科驭数正式发布“驭云”高性能云异构算力解决方案

5月10日至14日&#xff0c;由国家发展改革委联合国务院国资委、市场监管总局、国家知识产权局共同主办的第八届中国品牌日活动在上海世博展览馆举行。中科驭数高级副总裁张宇在中国品牌日新品首发首秀环节正式发布驭云高性能云异构算力解决方案&#xff0c;为企业提供更快部署、…

AWS ECS On Fargate 监控可观测最佳实践

概述 Amazon ECS on Fargate 为用户提供了简单、高效且可靠的容器化解决方案&#xff0c;使用户能够专注于应用程序开发和运行&#xff0c;而无需担心基础设施管理的复杂性。与其同时&#xff0c;用户需要实时了解在该环境中应用程序运行的性能、可用性、健康状况和资源使用情…

虾皮选品:Shopee首季盈利2.4亿;TikTok美区电商权限要求降低

2024年5月14号&#xff0c;跨境电商日报&#xff1a; 1.Ozon已成功回款 2.TikTok降低美区达人开通电商权限要求 3.Shopee首季盈利2.4亿 4.6月1日起&#xff0c;亚马逊退货处理费收取标准更新 5.欧盟委员会对从中国台湾地区和越南进口的不锈钢冷轧产品征收反补贴和反倾销税…

[Cesium]Cesium基础学习——Primitive

Cesium开发高级篇 | 01空间数据可视化之Primitive - 知乎 Primitive由两部分组成&#xff1a;几何体&#xff08;Geometry&#xff09;和外观&#xff08;Appearance&#xff09;。几何体定义了几何类型、位置和颜色&#xff0c;例如三角形、多边形、折线、点、标签等&#xf…

最佳实践 | 用HelpLook构建一体化企业知识中台

企业知识中台是内容与数据的双向交流的重要载体&#xff0c;它不仅能够让企业的内容说话&#xff0c;也能够倾听和分析数据。 你是否因寻找建立企业内部知识库/知识中台和说明文档平台的合适工具而苦恼&#xff1f;HelpLook数字内容平台正是你的理想之选。该平台以其简洁且用户…

一个开箱即用的已集成全部主流前端工具、类库的vue3+nuxt3服务端渲染ssr项目

项目背景&#xff1a; 需实现公司国际官网项目的seo如果是react就选用next&#xff0c;因为我最近在用vue3&#xff0c;就试试使用nuxt在网上找了很多模版&#xff0c;发现都不理想&#xff0c;缺的东西比较多&#xff0c;没法做到开箱即用&#xff0c;所以自己造个模版项目采…

【Java基础】枚举类的方法及应用

如何实现让一个类有固定个数的对象 手动封装构造方法&#xff08;private&#xff09; → 创建静态对象 → final修饰静态对象&#xff0c;使其成为常量 class Season { //枚举类public final static Season SPRING new Season();public final static Season SUMMER new Se…

【前端】打砖块游戏:实现细节介绍

打砖块游戏:实现细节介绍 在本文中,我将详细介绍如何使用HTML、CSS和JavaScript技术构建一个简单的打砖块游戏。我们将重点讨论游戏的三个核心技术方面:碰撞检测、画图和事件监听。 完整代码我放在:github可以直接拉取代码测试。 游戏概览 打砖块游戏中,玩家通过控制底…