k8s实践 | configmapsecretpvpvc

文章目录

  • configmap&secret&pv&pvc
  • 一、configMap
    • 1、应用场景
    • 2、创建configMap
      • 2.1、help文档
      • 2.2、使用目录创建
      • 2.3、根据文件创建
      • 2.4、文字创建
      • 2.5、直接方法
      • 2.6、pod中应用
      • 2.7、热更新
  • 二、secret
    • 1、Service Account
    • 2、opaque Secret
      • 2.1、创建示例
      • 2.2、使用方式
  • 三、k8s-volumes
    • 1、什么要用volumes?
    • 2、什么是volume?
    • 3、卷的类型
    • 4、emptyDir
    • 5、一个例子
    • 6、HostPath
    • 7、一个例子
    • 8、NFS网络存储
  • 四、PV&PVC
    • 1、pv&pvc说明
    • 2、生命周期
          • 供给
          • 静态
          • 动态
          • 绑定
          • 使用
          • 释放
          • 回收
    • 3、POD&PVC

configmap&secret&pv&pvc

一、configMap

我们在kubernetes上部署应用的时候,经常会需要传一些配置给我们的应用,比如数据库地址啊,用户名密码啊之类的。我们要做到这个,有好多种方案,比如:

  • 我们可以直接在打包镜像的时候写在应用配置文件里面,但是这种方式的坏处显而易见而且非常明显。
  • 我们可以在配置文件里面通过env环境变量传入,但是这样的话我们要修改env就必须去修改yaml文件,而且需要重启所有的container才行。
  • 我们可以在应用启动的时候去数据库或者某个特定的地方拿,没问题!但是第一,实现起来麻烦;第二,如果配置的地方变了怎么办?

当然还有别的方案,但是各种方案都有各自的问题。

而且,还有一个问题就是,如果说我的一个配置,是要多个应用一起使用的,以上除了第三种方案,都没办法进行配置的共享,就是说我如果要改配置的话,那得一个一个手动改。假如我们有100个应用,就得改100份配置,以此类推……

kubernetes对这个问题提供了一个很好的解决方案,就是用ConfigMap和Secret

ConfigMap功能在kubernetes1.2版本中引入,许多应用程序会从配置文件,命令行参数或环境变量中读取配置信息,ConfigAPI给我们提供了向容器中注入配置信息的机制,ConfigMap可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制大对象。

ConfigMap对像是一系列配置的集合,k8s会将这一集合注入到对应的Pod对像中,并为容器成功启动使用。注入的方式一般有两种,一种是挂载存储卷,一种是传递变量。ConfigMap被引用之前必须存在,属于名称空间级别,不能跨名称空间使用,内容明文显示。ConfigMap内容修改后,对应的pod必须重启或者重新加载配置(支持热更新的应用,不需要重启)。
Secret类似于ConfigMap,是用Base64加密,密文显示,一般存放敏感数据。一般有两种创建方式,一种是使用kubectl create创建,一种是用Secret配置文件。

1、应用场景

应用场景:镜像往往是一个应用的基础,还有很多需要自定义的参数或配置,例如资源的消耗、日志的位置级别等等,这些配置可能会有很多,因此不能放入镜像中,Kubernetes中提供了Configmap来实现向容器中提供配置文件或环境变量来实现不同配置,从而实现了镜像配置与镜像本身解耦,使容器应用做到不依赖于环境配置。

我们经常都需要为我们的应用程序配置一些特殊的数据,比如密钥、Token 、数据库连接地址或者其他私密的信息。你的应用可能会使用一些特定的配置文件进行配置,比如settings.py文件,或者我们可以在应用的业务逻辑中读取环境变量或者某些标志来处理配置信息。
我们要做到这个,有好多种方案,比如:
1.我们可以直接在打包镜像的时候写在应用配置文件里面,但是这种方式的坏处显而易见而且非常明显。
2.我们可以在配置文件里面通过 env 环境变量传入,但是这样的话我们要修改 env 就必须去修改 yaml 文件,而且需要重启所有的 container 才行。
3.我们可以在应用启动的时候去数据库或者某个特定的地方拿,没问题!但是第一,实现起来麻烦;第二,如果配置的地方变了怎么办?

