Kubernetes 基于NFS的动态存储申请

部署nfs-provisioner external-storage-nfs

  1. 创建工作目录

    $ mkdir -p /opt/k8s/nfs/data
    
  2. 下载nfs-provisioner对应的镜像,上传到自己的私有镜像中
    $ docker pull fishchen/nfs-provisioner:v2.2.2
    $ docker tag fishchen/nfs-provisioner:v2.2.2 192.168.0.107/k8s/nfs-provisioner:v2.2.2
    $ docker push 192.168.0.107/k8s/nfs-provisioner:v2.2.2
    
  3. 编辑启动nfs-provisioner的deploy.yml文件
    $ cd /opt/k8s/nfs
    $ cat > deploy.yml << EOF
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: nfs-provisioner
    ---
    kind: Service
    apiVersion: v1
    metadata:
      name: nfs-provisioner
      labels:
        app: nfs-provisioner
    spec:
      ports:
        - name: nfs
          port: 2049
        - name: mountd
          port: 20048
        - name: rpcbind
          port: 111
        - name: rpcbind-udp
          port: 111
          protocol: UDP
      selector:
        app: nfs-provisioner
    ---
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: nfs-provisioner
    spec:
      selector:
        matchLabels:
          app: nfs-provisioner
      replicas: 1
      strategy:
        type: Recreate
      template:
        metadata:
          labels:
            app: nfs-provisioner
        spec:
          serviceAccount: nfs-provisioner
          containers:
            - name: nfs-provisioner
              image: 192.168.0.107/k8s/nfs-provisioner:v2.2.2
              ports:
                - name: nfs
                  containerPort: 2049
                - name: mountd
                  containerPort: 20048
                - name: rpcbind
                  containerPort: 111
                - name: rpcbind-udp
                  containerPort: 111
                  protocol: UDP
              securityContext:
                capabilities:
                  add:
                    - DAC_READ_SEARCH
                    - SYS_RESOURCE
              args:
                - "-provisioner=myprovisioner.kubernetes.io/nfs"
              env:
                - name: POD_IP
                  valueFrom:
                    fieldRef:
                      fieldPath: status.podIP
                - name: SERVICE_NAME
                  value: nfs-provisioner
                - name: POD_NAMESPACE
                  valueFrom:
                    fieldRef:
                      fieldPath: metadata.namespace
              imagePullPolicy: "IfNotPresent"
              volumeMounts:
                - name: export-volume
                  mountPath: /export
          volumes:
            - name: export-volume
              hostPath:
                path: /opt/k8s/nfs/data
    EOF
    
    • volumes.hostPath 指向刚创建的数据目录,作为nfs的export目录,此目录可以是任意的Linux目录
    • args: - "-myprovisioner.kubernetes.io/nfs" 指定provisioner的名称,要和后面创建的storeClass中的名称保持一致
  4. 编辑自动创建pv相关的rbac文件
    $ cd /opt/k8s/nfs
    $ cat > rbac.yml << EOF
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: nfs-provisioner-runner
    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"]
      - apiGroups: [""]
        resources: ["services", "endpoints"]
        verbs: ["get"]
      - apiGroups: ["extensions"]
        resources: ["podsecuritypolicies"]
        resourceNames: ["nfs-provisioner"]
        verbs: ["use"]
    ---
    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: run-nfs-provisioner
    subjects:
      - kind: ServiceAccount
        name: nfs-provisioner
         # replace with namespace where provisioner is deployed
        namespace: default
    roleRef:
      kind: ClusterRole
      name: nfs-provisioner-runner
      apiGroup: rbac.authorization.k8s.io
    ---
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: leader-locking-nfs-provisioner
    rules:
      - apiGroups: [""]
        resources: ["endpoints"]
        verbs: ["get", "list", "watch", "create", "update", "patch"]
    ---
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: leader-locking-nfs-provisioner
    subjects:
      - kind: ServiceAccount
        name: nfs-provisioner
        # replace with namespace where provisioner is deployed
        namespace: default
    roleRef:
      kind: Role
      name: leader-locking-nfs-provisioner
      apiGroup: rbac.authorization.k8s.io
    
    EOF
    
  5. 编辑创建StorageClass的启动文件
    $ cd /opt/k8s/nfs
    $ cat > class.yml << EOF
    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
      name: example-nfs
    provisioner: myprovisioner.kubernetes.io/nfs
    mountOptions:
      - vers=4.1
    EOF
    
    • provisioner 对应的值要和前面deployment.yml中配置的值一样
  6. 启动nfs-provisioner
    $ kubectl create -f deploy.yml -f rbac.yml -f class.yml
    

验证和使用nfs-provisioner

下面我们通过一个简单的例子来验证刚创建的nfs-provisioner,例子中主要包含两个应用,一个busyboxy和一个web,两个应用挂载同一个PVC,其中busybox负责向共享存储中写入内容,web应用读取共享存储中的内容,并展示到界面。

  1. 编辑创建PVC文件

    $ cd /opt/k8s/nfs
    $ cat > claim.yml << EOF
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: nfs
    storageClassName: example-nfs
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 100Mi
    EOF
    
    • storageClassName: 指定前面创建的StorageClass对应的名称
    • accessModes: ReadWriteMany 允许多个node进行挂载和read、write
    • 申请资源是100Mi
  2. 创建PVC,并检查是否能自动创建相应的pv
    $ kubectl create -f claim.yml
    $ kubectl get pvc
    NAME   STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    nfs    Bound    pvc-10a1a98c-2d0f-4324-8617-618cf03944fe   100Mi      RWX            example-nfs    11s
    $kubectl get pv
    NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM         STORAGECLASS   REASON   AGE
    pvc-10a1a98c-2d0f-4324-8617-618cf03944fe   100Mi      RWX            Delete           Bound    default/nfs   example-nfs             18s
    
    • 可以看到自动给我们创建了一个pv对应的名称是pvc-10a1a98c-2d0f-4324-8617-618cf03944fe,STORAGECLASS是example-nfs,对应的claim是default/nfs
  3. 启动一个busybox应用,通过挂载共享目录,向其中写入数据
    1. 编辑启动文件

      $ cd /opt/k8s/nfs
      $ cat > deploy-busybox.yml << EOF
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nfs-busybox
      spec:
        replicas: 1
        selector:
          matchLabels:
            name: nfs-busybox
        template:
          metadata:
            labels:
              name: nfs-busybox
          spec:
            containers:
            - image: busybox
              command:
                - sh
                - -c
                - 'while true; do date > /mnt/index.html; hostname >> /mnt/index.html; sleep 20; done'
              imagePullPolicy: IfNotPresent
              name: busybox
              volumeMounts:
                # name must match the volume name below
                - name: nfs
                  mountPath: "/mnt"
            volumes:
            - name: nfs
              persistentVolumeClaim:
                claimName: nfs
      EOF
      
      • volumes.persistentVolumeClaim.claimName 设定成刚创建的PVC
    2. 启动busybox
      $ cd /opt/k8s/nfs
      $ kubectl create -f deploy-busybox.yml
      

      查看是否在对应的pv下生成了index.html

      $ cd /opt/k8s/nfs
      $ ls data/pvc-10a1a98c-2d0f-4324-8617-618cf03944fe/
      index.html
      $ cat data/pvc-10a1a98c-2d0f-4324-8617-618cf03944fe/index.html
      Sun Mar  1 12:51:30 UTC 2020
      nfs-busybox-6b677d655f-qcg5c
      
      • 可以看到在对应的pv下生成了文件,也正确写入了内容
  4. 启动web应用(nginx),读取共享挂载中的内容
    1. 编辑启动文件

      $ cd /opt/k8s/nfs
      $ cat >deploy-web.yml << EOF
      apiVersion: v1
      kind: Service
      metadata:
        name: nfs-web
      spec:
        type: NodePort
        selector:
          role: web-frontend
        ports:
        - name: http
          port: 80
          targetPort: 80
          nodePort: 8086
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nfs-web
      spec:
        replicas: 2
        selector:
          matchLabels:
            role: web-frontend
        template:
          metadata:
            labels:
              role: web-frontend
          spec:
            containers:
            - name: web
              image: nginx:1.9.1
              ports:
                - name: web
                  containerPort: 80
              volumeMounts:
                  # name must match the volume name below
                  - name: nfs
                    mountPath: "/usr/share/nginx/html"
            volumes:
            - name: nfs
              persistentVolumeClaim:
                claimName: nfs
      EOF
      
      • volumes.persistentVolumeClaim.claimName 设定成刚创建的PVC
    2. 启动web程序
      $ cd /opt/k8s/nfs
      $ kubectl create -f deploy-web.yml
      
    3. 访问页面

      • 可以看到正确读取了内容,没过20秒,持续观察可发现界面的时间可以刷新

遇到问题

参照github上的步骤执行,启动PVC后无法创建pv,查看nfs-provisioner服务的日志,有出现错误:

error syncing claim "20eddcd8-1771-44dc-b185-b1225e060c9d": failed to provision volume with StorageClass "example-nfs": error getting NFS server IP for volume: service SERVICE_NAME=nfs-provisioner is not valid; check that it has for ports map[{111 TCP}:true {111 UDP}:true {2049 TCP}:true {20048 TCP}:true] exactly one endpoint, this pod's IP POD_IP=172.30.22.3

错误原因issues/1262,之后把错误中提到端口保留,其他端口号都去掉,正常

原文地址:https://www.cnblogs.com/gaofeng-henu/p/12392076.html

时间: 2024-07-31 18:59:06

Kubernetes 基于NFS的动态存储申请的相关文章

Kubernetes使用NFS作为共享存储

Kubernetes使用NFS作为共享存储 kubernetes管理的容器是封装的,有时候我们需要将容器运行的日志,放到本地来或是共享存储来,以防止容器宕掉,日志还在还可以分析问题.kubernetes的共享存储方案目前比较流行的一般是三个,分别是:nfs,Glusterfs和ceph. 前面写过一篇kubernetes使用GlusterFS的文章,如果有兴趣也可以去实践下:http://blog.51cto.com/passed/2139299 今天要讲的是kubernetes使用nfs作为共

