• kubernetes 存储卷


                                       kubernetes 存储卷
    数据卷用于实现容器持久化数据,Kubernetes对于数据卷重新定义,提供了丰富强大的功能。
    在Kubernetes系统中,当Pod重建的时候,数据卷会丢失,Kubernetes也是通过数据卷来提供Pod数据的持久化的。Kubernetes数据卷是对Docker数据库的扩展,Kubernetes数据卷是Pod级别,可以用来实现Pod中容器的文件共享。

    通过命令查看支持的存储类型:kubectl explain pods.spec.volumes

    本地数据卷有2种:

    • emptyDir:临时目录
    • hostPath :使用宿主机主机的路径


    网络存储:

    • 传统的设备存储:NAS,SAN
    • 分布式存储:glusterfs,rbd,cephfs
    • 云存储:EBS,Azure,阿里云的

    一、emptyDir 的类型(容器数据共享)

    一个pod里面2个容器,挂载同一个目录。
    注意:emptyDir的生命周期同pod周期,简单来说,pod删除了,emptyDir也随之删除。

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-demo
      namespace: default
      labels:
        app: myapp
        tier: frontend
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80
        volumeMounts:  #容器挂载
        - name: html
          mountPath: /data/web/html/
      - name: busybox
        image: busybox:latest
        command: ["/bin/sh" ,"-c","sleep 3600"]
        volumeMounts:   #容器挂载
        - name: html
          mountPath: /data/
      volumes:     #定义存储
      - name: html
        emptyDir: {}
    

    进入busybox测试

    kubectl exec -it pod-demo -c busybox -- /bin/sh
    / # echo $(date) >>/data/index.html
    / # cat /data/index.html
    Sun Mar 17 08:20:03 UTC 2019
    进入myapp查看数据共享
    kubectl exec -it pod-demo -c myapp -- /bin/sh
    / # cat /data/web/html/index.html
    Sun Mar 17 08:20:03 UTC 2019
    

    二、hostPath 类型存储(访问宿主机数据)

    这种会把宿主机上的指定卷加载到容器之中,当然,如果 Pod 发生跨主机的重建,其内容就难保证了。

    这种卷一般和DaemonSet搭配使用,用来操作主机文件,例如进行日志采集的 FLK 中的 FluentD 就采用这种方式,加载主机的容器日志目录,达到收集本主机所有日志的目的。

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-volume
      namespace: default
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html/
      volumes:
      - name: html
        hostPath:
          path: /data/nginx/v1/      #目录会在节点上自动创建
          type: DirectoryOrCreate
    

    我们在节点的/data/nginx/html/创建一个文件

    [root@node01 html]# echo "hello nginx!!" >>/data/nginx/html/index.html
    [root@master volumes]# curl 172.17.8.7
    hello nginxll
    

     三、nfs 类型存储

    NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源。在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。

    首先要准备好nfs,我在192.168.247.144的机器上安装nfs,到处的目录为/nfs/data

    yum install nfs-utils -y
    
    vim /etc/exports  
    
    /data/volumes    192.168.247.0/16(rw,no_root_squash)   
    
    systemctl start nfs
    

    nfs准备好了,注意,在pod的节点机器要一定确定可以挂载nfs类型的,否则创建pod会出错。执行yum install nfs-utils -y 就可以挂载了

    nfs pod 的yaml文件:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-volume-nfs
      namespace: default
    spec:
      containers:
      - name: nginx-nfs
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html/
      volumes:
      - name: html
        nfs:
          path: /data/volumes
          server: 192.168.247.144
    

    nfs deployment的yaml文件,即多个副本同个存储。

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 2
      template:
        metadata:
          labels:
            app: web_server
        spec:
          containers:
          - name: nginx
            image: nginx
            ports:
            - containerPort: 80
            volumeMounts:
              - name: html
                mountPath: /usr/share/nginx/html/
          volumes:
            - name: html
              nfs:
                path: /fs01/nfs/html
                server: 172.31.182.154
    

    在nfs上添加测试文件

    [root@node volumes]# echo "hello nfs" >>/data/volumes/index.html
    [root@master volumes]# curl 172.17.8.7
    hello nfs
    

    四、pv,pvc的使用

    PersistentVolume 和 PersistentVolumeClaim 提供了对存储支持的抽象,也提供了基础设施和应用之间的分界,管理员创建一系列的 PV 提供存储,然后为应用提供 PVC,应用程序仅需要加载一个 PVC,就可以进行访问。
    对于pv和pvc,首先要准备存储的,我用的是nfs,在192.168.247.144的节点上划分了5个路径作为存储的设备。

    mkdir /data/volumes/{v1,v2,v3,v4,v5} -pv
    
    vim /etc/exports
    
    添加如下的内容:
    
    /data/volumes/v1 192.168.0.0/16(rw,no_root_squash)
    /data/volumes/v2 192.168.0.0/16(rw,no_root_squash)
    /data/volumes/v3 192.168.0.0/16(rw,no_root_squash)
    /data/volumes/v4 192.168.0.0/16(rw,no_root_squash)
    /data/volumes/v5 192.168.0.0/16(rw,no_root_squash)
    
    保存,导出下。
    
    exportfs -avr
    
    查看下是否正常。
    

    nfs的存储的好了。下一步要先创建pv,yaml文件如下

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv01
      labels:
        name: pv01
    spec:
      nfs:
        path: /data/v1/
        server: 192.168.247.144
      accessModes: ["ReadWriteOnce","ReadWriteMany"]
      capacity:
        storage: 5Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv02
      labels:
        name: pv02
    spec:
      nfs:
        path: /data/v2/
        server: 192.168.247.144
      accessModes: ["ReadWriteOnce","ReadWriteMany"]
      capacity:
        storage: 3Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv03
      labels:
        name: pv03
    spec:
      nfs:
        path: /data/v3/
        server: 192.168.247.144
      accessModes: ["ReadWriteOnce","ReadWriteMany"]
      capacity:
        storage: 5Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv04
      labels:
        name: pv04
    spec:
      nfs:
        path: /data/v4/
        server: 192.168.247.144
      accessModes: ["ReadWriteOnce","ReadWriteMany"]
      capacity:
        storage: 10Gi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv05
      labels:
        name: pv05
    spec:
      nfs:
        path: /data/v5/
        server: 192.168.247.144
      accessModes: ["ReadWriteOnce","ReadWriteMany"]
      capacity:
        storage: 10Gi
    

     #创建pv
     kubectl apply -f pv-nfs.yaml

    显示,pv创建完成

    接下来创建pvc和pod,yaml文件如下

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: mypvc
      namespace: default
    spec:
      accessModes: ["ReadWriteMany"]
      resources:
        requests:
          storage: 5Gi               #创建pvc的指定使用存储大小
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-volume-pvc
      namespace: default
    spec:
      containers:
      - name: nginx-pvc
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html/
      volumes:              
      - name: html
        persistentVolumeClaim:                  #指定pvc类型
          claimName: mypvc
    

    添加文件测试:

    [root@node v1]# echo "hello pvc01" >>index.html
    [root@master volumes]# curl 172.17.8.8
    hello pvc01
    

    显示pvc创建好了,同时pvc绑定了一个pv,到此pv和pvc的安装部署完成。

    ps:pv和pvc是一对一绑定的。但是多个pod可以挂载同一个pvc  

    通常使用的流程是,首先创建存储,在创建pv,接着创建pvc,pod挂载到相应的pvc。
    pv与pvc的完整生命周期:准备--绑定--使用--释放--回收
    存在问题,pvc申请时未必存在刚好符合需求的pv,因为设计了一种动态的申请pv叫StroageClass。
    不把配置写死在镜像中而是引入配置中心configMap
    configMap:明文

    配置容器化应用的方式:

        1、自定义命令行参数:
            args: []
        2、把配置文件直接配进镜像。
        3、环境变量
            (1)Cloud Mative的应用程序一般可直接通过环境变量加载配置;
            (2)通过entrypoint脚本来预处理变量为配置文件中的配置信息;
        4、存储卷
    

    configMap使用
    第一种方式:

    [root@master volumes]# kubectl create configmap nginx-config --from-literal=nginx_port=8080 --from-literal=server_name=myapp.com
    configmap/nginx-config created
    [root@master volumes]# kubectl get cm
    NAME           DATA      AGE
    nginx-config   2         9s
    [root@master volumes]# kubectl describe cm nginx-config
    Name:         nginx-config
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    
    Data
    ====
    nginx_port:
    ----
    8080
    server_name:
    ----
    myapp.com
    Events:  <none>
    

    第二种方式:

    [root@master configmap]# cat www.conf
    server {
        server_name myapp.com
        listen 80
        root /data/web/html/;
    }
    [root@master configmap]# kubectl create configmap nginx-www --from-file=./www.conf
    configmap/nginx-www created
    [root@master configmap]# kubectl get cm
    NAME           DATA      AGE
    nginx-config   2         4m
    nginx-www      1         8s
    [root@master configmap]# kubectl get cm nginx-www -o yaml
    apiVersion: v1
    data:
      www.conf: "server {
    	server_name myapp.com
    	listen 80
    	root /data/web/html/;
    }
    "
    kind: ConfigMap
    metadata:
      creationTimestamp: 2019-03-17T15:30:46Z
      name: nginx-www
      namespace: default
      resourceVersion: "276960"
      selfLink: /api/v1/namespaces/default/configmaps/nginx-www
      uid: a29267cb-48c9-11e9-9672-000c291e0db8
    

    创建pod

    [root@master configmap]# cat pod-configmap-demo.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-cm-1
      namespace: default
      labels:
        app: myapp
        tier: frontend
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80
        env:
        - name: NGINX_SERVER_PORT
          valueFrom:
            configMapKeyRef:
              name: nginx-config
              key:  nginx_port
        - name: NGINX_SERVER_NAME
          valueFrom:
            configMapKeyRef:
              name: nginx-config
              key: server_name
    
    [root@master configmap]# kubectl exec -it pod-cm-1 -- /bin/sh
    / # printenv
    MYAPP_SVC_PORT_80_TCP_ADDR=10.98.57.156
    KUBERNETES_SERVICE_PORT=443
    KUBERNETES_PORT=tcp://10.10.10.1:443
    MYAPP_SVC_PORT_80_TCP_PORT=80
    HOSTNAME=pod-cm-1
    SHLVL=1
    MYAPP_SVC_PORT_80_TCP_PROTO=tcp
    HOME=/root
    NGINX_SERVER_PORT=8080
    EUREKA_SERVICE_HOST=10.10.10.192
    NGINX_SERVER_NAME=myapp.com
    
    [root@master configmap]# cat pod-configmap-2.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-cm-2
      namespace: default
      labels:
        app: myapp
        tier: frontend
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80
        volumeMounts:
        - name: nginx-config
          mountPath: /etc/nginx/config.d/
          readOnly: true
      volumes:
      - name: nginx-config
        configMap:
          name: nginx-config
    






  • 相关阅读:
    macOS Sierra 如何打开任何来源
    centos 安装git服务器,配置使用证书登录并你用hook实现代码自动部署
    Linux下修改Mysql的用户(root)的密码
    mysql主从复制
    CentOS7下安装MySQL5.7安装与配置
    gulp安装和使用
    libiconv库的安装和使用
    Android 开发中常见的注意点
    扯一扯 C#委托和事件?策略模式?接口回调?
    Python 学习开篇
  • 原文地址:https://www.cnblogs.com/Dev0ps/p/10587598.html
Copyright © 2020-2023  润新知