kubernetes-notes

1. volume概述

容器中的进程看到的是由其 Docker 镜像和卷组成的文件系统视图。

Pod volume的使用方式

Pod 中的每个容器都必须独立指定每个卷的挂载位置,需要给Pod配置volume相关参数。

Pod的volume关键字段如下:

2. volume类型

2.1. emptyDir

1、特点

2、使用场景

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: {}

2.2. hostPath

1、特点

2、使用场景

hostPath的type字段

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

注意事项

3、示例

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

2.2.1. 同步文件变化到容器内

hostPath的挂载方式可以挂载目录和文件两种格式,如果使用文件挂载的方式,通过简单的vi等命令修改宿主机的文件,并不会实时同步到容器内的映射文件。而需要对容器进行重启的操作才可以把文件的修改内容同步到文件中,但生产的容器一般不建议执行重启的操作。因此我们可以通过以下的方式来避免这个问题的发生。

以上文件不同步的本质原因是容器在初次挂载的时候使用了宿主机的文件的inode number进行标识,而vi等操作会导致文件的inode number发生变化,所以当宿主机文件的inode number发生变化,容器内并不会发生变化,为了保持文件内容一致,则需要保持修改文件的同时文件的inode number不变。那么我们可以使用 cat 或echo 命令覆盖文件的内容则inode number不会发生变化。

示例:

      containers:
        volumeMounts:
        - mountPath: /etc/hosts
          name: hosts
          readOnly: true
      volumes:
      - hostPath:
          path: /etc/hosts
          type: FileOrCreate
        name: hosts

例如,以上的案例是通过挂载宿主机的/etc/hosts文件来映射到容器,如果想修改宿主机的hosts文件来同步容器内的hosts文件,可以通过以下的方式:

# 查看文件的inode
ls -i /etc/hosts
39324780 /etc/hosts

# 追加记录
echo "1.1.1.1 xxx.com" >> /etc/hosts

# 替换内容
sed 's/1.1.1.1/2.2.2.2/g' /etc/hosts > temp.txt
cat temp.txt > /etc/hosts

# 查看宿主机和容器内的inode号都没有发生变化
# crictl exec -it 20891de31a4a6 sh
/var/www/html # ls -i /etc/hosts
39324780 /etc/hosts

2.3. configMap

configMap提供了一种给Pod注入配置文件的方式,配置文件内容存储在configMap对象中,如果Pod使用configMap作为volume的类型,需要先创建configMap的对象。

示例

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: log-config
        items:
          - key: log_level
            path: log_level

2.4. cephfs

cephfs的方式将Pod的存储挂载到ceph集群中,通过外部存储的方式持久化Pod的数据(即当Pod被删除数据仍可以存储在ceph集群中),前提是先部署和维护好一个ceph集群。

示例

apiVersion: v1
kind: Pod
metadata:
  name: cephfs
spec:
  containers:
  - name: cephfs-rw
    image: kubernetes/pause
    volumeMounts:
    - mountPath: "/mnt/cephfs"
      name: cephfs
  volumes:
  - name: cephfs
    cephfs:
      monitors:
      - 10.16.154.78:6789
      - 10.16.154.82:6789
      - 10.16.154.83:6789
      # by default the path is /, but you can override and mount a specific path of the filesystem by using the path attribute
      # path: /some/path/in/side/cephfs 
      user: admin
      secretFile: "/etc/ceph/admin.secret"
      readOnly: true

更多可参考 CephFS 示例。

2.5. nfs

nfs的方式类似cephfs,即将Pod数据存储到NFS集群中,具体可参考NFS示例。

2.6. persistentVolumeClaim

persistentVolumeClaim 卷用于将PersistentVolume挂载到容器中。PersistentVolumes 是在用户不知道特定云环境的细节的情况下“声明”持久化存储(例如 GCE PersistentDisk 或 iSCSI 卷)的一种方式。

参考文章: