ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

K8S 的 Volume

2020-09-23 02:00:47  阅读:250  来源: 互联网

标签:name Volume nfs test Pod K8S config metadata


K8S 有很多 Volume 类型

  • awsElasticBlockStore
  • azureDisk
  • azureFile
  • cephfs
  • cinder
  • configMap
  • csi
  • downwardAPI
  • emptyDir
  • fc (fibre channel)
  • flexVolume
  • flocker
  • gcePersistentDisk
  • gitRepo (deprecated)
  • glusterfs
  • hostPath
  • iscsi
  • local
  • nfs
  • persistentVolumeClaim
  • projected
  • portworxVolume
  • quobyte
  • rbd
  • scaleIO
  • secret
  • storageos
  • vsphereVolume

详细信息可以查看官网
https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumes

这里只介绍几种:emptyDir,local,hostPath,nfs,secret,configMap

emptyDir

初始化为空目录,只在 Pod 运行时存在,当 Pod 停止或死掉后,目录下的所有数据都会被删除(如果只是 Container 死掉数据不会被删除),可以被同一个 Pod 下的不同 Container 使用

emptyDir 主要用于某些应用程序无需永久保存的临时目录,在多个容器之间共享数据等场景

下面是一个简单的例子,将 emptyDir 的 volume 给 mount 到 /cache 目录

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}

缺省情况下,emptyDir 是在 Pod 运行的主机的文件系统上创建临时目录

此外也可以通过将 emptyDir.medium 设定为 "Memory" 从而使用内存作为文件系统,这种情况速度会比较快,但空间会比较小,而且如果主机重启数据会丢失

local

使 Volume 和 Pod 被分配到同一个 Node,实现数据的本地化,适合一些对读写磁盘数据要求比较高的,比如数据库

这种做法的风险是 Volume 和 Pod 都被绑定到固定的一个 Node (暂时不支持动态配置),一但这个 Node 出问题,会影响 Volume 和 Pod,可用性会降低

先创建一个 StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

这里 WaitForFirstConsumer 表示不要立即绑定 Volume,而是等到 Pod 调度的时候再绑定

创建 PV

apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv
spec:
  capacity:
    storage: 100Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /mnt/disks/ssd1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - example-node

这个 PV 使用 example-node 节点的 /mnt/disks/ssd1 目录,并且指定 StorageClass 为前面创建的 local-storage

创建 PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: example-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: local-storage

通过指定 storageClass 为前面创建的 local-storage,这样会等到 Pod 调度的时候再绑定 PVC 和 PV,确保能找到合适的 PV 使得 Volume 和 Pod 在同一个 Node 上

创建 Pod

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - cache-volume
    persistentVolumeClaim:
      claimName: example-pvc

等这个 Pod 创建的时候 example-pvc 再去绑定合适的 pv 使得 Pod 和 Volume 跑在同一个 Node

hostPath

把 Volume 挂到 host 主机的路径,这和 local 很像,但有区别

host 模式下 Pod 的运行节点是随机的,假设 Pod 第一次起来的时候是在 Node-A,这时会在 Node-A 创建目录挂到 Pod,如果后来 Pod crash 然后重启,可能会被分配到 Node-B,这时会在 Node-B 创建目录挂到 Pod,但是之前保存在 Node-A 的数据就丢失了

local 模式下 Pod 和创建的目录一直是在同一台主机上

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /data
      # this field is optional
      type: Directory

适用场景的例子,比如如果需要读取主机的系统路径 /sys,读取主机的 docker 信息 /var/lib/docker,这些都是固定路径,每台机都有,而且只关心本机的信息

nfs

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    nfs:
      path: /data
      server: 192.168.1.10

或者

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs
spec:
  capacity:
    storage: 1Mi
  accessModes:
    - ReadWriteMany
  nfs:
    server: nfs-server.default.svc.cluster.local
    path: "/data/volumes"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 1Mi
---
apiVersion: v1
kind: ReplicationController
metadata:
  name: nfs-busybox
spec:
  replicas: 2
  selector:
    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 $(($RANDOM % 5 + 5)); done'
        imagePullPolicy: IfNotPresent
        name: busybox
        volumeMounts:
          # name must match the volume name below
          - name: nfs
            mountPath: "/mnt"
      volumes:
      - name: nfs
        persistentVolumeClaim:
          claimName: nfs

最终相当于执行

mount -t nfs nfs-server.default.svc.cluster.local:/data/volumes /mnt

注意需要保证目标主机的 nfs 是配置好的,相应的路径是可以 mount 的

secret

---
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm
type: Opaque
---
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret

secret 里面定义的 username 和 password 是 base64 编码的
可以看到启动的容器里面的 /etc/foo 目录下会有两个文件,名字分别是 username 和 password,里面的内容被自动按 base64 解码了

secret 安全性

  • 实际上 secret 通过 kubectl get secret mysecret -o yaml 同样可以看到 username 和 password 的值,当然这应该可以配置权限,使得只有相应的帐号可以查询使用
  • secret 是写在容器的内存文件系统而不是磁盘文件系统,不会落盘增加安全性
  • secret 的内容通过 base64 编码存在 etcd 中,挂到容器时会被自动解码为明文

可以看到实际上比起 ConfigMap 安全性似乎没多大提升,base64 实际上很容易解码,或许以后会改进

真正要求安全性的话可以考虑用 Vault

ConfigMap

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-cfg
data:
  redis_host: "192.168.1.100"
  redis_port: "6379"
  config.json: |-
    {
        "Postgres": {
            "Host": "192.168.1.200",
            "Port": "5432"
        },
        "Kafka": {
            "Host": "192.168.1.10:9092",
            "From": "smallest"
        }
    }
  config.properties: |
    username = admin
    password = admin
---
apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod
spec:
  containers:
    - name: test
      image: busybox
      volumeMounts:
        - name: config-vol
          mountPath: /etc/config
  volumes:
    - name: config-vol
      configMap:
        name: test-cfg

启动后可以看到 config map 定义的所有配置项都变成 /etc/config 目录下的文件

也可以只挂载 config map 定义的部分配置项

apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod
spec:
  containers:
    - name: test
      image: busybox
      volumeMounts:
        - name: config-vol
          mountPath: /etc/config
      env:
        - name: MY_REDIS_HOST
          valueFrom:
            configMapKeyRef:
              name: test-cfg
              key: redis_host
  volumes:
    - name: config-vol
      configMap:
        name: test-cfg
        items:
           - key: config.properties
             path: path/to/my-config.properties
           - key: config.json
             path: config.json

启动后可以看到 /etc/config 目录下只有 config.json 文件
而 config.properties 被重命名并放到 /etc/config/path/to/my-config.properties
另外 redis_host 被作为环境变量配置了进去

通过 subPath 选取 config map 的配置

apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod
spec:
  containers:
    - name: test
      image: busybox
      volumeMounts:
        - name: config-vol
          mountPath: /etc/config/my-config.json
          subPath: config.json
  volumes:
    - name: config-vol
      configMap:
        name: test-cfg

这样会自动到 test-cfg 这个 config map 寻找 config.json 配置项,将其重命名并挂载到 /etc/config/my-config.json



标签:name,Volume,nfs,test,Pod,K8S,config,metadata
来源: https://www.cnblogs.com/moonlight-lin/p/13715817.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有