当然还有别的方案,但是各种方案都有各自的问题。
而且,还有一个问题就是,如果说我的一个配置,是要多个应用一起使用的,以上除了第三种方案,都没办法进行配置的共享,就是说我如果要改配置的话,那得一个一个手动改。假如我们有 100 个应用,就得改 100 份配置,以此类推……

kubernetes 对这个问题提供了一个很好的解决方案,就是用 ConfigMap 和 Secret。    

向容器传递参数:

DockerKubernetes描述
ENTRYPOINTcommand容器中的可执行文件
CMDargs需要传递给可执行文件的参数

如果需要向容器传递参数,可以在Yaml文件中通过command和args或者环境变量的方式实现。

apiVersion: v1
kind: Pod
metadata:
  name: print-greeting
spec:
  containers:
  - name: env-print-demo
    image: hub.kaikeba.com/java12/bash:v1
    env:
    - name: GREETING
      value: "Warm greetings to"
    - name: HONORIFIC
      value: "The Most Honorable"
    - name: NAME
      value: "Kubernetes"
    command: ["echo"]
    args: ["$(GREETING) $(HONORIFIC) $(NAME)"]
    
    # 创建后,命令 echo Warm greetings to The Most Honorable Kubernetes 将在容器中运行,也就是环境变量中的值被传递到了容器中。
    # 查看pod就可以看出
    kubectl logs podname 

2、创建configMap

2.1、help文档

[root@k8s-master-155-221 configmap]# kubectl create  configmap --help
......
Aliases:
configmap, cm  #可以使用cm替代

Examples:
  # Create a new configmap named my-config based on folder bar
  kubectl create configmap my-config --from-file=path/to/bar  #从目录创建  文件名称为键  文件内容为值?
  
  # Create a new configmap named my-config with specified keys instead of file basenames on disk
  kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt #从文件创建 key1为键 文件内容为值
  
  # Create a new configmap named my-config with key1=config1 and key2=config2
  kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2   #直接命令行给定,键为key1 值为config1
  
  # Create a new configmap named my-config from the key=value pairs in the file
  kubectl create configmap my-config --from-file=path/to/bar   #从文件创建 文件名为键 文件内容为值
  
  # Create a new configmap named my-config from an env file
  kubectl create configmap my-config --from-env-file=path/to/bar.env

2.2、使用目录创建



# 指定目录
ls /docs/user-guide/configmap
#创建game.properties,ui.properties,game.cnf ui.conf ,game.yaml
# game.properties
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30

# ui.propertes
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice

#创建configmap ,指令
# game-config :configmap的名称
# --from-file:指定一个目录,目录下的所有内容都会被创建出来。以键值对的形式
# --from-file指定在目录下的所有文件都会被用在 ConfigMap 里面创建一个键值对,键的名字就是文件名,值就是文件的内容
kubectl create configmap game-config --from-file=docs/user-guide/configmap

# 查看configmap文件
kubectl get cm 

# 查看详细信息
kubectl get cm game-config -o yaml   

kubectl describe cm

2.3、根据文件创建

只需要指定为一个文件就可以从单个文件中创建ConfigMap

# 指定创建的文件即可
kubectl create configmap game-config-2 --from-file=/docs/user-guide/configmap/game.propertes

#查看
kubectl get configmaps game-config-2 -o yaml

–from-file这个参数可以使用多次,可以分别指定game.properties,ui.propertes.效果和指定整个目录是一样的。

2.4、文字创建

# 使用--from-literal 方式直接创建configmap
# Create the ConfigMap
$ kubectl create configmap my-config --from-literal=key1=value1 --from-literal=key2=value2
configmap "my-config" created 

# Get the ConfigMap Details for my-config
$ kubectl get configmaps my-config -o yaml
apiVersion: v1
data:
  key1: value1
  key2: value2