kvm 静态迁移、基于nfs的动态迁移

参考<kvm 虚拟化技术,实战与原理解析> 迁移:迁移包含系统整体的迁移和某个工作负载的迁移,按照迁移的特性可以分为以下几类: 静态迁移(冷迁移):指迁移过程中明显有一段时间,客户机的服务不可用,它还可以分为两种,一种是完全关闭客户机后,将硬盘镜像复制到另外的宿主机再启动起来,这种不会保存客户机的工作负载状态: 还有一种并不完全关闭客户机而是暂停客户机,而后用快照之类的方式,把当前的状态做成快照,复制快照到新的宿主机上启动. 动态迁移(热迁移):是指保证客户机上应用服务正常运行的同时,完成迁移

k8s实践17:kubernetes对接nfs存储实现pvc动态按需创建分配绑定pv

1.开始前的想法.前面测试pv&&pvc的部署和简单配置应用,实现pod应用数据存储到pvc并且和pod解耦的目的.前面操作是全手动操作,手动创建pv,手动创建pvc,如果集群pod少,这样操作可以.假如集群有1000个以上的pod,每个pod都需要使用pvc存储数据,如果只能手动去一个个创建pv,pvc,工作量不可想像.如果可以创建pod的时候,创建pod的用户定义pvc,然后集群能够根据用户的pvc需求创建pv,实现动态的pv&&pvc创建分配.kubernetes支持

基于NFS共享存储实现KVM虚拟机动态迁移

基于NFS共享存储实现KVM虚拟机动态迁移 一:配置环境 二:安装相关的依赖包 三:实现NFS共享存储 四:KVM机配置相同的步骤 五:安装KVM01安装虚拟机 六:实现迁移  实验初始配置:所有主机关闭防火墙与selinux [[email protected] ~]# iptables -F [[email protected] ~]# systemctl stop firewalld [[email protected] ~]# systemctl disable firewalld [[

k8s存储数据持久化,emptyDir,hostPath,基于Nfs服务的PV,PVC

在docker和K8S中都存在容器是有生命周期的,因此数据卷可以实现数据持久化. 数据卷解决的主要问题: 1.数据持久性:当我们写入数据时,文件都是暂时性的存在,当容器崩溃后,host就会将这个容器杀死,然后重新从镜像创建容器,数据就会丢失. 2.数据共享:在同一个Pod中运行容器,会存在共享文件的需求. 数据卷的类型: 1.emptyDiremptyDir数据卷类似于docker数据持久化的docker manager volume,该数据卷初分配时,是一个空目录,同一个Pod中的容器可以对该

LVS-NAT基于NFS存储部署Discuz

LVS (Linux Virtual Server) :Linux虚拟服务器.主要用于负载均衡场景,解决单节点服务器的压力,提高了容灾能力 LVS根据实现的方式不同分为:LVS-Nat.LVS-Dr.LVS-Tun.LVS-Fullnat LVS-nat特点: 1.调度器director配置双网卡,一块配置外部网络IP为VIP,另外一块网卡为DIP,必须和后端服务器RS的RIP在同一网络中,并且RIP的Gateway必须指向DIP 2.请求报文和响应报文都通过Director,因此,如果在较高的

Kubernetes 1.11.2使用NFS作为共享存储

环境:NFS服务器: 192.168.0.252 /data/nfs Kubernetes Master: 192.168.0.210Kubernetes Node: 192.168.0.211Kubernetes Node: 192.168.0.212 本地我们使用NFS作为Nginx的网站目录,使所有的pod共享一套代码 1.NFS服务器搭建 yum -y install nfs-utils 创建共享目录mkdir -p /data/nfs 修改配置文件vim /etc/exports/da

Longhorn:实现Kubernetes集群的持久化存储

Longhorn项目是Rancher Labs推出的开源的基于云和容器部署的分布式块存储新方式.Longhorn遵循微服务的原则,利用容器将小型独立组件构建为分布式块存储,并使用容器编排来协调这些组件,形成弹性分布式系统. 自2017年4月Longhorn项目发布以来,人们对在Kubernetes集群上运行Longhorn存储就产生了极大的兴趣.近日,Longhorn v0.2版本发布了,它可支持任何Kubernetes集群的持久化存储实现! Why Longhorn 如今,基于云和容器的部署规

LAMP平台扩展:基于NFS服务实现博客站点负载均衡

nfs简介: nfs:Network File System,网络文件系统:是一种分布式文件系统协议,最初由Sun公司开发.其功能旨在允许客户端主机可以像访问本地存储一样通过网络访问服务器端文件. NFS和其他许多协议一样,是基于RPC协议实现的. rpc:Remote Procedure Call,远程过程调用:是一个计算机通信协议.该协议允许运行于一台计算机的程序调用另一台计算机的子程序.调用远程主机上的函数,一部分功能由本地程序,另一部分功能由远程主机上的函数完成. rpcbind:RPC