zoukankan      html  css  js  c++  java
  • k8s学习-存储

    4.6、存储

    4.6.1、ConfigMap

    创建方式

    文件夹/文件创建
    mkdir dir
    cd dir
    cat > c1.properties <<EOF
    c1.name=c1
    EOF
    cat > c2.properties <<EOF
    c2.name=c2
    EOF
    
    cd ..
    cat > c3.properties <<EOF
    c3.name=c3
    EOF
    
    # configmap 简写为 cm
    # 根据目录创建
    kubectl create configmap cm-c1 --from-file=dir
    # 根据文件创建
    kubectl create configmap cm-c2 --from-file=c3.properties
    
    # 查看
    [root@k8s-master configmap]# kubectl get cm
    NAME    DATA   AGE
    cm-c1   2      12s
    cm-c2   1      7s
    
    # 查看内容
    [root@k8s-master configmap]# kubectl get cm cm-c2 -o yaml
    apiVersion: v1
    data:
      c3.properties: |
        c3.name=c3
    kind: ConfigMap
    metadata:
      creationTimestamp: "2020-03-08T02:55:45Z"
      name: cm-c2
      namespace: default
      resourceVersion: "280079"
      selfLink: /api/v1/namespaces/default/configmaps/cm-c2
      uid: d35bfd4e-42bc-491f-b30a-488633d36653
    
    
    字面量创建
    # 使用 --from-literal=KEY=VALUE 
    kubectl create cm cm-literal --from-literal=lt.name=bart --from-literal=lt.age=16
    # 查看
    [root@k8s-master configmap]# kubectl get cm cm-literal -o yaml
    apiVersion: v1
    data:
      lt.age: "16"
      lt.name: bart
    kind: ConfigMap
    metadata:
      creationTimestamp: "2020-03-08T02:59:41Z"
      name: cm-literal
      namespace: default
      resourceVersion: "280454"
      selfLink: /api/v1/namespaces/default/configmaps/cm-literal
      uid: 5bd18816-bfd9-4f5d-abd8-5fc20d4ead92
    
    配置文件创建

    vim cm.yml

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: cm-special-config
    data:
      special.how: very
      special.type: charm
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: cm-env-config
    data:
      log_level: INFO
    
    kubectl create -f cm.yml
    [root@k8s-master configmap]# kubectl get cm
    NAME                DATA   AGE
    cm-c1               2      46m
    cm-c2               1      45m
    cm-env-config       1      13s # 刚创建的
    cm-literal          2      41m
    cm-special-config   2      13s # 刚创建的
    

    Pod中使用ConfigMap

    env使用

    vim env.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: cm-test-pod
    spec:
      containers:
      - name: nginx
        image: habor-repo.com/library/nginx:v1
        command: ["/bin/sh", "-c", "env; echo -e $(SPECIAL_HOW)"] # 打印env和指定key
        env: # 容器添加环境变量
        - name: SPECIAL_HOW
          valueFrom: # 引用 configmap 的值
            configMapKeyRef:
              name: cm-special-config # configmap 的 name
              key: special.how # configmap 中的 key
        envFrom: # 环境变量导入
        - configMapRef:
            name: cm-env-config # configmap 的 name
      restartPolicy: Never # 不重启
    
    
    kubectl create -f env.yaml
    kubectl get pod
    # 查看日志 
    [root@k8s-master configmap]# kubectl logs cm-test-pod
    KUBERNETES_SERVICE_PORT=443
    KUBERNETES_PORT=tcp://10.96.0.1:443
    HOSTNAME=cm-test-pod
    HOME=/root
    PKG_RELEASE=1~buster
    KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
    NGINX_VERSION=1.17.9
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    KUBERNETES_PORT_443_TCP_PORT=443
    NJS_VERSION=0.3.9
    KUBERNETES_PORT_443_TCP_PROTO=tcp
    log_level=INFO # fromEnv 中的值
    SPECIAL_HOW=very
    KUBERNETES_SERVICE_PORT_HTTPS=443
    KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
    KUBERNETES_SERVICE_HOST=10.96.0.1
    PWD=/
    nvery # 打印的 env的value
    
    
    挂载使用

    vim volume.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: cm-test-pod2
    spec:
      containers:
      - name: nginx
        image: habor-repo.com/library/nginx:v1
        command: ["/bin/sh", "-c", "cat /etc/config/special.how"] # 文件名就是key,内容就是value
        volumeMounts:
        - name: config-volume # 挂载位置绑定挂在卷名字
          mountPath: /etc/config
      volumes:
      - name: config-volume # 定义一个挂载卷为configmap的内容
        configMap: 
          name: cm-special-config
      restartPolicy: Never # 不重启
    
    kubectl create -f volume.yml
    kubectl get pod
    # 查看日志 
    [root@k8s-master configmap]# kubectl logs cm-test-pod2
    very
    

    热更新

    vim hot.yml

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: cm-test-pod3
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: cm-test-pod3
        spec:
          containers:
          - name: nginx
            image: habor-repo.com/library/nginx:v1
            volumeMounts:
            - name: config-volume # 挂载位置绑定挂在卷名字
              mountPath: /etc/config
          volumes:
          - name: config-volume # 定义一个挂载卷为configmap的内容
            configMap: 
              name: cm-special-config
          restartPolicy: Always # 不支持Never
    
    kubectl create -f hot.yml
    [root@k8s-master configmap]# kubectl get pod
    NAME                            READY   STATUS      RESTARTS   AGE
    cm-test-pod                     0/1     Completed   0          36m
    cm-test-pod2                    0/1     Completed   0          22m
    cm-test-pod3-75fbd58f94-v7rph   1/1     Running     0          5s
    # 查看内容
    kubectl exec cm-test-pod3-75fbd58f94-v7rph -it -- cat /etc/config/special.type
    
    # 修改 cm-special-config 的值 
    kubectl edit cm cm-special-config
    # 再次查看 (大概10秒钟左右值会自动改变)
    kubectl exec cm-test-pod3 -it -- cat /etc/config/special.type
    
    # 修改pod内容强制触发滚动更新,适用于Env环境变量引用的configMap的情况
    kubectl patch deployment cm-test-pod3 --patch '{"spec": {"template": {"metadata": {"annotations": {"version/config": "20200309"}}}}}'
    
    [root@k8s-master configmap]# kubectl get pod
    NAME                          READY   STATUS      RESTARTS   AGE
    cm-test-pod                   0/1     Completed   0          38m
    cm-test-pod2                  0/1     Completed   0          24m
    cm-test-pod3-59688486-xd5zs   1/1     Running     0          23s # pod 已经重启了
    
    

    主意:!!!

    • 使用ConfigMap挂载的Env不会同步更新(除非Pod重新加载)
    • 使用ConfigMap挂载的Volume会更新(大概10秒)

    4.6.2、Secret

    Service Account

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

    # 假如有个pod为nginx
    kubectl exec nignx -it -- ls /run/secrets/kubernetes.io/serviceaccount
    ca.crt
    namespace
    token
    

    OpqueSecret

    使用base64来加密一些配置项

    echo "admin" | base64 # YWRtaW4K
    echo "YWRtaW4K" | base64 -d # admin
    
    echo "123456" | base64 # MTIzNDU2Cg==
    echo "MTIzNDU2Cg==" | base64 -d # 123456
    
    

    vim secret.yml

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    data:
      name: YWRtaW4K
      password: MTIzNDU2Cg==
    
    kubectl create -f secret.yml
    # 查看内容
    kubectl get secret mysecret -o yaml
    

    vim pod.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-test-pod
    spec:
      containers:
      - name: nginx
        image: habor-repo.com/library/nginx:v1
        env: # 容器添加环境变量
        - name: SEC_USER_NAME
          valueFrom: # 引用 secret 的值
            secretKeyRef:
              name: mysecret # mysecret 的 name
              key: name # mysecret 中的 key
        - name: SEC_USER_PASSWORD
          valueFrom: 
            secretKeyRef:
              name: mysecret 
              key: password 
        volumeMounts:
        - name: secret-volume # 挂载位置绑定挂在卷名字
          mountPath: /etc/config
      volumes:
      - name: secret-volume # 定义一个挂载卷为configmap的内容
        secret: 
          secretName: mysecret
      restartPolicy: Never # 不重启
    
    kubectl create -f pod.yml
    kubectl get pod
    # 查看挂载文件
    [root@k8s-master secret]# kubectl exec secret-test-pod -it -- ls /etc/config
    name  password
    # 查看环境变量(进入容器内部查看)
    [root@k8s-master secret]# kubectl exec secret-test-pod -it -- /bin/bash
    root@secret-test-pod:/# echo $SEC_USER_NAME $SEC_USER_PASSWORD
    admin 123456
    
    

    kubernetes.io/dockerconfigjson

    使用kubectl创建docker registry认证的secret

    kubectl create secret docker-registry <registrykey名字> --docker-server=<docker仓库域名> --docker-username=<仓库登录名> --docker-password=<登录密码> --docker-emai=<邮箱(随便给)>
    
    # 使用 docker login登录也可以
    docker login <docker仓库域名>
    

    在创建Pod的时候指定imagePullSecrets参数

    apiVersion: v1
    kind: Pod
    metadata:  
    name: foo
    spec:  
      containers:    
      - name: foo      
        image: roc/awangyang:v1  
      imagePullSecrets:     
      - name: myregistrykey # 对应上面创建的 <registrykey名字>
    

    4.6.3、Volume

    emptyDir

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

    emptyDir的用法有:

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

    vim emptydir.yml

    apiVersion: v1
    kind: Pod
    metadata:  
      name: test-pd
    spec: 
      containers:
      - image: habor-repo.com/library/nginx:v1
        name: nginx
        volumeMounts:    
        - mountPath: /cache      
          name: cache-volume  
      - image: habor-repo.com/library/busybox:v1
        command: ["/bin/sh", "-c", "sleep 3600s;"]
        name: busybox    
        volumeMounts:    
        - mountPath: /cache      
          name: cache-volume  
      volumes:  
      - name: cache-volume 
        emptyDir: {}
    
    kubectl create -f emptydir.yml
    kubectl get pod 
    kubectl describe pod test-pd
    kubectl exec test-pd -c nginx -it -- /bin/bash
    # date > /cache/a.txt 
    kubectl exec test-pd -c nginx -it -- cat /cache/a.txt
    # 查看另外一个 
    kubectl exec test-pd -c busybox -it -- cat /cache/a.txt
    
    

    hostPath

    hostPath卷将主机节点的文件系统中的文件或目录挂载到集群中

    • hostPath的用途如下:运行需要访问 Docker 内部的容器;使用/var/lib/docker的hostPath
    • 在容器中运行 cAdvisor;使用/dev/cgroups的hostPath允许 pod 指定给定的 hostPath 是否应该在 pod
    • 运行之前存在,是否应该创建,以及它应该以什么形式存在

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

    行为
    空字符串(默认)用于向后兼容,这意味着在挂载 hostPath 卷之前不会执行任何检查。
    DirectoryOrCreate 如果在给定的路径上没有任何东西存在,那么将根据需要在那里创建一个空目录,权限设置为 0755,与 Kubelet 具有相同的组和所有权。
    Directory 给定的路径下必须存在目录
    FileOrCreate 如果在给定的路径上没有任何东西存在,那么会根据需要创建一个空文件,权限设置为 0644,与 Kubelet 具有相同的组和所有权。
    File 给定的路径下必须存在文件
    Socket 给定的路径下必须存在 UNIX 套接字
    CharDevice 给定的路径下必须存在字符设备
    BlockDevice 给定的路径下必须存在块设备

    使用这种卷类型是请注意,因为:

    • 由于每个节点上的文件都不同,具有相同配置(例如从 podTemplate 创建的)的 pod 在不同节点上的行为可能会有所不同
    • 当 Kubernetes 按照计划添加资源感知调度时,将无法考虑hostPath使用的资源
    • 在底层主机上创建的文件或目录只能由 root 写入。您需要在特权容器中以 root 身份运行进程,或修改主机上的文件权限以便写入hostPath卷

    vim hostpath.yml

    apiVersion: v1
    kind: Pod
    metadata:  
      name: test-pd2
    spec: 
      containers:
      - image: habor-repo.com/library/nginx:v1
        name: nginx
        volumeMounts:    
        - mountPath: /cache      
          name: cache-volume  
      - image: habor-repo.com/library/busybox:v1
        command: ["/bin/sh", "-c", "sleep 3600s;"]
        name: busybox    
        volumeMounts:    
        - mountPath: /cache      
          name: cache-volume  
      volumes:  
      - name: cache-volume 
        hostPath: 
          path: /data # 本地路径
          type: Directory # 目录
    
    # 在所有节点上创建 /data 目录
    mkdir /data
    kubectl create -f hostpath.yml
    kubectl get pod -o wide 
    # 假设在 k8s-node2 节点上
    # date >/data/a.txt
    
    kubectl exec test-pd2 -c nginx -it -- cat /cache/a.txt
    # 查看另外一个 
    kubectl exec test-pd2 -c busybox -it -- cat /cache/a.txt
    
    # 发现有内容
    

    4.6.4、PV&PVC

    概念

    PersistentVolume(PV)

    是由管理员设置的存储,它是群集的一部分。就像节点是集群中的资源一样,PV 也是集群中的资源。 PV 是Volume 之类的卷插件,但具有独立于使用 PV 的 Pod 的生命周期。此 API 对象包含存储实现的细节,即 NFS、iSCSI 或特定于云供应商的存储系统

    PersistentVolumeClaim(PVC)

    是用户存储的请求。它与 Pod 相似。Pod 消耗节点资源,PVC 消耗 PV 资源。Pod 可以请求特定级别的资源(CPU 和内存)。声明可以请求特定的大小和访问模式(例如,可以以读/写一次或只读多次模式挂载)

    • 静态 pv

      • 集群管理员创建一些 PV。它们带有可供群集用户使用的实际存储的细节。它们存在于 Kubernetes API 中,可用于消费
    • 动态

      • 当管理员创建的静态 PV 都不匹配用户的PersistentVolumeClaim时,集群可能会尝试动态地为 PVC 创建卷。此配置基于StorageClasses:PVC 必须请求 [存储类],并且管理员必须创建并配置该类才能进行动态创建。声明该类为""可以有效地禁用其动态配置
      • 要启用基于存储级别的动态存储配置,集群管理员需要启用 API server 上的DefaultStorageClass[准入控制器]。例如,通过确保DefaultStorageClass位于 API server 组件的--admission-control标志,使用逗号分隔的有序值列表中,可以完成此操作
    • 绑定

      • master 中的控制环路监视新的 PVC,寻找匹配的 PV(如果可能),并将它们绑定在一起。如果为新的 PVC 动态调配 PV,则该环路将始终将该 PV 绑定到 PVC。否则,用户总会得到他们所请求的存储,但是容量可能超出要求的数量。一旦 PV 和 PVC 绑定后,PersistentVolumeClaim绑定是排他性的,不管它们是如何绑定的。 PVC 跟PV 绑定是一对一的映射

    持久化卷声明的保护

    PVC 保护的目的是确保由 pod 正在使用的 PVC 不会从系统中移除,因为如果被移除的话可能会导致数据丢失当启用PVC 保护 alpha 功能时,如果用户删除了一个 pod 正在使用的 PVC,则该 PVC 不会被立即删除。PVC 的删除将被推迟,直到 PVC 不再被任何 pod 使用

    PersistentVolume类型以插件形式实现。Kubernetes 目前支持以下插件类型:

    • GCEPersistentDisk、AWSElasticBlockStore、AzureFile、AzureDisk、FC (Fibre Channel)
    • FlexVolume、Flocker、NFS、iSCSI、RBD (Ceph Block Device)、CephFS
    • Cinder (OpenStack block storage)、Glusterfs、VsphereVolume、Quobyte Volumes
    • HostPath、 VMware Photon、Portworx Volumes、ScaleIO Volumes、StorageOS

    PV 访问模式

    PersistentVolume可以以资源提供者支持的任何方式挂载到主机上。如下表所示,供应商具有不同的功能,每个PV 的访问模式都将被设置为该卷支持的特定模式。例如,NFS 可以支持多个读/写客户端,但特定的 NFS PV 可能以只读方式导出到服务器上。每个 PV 都有一套自己的用来描述特定功能的访问模式:

    • ReadWriteOnce——该卷可以被单个节点以读/写模式挂载
    • ReadOnlyMany——该卷可以被多个节点以只读模式挂载
    • ReadWriteMany——该卷可以被多个节点以读/写模式挂载

    在命令行中,访问模式缩写为:

    • RWO - ReadWriteOnce

    • ROX - ReadOnlyMany

    • RWX - ReadWriteMany

    Volume 插件 ReadWriteOnce ReadOnlyMany ReadWriteMany
    AWSElasticBlockStoreAWSElasticBlockStore - -
    AzureFile
    AzureDisk - -
    CephFS
    Cinder - -
    FC -
    FlexVolume -
    Flocker - -
    GCEPersistentDisk -
    Glusterfs
    HostPath - -
    iSCSI -
    PhotonPersistentDisk - -
    Quobyte
    NFS
    RBD -
    VsphereVolume - - (pod 并列时有效)
    PortworxVolume -
    ScaleIO -
    StorageOS - -

    回收策略

    • Retain(保留)——手动回收
    • Recycle(回收)——基本擦除(rm -rf /thevolume/*)
    • Delete(删除)——关联的存储资产(例如 AWS EBS、GCE PD、Azure Disk 和 OpenStack Cinder 卷)将被删除

    当前,只有 NFS 和 HostPath 支持回收策略。AWS EBS、GCE PD、Azure Disk 和 Cinder 卷支持删除策略

    状态

    卷可以处于以下的某种状态:

    • Available(可用):一块空闲资源还没有被任何声明绑定
    • Bound(已绑定):卷已经被声明绑定
    • Released(已释放):声明被删除,但是资源还未被集群重新声明
    • Failed(失败):该卷的自动回收失败

    命令行会显示绑定到 PV 的 PVC 的名称

    例子

    安装nfs

    1)NFS 服务主要进程:

    • rpc.nfsd:最主要的 NFS 进程,管理客户端是否可登录
    • rpc.mountd:挂载和卸载 NFS 文件系统,包括权限管理
    • rpc.lockd:非必要,管理文件锁,避免同时写出错
    • rpc.statd:非必要,检查文件一致性,可修复文件

    2)关键工具

    • 主要配置文件:/etc/exports
    • NFS 文件系统维护命令:/usr/bin/exportfs
    • 共享资源的日志文件:/var/lib/nfs/*tab
    • 客户端查询共享资源命令:/usr/sbin/showmount
    • 端口配置:/etc/sysconfig/nfs

    3)NFS 服务端配置

    在 NFS 服务器端的主要配置文件为 /etc/exports 时,通过此配置文件可以设置共享文件目录。每条配置记录由 NFS 共享目录、NFS 客户端地址和参数这 3 部分组成,格式如下:

    [NFS 共享目录] [NFS 客户端地址 1 (参数 1, 参数 2, 参数 3……)] [客户端地址 2 (参数 1, 参数 2, 参数 3……)]
    
    • NFS 共享目录:服务器上共享出去的文件目录
    • NFS 客户端地址:允许其访问的 NFS 服务器的客户端地址,可以是客户端 IP 地址,也可以是一个网段 (192.168.141.0/24)
    • 访问参数:括号中逗号分隔项,主要是一些权限选项

    3.1)访问权限参数:

    • ro:客户端对于共享文件目录为只读权限。默认
    • rw:客户端对于共享文件目录具有读写权限

    3.2)用户映射参数

    • root_squash:使客户端使用 root 账户访冋时,服务器映射为服务器本地的匿名账号
    • no_root_squash:客户端连接服务端时如果使用的是 root,那么也拥有对服务端分享的目录的 root 权限
    • all_squash:将所有客户端用户请求映射到匿名用户或用户组(nfsnobody)
    • no_all_squash:与上相反。默认
    • anonuid=xxx:将远程访问的所有用户都映射为匿名用户,并指定该用户为本地用户(UID=xxx)
    • anongid=xxx:将远程访问的所有用户组都映射为匿名用户组账户,并指定该匿名用户组账户为本地用户组账户(GUI=xxx)

    3.3)其它配置参数

    • sync:同步写操作,数据写入存储设备后返回成功信息。默认
    • async:异步写提作,数据在未完全写入存储设备前就返回成功信息,实际还在内存
    • wdelay:延迟写入选项,将多个写提请求合并后写入硬盘,减少 I/O 次数, NFS 非正常关闭数据可能丢失。默认
    • no_wdelay:与上相反,不与 async 同时生效,如果 NFS 服务器主要收到小且不相关的请求,该选项实际会降低性能
    • subtree:若输出目录是一个子目录,则 NFS 服务器将检查其父目录的权限。默认
    • no_subtree:即使输出目录是一个子目录, NFS 服务器也不检查其父目录的权限,这样可以提高效率
    • secure:限制客户端只能从小于 1024 的 TCP/IP 端口连接 NFS 服务器。默认
    • insecure:允许客户端从大于 1024 的 TCP/IP 端口连接服务器

    4)安装:

    #创建一个目录作为共享文件目录
    mkdir -p /usr/local/kubernetes/volumes
    
    #给目录增加读写权限
    chmod a+rw /usr/local/kubernetes/volumes
    
    #**************** 安装 NFS 服务端 *******************
    rpm -qa nfs-utils rpcbind
    yum install -y nfs-utils rpcbind
    systemctl start rpcbind #启动rpc服务 
    systemctl status rpcbind #查看rpc服务状态 
    systemctl start nfs #启动nfs服务 
    systemctl status nfs #查看nfs服务状态 
    # 注意:必须要先启动rpc服务,然后再启动NFS服务,如果先启动NFS服务,启动服务时会失败
    # 检查开机是否自启动
    # 1). chkconfig 配置开机自启动
    chkconfig nfs on 
    chkconfig rpcbind on 
    chkconfig --list nfs 
    #nfs  0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭 
    chkconfig --list rpcbind 
    #rpcbind 0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭 
    # 2). /etc/rc.local 配置开机自启动
    vim /etc/rc.local # 添加下面两行
    systemctl start rpcbind
    systemctl start nfs
    
    #**************** 安装 NFS 客户端 *******************
    # 安装客户端,实际上和服务端一样的
    rpm -qa nfs-utils rpcbind
    yum install -y nfs-utils rpcbind
    systemctl start rpcbind #启动rpc服务 
    systemctl status rpcbind #查看rpc服务状态 
    systemctl start nfs #启动nfs服务 
    systemctl status nfs #查看nfs服务状态
    
    #**************** 分享目录 *******************
    mkdir -p /usr/local/kubernetes/volumes
    vi /etc/exports
    /usr/local/kubernetes/volumes *(rw,sync,no_subtree_check)
    # 说明:
    # /usr/local/kubernetes/volumes:作为服务目录向客户端开放
    # *:表示任何 IP 都可以访问
    # rw:读写权限
    # sync:同步权限
    # no_subtree_check:表示如果输出目录是一个子目录,NFS 服务器不检查其父目录的权限 /usr/local/kubernetes/volumes *(rw,sync,no_subtree_check)
    # 重启服务,使配置生效:
    systemctl restart nfs
    
    #**************** 客户端挂载分享目录 *******************
    # 创建挂载目录
    mkdir -p /usr/local/kubernetes/volumes-mount
    # 将服务端的目录挂载到本地
    mount 192.168.0.130:/usr/local/kubernetes/volumes /usr/local/kubernetes/volumes-mount
    #使用 df 查看挂载
    # 取消挂载
    umount /usr/local/kubernetes/volumes-mount
    
    测试

    创建PV

    vim pv.yml

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: nfs-pv-test
    spec:
      # 设置容量
      capacity:
        storage: 1Gi
      # 访问模式
      accessModes:
        # 该卷能够以读写模式被多个节点同时加载
        - ReadWriteMany
      # 回收策略,这里是基础擦除 `rm-rf/thevolume/*`
      persistentVolumeReclaimPolicy: Recycle
      storageClassName: nfs
      nfs:
        # NFS 服务端配置的路径
        path: "/usr/local/kubernetes/volumes"
        # NFS 服务端地址
        server: 192.168.0.130
        readOnly: false
    
    # 部署
    kubectl create -f pv.yml
    
    # 查看
    [root@k8s-master pv]# kubectl get pv
    NAME          CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
    nfs-pv-test   1Gi        RWX            Recycle          Available           nfs                     2s
    # 删除
    kubectl delete pv --all
    
    # 释放资源,删除对应的claimRef保存退出即可
    kubectl edit pv nfs-pv-test
    

    创建服务和PVC

    1)使用spec.template.volumeClaimTemplates定义pvc

    vim pvc.yml

    apiVersion: v1
    kind: Service
    metadata:
      name: svc-pvc-nginx
      labels:
        app: svc-pvc-nginx
    spec:
      selector:
        app: nginx
      ports:
      - name: web
        port: 8090
        targetPort: 80
      clusterIP: None # headless
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:  
      name: web
    spec:
      selector:
        matchLabels:
          app: nginx
      serviceName: svc-pvc-nginx
      replicas: 1 # 为什么给1因为上面创建了一个pv,但是pvc和是一一对应的关系,如果多了就会出问题
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: habor-repo.com/library/nginx:v1
            ports:
            - name: web
              containerPort: 80
            volumeMounts:
            - name: www
              mountPath: /usr/share/nginx/html
      volumeClaimTemplates:
      - metadata:
          name: www
        spec:
          #必须和要使用的pv的accessModes一致,根据accessModes和storageClassName去请求
          accessModes: ["ReadWriteMany"] 
          storageClassName: nfs
          resources:
            requests: # 请求使用资源
              #Ki、Mi、Gi、Ti、Pi、Ei(International System of units)
              #http://physics.nist.gov/cuu/Units/binary.html
              storage: 500Mi       
    
    kubectl apply -f pvc.yml
    kubectl get statefulset
    kubectl get pvc
    kubectl get pod
    
    # 测试
    # 进入 nfs 服务端的分享目录
    cd /usr/local/kubernetes/volumes
    date >index.html
    
    # 请求测试
    kubectl get pod -o wide
    [root@k8s-master pv]# kubectl get pod -o wide
    NAME    READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
    web-0   1/1     Running   0          33s   10.244.2.155   k8s-node2   <none>           <none>
    [root@k8s-master pv]# curl 10.244.2.155
    2020年 03月 08日 星期日 19:31:19 CST
    
    # 删除
    kubectl delete statefulset --all
    kubectl delete pvc --all
    kubectl delete pod --all
    

    2)使用PersistentVolume定义pvc

    vim pvc2.yml

    apiVersion: v1
    kind: Service
    metadata:
      name: svc-pvc-nginx
      labels:
        app: svc-pvc-nginx
    spec:
      selector:
        app: nginx
      ports:
      - name: web
        port: 8090
        targetPort: 80
      clusterIP: None # headless
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:  
      name: web
    spec:
      selector:
        matchLabels:
          app: nginx
      serviceName: svc-pvc-nginx
      replicas: 1 # 为什么给1因为上面创建了一个pv,但是pvc和是一一对应的关系,如果多了就会出问题
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: habor-repo.com/library/nginx:v1
            ports:
            - name: web
              containerPort: 80
            volumeMounts:
            - name: mypd
              mountPath: /usr/share/nginx/html
          volumes:
          - name: mypd
            persistentVolumeClaim:
              claimName: www
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: www
    spec:
      #必须和要使用的pv的accessModes一致,根据accessModes和storageClassName去请求
      accessModes: ["ReadWriteMany"] 
      storageClassName: nfs
      resources:
        requests:
          storage: 100Mi
    
    kubectl apply -f pvc2.yml
    kubectl get statefulset
    kubectl get pvc
    kubectl get pod
    
    # 测试
    # 进入 nfs 服务端的分享目录
    cd /usr/local/kubernetes/volumes
    date >>index.html
    
    # 请求测试
    kubectl get pod -o wide
    [root@k8s-master pv]# kubectl get pod -o wide
    NAME    READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
    web-0   1/1     Running   0          33s   10.244.2.155   k8s-node2   <none>           <none>
    [root@k8s-master pv]# curl 10.244.2.155
    2020年 03月 08日 星期日 19:31:19 CST
    2020年 03月 08日 星期日 20:00:38 CST
    
    # 删除
    kubectl delete statefulset --all
    kubectl delete pvc --all
    kubectl delete pod --all
    
  • 相关阅读:
    答《同样 25 岁,为什么有的人事业小成、家庭幸福,有的人却还在一无所有的起点上?》
    [面试记录-附部分面试题]2014第一波的找工作的记录
    项目总结(二)->一些常用的工具浅谈
    项目总结(一)->项目的七宗罪
    Android学习笔记(三)Application类简介
    Android学习笔记(二)Manifest文件节点详解
    Android学习笔记(一)Android应用程序的组成部分
    Mac下搭建Eclipse Android开发环境
    Android开发必知--自定义Toast提示
    正则表达式(一)
  • 原文地址:https://www.cnblogs.com/bartggg/p/13021377.html
Copyright © 2011-2022 走看看