kind: ConfigMap
metadata:
  creationTimestamp: 2017-05-31T07:21:55Z
  name: my-config
  namespace: default
  resourceVersion: "241345"
  selfLink: /api/v1/namespaces/default/configmaps/my-config
  uid: d35f0a3d-45d1-11e7-9e62-080027a46057
  
# 文字方式
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm

#查看
kubectlget configmaps special-config -o yaml 

使用文字方式创建,利用 --from-literal 参数传递配置信息,改参数可以使用多次。

2.5、直接方法


# 直接通过配置文件的方式创建  
# 耦合方式创建
apiVersion: v1
data:
  game.properties: |
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
  ui.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
kind: ConfigMap
metadata:
  name: game-config
  namespace: default

2.6、pod中应用

# 创建configMap,   special.how: very   键名:键值
apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm
  
# 创建第二个configMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config
  namespace: default
data:
  log_level: INFO

# 第一种方式: 在pod中使用configmap配置,使用ConfigMap来替代环境变量
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: hub.kaikeba.com/library/myapp:v1 
      command: ["/bin/sh", "-c", "env"]
      env:
        - name: SPECIAL_LEVEL_KEY 
          valueFrom:
            configMapKeyRef: 
              name: special-config  # 第一种导入方式:在env中导入
              key: special.how              
        - name: SPECIAL_TYPE_KEY
          valueFrom: 
            configMapKeyRef: 
              name: special-config 
              key: special.type 
      envFrom:                      # 第二种导入方式,直接使用envFrom导入
        - configMapRef: 
            name: env-config 
  restartPolicy: Never
  
# 查看日志可以发现,环境变量注入到了容器中了,打印env就结束了
kubectl  logs  test-pod 
...
SPECIAL_TYPE_KEY=charm
SPECIAL_LEVEL_KEY=very
log_level=INFO
  
  
#第二种方式:用ConfigMap设置命令行参数
#用作命令行参数,将 ConfigMap 用作命令行参数时,需要先把 ConfigMap 的数据保存在环境变量中,然后通过 $(VAR_NAME) 的方式引用环境变量.
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: hub.kaikeba.com/library/myapp:v1
      command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] 
      env:
        - name: SPECIAL_LEVEL_KEY 
          valueFrom: 
            configMapKeyRef: 
              name: special-config 
              key: special.how 
        - name: SPECIAL_TYPE_KEY 
          valueFrom: 
            configMapKeyRef: 
              name: special-config 
              key: special.type 
  restartPolicy: Never
  
  
# 第三种方式:通过数据卷插件使用ConfigMap
#在数据卷里面使用这个ConfigMap,有不同的选项。最基本的就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容

apiversion: v1
kind: Pod
metadata:
  name: test-pod3
spec:
  containers:
    - name: test-container
      image: hub.kaikeba.com/library/myapp:v1
      command: [ "/bin/sh", "-c", "sleep 600s" ] 
      volumeMounts:
        - name: config-volume
          mountPath: /etc/config # 表示把conifg-volume挂载卷挂载到容器的/etc/config目录下
  volumes:    # 开启挂载外部configmap
    - name: config-volume
      configMap:
        name: special-config
  restartPolicy: Never
  
  # 登录容器查看/etc/config目录下是否挂载成功
  

2.7、热更新

# ConfigMap的热更新
apiVersion: v1
kind: ConfigMap
metadata:
  name: log-config
  namespace: default
data:
  log_level:INFO
---
apiVersion: extensions/v1beta1 
kind: Deployment 
metadata: 
  name: my-nginx 
spec:
  replicas: 1
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
        - name: my-nginx
          image: hub.kaikeba.com/java12/myapp:v1 
          ports:
            - containerPort: 80 
          volumeMounts:
            - name: config-volume 
              mountPath: /etc/config 
      volumes:
        - name: config-volume 
          configMap:
            name: log-config

# 获取值
kubectl exec my-nginx-7b55868ff4-wqh2q -it -- cat /etc/config/log_level
#输出
INFO

修改ConfigMap

$ kubectl edit configmap log-config
修改log-level的值为DEBUG等待大概10秒钟时间,再次查看环境变量的值

二、secret

​ Secret对象存储数据的方式是以键值方式存储数据,在Pod资源进行调用Secret的方式是通过环境变量或者存储卷的方式进行访问数据,解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。

​ 另外,Secret对象的数据存储和打印格式为Base64编码的字符串,因此用户在创建Secret对象时,也需要提供该类型的编码格式的数据。在容器中以环境变量或存储卷的方式访问时,会自动解码为明文格式。需要注意的是,如果是在Master节点上,Secret对象以非加密的格式存储在etcd中,所以需要对etcd的管理和权限进行严格控制。
Secret有4种类型:

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

1、Service Account

Service Account 用来访问kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中.

Service Account 不需要我们自己去管理的,此证书是由kubernetes自己来进行维护管理的。

# 创建pod
kubectl run my-nginx --image=hub.kaikeba.com/java12/nginx:v1 

# 查看证书
kubctl exec -it podName -- sh
# 进入证书目录/run/secrets/kubernetes.io/serviceaccount查看即可
ca
namespace
token

2、opaque Secret

2.1、创建示例

Opaque类型的数据一个map类型,要求value是base64编码格式

# base64对用户名,密码加密效果演示
echo -n "admin" | base64
YWRtaW4=

echo -n "abcdefgh" | base64
YWJjZGVmZ2g=


# secret.yaml配置文件方式
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
 password: YWJjZGVmZ2g=
 username: YWRtaW4=

2.2、使用方式

# 将secret挂载到volume中
apiVersion: v1
kind: pod
metadata:
 name: secret-test
 labels:
   name: secret-test
spec:
  volumes:
  - name: secrets
    secret:
      secretName: mysecret
  containers:
  - image: hub.kaikeba.com/java12/myapp:v1
    name: db
    volumeMounts:
    - name: secrets
      mountPath: "/etc/secrets"
      readOnly: true
   


# 将secret导出到环境变量中
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: secret-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: pod-deployment
    spec:
      containers:
      - name: pod-1
        image: hub.kaikeba.com/java12/myapp:v1
        ports:
        - containerPort: 80
        env:
        - name: TEST_USER
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: username
        - name: TEST_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: password

三、k8s-volumes

1、什么要用volumes?

k8s中容器中的磁盘的生命周期是短暂的, 这就带来了一些列的问题

  1. 当一个容器损坏之后, kubelet会重启这个容器, 但是容器中的文件将丢失----容器以干净的状态重新启动
  2. 当很多容器运行在同一个pod中时, 很多时候需要数据文件的共享
  3. k8s中,由于pod分布在各个不同的节点之上,并不能实现不同节点之间持久性数据的共享,并且,在节点故障时,可能会导致数据的永久性丢失。

volumes就是用来解决以上问题的

Volume 的生命周期独立于容器,Pod 中的容器可能被销毁和重建,但 Volume 会被保留。

注意:docker磁盘映射的数据将会被保留,和kubernetes有一些不一样

2、什么是volume?

volume用来对容器的数据进行挂载,存储容器运行时所需的一些数据。当容器被重新创建时,实际上我们发现volume挂载卷并没有发生变化。

​ kubernetes中的卷有明确的寿命————与封装它的pod相同。所以,卷的生命比pod中的所有容器都长,当这个容器重启时数据仍然得以保存。

当然,当pod不再存在时,卷也不复存在,也许更重要的是kubernetes支持多种类型的卷,pod可以同时使用任意数量的卷

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oacvq1xO-1679666378136)(assets/image-20200511204534341.png)]

3、卷的类型

kubenetes卷的类型:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vT8zWo1N-1679666378138)(assets/image-20200511111331467.png)]

第一种就是本地卷

像hostPath类型与docker里面的bind mount类型,就是直接挂载到宿主机文件的类型
像emptyDir是这样本地卷,也就是类似于volume类型
这两点都是绑定node节点的

第二种就是网络数据卷

比如Nfs、ClusterFs、Ceph,这些都是外部的存储都可以挂载到k8s上

第三种就是云盘

比如AWS、微软(azuredisk)

第四种就是k8s自身的资源

比如secret、configmap、downwardAPI

4、emptyDir

先来看一下本地卷
像emptyDir类似与docker的volume,而docker删除容器,数据卷还会存在,而emptyDir删除容器,数据卷也会丢失,一般这个只做临时数据卷来使用

创建一个空卷,挂载到Pod中的容器。Pod删除该卷也会被删除。

应用场景:Pod中容器之间数据共享

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

注意:容器崩溃不会从节点中移除pod,因此emptyDir卷中的数据在容器崩溃时是安全的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xquYaKw6-1679666378139)(assets/image-20200511205218768.png)]

emptyDir的用法

1、暂存空间,例如用于基于磁盘的合并排序
2、用作长时间计算崩溃恢复时候的检查点
3、web服务器容器提供数据时,保存内容管理器容器提取的文件

5、一个例子

apiVersion: v1
kind: Pod
metadata:
  name: test-pod1
spec:
  containers:
  - image: hub.kaikeba.com/library/myapp:v1
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}
    

---
apiVersion: v1
kind: Pod
metadata:
  name: test-pod2
spec:
  containers:
  - image: hub.kaikeba.com/library/myapp:v1
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  - name: test-1
    image: hub.kaikeba.com/library/busybox:v1
    command: ["/bin/sh","-c","sleep 3600s"]
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}

6、HostPath

挂载Node文件系统上文件或者目录到Pod中的容器。

应用场景:Pod中容器需要访问宿主机文件 ;

7、一个例子

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - image: hub.kaikeba.com/library/myapp:v1
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    hostPath:
      path: /data
      type: Directory

这里创建的数据和我们被分配的node节点的数据都是一样的,创建的数据都会更新上去,删除容器,不会删除数据卷的数据。

type类型

除了所需的path属性职位,用户还可以为hostPath卷指定type.

image-20200511114734100

8、NFS网络存储

Kubernetes进阶之PersistentVolume 静态供给实现NFS网络存储

NFS是一种很早的技术,单机的存储在服务器方面还是非常主流的,但nfs唯一的就是缺点比较大就是没有集群版,做集群化还是比较费劲的,文件系统做不了,这是一个很大的弊端,大规模的还是需要选择一些分布式的存储,nfs就是一个网络文件存储服务器,装完nfs之后,共享一个目录,其他的服务器就可以通过这个目录挂载到本地了,在本地写到这个目录的文件,就会同步到远程服务器上,实现一个共享存储的功能,一般都是做数据的共享存储,比如多台web服务器,肯定需要保证这些web服务器的数据一致性,那就会用到这个共享存储了,要是将nfs挂载到多台的web服务器上,网站根目录下,网站程序就放在nfs服务器上,这样的话。每个网站,每个web程序都能读取到这个目录,一致性的数据,这样的话就能保证多个节点,提供一致性的程序了。

1)、单独拿一台服务器做nfs服务器,我们这里先搭建一台NFS服务器用来存储我们的网页根目录

yum install nfs-utils -y

2)、暴露目录,让是让其他服务器能挂载这个目录

mkdir /opt/k8s
vim /etc/exports
/opt/k8s 192.168.30.0/24(rw,no_root_squash)

给这个网段加上权限,可读可写

[root@nfs ~]# systemctl start nfs

找个节点去挂载测试一下,只要去共享这个目录就要都去安装这个客户端

#其他节点也需要安装nfs
yum install nfs-utils -y
mount -t nfs 192.168.30.27:/opt/k8s /mnt
cd /mnt
df -h
192.168.30.27:/opt/k8s    36G  5.8G   30G   17% /mnt
touch a.txt

去服务器端查看已经数据共享过来了

删除nfs服务器的数据也会删除
接下来怎么将K8s进行使用
我们把网页目录都放在这个目录下

# mkdir wwwroot
# vim nfs.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nfs
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: hub.kaikeba.com/library/myapp:v1
        volumeMounts:
        - name: wwwroot
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
      volumes:
      - name: wwwroot
        nfs:
          server: 192.168.66.13
          path: /opt/k8s/wwwroot
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
  type: NodePort

我们在源pod的网页目录下写入数据,并查看我们的nfs服务器目录下也会共享

四、PV&PVC

1、pv&pvc说明

管理存储和管理计算有着明显的不同。PersistentVolume给用户和管理员提供了一套API,抽象出存储是如何提供和消耗的细节。在这里,我们介绍两种新的API资源:PersistentVolume(简称PV)PersistentVolumeClaim(简称PVC)

  • PersistentVolume(持久卷,简称PV)是集群内,由管理员提供的网络存储的一部分。就像集群中的节点一样,PV也是集群中的一种资源。它也像Volume一样,是一种volume插件,但是它的生命周期却是和使用它的Pod相互独立的。PV这个API对象,捕获了诸如NFS、ISCSI、或其他云存储系统的实现细节。
  • PersistentVolumeClaim(持久卷声明,简称PVC)是用户的一种存储请求。它和Pod类似,Pod消耗Node资源,而PVC消耗PV资源。Pod能够请求特定的资源(如CPU和内存)。PVC能够请求指定的大小和访问的模式(可以被映射为一次读写或者多次只读)。

PVC允许用户消耗抽象的存储资源,用户也经常需要各种属性(如性能)的PV。集群管理员需要提供各种各样、不同大小、不同访问模式的PV,而不用向用户暴露这些volume如何实现的细节。因为这种需求,就催生出一种StorageClass资源。

StorageClass提供了一种方式,使得管理员能够描述他提供的存储的等级。集群管理员可以将不同的等级映射到不同的服务等级、不同的后端策略。

K8s为了做存储的编排
数据持久卷PersistentVolume 简称pv/pvc主要做容器存储的编排

• PersistentVolume(PV):对存储资源创建和使用的抽象,使得存储作为集群中的资源管理
pv都是运维去考虑,用来管理外部存储的

• 静态 :提前创建好pv,比如创建一个100G的pv,200G的pv,让有需要的人拿去用,就是说pvc连接pv,就是知道pv创建的是多少,空间大小是多少,创建的名字是多少,有一定的可匹配性

• 动态

• PersistentVolumeClaim(PVC):让用户不需要关心具体的Volume实现细节
使用多少个容量来定义,比如开发要部署一个服务要使用10个G,那么就可以使用pvc这个资源对象来定义使用10个G,其他的就不用考虑了

pv&pvc区别

PersistentVolume(持久卷)PersistentVolumeClaim(持久卷申请)是k8s提供的两种API资源,用于抽象存储细节。

管理员关注如何通过pv提供存储功能而无需关注用户如何使用,同样的用户只需要挂载pvc到容器中而不需要关注存储卷采用何种技术实现。

pvc和pv的关系与pod和node关系类似,前者消耗后者的资源。pvc可以向pv申请指定大小的存储资源并设置访问模式,这就可以通过Provision -> Claim 的方式,来对存储资源进行控制。

2、生命周期

volume 和 claim 的生命周期,PV是集群中的资源,PVC是对这些资源的请求,同时也是这些资源的“提取证”。PV和PVC的交互遵循以下生命周期:

3、POD&PVC

先创建一个容器应用

#vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
    containers:
    - name: nginx
      image: nginx:latest
      ports:
      - containerPort: 80
      volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumes:
    - name: www
      persistentVolumeClaim:
        claimName: my-pvc

卷需求yaml,这里的名称一定要对应,一般两个文件都放在一块

# vim pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

接下来就是运维出场了,提前创建好pv

# vim pv1.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv1
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/k8s/demo1
    server: 192.168.66.13

提前创建好pv,以及挂载目录

我再创建一个pv,在nfs服务器提前把目录创建好,名称修改一下

# vim pv2.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv2
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/k8s/demo2
    server: 192.168.66.13

然后现在创建一下我们的pod和pvc,这里我写在一起了

# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
      - name: www
        mountPath: /usr/share/nginx/html
  volumes:
    - name: www
      persistentVolumeClaim:
        claimName: my-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

es:
- ReadWriteMany
nfs:
path: /opt/k8s/demo1
server: 192.168.66.13


提前创建好pv,以及挂载目录

我再创建一个pv,在nfs服务器提前把目录创建好,名称修改一下

```yaml
# vim pv2.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv2
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/k8s/demo2
    server: 192.168.66.13

然后现在创建一下我们的pod和pvc,这里我写在一起了

# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
      - name: www
        mountPath: /usr/share/nginx/html
  volumes:
    - name: www
      persistentVolumeClaim:
        claimName: my-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

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

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

相关文章

eNSP 本地AAA配置实验

关于本实验本实验要求将路由器AR1配置为AAA服务器,以本地认证方式对尝试登录AR1的用户进行身份认证和授权。路由器AR2作为登录用户(AAA客户端),以Telnet的方式登录AR1.读者需要在AR1中创建一个名为datacom的管理员域,并…

【Unity游戏开发教程】零基础带你从小白到超神22——旧动画和新动画组件的使用

制作一个动画 创建动画 添加变化属性 实现方块向右移动10 添加关键帧 实现先慢后快的效果 录制动画 旧动画组件(Animation组件) 如果想让一个游

PMP项管2023年5月的备考准备攻略!

2023年共有4次PMP考试,分别是3月、5月、8月、11月,由于3月份考试不开放新报名,所以第一次备考PMP的同学可以选择参加5月份考试。那么,现在备考5月份PMP考试还来得及吗? 现在开始备考5月PMP考试,时间是非常…

GEE:克里金 Kriging 插值(以陕西省2013年生物量为例)

本文记录了在Google Earth Engine(GEE)平台上进行 Kriging 插值的介绍和代码案例。本文通过选取的2013年陕西省生物量样本点数据为例,利用 Kriging 插值对未知区域做了插值计算。 Google Earth Engine(GEE)是一个用于分析地理空间数据的云平台,其中包含了许多地理空间分…

Office E5 OneDrive API使用指南:注册+密钥获取+获取临时上传链接+分片

异想之旅:本人原创博客完全手敲,绝对非搬运,全网不可能有重复;本人无团队,仅为技术爱好者进行分享,所有内容不牵扯广告。本人所有文章仅在CSDN、掘金和个人博客(一定是异想之旅域名)…

Java 各种锁的理解与实现

1. volatile 是轻量级锁: 只能修饰在变量上,使得 cpu 每次对于该变量的修改和读取都从内存中操作,而不是从CPU cache 中操作,保证共享变量对所有线程的可见性,但是并不能保证原子性 2. synchronized 悲观锁&#xff…

Mybatis的CRUD使用详解

文章目录一.Mybatis的CRUD使用详解1.1 select1.2 insert1.3 update1.3 delete二.常见错误一.Mybatis的CRUD使用详解 注意&#xff1a;增删改需要提交事务。 namespace&#xff08;UserMapper.xml&#xff09; namespace中的包名需要和Dao/mapper接口的包名一致。 <!--na…

论文阅读 10 | Instance Credibility Inference for Few-Shot Learning

小样本学习的实例可信度推理作者摘要1. Introduction2. Related Work作者 摘要 小样本学习&#xff08;FSL&#xff09;旨在识别每个类别极其有限的训练数据的新对象。以前的努力是通过利用元学习范式或数据增强中的新原理来缓解这个极其缺乏数据的问题。相比之下&#xff0c;本…

taro--之使用nutui组件库

安装 Taro 脚手架# 使用 npm 安装 CLI npm install -g tarojs/cli# 使用 yarn 安装 CLI yarn global add tarojs/cli# 使用 cnpm 安装 CLI cnpm install -g tarojs/cli使用 NutUI 模板创建项目1、使用命令创建 Taro 项目&#xff1a;taro init myApp2、按照下方图片依次选择&am…

ChatGPT如何批量撰写最新的热点自媒体文章

如何用ChatGPT创作高质量的自媒体文章 自媒体已成为互联网上的一个重要组成部分&#xff0c;无论您是想在社交媒体、博客中发布内容&#xff0c;高质量的文章都是自媒体成功的重要组成部分。ChatGPT是一个智能文章生成器&#xff0c;能够帮助创作者快速、高效地生成高质量的自…

数据结构——二叉搜索树

一、二叉搜索树概念 二叉搜索树又叫二叉排序树&#xff0c;它或是空树&#xff0c;或是具有以下性质的二叉树&#xff1a; &#xff08;1&#xff09;若它的左子树不为空&#xff0c;则左子树上的所有节点的值都小于根节点的值&#xff1b; &#xff08;2&#xff09;若它的…

LeetCode-718. 最长重复子数组

目录题目思路动态规划遇到的坑动态规划(优化)题目来源 718. 最长重复子数组 题目思路 用二维数组可以记录两个字符串的所有比较情况&#xff0c;这样就比较好推递推公式了。 动态规划 1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i][j]的定义也就决定…

【云原生】我将ChatGPT变成Kubernetes 和Helm 终端

{kubectl get po&#xff0c;deploy&#xff0c;svc}{kubectl run --imagenginx nginx-app --port80 --env“DOMAINcluster”}{kubectl expose deployment nginx-app --port80 --namenginx-http}{kubectl get po&#xff0c;svc&#xff0c;deploy}{curl 10.100.67.94:80}{helm…

Spring事务

目录 手动操作 声明式提交 注解的属性 事务隔离级别 事务传播机制 事务可以将一组操作封装成为一个单元&#xff0c;一组操作要么全部成功&#xff0c;要么全部失败 Mysql中操作事务&#xff0c;有三个步骤&#xff1b; 1、start transaction &#xff1b;开启事务 2、com…

springboot 整合Mybatis-Plus分页、自动填充功能

springboot 整合Mybatis-Plus分页、自动填充功能功能 此次分页、自动填充功能的实现是在Spring Boot整合 druid、Mybatis-plus实现的基础上完成的&#xff0c;包括数据源配置、各种依赖添加、mapper和service的实现。不在重复记录。 Java开发手册要求数据表必须要有三个字段&am…

【lwIP(第九章)】ICMP协议

目录一、ICMP协议简介1. ICMP协议类型与结构2. ICMP 差错报文3. ICMP 查询报文二、ICMP协议原理1. ICMP报文数据结构2. ICMP的差错报文3. 差错报文的原理4. ICMP的查询报文一、ICMP协议简介 ICMP协议是一个网络层协议。 一个新搭建好的网络&#xff0c;往往需要先进行一个简单的…

为什么说学人工智能一定要学Python?

学习人工智能需要掌握大量的数据处理和算法实现&#xff0c;而Python作为一种高级编程语言&#xff0c;具有简单易学、灵活多变、开源丰富的库等优点&#xff0c;成为了人工智能领域广泛应用的语言之一。 具体来说&#xff0c;Python在人工智能中的优势包括&#xff1a; ​​…

Matlab群体智能优化算法之巨型睡莲优化算法(VAO)

Matlab群体智能优化算法之巨型睡莲优化算法(VAO) 摘要&#xff1a;介绍一种新型智能优化算法&#xff0c;巨型睡莲优化算法。其应用于24个基准测试函数&#xff0c;并与其他10个著名算法进行了比较。提出的算法在10个优化问题上进行了测试&#xff1a;最小生成树、枢纽位置分配…

Nginx学习(9)—— 负载均衡模块

文章目录Nginx负载均衡模块负载均衡配置指令钩子初始化配置初始化请求peer.get和peer.free回调函数小结Nginx负载均衡模块 负载均衡模块用于从”upstream”指令定义的后端主机列表中选取一台主机。nginx先使用负载均衡模块找到一台主机&#xff0c;再使用upstream模块实现与这…

HTTP代理端口是什么意思?

HTTP代理端口是指代理服务器所使用的端口。代理服务器是一种介于客户端和服务器之间的计算机系统&#xff0c;它可以拦截客户端发送给服务器的请求&#xff0c;并将其转发到服务器。而HTTP代理端口则是代理服务器上专门用于处理HTTP请求和响应的端口号。默认情况下&#xff0c;…